Skip to content

Commit 5b2fe55

Browse files
committed
Merge #642: Dynamic federations
f7905d6 Generalize the number of epochs old a peg-in can be and still be valid (Gregory Sanders) b105ff4 feature_fedpeg.py: Run in various dynafed transition settings (Gregory Sanders) feef196 Fix compilation of raw transaction operations with peg-in inputs (Gregory Sanders) 953dd82 p2sh-wrap peg-in addresses if fedpeg_program is p2sh-wrapped (Gregory Sanders) e2be235 Refactor IsPAKValid to not magically acquire chainparams (Gregory Sanders) ecdefc5 Remove script/standard dependence of ContextualCheckDynaFedHeader (Gregory Sanders) 59bed57 Remove dyanfed.cpp's dependency on script/standard.h (Gregory Sanders) 50a2b59 After a reorg, boot all peg-ins and peg-outs from mempool (Gregory Sanders) 6000752 Enforce PAK checks on dynafed proposals (Gregory Sanders) dce4cec Replace fedpeg template init check for pak one (Gregory Sanders) afdf023 Update python test framework for DynaFedParamEntry fedpeg program (Gregory Sanders) 95d8339 Add functional test for illegal proposals (Gregory Sanders) 1baad6b Update dynafed functional test to new behavior (Gregory Sanders) a3cf151 fixup proposal checks (Gregory Sanders) 04cc767 getnewblockhex fills out proposal fedpeg program (Gregory Sanders) 44f55d3 Make future parent segwit versions in fedpegscripts be vacuously true (Gregory Sanders) d7faffd Add dynafed proposal restrictions (Gregory Sanders) 37f90ba Add description of NextBlockIsParameterTransition (Gregory Sanders) d9387cb Remove misleading comment for ContextualCheckDynaFedHeader use (Gregory Sanders) bd11097 Add fedpeg_program field in dynafed header (Gregory Sanders) 4ad2b80 CreatePAKListFromExtensionSpace just uses FromBytes for correctness (Gregory Sanders) 6a5eaa1 Remove short-circuit dynafed vote fail for readability (Gregory Sanders) dddc040 s/m_dyna_params/m_dynafed_params/ (Gregory Sanders) 6ed63c1 Light explanation of dynamic federations fields (Gregory Sanders) 1599638 s/ConsensusParamEntry/DynaFedParamEntry/ (Gregory Sanders) 642260a s/m_sbs_wit_limit/m_signblock_witness_limit/ (Gregory Sanders) b668046 s/HF_MASK/DYNAFED_HF_MASK/ (Gregory Sanders) 0fd39ed s/d_params/dynafed_params/ (Gregory Sanders) 1779956 signrawtransaction* should use up to date fedpegscript for peg-in signing (Gregory Sanders) 47db75e Dynafed RPC support, tests, and deployment for custom chains (Gregory Sanders) aac354b OP_TRUE outputs should be allowed to be segwit-ified by decodescript (Gregory Sanders) 055514b Have removeForBlock boot transactions when required (Gregory Sanders) 525b24c Expose fedpeg fetching to consensus and mempool internals (Gregory Sanders) 4ac437b GetTransactionSigOpCost shouldn't need fedpegscript to evaluate (Gregory Sanders) 5097c38 Add and update startup args for dynafed (Gregory Sanders) 24535d6 Add unused dynamic genesis block style in chainparams (Gregory Sanders) d10c42a Create epoch length chainparam (Gregory Sanders) b996a42 Set default of multi_data_permitted to enforce_pak (Gregory Sanders) f6f6308 Correct comment about liquidv1 fedpeg matching template (Gregory Sanders) 4c00eb4 Miner should stop trying to account for old PAK system (Gregory Sanders) 0e10287 Add miner ability to make dynafed blocks (Gregory Sanders) 5d281e7 ContextualCheckBlockHeader: dynafed doesn't call CheckChallenge (Gregory Sanders) 9fe43cd Introduce contextual block checks for dynafed (Gregory Sanders) 3605505 Enable pak enforcement at mempool/block level when appropriate (Gregory Sanders) 802a055 ScriptHasValidPAKProof takes fedpeg as arg (Gregory Sanders) 89174e9 Remove old mempool-booting logic (Gregory Sanders) edb865c Remove standardness checks for PAK (Gregory Sanders) 804cd9f Update PAK internals, helper functions (Gregory Sanders) 16b87ba Disable PAK loading from configuration on init, disable pak test (Gregory Sanders) 918896d Add inactive versionbits dynafed deployment (Gregory Sanders) 0a8565b ReadBlockFromDisk: do genesis block check before block proof check (Gregory Sanders) 6f0d924 Bump last old block version for versonbits due to elements (Gregory Sanders) 563cd93 Add python implementation of dynafed block serialization (Gregory Sanders) 8d3091b Deserialize merkle proofs without witness, which matters for dynafed (Gregory Sanders) 830f917 Add fedpegscript-fetching helper (Gregory Sanders) b56fe14 calculate_contract: remove most template checks and assert in preperation for dynafed (Gregory Sanders) fd63cee Add note on peg-in sigops (Gregory Sanders) f17d7de Add dynafed helper functions (Gregory Sanders) 4aa5f99 Refactor block_proof to support dynafed (Gregory Sanders) 4e52f2c Add dynamic federation blockheader fields to chaindb serialization (Gregory Sanders) a74accf Add dynamic federations blockheader serialization with HF bit (Gregory Sanders) 2845e78 Define dynamic federations primitives (Gregory Sanders) Pull request description: This is a proposal implementation of something myself and Andrew have been working on, to enable dynamic membership in the blocksigning set, fedpeg signing set, and under the same coordination mechanism, the PAK enforcement. At a really high level: 1) If 4/5 of last N(what we call an epoch length) blocks signal desire for a change in the parameters of the system, they are replaced with the proposed. These changes can be proposed/driven by `getnewblockhex`. 2) Once dynamic federations is active(versionbits deployment), signblockscripts can only be native segwit scripts, in other words, must be a version byte followed by the witness program. The blockheader now has a witness stack as well. 3) The fedpegscript of last N epochs are both allowed as a grace period for users putting money into the system. 4) PAK enforcement has been upgraded to consensus-enforcement once dynamic federations activates A design document is forthcoming. Tree-SHA512: 26c6e05c85adb77345d8d481f20e8095bc2f9e5ad7b9a8824008a056637af7c6e87e522b038a6c6c108889d60b2fd1d6ecbd3e0afe2b696579000d18b0f1ecad
2 parents 7c302d2 + f7905d6 commit 5b2fe55

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1898
-800
lines changed

src/Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ BITCOIN_CORE_H = \
134134
core_io.h \
135135
core_memusage.h \
136136
cuckoocache.h \
137+
dynafed.h \
137138
fs.h \
138139
httprpc.h \
139140
httpserver.h \
@@ -401,10 +402,13 @@ libbitcoin_consensus_a_SOURCES = \
401402
arith_uint256.cpp \
402403
arith_uint256.h \
403404
asset.cpp \
405+
chain.h \
406+
chain.cpp \
404407
consensus/merkle.cpp \
405408
consensus/merkle.h \
406409
consensus/params.h \
407410
consensus/validation.h \
411+
dynafed.cpp \
408412
hash.cpp \
409413
hash.h \
410414
prevector.h \

src/block_proof.cpp

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,18 @@ bool CheckChallenge(const CBlockHeader& block, const CBlockIndex& indexLast, con
1919
}
2020
}
2121

22-
void ResetChallenge(CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params& params)
22+
static bool CheckProofGeneric(const CBlockHeader& block, const uint32_t max_block_signature_size, const CScript& challenge, const CScript& scriptSig, const CScriptWitness& witness)
2323
{
24-
block.proof.challenge = indexLast.proof.challenge;
25-
}
26-
27-
static bool CheckProofGeneric(const CBlockHeader& block, const Consensus::Params& params, const CScript& challenge)
28-
{
29-
if (block.GetHash() == params.hashGenesisBlock)
30-
return true;
24+
// scriptSig or witness will be nonempty, but not both, so just compare both limits
25+
if (scriptSig.size() > max_block_signature_size) {
26+
return false;
27+
}
3128

32-
if (block.proof.solution.size() > params.max_block_signature_size) {
29+
if (witness.GetSerializedSize() > max_block_signature_size) {
3330
return false;
3431
}
3532

36-
// Some anti-DoS flags, though consensus.max_block_signature_size caps the possible
33+
// Some anti-DoS flags, though max_block_signature_size caps the possible
3734
// danger in malleation of the block witness data.
3835
unsigned int proof_flags = SCRIPT_VERIFY_P2SH // For cleanstack evalution under segwit flag
3936
| SCRIPT_VERIFY_STRICTENC // Minimally-sized DER sigs
@@ -42,26 +39,36 @@ static bool CheckProofGeneric(const CBlockHeader& block, const Consensus::Params
4239
| SCRIPT_VERIFY_MINIMALDATA // Pushes are minimally-sized
4340
| SCRIPT_VERIFY_SIGPUSHONLY // Witness is push-only
4441
| SCRIPT_VERIFY_LOW_S // Stop easiest signature fiddling
45-
| SCRIPT_VERIFY_WITNESS // Required for cleanstack eval in VerifyScript
42+
| SCRIPT_VERIFY_WITNESS // Witness and to enforce cleanstack
4643
| SCRIPT_NO_SIGHASH_BYTE; // non-Check(Multi)Sig signatures will not have sighash byte
47-
return GenericVerifyScript(block.proof.solution, challenge, proof_flags, block);
44+
return GenericVerifyScript(scriptSig, witness, challenge, proof_flags, block);
4845
}
4946

5047
bool CheckProof(const CBlockHeader& block, const Consensus::Params& params)
5148
{
5249
if (g_signed_blocks) {
53-
return CheckProofGeneric(block, params, params.signblockscript);
50+
const DynaFedParams& dynafed_params = block.m_dynafed_params;
51+
if (dynafed_params.IsNull()) {
52+
return CheckProofGeneric(block, params.max_block_signature_size, params.signblockscript, block.proof.solution, CScriptWitness());
53+
} else {
54+
return CheckProofGeneric(block, dynafed_params.m_current.m_signblock_witness_limit, dynafed_params.m_current.m_signblockscript, CScript(), block.m_signblock_witness);
55+
}
5456
} else {
5557
return CheckProofOfWork(block.GetHash(), block.nBits, params);
5658
}
5759
}
5860

5961
bool CheckProofSignedParent(const CBlockHeader& block, const Consensus::Params& params)
6062
{
61-
return CheckProofGeneric(block, params, params.parent_chain_signblockscript);
62-
}
63-
64-
void ResetProof(CBlockHeader& block)
65-
{
66-
block.proof.solution.clear();
63+
const DynaFedParams& dynafed_params = block.m_dynafed_params;
64+
if (dynafed_params.IsNull()) {
65+
return CheckProofGeneric(block, params.max_block_signature_size, params.parent_chain_signblockscript, block.proof.solution, CScriptWitness());
66+
} else {
67+
// Dynamic federations means we cannot validate the signer set
68+
// at least without tracking the parent chain more directly.
69+
// Note that we do not even serialize dynamic federation block witness data
70+
// currently for merkle proofs which is the only context in which
71+
// this function is currently used.
72+
return true;
73+
}
6774
}

src/block_proof.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ class CScript;
2020
/** Check on header proof, depending on chain type, PoW or signed **/
2121
bool CheckProof(const CBlockHeader& block, const Consensus::Params&);
2222
bool CheckProofSignedParent(const CBlockHeader& block, const Consensus::Params&);
23-
void ResetProof(CBlockHeader& block);
2423
bool CheckChallenge(const CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params&);
25-
void ResetChallenge(CBlockHeader& block, const CBlockIndex& indexLast, const Consensus::Params&);
2624

2725
#endif // BITCOIN_BLOCK_PROOF_H

src/chain.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ class CBlockIndex
221221
uint32_t nBits;
222222
uint32_t nNonce;
223223
CProof proof;
224+
// Dynamic federation fields
225+
DynaFedParams dynafed_params;
226+
CScriptWitness m_signblock_witness;
224227

225228
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
226229
int32_t nSequenceId;
@@ -250,6 +253,8 @@ class CBlockIndex
250253
nBits = 0;
251254
nNonce = 0;
252255
proof.SetNull();
256+
dynafed_params.SetNull();
257+
m_signblock_witness.SetNull();
253258
}
254259

255260
CBlockIndex()
@@ -267,6 +272,8 @@ class CBlockIndex
267272
nBits = block.nBits;
268273
nNonce = block.nNonce;
269274
proof = block.proof;
275+
dynafed_params = block.m_dynafed_params;
276+
m_signblock_witness = block.m_signblock_witness;
270277
}
271278

272279
CDiskBlockPos GetBlockPos() const {
@@ -301,6 +308,8 @@ class CBlockIndex
301308
block.nBits = nBits;
302309
block.nNonce = nNonce;
303310
block.proof = proof;
311+
block.m_dynafed_params = dynafed_params;
312+
block.m_signblock_witness = m_signblock_witness;
304313
return block;
305314
}
306315

@@ -423,13 +432,35 @@ class CDiskBlockIndex : public CBlockIndex
423432
READWRITE(VARINT(nUndoPos));
424433

425434
// block header
426-
READWRITE(this->nVersion);
435+
436+
// Detect dynamic federation block serialization using "HF bit",
437+
// or the signed bit which is invalid in Bitcoin
438+
bool is_dyna = false;
439+
int32_t nVersion;
440+
if (ser_action.ForRead()) {
441+
READWRITE(nVersion);
442+
is_dyna = nVersion < 0;
443+
this->nVersion = ~CBlockHeader::DYNAFED_HF_MASK & nVersion;
444+
} else {
445+
nVersion = this->nVersion;
446+
if (!dynafed_params.IsNull()) {
447+
nVersion |= CBlockHeader::DYNAFED_HF_MASK;
448+
is_dyna = true;
449+
}
450+
READWRITE(nVersion);
451+
}
452+
427453
READWRITE(hashPrev);
428454
READWRITE(hashMerkleRoot);
429455
READWRITE(nTime);
430456
// For compatibility with elements 0.14 based chains
431457
if (g_signed_blocks) {
432-
READWRITE(proof);
458+
if (is_dyna) {
459+
READWRITE(dynafed_params);
460+
READWRITE(m_signblock_witness.stack);
461+
} else {
462+
READWRITE(proof);
463+
}
433464
} else {
434465
READWRITE(nBits);
435466
READWRITE(nNonce);
@@ -449,6 +480,7 @@ class CDiskBlockIndex : public CBlockIndex
449480
block.nBits = nBits;
450481
block.nNonce = nNonce;
451482
block.proof = proof;
483+
block.m_dynafed_params = dynafed_params;
452484
return block.GetHash();
453485
}
454486

src/chainparams.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class CMainParams : public CChainParams {
134134
g_signed_blocks = false;
135135
g_con_elementsmode = false;
136136
g_con_blockheightinheader = false;
137+
consensus.total_valid_epochs = 0;
137138

138139
/**
139140
* The message start string is designed to be unlikely to occur in normal data.
@@ -263,6 +264,7 @@ class CTestNetParams : public CChainParams {
263264
g_signed_blocks = false;
264265
g_con_elementsmode = false;
265266
g_con_blockheightinheader = false;
267+
consensus.total_valid_epochs = 0;
266268

267269
pchMessageStart[0] = 0x0b;
268270
pchMessageStart[1] = 0x11;
@@ -366,6 +368,7 @@ class CRegTestParams : public CChainParams {
366368
g_signed_blocks = false;
367369
g_con_elementsmode = false;
368370
g_con_blockheightinheader = false;
371+
consensus.total_valid_epochs = 0;
369372

370373
pchMessageStart[0] = 0xfa;
371374
pchMessageStart[1] = 0xbf;
@@ -482,6 +485,11 @@ class CCustomParams : public CRegTestParams {
482485

483486
consensus.nMinimumChainWork = uint256S(args.GetArg("-con_nminimumchainwork", "0x0"));
484487
consensus.defaultAssumeValid = uint256S(args.GetArg("-con_defaultassumevalid", "0x00"));
488+
// TODO: Embed in genesis block in nTime field with new genesis block type
489+
consensus.dynamic_epoch_length = args.GetArg("-dynamic_epoch_length", 10);
490+
// TODO: pass in serialized vector of byte vectors, parse into extension space
491+
// Junk keys for testing
492+
consensus.first_extension_space = {ParseHex("02fcba7ecf41bc7e1be4ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f02fcba7ecf41bc7e1be4ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f")};
485493

486494
nPruneAfterHeight = (uint64_t)args.GetArg("-npruneafterheight", nPruneAfterHeight);
487495
fDefaultConsistencyChecks = args.GetBoolArg("-fdefaultconsistencychecks", fDefaultConsistencyChecks);
@@ -558,7 +566,7 @@ class CCustomParams : public CRegTestParams {
558566
enforce_pak = args.GetBoolArg("-enforce_pak", false);
559567

560568
// Allow multiple op_return outputs by relay policy
561-
multi_data_permitted = args.GetBoolArg("-multi_data_permitted", true);
569+
multi_data_permitted = args.GetBoolArg("-multi_data_permitted", enforce_pak);
562570

563571
// bitcoin regtest is the parent chain by default
564572
parentGenesisBlockHash = uint256S(args.GetArg("-parentgenesisblockhash", "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
@@ -577,6 +585,8 @@ class CCustomParams : public CRegTestParams {
577585
uint256 entropy;
578586
GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash);
579587

588+
consensus.total_valid_epochs = args.GetArg("-total_valid_epochs", 2);
589+
580590
// Elements serialization uses derivation, bitcoin serialization uses 0x00
581591
if (g_con_elementsmode) {
582592
CalculateAsset(consensus.pegged_asset, entropy);
@@ -600,6 +610,10 @@ class CCustomParams : public CRegTestParams {
600610
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = args.GetArg("-con_csv_deploy_start", Consensus::BIP9Deployment::ALWAYS_ACTIVE);
601611
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
602612

613+
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25;
614+
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = args.GetArg("-con_dyna_deploy_start", Consensus::BIP9Deployment::ALWAYS_ACTIVE);
615+
consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
616+
603617
}
604618

605619
void SetGenesisBlock() {
@@ -613,6 +627,11 @@ class CCustomParams : public CRegTestParams {
613627
if (initialFreeCoins != 0 || initial_reissuance_tokens != 0) {
614628
AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), parentGenesisBlockHash, (initialFreeCoins > 0) ? 1 : 0, initialFreeCoins, (initial_reissuance_tokens > 0) ? 1 : 0, initial_reissuance_tokens, CScript() << OP_TRUE);
615629
}
630+
} else if (consensus.genesis_style == "dynamic") {
631+
// Liquid v2 HF, from genesis. Upgrading networks still use "elements".
632+
// TODO fill out genesis block with special commitments including epoch
633+
// length in nTime
634+
throw std::runtime_error(strprintf("Invalid -genesis_style (%s)", consensus.genesis_style));
616635
} else {
617636
throw std::runtime_error(strprintf("Invalid -genesis_style (%s)", consensus.genesis_style));
618637
}

src/chainparamsbase.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,13 @@ void SetupChainParamsBaseOptions()
4242
gArgs.AddArg("-con_parentpowlimit", "The proof-of-work limit value for the parent chain.", false, OptionsCategory::CHAINPARAMS);
4343
gArgs.AddArg("-con_parent_chain_signblockscript", "Whether parent chain uses pow or signed blocks. If the parent chain uses signed blocks, the challenge (scriptPubKey) script. If not, an empty string. (default: empty script [ie parent uses pow])", false, OptionsCategory::CHAINPARAMS);
4444

45-
gArgs.AddArg("-fedpegscript", "The script for the federated peg.", false, OptionsCategory::CHAINPARAMS);
46-
gArgs.AddArg("-enforce_pak", "Causes standardness checks to enforce Pegout Authorization Key(PAK) validation, and miner to include PAK commitments when configured. Can not be set when acceptnonstdtx is set to true.", false, OptionsCategory::ELEMENTS);
47-
gArgs.AddArg("-multi_data_permitted", "Allow relay of multiple OP_RETURN outputs. (default: true)", false, OptionsCategory::ELEMENTS);
48-
gArgs.AddArg("-pak", "Entries in the PAK list. Order of entries matter.", false, OptionsCategory::ELEMENTS);
45+
gArgs.AddArg("-fedpegscript", "The script for the federated peg enforce from genesis block. This script may stop being enforced once dynamic federations activates.", false, OptionsCategory::CHAINPARAMS);
46+
gArgs.AddArg("-enforce_pak", "Causes standardness checks to enforce Pegout Authorization Key(PAK) validation before dynamic federations, and consensus enforcement after.", false, OptionsCategory::ELEMENTS);
47+
gArgs.AddArg("-multi_data_permitted", "Allow relay of multiple OP_RETURN outputs. (default: -enforce_pak)", false, OptionsCategory::ELEMENTS);
4948
gArgs.AddArg("-con_csv_deploy_start", "Starting height for CSV deployment. (default: -1, which means ACTIVE from genesis)", false, OptionsCategory::ELEMENTS);
49+
gArgs.AddArg("-con_dyna_deploy_start", "Starting height for Dynamic Federations deployment. Once active, signblockscript becomes a BIP141 WSH scriptPubKey of the original signblockscript. All other dynamic parameters stay constant.(default: -1, which means ACTIVE from genesis)", false, OptionsCategory::ELEMENTS);
50+
gArgs.AddArg("-dynamic_epoch_length", "Per-chain parameter that sets how many blocks dynamic federation voting and enforcement are in effect for.", false, OptionsCategory::ELEMENTS);
51+
gArgs.AddArg("-total_valid_epochs", "Per-chain parameter that sets how long a particular fedpegscript is in effect for.", false, OptionsCategory::ELEMENTS);
5052
// END ELEMENTS
5153
//
5254
}

src/consensus/params.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum DeploymentPos
2222
DEPLOYMENT_TESTDUMMY,
2323
DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113.
2424
DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147.
25+
DEPLOYMENT_DYNA_FED, // Deployment of dynamic federation
2526
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
2627
MAX_VERSION_BITS_DEPLOYMENTS
2728
};
@@ -99,6 +100,13 @@ struct Params {
99100
CScript signblockscript;
100101
uint32_t max_block_signature_size;
101102
// g_signed_blocks - Whether blocks are signed or not, get around circular dep
103+
// Set positive to avoid division by 0
104+
// for non-dynafed chains and unit tests
105+
uint32_t dynamic_epoch_length = std::numeric_limits<uint32_t>::max();
106+
// Used to seed the extension space for first dynamic blocks
107+
std::vector<std::vector<unsigned char>> first_extension_space;
108+
// Used to allow M-epoch-old peg-in addresses as deposits
109+
size_t total_valid_epochs;
102110
};
103111
} // namespace Consensus
104112

src/consensus/tx_verify.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,24 +157,28 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
157157
nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR;
158158
}
159159

160+
// Note that we only count segwit sigops for peg-in inputs
160161
for (unsigned int i = 0; i < tx.vin.size(); i++)
161162
{
162-
CTxOut prevout;
163+
CScript scriptPubKey;
163164
if (tx.vin[i].m_is_pegin) {
164165
std::string err;
165-
// Make sure witness exists and is properly formatted
166-
if (tx.witness.vtxinwit.size() != tx.vin.size() || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, tx.vin[i].prevout, err, false)) {
166+
// Make sure witness exists and has enough peg-in witness fields for
167+
// the claim_script
168+
if (tx.witness.vtxinwit.size() != tx.vin.size() ||
169+
tx.witness.vtxinwit[i].m_pegin_witness.stack.size() < 4) {
167170
continue;
168171
}
169-
prevout = GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness);
172+
const auto pegin_witness = tx.witness.vtxinwit[i].m_pegin_witness;
173+
scriptPubKey = CScript(pegin_witness.stack[3].begin(), pegin_witness.stack[3].end());
170174
} else {
171175
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
172176
assert(!coin.IsSpent());
173-
prevout = coin.out;
177+
scriptPubKey = coin.out.scriptPubKey;
174178
}
175179

176180
const CScriptWitness* pScriptWitness = tx.witness.vtxinwit.size() > i ? &tx.witness.vtxinwit[i].scriptWitness : NULL;
177-
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, pScriptWitness, flags);
181+
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, scriptPubKey, pScriptWitness, flags);
178182
}
179183
return nSigOps;
180184
}
@@ -239,7 +243,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state, bool fChe
239243
}
240244

241245
namespace Consensus {
242-
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks)
246+
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks, const std::vector<std::pair<CScript, CScript>>& fedpegscripts)
243247
{
244248
// are the actual inputs available?
245249
if (!inputs.HaveInputs(tx)) {
@@ -254,7 +258,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
254258
if (tx.vin[i].m_is_pegin) {
255259
// Check existence and validity of pegin witness
256260
std::string err;
257-
if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, prevout, err, true)) {
261+
if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, fedpegscripts, prevout, err, true)) {
258262
return state.DoS(0, false, REJECT_PEGIN, "bad-pegin-witness", false, err);
259263
}
260264
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.witness.vtxinwit[i].m_pegin_witness.stack[2]), prevout);

src/consensus/tx_verify.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace Consensus {
3131
* @param[out] fee_map Set to the transaction fee if successful.
3232
* Preconditions: tx.IsCoinBase() is false.
3333
*/
34-
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks);
34+
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks, const std::vector<std::pair<CScript, CScript>>& fedpegscripts);
3535
} // namespace Consensus
3636

3737
/** Auxiliary functions for transaction validation (ideally should not be exposed) */

0 commit comments

Comments
 (0)