mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
Merge pull request #1885 from codablock/pr_bip147_nulldummy
Backport BIP147 (nulldummy enforcement)
This commit is contained in:
commit
50463788d2
@ -26,3 +26,4 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**):
|
||||
* [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)).
|
||||
* [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)).
|
||||
* [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)).
|
||||
* [`BIP 147`](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki): NULLDUMMY softfork as of **v0.13.1** ([PR 8636](https://github.com/bitcoin/bitcoin/pull/8636) and [PR 8937](https://github.com/bitcoin/bitcoin/pull/8937)).
|
||||
|
@ -30,6 +30,9 @@ The interface is defined in the C header `dashconsensus.h` located in `src/scri
|
||||
- `dashconsensus_SCRIPT_FLAGS_VERIFY_NONE`
|
||||
- `dashconsensus_SCRIPT_FLAGS_VERIFY_P2SH` - Evaluate P2SH ([BIP16](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki)) subscripts
|
||||
- `dashconsensus_SCRIPT_FLAGS_VERIFY_DERSIG` - Enforce strict DER ([BIP66](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki)) compliance
|
||||
- `dashconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY` - Enforce NULLDUMMY ([BIP147](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki))
|
||||
- `dashconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY` - Enable CHECKLOCKTIMEVERIFY ([BIP65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki))
|
||||
- `dashconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY` - Enable CHECKSEQUENCEVERIFY ([BIP112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki))
|
||||
|
||||
##### Errors
|
||||
- `dashconsensus_ERR_OK` - No errors with input parameters *(see the return value of `dashconsensus_verify_script` for the verification status)*
|
||||
|
@ -159,6 +159,7 @@ testScripts = [
|
||||
'preciousblock.py',
|
||||
'importprunedfunds.py',
|
||||
'signmessages.py',
|
||||
'nulldummy.py',
|
||||
'import-rescan.py',
|
||||
'rpcnamedargs.py',
|
||||
'listsinceblock.py',
|
||||
|
136
qa/rpc-tests/nulldummy.py
Executable file
136
qa/rpc-tests/nulldummy.py
Executable file
@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2016 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
from test_framework.mininode import CTransaction, NetworkThread
|
||||
from test_framework.blocktools import create_coinbase, create_block
|
||||
from test_framework.script import CScript
|
||||
from io import BytesIO
|
||||
import time
|
||||
|
||||
NULLDUMMY_ERROR = "64: non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)"
|
||||
|
||||
def trueDummy(tx):
|
||||
scriptSig = CScript(tx.vin[0].scriptSig)
|
||||
newscript = []
|
||||
for i in scriptSig:
|
||||
if (len(newscript) == 0):
|
||||
assert(len(i) == 0)
|
||||
newscript.append(b'\x51')
|
||||
else:
|
||||
newscript.append(i)
|
||||
tx.vin[0].scriptSig = CScript(newscript)
|
||||
tx.rehash()
|
||||
|
||||
'''
|
||||
This test is meant to exercise NULLDUMMY softfork.
|
||||
Connect to a single node.
|
||||
Generate 2 blocks (save the coinbases for later).
|
||||
Generate 427 more blocks.
|
||||
[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in the 430th block.
|
||||
[Policy] Check that non-NULLDUMMY transactions are rejected before activation.
|
||||
[Consensus] Check that the new NULLDUMMY rules are not enforced on the 431st block.
|
||||
[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block.
|
||||
'''
|
||||
|
||||
class NULLDUMMYTest(BitcoinTestFramework):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.num_nodes = 1
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def setup_network(self):
|
||||
# Must set the blockversion for this test
|
||||
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir,
|
||||
extra_args=[['-debug', '-whitelist=127.0.0.1']])
|
||||
|
||||
def run_test(self):
|
||||
self.address = self.nodes[0].getnewaddress()
|
||||
self.ms_address = self.nodes[0].addmultisigaddress(1,[self.address])
|
||||
|
||||
NetworkThread().start() # Start up network handling in another thread
|
||||
self.coinbase_blocks = self.nodes[0].generate(2) # Block 2
|
||||
coinbase_txid = []
|
||||
for i in self.coinbase_blocks:
|
||||
coinbase_txid.append(self.nodes[0].getblock(i)['tx'][0])
|
||||
self.nodes[0].generate(427) # Block 429
|
||||
self.lastblockhash = self.nodes[0].getbestblockhash()
|
||||
self.tip = int("0x" + self.lastblockhash, 0)
|
||||
self.lastblockheight = 429
|
||||
self.lastblocktime = int(time.time()) + 429
|
||||
|
||||
print ("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]")
|
||||
test1txs = [self.create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)]
|
||||
txid1 = self.tx_submit(self.nodes[0], test1txs[0])
|
||||
test1txs.append(self.create_transaction(self.nodes[0], txid1, self.ms_address, 48))
|
||||
txid2 = self.tx_submit(self.nodes[0], test1txs[1])
|
||||
self.block_submit(self.nodes[0], test1txs, True)
|
||||
|
||||
print ("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation")
|
||||
test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 48)
|
||||
trueDummy(test2tx)
|
||||
txid4 = self.tx_submit(self.nodes[0], test2tx, NULLDUMMY_ERROR)
|
||||
|
||||
print ("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]")
|
||||
self.block_submit(self.nodes[0], [test2tx], True)
|
||||
|
||||
print ("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation")
|
||||
test4tx = self.create_transaction(self.nodes[0], txid4, self.address, 47)
|
||||
test6txs=[CTransaction(test4tx)]
|
||||
trueDummy(test4tx)
|
||||
self.tx_submit(self.nodes[0], test4tx, NULLDUMMY_ERROR)
|
||||
self.block_submit(self.nodes[0], [test4tx])
|
||||
|
||||
print ("Test 6: NULLDUMMY compliant transactions should be accepted to mempool and in block after activation [432]")
|
||||
for i in test6txs:
|
||||
self.tx_submit(self.nodes[0], i)
|
||||
self.block_submit(self.nodes[0], test6txs, True)
|
||||
|
||||
|
||||
def create_transaction(self, node, txid, to_address, amount):
|
||||
inputs = [{ "txid" : txid, "vout" : 0}]
|
||||
outputs = { to_address : amount }
|
||||
rawtx = node.createrawtransaction(inputs, outputs)
|
||||
signresult = node.signrawtransaction(rawtx)
|
||||
tx = CTransaction()
|
||||
f = BytesIO(hex_str_to_bytes(signresult['hex']))
|
||||
tx.deserialize(f)
|
||||
return tx
|
||||
|
||||
|
||||
def tx_submit(self, node, tx, msg = ""):
|
||||
tx.rehash()
|
||||
try:
|
||||
node.sendrawtransaction(bytes_to_hex_str(tx.serialize()), True)
|
||||
except JSONRPCException as exp:
|
||||
assert_equal(exp.error["message"], msg)
|
||||
else:
|
||||
assert_equal('', msg)
|
||||
return tx.hash
|
||||
|
||||
|
||||
def block_submit(self, node, txs, accept = False):
|
||||
block = create_block(self.tip, create_coinbase(self.lastblockheight + 1), self.lastblocktime + 1)
|
||||
block.nVersion = 4
|
||||
for tx in txs:
|
||||
tx.rehash()
|
||||
block.vtx.append(tx)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
block.solve()
|
||||
node.submitblock(bytes_to_hex_str(block.serialize()))
|
||||
if (accept):
|
||||
assert_equal(node.getbestblockhash(), block.hash)
|
||||
self.tip = block.sha256
|
||||
self.lastblockhash = block.hash
|
||||
self.lastblocktime += 1
|
||||
self.lastblockheight += 1
|
||||
else:
|
||||
assert_equal(node.getbestblockhash(), self.lastblockhash)
|
||||
|
||||
if __name__ == '__main__':
|
||||
NULLDUMMYTest().main()
|
@ -165,6 +165,13 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 4032;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThreshold = 3226; // 80% of 4032
|
||||
|
||||
// Deployment of BIP147
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1519952400; // Feb 30th, 2018
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1551488400; // Feb 30th, 2019
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 4032;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThreshold = 3226; // 80% of 4032
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000100a308553b4863b755"); // 782700
|
||||
|
||||
@ -307,6 +314,13 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThreshold = 50; // 50% of 100
|
||||
|
||||
// Deployment of BIP147
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1517792400; // Feb 5th, 2018
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1549328400; // Feb 5th, 2019
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThreshold = 59; // 50% of 100
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000924e924a21715"); // 37900
|
||||
|
||||
@ -426,6 +440,13 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nWindowSize = 100;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nThreshold = 50; // 50% of 100
|
||||
|
||||
// Deployment of BIP147
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 1517792400; // Feb 5th, 2018
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 1549328400; // Feb 5th, 2019
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nWindowSize = 100;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nThreshold = 59; // 50% of 100
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000000000000000");
|
||||
|
||||
@ -539,6 +560,9 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].bit = 1;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nStartTime = 0;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_DIP0001].nTimeout = 999999999999ULL;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].bit = 2;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nStartTime = 0;
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_BIP147].nTimeout = 999999999999ULL;
|
||||
|
||||
// The best chain should have at least this much work.
|
||||
consensus.nMinimumChainWork = uint256S("0x00");
|
||||
|
@ -17,6 +17,7 @@ enum DeploymentPos
|
||||
DEPLOYMENT_TESTDUMMY,
|
||||
DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113.
|
||||
DEPLOYMENT_DIP0001, // Deployment of DIP0001 and lower transaction fees.
|
||||
DEPLOYMENT_BIP147, // Deployment of BIP147 (NULLDUMMY)
|
||||
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
|
||||
MAX_VERSION_BITS_DEPLOYMENTS
|
||||
};
|
||||
|
@ -1270,6 +1270,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
|
||||
softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
|
||||
BIP9SoftForkDescPushBack(bip9_softforks, "csv", consensusParams, Consensus::DEPLOYMENT_CSV);
|
||||
BIP9SoftForkDescPushBack(bip9_softforks, "dip0001", consensusParams, Consensus::DEPLOYMENT_DIP0001);
|
||||
BIP9SoftForkDescPushBack(bip9_softforks, "bip147", consensusParams, Consensus::DEPLOYMENT_BIP147);
|
||||
obj.push_back(Pair("softforks", softforks));
|
||||
obj.push_back(Pair("bip9_softforks", bip9_softforks));
|
||||
|
||||
|
@ -47,6 +47,7 @@ enum
|
||||
dashconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0,
|
||||
dashconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts
|
||||
dashconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance
|
||||
dashconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY = (1U << 4), // enforce NULLDUMMY (BIP147)
|
||||
dashconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65)
|
||||
dashconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // enable CHECKSEQUENCEVERIFY (BIP112)
|
||||
};
|
||||
|
@ -2131,6 +2131,10 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd
|
||||
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
|
||||
}
|
||||
|
||||
if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_BIP147, versionbitscache) == THRESHOLD_ACTIVE) {
|
||||
flags |= SCRIPT_VERIFY_NULLDUMMY;
|
||||
}
|
||||
|
||||
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
|
||||
LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001);
|
||||
|
||||
|
@ -21,6 +21,11 @@ const struct BIP9DeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION
|
||||
/*.name =*/ "dip0001",
|
||||
/*.gbt_force =*/ true,
|
||||
/*.check_mn_protocol =*/ true,
|
||||
},
|
||||
{
|
||||
/*.name =*/ "bip147",
|
||||
/*.gbt_force =*/ true,
|
||||
/*.check_mn_protocol =*/ false,
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user