[mining] segwit option must be set in GBT
Calling getblocktemplate without the segwit rule specified is most likely a client error, since it results in lower fees for the miner. Prevent this client error by failing getblocktemplate if called without the segwit rule specified.
This commit is contained in:
parent
5f23460c7e
commit
0025c9eae4
10 changed files with 30 additions and 62 deletions
|
@ -27,7 +27,7 @@ static std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey
|
||||||
{
|
{
|
||||||
auto block = std::make_shared<CBlock>(
|
auto block = std::make_shared<CBlock>(
|
||||||
BlockAssembler{Params()}
|
BlockAssembler{Params()}
|
||||||
.CreateNewBlock(coinbase_scriptPubKey, /* fMineWitnessTx */ true)
|
.CreateNewBlock(coinbase_scriptPubKey)
|
||||||
->block);
|
->block);
|
||||||
|
|
||||||
block->nTime = ::chainActive.Tip()->GetMedianTimePast() + 1;
|
block->nTime = ::chainActive.Tip()->GetMedianTimePast() + 1;
|
||||||
|
|
|
@ -95,7 +95,7 @@ void BlockAssembler::resetBlock()
|
||||||
nFees = 0;
|
nFees = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx)
|
std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn)
|
||||||
{
|
{
|
||||||
int64_t nTimeStart = GetTimeMicros();
|
int64_t nTimeStart = GetTimeMicros();
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||||
// not activated.
|
// not activated.
|
||||||
// TODO: replace this with a call to main to assess validity of a mempool
|
// TODO: replace this with a call to main to assess validity of a mempool
|
||||||
// transaction (which in most cases can be a no-op).
|
// transaction (which in most cases can be a no-op).
|
||||||
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx;
|
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
|
||||||
|
|
||||||
int nPackagesSelected = 0;
|
int nPackagesSelected = 0;
|
||||||
int nDescendantsUpdated = 0;
|
int nDescendantsUpdated = 0;
|
||||||
|
|
|
@ -157,7 +157,7 @@ public:
|
||||||
BlockAssembler(const CChainParams& params, const Options& options);
|
BlockAssembler(const CChainParams& params, const Options& options);
|
||||||
|
|
||||||
/** Construct a new block template with coinbase to scriptPubKeyIn */
|
/** 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);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// utility functions
|
// utility functions
|
||||||
|
|
|
@ -311,7 +311,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
" https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
|
" https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
|
||||||
" https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n",
|
" https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n",
|
||||||
{
|
{
|
||||||
{"template_request", RPCArg::Type::OBJ, /* opt */ true, /* default_val */ "", "A json object in the following spec",
|
{"template_request", RPCArg::Type::OBJ, /* opt */ false, /* default_val */ "", "A json object in the following spec",
|
||||||
{
|
{
|
||||||
{"mode", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
|
{"mode", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
|
||||||
{"capabilities", RPCArg::Type::ARR, /* opt */ true, /* default_val */ "", "A list of strings",
|
{"capabilities", RPCArg::Type::ARR, /* opt */ true, /* default_val */ "", "A list of strings",
|
||||||
|
@ -319,7 +319,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
{"support", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
|
{"support", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "client side supported feature, 'longpoll', 'coinbasetxn', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{"rules", RPCArg::Type::ARR, /* opt */ true, /* default_val */ "", "A list of strings",
|
{"rules", RPCArg::Type::ARR, /* opt */ false, /* default_val */ "", "A list of strings",
|
||||||
{
|
{
|
||||||
{"support", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "client side supported softfork deployment"},
|
{"support", RPCArg::Type::STR, /* opt */ true, /* default_val */ "", "client side supported softfork deployment"},
|
||||||
},
|
},
|
||||||
|
@ -503,21 +503,17 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct VBDeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT];
|
const struct VBDeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT];
|
||||||
// If the caller is indicating segwit support, then allow CreateNewBlock()
|
// GBT must be called with 'segwit' set in the rules
|
||||||
// to select witness transactions, after segwit activates (otherwise
|
if (setClientRules.count(segwit_info.name) != 1) {
|
||||||
// don't).
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "getblocktemplate must be called with the segwit rule set (call with {\"rules\": [\"segwit\"]})");
|
||||||
bool fSupportsSegwit = setClientRules.find(segwit_info.name) != setClientRules.end();
|
}
|
||||||
|
|
||||||
// Update block
|
// Update block
|
||||||
static CBlockIndex* pindexPrev;
|
static CBlockIndex* pindexPrev;
|
||||||
static int64_t nStart;
|
static int64_t nStart;
|
||||||
static std::unique_ptr<CBlockTemplate> pblocktemplate;
|
static std::unique_ptr<CBlockTemplate> pblocktemplate;
|
||||||
// Cache whether the last invocation was with segwit support, to avoid returning
|
|
||||||
// a segwit-block to a non-segwit caller.
|
|
||||||
static bool fLastTemplateSupportsSegwit = true;
|
|
||||||
if (pindexPrev != chainActive.Tip() ||
|
if (pindexPrev != chainActive.Tip() ||
|
||||||
(mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5) ||
|
(mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 5))
|
||||||
fLastTemplateSupportsSegwit != fSupportsSegwit)
|
|
||||||
{
|
{
|
||||||
// Clear pindexPrev so future calls make a new block, despite any failures from here on
|
// Clear pindexPrev so future calls make a new block, despite any failures from here on
|
||||||
pindexPrev = nullptr;
|
pindexPrev = nullptr;
|
||||||
|
@ -526,11 +522,10 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
|
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
|
||||||
CBlockIndex* pindexPrevNew = chainActive.Tip();
|
CBlockIndex* pindexPrevNew = chainActive.Tip();
|
||||||
nStart = GetTime();
|
nStart = GetTime();
|
||||||
fLastTemplateSupportsSegwit = fSupportsSegwit;
|
|
||||||
|
|
||||||
// Create new block
|
// Create new block
|
||||||
CScript scriptDummy = CScript() << OP_TRUE;
|
CScript scriptDummy = CScript() << OP_TRUE;
|
||||||
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy, fSupportsSegwit);
|
pblocktemplate = BlockAssembler(Params()).CreateNewBlock(scriptDummy);
|
||||||
if (!pblocktemplate)
|
if (!pblocktemplate)
|
||||||
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
||||||
|
|
||||||
|
@ -682,7 +677,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
|
||||||
result.pushKV("bits", strprintf("%08x", pblock->nBits));
|
result.pushKV("bits", strprintf("%08x", pblock->nBits));
|
||||||
result.pushKV("height", (int64_t)(pindexPrev->nHeight+1));
|
result.pushKV("height", (int64_t)(pindexPrev->nHeight+1));
|
||||||
|
|
||||||
if (!pblocktemplate->vchCoinbaseCommitment.empty() && fSupportsSegwit) {
|
if (!pblocktemplate->vchCoinbaseCommitment.empty()) {
|
||||||
result.pushKV("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end()));
|
result.pushKV("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ std::shared_ptr<CBlock> Block(const uint256& prev_hash)
|
||||||
CScript pubKey;
|
CScript pubKey;
|
||||||
pubKey << i++ << OP_TRUE;
|
pubKey << i++ << OP_TRUE;
|
||||||
|
|
||||||
auto ptemplate = BlockAssembler(Params()).CreateNewBlock(pubKey, false);
|
auto ptemplate = BlockAssembler(Params()).CreateNewBlock(pubKey);
|
||||||
auto pblock = std::make_shared<CBlock>(ptemplate->block);
|
auto pblock = std::make_shared<CBlock>(ptemplate->block);
|
||||||
pblock->hashPrevBlock = prev_hash;
|
pblock->hashPrevBlock = prev_hash;
|
||||||
pblock->nTime = ++time;
|
pblock->nTime = ++time;
|
||||||
|
|
|
@ -90,7 +90,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||||
|
|
||||||
self.log.info("Verify sigops are counted in GBT with pre-BIP141 rules before the fork")
|
self.log.info("Verify sigops are counted in GBT with pre-BIP141 rules before the fork")
|
||||||
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
|
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
|
||||||
tmpl = self.nodes[0].getblocktemplate({})
|
tmpl = self.nodes[0].getblocktemplate({'rules': ['segwit']})
|
||||||
assert(tmpl['sizelimit'] == 1000000)
|
assert(tmpl['sizelimit'] == 1000000)
|
||||||
assert('weightlimit' not in tmpl)
|
assert('weightlimit' not in tmpl)
|
||||||
assert(tmpl['sigoplimit'] == 20000)
|
assert(tmpl['sigoplimit'] == 20000)
|
||||||
|
@ -232,15 +232,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||||
assert(tx.wit.is_null())
|
assert(tx.wit.is_null())
|
||||||
assert(txid3 in self.nodes[0].getrawmempool())
|
assert(txid3 in self.nodes[0].getrawmempool())
|
||||||
|
|
||||||
# Now try calling getblocktemplate() without segwit support.
|
# Check that getblocktemplate includes all transactions.
|
||||||
template = self.nodes[0].getblocktemplate()
|
|
||||||
|
|
||||||
# Check that tx1 is the only transaction of the 3 in the template.
|
|
||||||
template_txids = [t['txid'] for t in template['transactions']]
|
|
||||||
assert(txid2 not in template_txids and txid3 not in template_txids)
|
|
||||||
assert(txid1 in template_txids)
|
|
||||||
|
|
||||||
# Check that running with segwit support results in all 3 being included.
|
|
||||||
template = self.nodes[0].getblocktemplate({"rules": ["segwit"]})
|
template = self.nodes[0].getblocktemplate({"rules": ["segwit"]})
|
||||||
template_txids = [t['txid'] for t in template['transactions']]
|
template_txids = [t['txid'] for t in template['transactions']]
|
||||||
assert(txid1 in template_txids)
|
assert(txid1 in template_txids)
|
||||||
|
|
|
@ -30,7 +30,7 @@ from test_framework.script import CScriptNum
|
||||||
def assert_template(node, block, expect, rehash=True):
|
def assert_template(node, block, expect, rehash=True):
|
||||||
if rehash:
|
if rehash:
|
||||||
block.hashMerkleRoot = block.calc_merkle_root()
|
block.hashMerkleRoot = block.calc_merkle_root()
|
||||||
rsp = node.getblocktemplate(template_request={'data': b2x(block.serialize()), 'mode': 'proposal'})
|
rsp = node.getblocktemplate(template_request={'data': b2x(block.serialize()), 'mode': 'proposal', 'rules': ['segwit']})
|
||||||
assert_equal(rsp, expect)
|
assert_equal(rsp, expect)
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class MiningTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# Mine a block to leave initial block download
|
# Mine a block to leave initial block download
|
||||||
node.generatetoaddress(1, node.get_deterministic_priv_key().address)
|
node.generatetoaddress(1, node.get_deterministic_priv_key().address)
|
||||||
tmpl = node.getblocktemplate()
|
tmpl = node.getblocktemplate({'rules': ['segwit']})
|
||||||
self.log.info("getblocktemplate: Test capability advertised")
|
self.log.info("getblocktemplate: Test capability advertised")
|
||||||
assert 'proposal' in tmpl['capabilities']
|
assert 'proposal' in tmpl['capabilities']
|
||||||
assert 'coinbasetxn' not in tmpl
|
assert 'coinbasetxn' not in tmpl
|
||||||
|
@ -86,6 +86,9 @@ class MiningTest(BitcoinTestFramework):
|
||||||
block.nNonce = 0
|
block.nNonce = 0
|
||||||
block.vtx = [coinbase_tx]
|
block.vtx = [coinbase_tx]
|
||||||
|
|
||||||
|
self.log.info("getblocktemplate: segwit rule must be set")
|
||||||
|
assert_raises_rpc_error(-8, "getblocktemplate must be called with the segwit rule set", node.getblocktemplate)
|
||||||
|
|
||||||
self.log.info("getblocktemplate: Test valid block")
|
self.log.info("getblocktemplate: Test valid block")
|
||||||
assert_template(node, block, None)
|
assert_template(node, block, None)
|
||||||
|
|
||||||
|
@ -102,7 +105,7 @@ class MiningTest(BitcoinTestFramework):
|
||||||
assert_raises_rpc_error(-22, "Block does not start with a coinbase", node.submitblock, b2x(bad_block.serialize()))
|
assert_raises_rpc_error(-22, "Block does not start with a coinbase", node.submitblock, b2x(bad_block.serialize()))
|
||||||
|
|
||||||
self.log.info("getblocktemplate: Test truncated final transaction")
|
self.log.info("getblocktemplate: Test truncated final transaction")
|
||||||
assert_raises_rpc_error(-22, "Block decode failed", node.getblocktemplate, {'data': b2x(block.serialize()[:-1]), 'mode': 'proposal'})
|
assert_raises_rpc_error(-22, "Block decode failed", node.getblocktemplate, {'data': b2x(block.serialize()[:-1]), 'mode': 'proposal', 'rules': ['segwit']})
|
||||||
|
|
||||||
self.log.info("getblocktemplate: Test duplicate transaction")
|
self.log.info("getblocktemplate: Test duplicate transaction")
|
||||||
bad_block = copy.deepcopy(block)
|
bad_block = copy.deepcopy(block)
|
||||||
|
@ -132,7 +135,7 @@ class MiningTest(BitcoinTestFramework):
|
||||||
bad_block_sn = bytearray(block.serialize())
|
bad_block_sn = bytearray(block.serialize())
|
||||||
assert_equal(bad_block_sn[TX_COUNT_OFFSET], 1)
|
assert_equal(bad_block_sn[TX_COUNT_OFFSET], 1)
|
||||||
bad_block_sn[TX_COUNT_OFFSET] += 1
|
bad_block_sn[TX_COUNT_OFFSET] += 1
|
||||||
assert_raises_rpc_error(-22, "Block decode failed", node.getblocktemplate, {'data': b2x(bad_block_sn), 'mode': 'proposal'})
|
assert_raises_rpc_error(-22, "Block decode failed", node.getblocktemplate, {'data': b2x(bad_block_sn), 'mode': 'proposal', 'rules': ['segwit']})
|
||||||
|
|
||||||
self.log.info("getblocktemplate: Test bad bits")
|
self.log.info("getblocktemplate: Test bad bits")
|
||||||
bad_block = copy.deepcopy(block)
|
bad_block = copy.deepcopy(block)
|
||||||
|
|
|
@ -15,14 +15,14 @@ class LongpollThread(threading.Thread):
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
# query current longpollid
|
# query current longpollid
|
||||||
template = node.getblocktemplate()
|
template = node.getblocktemplate({'rules': ['segwit']})
|
||||||
self.longpollid = template['longpollid']
|
self.longpollid = template['longpollid']
|
||||||
# create a new connection to the node, we can't use the same
|
# create a new connection to the node, we can't use the same
|
||||||
# connection from two threads
|
# connection from two threads
|
||||||
self.node = get_rpc_proxy(node.url, 1, timeout=600, coveragedir=node.coverage_dir)
|
self.node = get_rpc_proxy(node.url, 1, timeout=600, coveragedir=node.coverage_dir)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.node.getblocktemplate({'longpollid':self.longpollid})
|
self.node.getblocktemplate({'longpollid': self.longpollid, 'rules': ['segwit']})
|
||||||
|
|
||||||
class GetBlockTemplateLPTest(BitcoinTestFramework):
|
class GetBlockTemplateLPTest(BitcoinTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
|
@ -34,10 +34,10 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
|
||||||
def run_test(self):
|
def run_test(self):
|
||||||
self.log.info("Warning: this test will take about 70 seconds in the best case. Be patient.")
|
self.log.info("Warning: this test will take about 70 seconds in the best case. Be patient.")
|
||||||
self.nodes[0].generate(10)
|
self.nodes[0].generate(10)
|
||||||
template = self.nodes[0].getblocktemplate()
|
template = self.nodes[0].getblocktemplate({'rules': ['segwit']})
|
||||||
longpollid = template['longpollid']
|
longpollid = template['longpollid']
|
||||||
# longpollid should not change between successive invocations if nothing else happens
|
# longpollid should not change between successive invocations if nothing else happens
|
||||||
template2 = self.nodes[0].getblocktemplate()
|
template2 = self.nodes[0].getblocktemplate({'rules': ['segwit']})
|
||||||
assert(template2['longpollid'] == longpollid)
|
assert(template2['longpollid'] == longpollid)
|
||||||
|
|
||||||
# Test 1: test that the longpolling wait if we do nothing
|
# Test 1: test that the longpolling wait if we do nothing
|
||||||
|
|
|
@ -142,10 +142,10 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
|
||||||
# getblocktemplate to (eventually) return a new block.
|
# getblocktemplate to (eventually) return a new block.
|
||||||
mock_time = int(time.time())
|
mock_time = int(time.time())
|
||||||
self.nodes[0].setmocktime(mock_time)
|
self.nodes[0].setmocktime(mock_time)
|
||||||
template = self.nodes[0].getblocktemplate()
|
template = self.nodes[0].getblocktemplate({'rules': ['segwit']})
|
||||||
self.nodes[0].prioritisetransaction(txid=tx_id, fee_delta=-int(self.relayfee*COIN))
|
self.nodes[0].prioritisetransaction(txid=tx_id, fee_delta=-int(self.relayfee*COIN))
|
||||||
self.nodes[0].setmocktime(mock_time+10)
|
self.nodes[0].setmocktime(mock_time+10)
|
||||||
new_template = self.nodes[0].getblocktemplate()
|
new_template = self.nodes[0].getblocktemplate({'rules': ['segwit']})
|
||||||
|
|
||||||
assert(template != new_template)
|
assert(template != new_template)
|
||||||
|
|
||||||
|
|
|
@ -545,31 +545,13 @@ class SegWitTest(BitcoinTestFramework):
|
||||||
|
|
||||||
@subtest
|
@subtest
|
||||||
def test_getblocktemplate_before_lockin(self):
|
def test_getblocktemplate_before_lockin(self):
|
||||||
# Node0 is segwit aware, node2 is not.
|
|
||||||
for node in [self.nodes[0], self.nodes[2]]:
|
|
||||||
gbt_results = node.getblocktemplate()
|
|
||||||
block_version = gbt_results['version']
|
|
||||||
# If we're not indicating segwit support, we will still be
|
|
||||||
# signalling for segwit activation.
|
|
||||||
assert_equal((block_version & (1 << VB_WITNESS_BIT) != 0), node == self.nodes[0])
|
|
||||||
# If we don't specify the segwit rule, then we won't get a default
|
|
||||||
# commitment.
|
|
||||||
assert('default_witness_commitment' not in gbt_results)
|
|
||||||
|
|
||||||
# Workaround:
|
|
||||||
# Can either change the tip, or change the mempool and wait 5 seconds
|
|
||||||
# to trigger a recomputation of getblocktemplate.
|
|
||||||
txid = int(self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1), 16)
|
txid = int(self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1), 16)
|
||||||
# Using mocktime lets us avoid sleep()
|
|
||||||
sync_mempools(self.nodes)
|
|
||||||
self.nodes[0].setmocktime(int(time.time()) + 10)
|
|
||||||
self.nodes[2].setmocktime(int(time.time()) + 10)
|
|
||||||
|
|
||||||
for node in [self.nodes[0], self.nodes[2]]:
|
for node in [self.nodes[0], self.nodes[2]]:
|
||||||
gbt_results = node.getblocktemplate({"rules": ["segwit"]})
|
gbt_results = node.getblocktemplate({"rules": ["segwit"]})
|
||||||
block_version = gbt_results['version']
|
block_version = gbt_results['version']
|
||||||
if node == self.nodes[2]:
|
if node == self.nodes[2]:
|
||||||
# If this is a non-segwit node, we should still not get a witness
|
# If this is a non-segwit node, we should not get a witness
|
||||||
# commitment, nor a version bit signalling segwit.
|
# commitment, nor a version bit signalling segwit.
|
||||||
assert_equal(block_version & (1 << VB_WITNESS_BIT), 0)
|
assert_equal(block_version & (1 << VB_WITNESS_BIT), 0)
|
||||||
assert('default_witness_commitment' not in gbt_results)
|
assert('default_witness_commitment' not in gbt_results)
|
||||||
|
@ -586,10 +568,6 @@ class SegWitTest(BitcoinTestFramework):
|
||||||
script = get_witness_script(witness_root, 0)
|
script = get_witness_script(witness_root, 0)
|
||||||
assert_equal(witness_commitment, bytes_to_hex_str(script))
|
assert_equal(witness_commitment, bytes_to_hex_str(script))
|
||||||
|
|
||||||
# undo mocktime
|
|
||||||
self.nodes[0].setmocktime(0)
|
|
||||||
self.nodes[2].setmocktime(0)
|
|
||||||
|
|
||||||
@subtest
|
@subtest
|
||||||
def advance_to_segwit_lockin(self):
|
def advance_to_segwit_lockin(self):
|
||||||
"""Mine enough blocks to lock in segwit, but don't activate."""
|
"""Mine enough blocks to lock in segwit, but don't activate."""
|
||||||
|
|
Loading…
Reference in a new issue