Skip to content

Commit b72e8f0

Browse files
committed
Consensus and mempool parts of segwit-light.
This implements "segwit-light" in the node (consensus and mempool): After activation of a new fork, outputs created by new transactions are referred to by the creating transaction's bare txid rather than the normal hash (txid). This makes chains of constructed transactions immune to transaction malleability. In the mempool, we use the current chain tip to determine the activation state of the fork, as we can't know for sure when a transaction will be confirmed (and thus what activation state will be in effect then). This will lead to issues right around the fork activation time, but we will simply disallow spending of unconfirmed outputs in the mempool and wallet "around" the fork time temporarily to resolve this. The wallet is also not yet updated to take the change into account when selecting coins.
1 parent 3be481d commit b72e8f0

File tree

9 files changed

+45
-10
lines changed

9 files changed

+45
-10
lines changed

divi/src/ActiveChainManager.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <chain.h>
66
#include <coins.h>
77
#include <BlockUndo.h>
8+
#include <ForkActivation.h>
89
#include <Logging.h>
910
#include <addressindex.h>
1011
#include <txdb.h>
@@ -87,7 +88,8 @@ bool ActiveChainManager::DisconnectBlock(
8788
return error("DisconnectBlock() : block and undo data inconsistent");
8889
}
8990

90-
const BlockUtxoHasher utxoHasher;
91+
const ActivationState as(pindex);
92+
const BlockUtxoHasher utxoHasher(as);
9193

9294
bool fClean = true;
9395
IndexDatabaseUpdates indexDBUpdates;

divi/src/ForkActivation.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ const std::unordered_map<Fork, int64_t,std::hash<int>> ACTIVATION_TIMES = {
2525
{Fork::TestByTimestamp, 1000000000},
2626
{Fork::HardenedStakeModifier, unixTimestampForDec31stMidnight},
2727
{Fork::UniformLotteryWinners, unixTimestampForDec31stMidnight},
28+
/* FIXME: Set real activation time for segwit light. It is after
29+
staking vaults. */
30+
{Fork::SegwitLight, 2000000000},
2831
};
2932

3033
} // anonymous namespace
3134

3235
ActivationState::ActivationState(const CBlockIndex* pi)
33-
: nTime(pi->nTime)
36+
: nTime(pi == nullptr ? 0 : pi->nTime)
3437
{}
3538

3639
ActivationState::ActivationState(const CBlockHeader& block)

divi/src/ForkActivation.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,18 @@ class CBlockIndex;
1818
*/
1919
enum Fork
2020
{
21-
/* Test forks not actually deployed / active but used for unit tests. */
22-
TestByTimestamp,
2321
HardenedStakeModifier,
2422
UniformLotteryWinners,
23+
24+
/**
25+
* Start of "segwit light": The UTXOs created by transactions from after
26+
* the fork will be indexed by a "bare txid", which does not include
27+
* any signature data. This fixes transaction malleability.
28+
*/
29+
SegwitLight,
30+
31+
/* Test forks not actually deployed / active but used for unit tests. */
32+
TestByTimestamp,
2533
};
2634

2735
/**

divi/src/UtxoCheckingAndUpdating.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <UtxoCheckingAndUpdating.h>
22

3+
#include <ForkActivation.h>
34
#include <primitives/transaction.h>
45
#include <Logging.h>
56
#include <coins.h>
@@ -16,6 +17,8 @@ extern BlockMap mapBlockIndex;
1617

1718
OutputHash BlockUtxoHasher::GetUtxoHash(const CTransaction& tx) const
1819
{
20+
if (as.IsActive(Fork::SegwitLight))
21+
return OutputHash(tx.GetBareTxid());
1922
return OutputHash(tx.GetHash());
2023
}
2124

divi/src/UtxoCheckingAndUpdating.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <amount.h>
88
#include <uint256.h>
99

10+
class ActivationState;
1011
class CTransaction;
1112
class CValidationState;
1213
class CCoinsViewCache;
@@ -55,8 +56,17 @@ class TransactionUtxoHasher
5556
class BlockUtxoHasher : public TransactionUtxoHasher
5657
{
5758

59+
private:
60+
61+
/** The activation state used for checking on segwit light. */
62+
const ActivationState& as;
63+
5864
public:
5965

66+
explicit BlockUtxoHasher(const ActivationState& a)
67+
: as(a)
68+
{}
69+
6070
OutputHash GetUtxoHash(const CTransaction& tx) const override;
6171

6272
};

divi/src/main.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "coins.h"
2222
#include <defaultValues.h>
2323
#include "FeeRate.h"
24+
#include "ForkActivation.h"
2425
#include "init.h"
2526
#include "kernel.h"
2627
#include "libzerocoin/bignum.h"
@@ -1074,7 +1075,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
10741075
LogWalletBalance();
10751076
static const CChainParams& chainParameters = Params();
10761077

1077-
const BlockUtxoHasher utxoHasher;
1078+
const ActivationState as(block);
1079+
const BlockUtxoHasher utxoHasher(as);
10781080

10791081
VerifyBestBlockIsAtPreviousBlock(pindex,view);
10801082
if (block.GetHash() == Params().HashGenesisBlock())
@@ -2346,7 +2348,8 @@ bool static LoadBlockIndexDB(string& strError)
23462348
strError = "The wallet has been not been closed gracefully and has caused corruption of blocks stored to disk. Data directory is in an unusable state";
23472349
return false;
23482350
}
2349-
const BlockUtxoHasher utxoHasher;
2351+
const ActivationState as(block);
2352+
const BlockUtxoHasher utxoHasher(as);
23502353

23512354
std::vector<CTxUndo> vtxundo;
23522355
vtxundo.reserve(block.vtx.size() - 1);

divi/src/rpcblockchain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ Value gettxout(const Array& params, bool fHelp)
415415
"gettxout \"txid\" n ( includemempool )\n"
416416
"\nReturns details about an unspent transaction output.\n"
417417
"\nArguments:\n"
418-
"1. \"txid\" (string, required) The transaction id\n"
418+
"1. \"txid\" (string, required) The transaction id or bare txid (after segwit-light)\n"
419419
"2. n (numeric, required) vout value\n"
420420
"3. includemempool (boolean, optional) Whether to included the mem pool\n"
421421
"\nResult:\n"

divi/src/test/wallet_coinmanagement_tests.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,7 @@ BOOST_AUTO_TEST_CASE(willUseUtxoHashForSpendingCoins)
453453
wallet.FakeAddToChain(wtx);
454454

455455
const CScript sendTo = CScript() << OP_TRUE;
456-
std::string strError;
457456
CReserveKey reserveKey(wallet);
458-
CAmount nFeeRequired;
459457
CWalletTx wtxNew;
460458
BOOST_CHECK(wallet.CreateTransaction({{sendTo, COIN / 10}}, wtxNew, reserveKey, ALL_SPENDABLE_COINS, nullptr).second);
461459

divi/src/txmempool.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "txmempool.h"
88

99
#include "clientversion.h"
10+
#include "ForkActivation.h"
1011
#include "main.h"
1112
#include "streams.h"
1213
#include "Logging.h"
@@ -363,14 +364,21 @@ class CMinerPolicyEstimator
363364
namespace
364365
{
365366

366-
/** The UTXO hasher used in mempool logic. */
367+
/** The UTXO hasher used in mempool logic. It uses the state of segwit-light
368+
* based on the latest chain tip (since we can't know when a particular
369+
* transaction will be confirmed / what the real activation state will be then).
370+
* Spending of unconfirmed change around the fork will be discouraged by
371+
* policy, so that this should not be an issue in practice. */
367372
class MempoolUtxoHasher : public TransactionUtxoHasher
368373
{
369374

370375
public:
371376

372377
OutputHash GetUtxoHash(const CTransaction& tx) const override
373378
{
379+
const ActivationState as(chainActive.Tip());
380+
if (as.IsActive(Fork::SegwitLight))
381+
return OutputHash(tx.GetBareTxid());
374382
return OutputHash(tx.GetHash());
375383
}
376384

0 commit comments

Comments
 (0)