Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP, 0.17] Signed blocks #452

Closed
wants to merge 66 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
4640056
Add CProof structure for signed headers
instagibbs Oct 29, 2018
6b3a550
Add signblockscript custom chain argument
instagibbs Oct 29, 2018
cc7cbb6
Add non-serialized CProof to block header
instagibbs Oct 29, 2018
0108dac
Introduce a no sighash byte signature check flag for blocks and other…
instagibbs Oct 29, 2018
d8f9470
Add more blocksigning infrastructure
instagibbs Oct 29, 2018
cb5571f
Add signblockscript argument to employ signed blocks
instagibbs Oct 29, 2018
5e33033
'f'Add signblockscript argument to employ signed blocks
instagibbs Oct 29, 2018
5f780bb
add functional tests for signed blockchain
instagibbs Oct 29, 2018
e80e88f
add signblock fields to blockchain RPC results
instagibbs Oct 30, 2018
0096526
fixup rpc results
instagibbs Oct 30, 2018
07ca9b9
some more functional test stuff
instagibbs Oct 30, 2018
89aeade
break this up! checkin
instagibbs Oct 30, 2018
d35e615
more fixes
instagibbs Nov 5, 2018
9176ff0
fixup
instagibbs Nov 5, 2018
1ac9215
fixup
instagibbs Nov 5, 2018
40c794b
more fixes
instagibbs Nov 5, 2018
a349327
fix zmq test
instagibbs Nov 6, 2018
c933511
add blocksigning RPC calls
instagibbs Nov 7, 2018
4d1e511
fixup rpc mining call
instagibbs Nov 7, 2018
7c80bce
add compact block rpc calls
instagibbs Nov 7, 2018
9852783
checkin feature_blocksign.py fixup
instagibbs Nov 7, 2018
450276a
test compact block rpcs
instagibbs Sep 12, 2018
9003d46
f'add blocksigning RPC calls'
instagibbs Nov 7, 2018
166ea71
f'add compact block rpc calls'
instagibbs Nov 7, 2018
fbc0897
fixup miner rpc call
instagibbs Nov 7, 2018
6162015
add RPC test for getnewblockhex required_wait
instagibbs Nov 7, 2018
3c50b84
f'c933511300083a4573d935af037389a2c03b35b0'
instagibbs Nov 7, 2018
ee717e7
fixup combineblocksigs
instagibbs Nov 8, 2018
90d6bbc
fixup signblock
instagibbs Nov 8, 2018
f21925c
fixup compact block rpcs
instagibbs Nov 8, 2018
10da603
fixup signblock rpc
instagibbs Nov 13, 2018
ed5bc23
fixup signblock RPC
instagibbs Nov 14, 2018
9d383f5
fixup combineblocksig (still not working)
instagibbs Nov 14, 2018
2dfd03a
fixup generic signing
instagibbs Nov 14, 2018
06c4ca3
fixup generic signing
instagibbs Nov 14, 2018
caf8ba6
fixup CheckSignatureEncoding for non-sighash-byte based sigs
instagibbs Nov 14, 2018
3902a29
fixup combineblocksigs
instagibbs Nov 14, 2018
8f287d4
fixup CreateNewBlock required age of transactions
instagibbs Nov 14, 2018
5ac003e
add testproposedblock rpc call
instagibbs Nov 14, 2018
817f683
fixup combineblocksigs
instagibbs Nov 14, 2018
c01f8a5
fixup signblock
instagibbs Nov 14, 2018
1648fb9
fixup signed block rpc functional tests
instagibbs Nov 14, 2018
4d249f3
signblock: use blockheader hash not entire serialized block
instagibbs Nov 15, 2018
f56f3d5
fixup rpc test
instagibbs Nov 15, 2018
f15dcf9
Add TX_TRUE output format, accept in wallet with
instagibbs Nov 15, 2018
3c9aabe
checking functional test
instagibbs Nov 15, 2018
d1c1749
finally fixed feature_blocksign.py
instagibbs Nov 15, 2018
7f2302b
finalize functional test for blocksigning
instagibbs Nov 15, 2018
bdb1737
fixup blocksign functional tests again...
instagibbs Nov 15, 2018
cca86c0
ProduceSignature should have additional flags only
instagibbs Nov 15, 2018
6e32857
fixup include spacing for compact block rpcs
instagibbs Nov 15, 2018
6edf137
remove circular dep from generic signer
instagibbs Nov 15, 2018
fe156a6
remove unneeded STANDARD_VERIFY flag causing circular dep
instagibbs Nov 15, 2018
b3004ad
remove policy include for block signature production
instagibbs Nov 15, 2018
1b7559e
fixup testproposedblock include
instagibbs Nov 15, 2018
ad8814f
remove sign.h include from pow.cpp
instagibbs Nov 15, 2018
fcf77ab
fixup getnewblcokhex
instagibbs Nov 15, 2018
1abaed3
remove unused includes in blocksign test
instagibbs Nov 15, 2018
e456e1e
remove unused decimal in rpc test
instagibbs Nov 15, 2018
561f56d
remove unused include rpc_blockchain.py
instagibbs Nov 15, 2018
4137016
fixup functional test
instagibbs Nov 15, 2018
f26b992
fixup functional test
instagibbs Nov 15, 2018
18a804c
CreateNewBlock: Only do signed block stuff when active
instagibbs Nov 16, 2018
6df5c86
fixup combineblocksigs results
instagibbs Nov 16, 2018
52cfdca
Clarify block validation flags in light of max_block_signature_size
instagibbs Nov 16, 2018
3e785f2
combineblocksigs should check if signed blocks are active
instagibbs Nov 16, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ BITCOIN_CORE_H = \
rpc/util.h \
scheduler.h \
script/descriptor.h \
script/generic.hpp \
script/ismine.h \
script/sigcache.h \
script/sign.h \
Expand Down
12 changes: 9 additions & 3 deletions src/blockencodings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ uint64_t CBlockHeaderAndShortTxIDs::GetShortID(const uint256& txhash) const {
return SipHashUint256(shorttxidk0, shorttxidk1, txhash) & 0xffffffffffffL;
}


std::vector<CTransactionRef> PartiallyDownloadedBlock::GetAvailableTx() {
std::vector<CTransactionRef> found_tx;
for (unsigned int i = 0; i < txn_available.size(); i++) {
if (txn_available[i]) found_tx.push_back(txn_available[i]);
}
return found_tx;
}

ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn) {
if (cmpctblock.header.IsNull() || (cmpctblock.shorttxids.empty() && cmpctblock.prefilledtxn.empty()))
Expand Down Expand Up @@ -173,7 +179,7 @@ bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const {
return txn_available[index] != nullptr;
}

ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing) {
ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing, bool check_pow) {
assert(!header.IsNull());
uint256 hash = header.GetHash();
block = header;
Expand All @@ -197,7 +203,7 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<
return READ_STATUS_INVALID;

CValidationState state;
if (!CheckBlock(block, state, Params().GetConsensus())) {
if (!CheckBlock(block, state, Params().GetConsensus(), check_pow)) {
// TODO: We really want to just check merkle tree manually here,
// but that is expensive, and CheckBlock caches a block's
// "checked-status" (in the CBlock?). CBlock should be able to
Expand Down
3 changes: 2 additions & 1 deletion src/blockencodings.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,11 @@ class PartiallyDownloadedBlock {
CBlockHeader header;
explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {}

std::vector<CTransactionRef> GetAvailableTx();
// extra_txn is a list of extra transactions to look at, in <witness hash, reference> form
ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn);
bool IsTxAvailable(size_t index) const;
ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing);
ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing, bool check_pow = true);
};

#endif // BITCOIN_BLOCKENCODINGS_H
5 changes: 5 additions & 0 deletions src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ void CBlockIndex::BuildSkip()

arith_uint256 GetBlockProof(const CBlockIndex& block)
{
// All valid signed blocks have "weight" 1
if (g_signed_blocks) {
return 1;
}

arith_uint256 bnTarget;
bool fNegative;
bool fOverflow;
Expand Down
6 changes: 6 additions & 0 deletions src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class CBlockIndex
uint32_t nTime;
uint32_t nBits;
uint32_t nNonce;
CProof proof;

//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
int32_t nSequenceId;
Expand Down Expand Up @@ -240,6 +241,7 @@ class CBlockIndex
nTime = 0;
nBits = 0;
nNonce = 0;
proof.SetNull();
}

CBlockIndex()
Expand All @@ -256,6 +258,7 @@ class CBlockIndex
nTime = block.nTime;
nBits = block.nBits;
nNonce = block.nNonce;
proof = block.proof;
}

CDiskBlockPos GetBlockPos() const {
Expand Down Expand Up @@ -286,6 +289,7 @@ class CBlockIndex
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.proof = proof;
return block;
}

Expand Down Expand Up @@ -405,6 +409,7 @@ class CDiskBlockIndex : public CBlockIndex
READWRITE(nTime);
READWRITE(nBits);
READWRITE(nNonce);
READWRITE(proof);
}

uint256 GetBlockHash() const
Expand All @@ -416,6 +421,7 @@ class CDiskBlockIndex : public CBlockIndex
block.nTime = nTime;
block.nBits = nBits;
block.nNonce = nNonce;
block.proof = proof;
return block.GetHash();
}

Expand Down
27 changes: 20 additions & 7 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
static CBlock CreateGenesisBlock(const Consensus::Params& params, const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
{
CMutableTransaction txNew;
txNew.nVersion = 1;
Expand All @@ -35,6 +35,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
genesis.hashPrevBlock.SetNull();
genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
genesis.proof = CProof(params.signblockscript, CScript());
return genesis;
}

Expand All @@ -49,11 +50,11 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
* vMerkleTree: 4a5e1e
*/
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward)
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward, const Consensus::Params& params)
{
const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
return CreateGenesisBlock(params, pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}

/**
Expand Down Expand Up @@ -106,6 +107,7 @@ class CMainParams : public CChainParams {

consensus.genesis_subsidy = 50*COIN;
consensus.connect_genesis_outputs = false;
anyonecanspend_aremine = false;

/**
* The message start string is designed to be unlikely to occur in normal data.
Expand All @@ -119,7 +121,7 @@ class CMainParams : public CChainParams {
nDefaultPort = 8333;
nPruneAfterHeight = 100000;

genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN);
genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN, consensus);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
Expand Down Expand Up @@ -223,6 +225,7 @@ class CTestNetParams : public CChainParams {

consensus.genesis_subsidy = 50*COIN;
consensus.connect_genesis_outputs = false;
anyonecanspend_aremine = false;

pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
Expand All @@ -231,7 +234,7 @@ class CTestNetParams : public CChainParams {
nDefaultPort = 18333;
nPruneAfterHeight = 1000;

genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN);
genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN, consensus);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
Expand Down Expand Up @@ -315,6 +318,7 @@ class CRegTestParams : public CChainParams {

consensus.genesis_subsidy = 50*COIN;
consensus.connect_genesis_outputs = false;
anyonecanspend_aremine = false;

pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
Expand All @@ -325,7 +329,7 @@ class CRegTestParams : public CChainParams {

UpdateVersionBitsParametersFromArgs(args);

genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN);
genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN, consensus);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"));
assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
Expand Down Expand Up @@ -436,9 +440,18 @@ class CCustomParams : public CRegTestParams {
std::vector<unsigned char> man_bytes = ParseHex(gArgs.GetArg("-con_mandatorycoinbase", ""));
consensus.mandatory_coinbase_destination = CScript(man_bytes.begin(), man_bytes.end()); // Blank script allows any coinbase destination

// Block signing encumberance script, default of 51 aka OP_TRUE
std::vector<unsigned char> sign_bytes = ParseHex(gArgs.GetArg("-signblockscript", "51"));
consensus.signblockscript = CScript(sign_bytes.begin(), sign_bytes.end());
// Default signature size is the size of dummy push, and single 72 byte DER signature
consensus.max_block_signature_size = gArgs.GetArg("-con_max_block_sig_size", 74);
g_signed_blocks = gArgs.GetBoolArg("-con_signed_blocks", true);

// Custom chains connect coinbase outputs to db by default
consensus.connect_genesis_outputs = gArgs.GetArg("-con_connect_coinbase", true);

anyonecanspend_aremine = gArgs.GetBoolArg("-anyonecanspendaremine", true);

nPruneAfterHeight = (uint64_t)args.GetArg("-npruneafterheight", nPruneAfterHeight);
fDefaultConsistencyChecks = args.GetBoolArg("-fdefaultconsistencychecks", fDefaultConsistencyChecks);
fMineBlocksOnDemand = args.GetBoolArg("-fmineblocksondemand", fMineBlocksOnDemand);
Expand Down Expand Up @@ -476,7 +489,7 @@ class CCustomParams : public CRegTestParams {
{
strNetworkID = chain;
UpdateFromArgs(args);
genesis = CreateGenesisBlock(strNetworkID.c_str(), CScript(OP_TRUE), 1296688602, 2, 0x207fffff, 1, 50 * COIN);
genesis = CreateGenesisBlock(consensus, strNetworkID.c_str(), CScript(OP_TRUE), 1296688602, 2, 0x207fffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
}
};
Expand Down
1 change: 1 addition & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class CChainParams
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
const ChainTxData& TxData() const { return chainTxData; }
bool anyonecanspend_aremine;
protected:
CChainParams() {}

Expand Down
3 changes: 3 additions & 0 deletions src/chainparamsbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ void SetupChainParamsBaseOptions()
gArgs.AddArg("-seednode=<ip>", "Use specified node as seed node. This option can be specified multiple times to connect to multiple nodes. (custom only)", true, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_blocksubsidy", "Defines the amount of block subsidy to start with, at genesis block.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_connect_coinbase", "Connect outputs in genesis block to utxo database.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_signed_blocks", "Signed blockchain. Uses input of `-signblockscript` to define what signatures are necessary to solve it.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-signblockscript", "Signed blockchain enumberance. Only active when `-con_signed_blcoks` set to true.", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_max_block_sig_size", "Max allowed witness data for the signed block header.", false, OptionsCategory::CHAINPARAMS);
}

static std::unique_ptr<CBaseChainParams> globalChainBaseParams;
Expand Down
3 changes: 3 additions & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ struct Params {
CScript mandatory_coinbase_destination;
CAmount genesis_subsidy;
bool connect_genesis_outputs;
CScript signblockscript;
uint32_t max_block_signature_size;
// g_signed_blocks - Whether blocks are signed or not, get around circular dep
};
} // namespace Consensus

Expand Down
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ void SetupServerArgs()
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), false, OptionsCategory::NODE_RELAY);
gArgs.AddArg("-whitelistforcerelay", strprintf("Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d)", DEFAULT_WHITELISTFORCERELAY), false, OptionsCategory::NODE_RELAY);
gArgs.AddArg("-whitelistrelay", strprintf("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), false, OptionsCategory::NODE_RELAY);
gArgs.AddArg("-anyonecanspendaremine", strprintf("Treat OP_TRUE outputs as funds for the wallet. Default true for custom chains."), true, OptionsCategory::DEBUG_TEST);


gArgs.AddArg("-blockmaxweight=<n>", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), false, OptionsCategory::BLOCK_CREATION);
Expand Down
24 changes: 20 additions & 4 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ void BlockAssembler::resetBlock()
nFees = 0;
}

std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx)
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx, int required_age_in_secs)
{
assert(required_age_in_secs >= 0);
int64_t nTimeStart = GetTimeMicros();

resetBlock();
Expand Down Expand Up @@ -142,9 +143,18 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
// transaction (which in most cases can be a no-op).
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx;

if (g_signed_blocks) {
// Pad block weight by block proof fields (including upper-bound of signature)
nBlockWeight += chainparams.GetConsensus().signblockscript.size() * WITNESS_SCALE_FACTOR;
nBlockWeight += chainparams.GetConsensus().max_block_signature_size * WITNESS_SCALE_FACTOR;
// Reset block proof
ResetProof(*pblock);
ResetChallenge(*pblock, *pindexPrev, chainparams.GetConsensus());
}

int nPackagesSelected = 0;
int nDescendantsUpdated = 0;
addPackageTxs(nPackagesSelected, nDescendantsUpdated);
addPackageTxs(nPackagesSelected, nDescendantsUpdated, required_age_in_secs);

int64_t nTime1 = GetTimeMicros();

Expand All @@ -168,7 +178,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
pblock->nBits = g_signed_blocks ? 0 : GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
pblock->nNonce = 0;
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);

Expand Down Expand Up @@ -303,7 +313,7 @@ void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, std::ve
// Each time through the loop, we compare the best transaction in
// mapModifiedTxs with the next transaction in the mempool to decide what
// transaction package to work on next.
void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated)
void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int required_age_in_secs)
{
// mapModifiedTx will store sorted packages after they are modified
// because some of their txs are already in the block
Expand Down Expand Up @@ -359,6 +369,12 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
}
}

// Skip transactions that are under X seconds in mempool
// required_age_in_secs value of 0 is considered "inactive", in case of mocktime
if (required_age_in_secs > 0 && iter->GetTime() > GetTime() - required_age_in_secs) {
continue;
}

// We skip mapTx entries that are inBlock, and mapModifiedTx shouldn't
// contain anything that is inBlock.
assert(!inBlock.count(iter));
Expand Down
4 changes: 2 additions & 2 deletions src/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class BlockAssembler
BlockAssembler(const CChainParams& params, const Options& options);

/** Construct a new block template with coinbase to scriptPubKeyIn */
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx=true);
std::unique_ptr<CBlockTemplate> CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx=true, int required_wait=0);

private:
// utility functions
Expand All @@ -170,7 +170,7 @@ class BlockAssembler
/** Add transactions based on feerate including unconfirmed ancestors
* Increments nPackagesSelected / nDescendantsUpdated with corresponding
* statistics from the package selection (for logging statistics). */
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, int required_wait=0) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);

// helper functions for addPackageTxs()
/** Remove confirmed (inBlock) entries from given set */
Expand Down
Loading