mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-03 17:54:19 +02:00
SegWit wallet support
This introduces two command line flags (-addresstype and -changetype) which control the type of addresses/outputs created by the GUI and RPCs. Certain RPCs allow overriding these (`getnewaddress` and `getrawchangeaddress`). Supported types are "legacy" (P2PKH and P2SH-multisig), "p2sh-segwit" (P2SH-P2WPKH and P2SH-P2WSH-multisig), and "bech32" (P2WPKH and P2WSH-multisig). A few utility functions are added to the wallet to construct different address type and to add the necessary entries to the wallet file to be compatible with earlier versions (see `CWallet::LearnRelatedScripts`, `GetDestinationForKey`, `GetAllDestinationsForKey`, `CWallet::AddAndGetDestinationForScript`).
This commit is contained in:
@@ -95,7 +95,7 @@ class BIP68_112_113Test(ComparisonTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.setup_clean_chain = True
|
||||
self.extra_args = [['-whitelist=127.0.0.1', '-blockversion=4']]
|
||||
self.extra_args = [['-whitelist=127.0.0.1', '-blockversion=4', '-addresstype=legacy']]
|
||||
|
||||
def run_test(self):
|
||||
test = TestManager(self, self.options.tmpdir)
|
||||
|
||||
@@ -362,9 +362,10 @@ class BIP68Test(BitcoinTestFramework):
|
||||
block.vtx.extend([tx1, tx2, tx3])
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
add_witness_commitment(block)
|
||||
block.solve()
|
||||
|
||||
self.nodes[0].submitblock(ToHex(block))
|
||||
self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True)))
|
||||
assert_equal(self.nodes[0].getbestblockhash(), block.hash)
|
||||
|
||||
def activateCSV(self):
|
||||
|
||||
@@ -194,7 +194,7 @@ def test_settxfee(rbf_node, dest_address):
|
||||
requested_feerate = Decimal("0.00025000")
|
||||
rbf_node.settxfee(requested_feerate)
|
||||
bumped_tx = rbf_node.bumpfee(rbfid)
|
||||
actual_feerate = bumped_tx["fee"] * 1000 / rbf_node.getrawtransaction(bumped_tx["txid"], True)["size"]
|
||||
actual_feerate = bumped_tx["fee"] * 1000 / rbf_node.getrawtransaction(bumped_tx["txid"], True)["vsize"]
|
||||
# Assert that the difference between the requested feerate and the actual
|
||||
# feerate of the bumped transaction is small.
|
||||
assert_greater_than(Decimal("0.00001000"), abs(requested_feerate - actual_feerate))
|
||||
@@ -290,6 +290,7 @@ def submit_block_with_tx(node, tx):
|
||||
block.vtx.append(ctx)
|
||||
block.rehash()
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
blocktools.add_witness_commitment(block)
|
||||
block.solve()
|
||||
node.submitblock(bytes_to_hex_str(block.serialize(True)))
|
||||
return block
|
||||
|
||||
@@ -119,7 +119,7 @@ class ImportRescanTest(BitcoinTestFramework):
|
||||
self.num_nodes = 2 + len(IMPORT_NODES)
|
||||
|
||||
def setup_network(self):
|
||||
extra_args = [[] for _ in range(self.num_nodes)]
|
||||
extra_args = [["-addresstype=legacy"] for _ in range(self.num_nodes)]
|
||||
for i, import_node in enumerate(IMPORT_NODES, 2):
|
||||
if import_node.prune:
|
||||
extra_args[i] += ["-prune=1"]
|
||||
|
||||
@@ -9,6 +9,7 @@ from test_framework.util import *
|
||||
class ImportMultiTest (BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"]]
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def setup_network(self):
|
||||
|
||||
@@ -42,7 +42,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
|
||||
self.setup_clean_chain = True
|
||||
# This script tests NULLDUMMY activation, which is part of the 'segwit' deployment, so we go through
|
||||
# normal segwit activation here (and don't use the default always-on behaviour).
|
||||
self.extra_args = [['-whitelist=127.0.0.1', '-walletprematurewitness', '-vbparams=segwit:0:999999999999']]
|
||||
self.extra_args = [['-whitelist=127.0.0.1', '-walletprematurewitness', '-vbparams=segwit:0:999999999999', '-addresstype=legacy']]
|
||||
|
||||
def run_test(self):
|
||||
self.address = self.nodes[0].getnewaddress()
|
||||
|
||||
@@ -20,6 +20,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 3
|
||||
self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"], ["-addresstype=legacy"]]
|
||||
|
||||
def setup_network(self, split=False):
|
||||
super().setup_network()
|
||||
@@ -135,7 +136,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
break
|
||||
|
||||
bal = self.nodes[0].getbalance()
|
||||
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex']}]
|
||||
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}]
|
||||
outputs = { self.nodes[0].getnewaddress() : 2.19 }
|
||||
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
|
||||
rawTxPartialSigned = self.nodes[1].signrawtransaction(rawTx, inputs)
|
||||
@@ -180,7 +181,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
break
|
||||
|
||||
bal = self.nodes[0].getbalance()
|
||||
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex']}]
|
||||
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex'], "amount" : vout['value']}]
|
||||
outputs = { self.nodes[0].getnewaddress() : 2.19 }
|
||||
rawTx2 = self.nodes[2].createrawtransaction(inputs, outputs)
|
||||
rawTxPartialSigned1 = self.nodes[1].signrawtransaction(rawTx2, inputs)
|
||||
|
||||
@@ -78,9 +78,9 @@ class SegWitTest(BitcoinTestFramework):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 3
|
||||
# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.
|
||||
self.extra_args = [["-walletprematurewitness", "-rpcserialversion=0", "-vbparams=segwit:0:999999999999"],
|
||||
["-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=1", "-vbparams=segwit:0:999999999999"],
|
||||
["-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-vbparams=segwit:0:999999999999"]]
|
||||
self.extra_args = [["-walletprematurewitness", "-rpcserialversion=0", "-vbparams=segwit:0:999999999999", "-addresstype=legacy"],
|
||||
["-blockversion=4", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-rpcserialversion=1", "-vbparams=segwit:0:999999999999", "-addresstype=legacy"],
|
||||
["-blockversion=536870915", "-promiscuousmempoolflags=517", "-prematurewitness", "-walletprematurewitness", "-vbparams=segwit:0:999999999999", "-addresstype=legacy"]]
|
||||
|
||||
def setup_network(self):
|
||||
super().setup_network()
|
||||
@@ -135,9 +135,9 @@ class SegWitTest(BitcoinTestFramework):
|
||||
self.pubkey.append(self.nodes[i].validateaddress(newaddress)["pubkey"])
|
||||
multiaddress = self.nodes[i].addmultisigaddress(1, [self.pubkey[-1]])
|
||||
multiscript = CScript([OP_1, hex_str_to_bytes(self.pubkey[-1]), OP_1, OP_CHECKMULTISIG])
|
||||
p2sh_addr = self.nodes[i].addwitnessaddress(newaddress, True)
|
||||
p2sh_addr = self.nodes[i].addwitnessaddress(newaddress)
|
||||
bip173_addr = self.nodes[i].addwitnessaddress(newaddress, False)
|
||||
p2sh_ms_addr = self.nodes[i].addwitnessaddress(multiaddress, True)
|
||||
p2sh_ms_addr = self.nodes[i].addwitnessaddress(multiaddress)
|
||||
bip173_ms_addr = self.nodes[i].addwitnessaddress(multiaddress, False)
|
||||
assert_equal(p2sh_addr, key_to_p2sh_p2wpkh(self.pubkey[-1]))
|
||||
assert_equal(bip173_addr, key_to_p2wpkh(self.pubkey[-1]))
|
||||
|
||||
@@ -11,6 +11,7 @@ class SignMessagesTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [["-addresstype=legacy"]]
|
||||
|
||||
def run_test(self):
|
||||
message = 'This is just a test message'
|
||||
|
||||
@@ -86,6 +86,7 @@ BASE_SCRIPTS= [
|
||||
'mempool_resurrect_test.py',
|
||||
'txn_doublespend.py --mineblock',
|
||||
'txn_clone.py',
|
||||
'txn_clone.py --segwit',
|
||||
'getchaintips.py',
|
||||
'rest.py',
|
||||
'mempool_spendcoinbase.py',
|
||||
|
||||
@@ -14,6 +14,8 @@ class TxnMallTest(BitcoinTestFramework):
|
||||
def add_options(self, parser):
|
||||
parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true",
|
||||
help="Test double-spend of 1-confirmed transaction")
|
||||
parser.add_option("--segwit", dest="segwit", default=False, action="store_true",
|
||||
help="Test behaviour with SegWit txn (which should fail")
|
||||
|
||||
def setup_network(self):
|
||||
# Start with split network:
|
||||
@@ -22,6 +24,11 @@ class TxnMallTest(BitcoinTestFramework):
|
||||
disconnect_nodes(self.nodes[2], 1)
|
||||
|
||||
def run_test(self):
|
||||
if self.options.segwit:
|
||||
output_type="p2sh-segwit"
|
||||
else:
|
||||
output_type="legacy"
|
||||
|
||||
# All nodes should start with 1,250 BTC:
|
||||
starting_balance = 1250
|
||||
for i in range(4):
|
||||
@@ -31,11 +38,11 @@ class TxnMallTest(BitcoinTestFramework):
|
||||
# Assign coins to foo and bar accounts:
|
||||
self.nodes[0].settxfee(.001)
|
||||
|
||||
node0_address_foo = self.nodes[0].getnewaddress("foo")
|
||||
node0_address_foo = self.nodes[0].getnewaddress("foo", output_type)
|
||||
fund_foo_txid = self.nodes[0].sendfrom("", node0_address_foo, 1219)
|
||||
fund_foo_tx = self.nodes[0].gettransaction(fund_foo_txid)
|
||||
|
||||
node0_address_bar = self.nodes[0].getnewaddress("bar")
|
||||
node0_address_bar = self.nodes[0].getnewaddress("bar", output_type)
|
||||
fund_bar_txid = self.nodes[0].sendfrom("", node0_address_bar, 29)
|
||||
fund_bar_tx = self.nodes[0].gettransaction(fund_bar_txid)
|
||||
|
||||
@@ -106,6 +113,10 @@ class TxnMallTest(BitcoinTestFramework):
|
||||
# Send clone and its parent to miner
|
||||
self.nodes[2].sendrawtransaction(fund_foo_tx["hex"])
|
||||
txid1_clone = self.nodes[2].sendrawtransaction(tx1_clone["hex"])
|
||||
if self.options.segwit:
|
||||
assert_equal(txid1, txid1_clone)
|
||||
return
|
||||
|
||||
# ... mine a block...
|
||||
self.nodes[2].generate(1)
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ def read_dump(file_name, addrs, hd_master_addr_old):
|
||||
class WalletDumpTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.extra_args = [["-keypool=90"]]
|
||||
self.extra_args = [["-keypool=90", "-addresstype=legacy"]]
|
||||
|
||||
def setup_network(self, split=False):
|
||||
# Use 1 minute timeout because the initial getnewaddress RPC can take
|
||||
|
||||
@@ -27,6 +27,9 @@ class WalletTest(BitcoinTestFramework):
|
||||
assert_fee_amount(fee, tx_size, fee_per_byte * 1000)
|
||||
return curr_balance
|
||||
|
||||
def get_vsize(self, txn):
|
||||
return self.nodes[0].decoderawtransaction(txn)['vsize']
|
||||
|
||||
def run_test(self):
|
||||
# Check that there's no UTXO on none of the nodes
|
||||
assert_equal(len(self.nodes[0].listunspent()), 0)
|
||||
@@ -162,7 +165,7 @@ class WalletTest(BitcoinTestFramework):
|
||||
txid = self.nodes[2].sendtoaddress(address, 10, "", "", False)
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all([self.nodes[0:3]])
|
||||
node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid)))
|
||||
node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), Decimal('84'), fee_per_byte, self.get_vsize(self.nodes[2].getrawtransaction(txid)))
|
||||
assert_equal(self.nodes[0].getbalance(), Decimal('10'))
|
||||
|
||||
# Send 10 BTC with subtract fee from amount
|
||||
@@ -171,14 +174,14 @@ class WalletTest(BitcoinTestFramework):
|
||||
self.sync_all([self.nodes[0:3]])
|
||||
node_2_bal -= Decimal('10')
|
||||
assert_equal(self.nodes[2].getbalance(), node_2_bal)
|
||||
node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), Decimal('20'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid)))
|
||||
node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), Decimal('20'), fee_per_byte, self.get_vsize(self.nodes[2].getrawtransaction(txid)))
|
||||
|
||||
# Sendmany 10 BTC
|
||||
txid = self.nodes[2].sendmany('from1', {address: 10}, 0, "", [])
|
||||
self.nodes[2].generate(1)
|
||||
self.sync_all([self.nodes[0:3]])
|
||||
node_0_bal += Decimal('10')
|
||||
node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid)))
|
||||
node_2_bal = self.check_fee_amount(self.nodes[2].getbalance(), node_2_bal - Decimal('10'), fee_per_byte, self.get_vsize(self.nodes[2].getrawtransaction(txid)))
|
||||
assert_equal(self.nodes[0].getbalance(), node_0_bal)
|
||||
|
||||
# Sendmany 10 BTC with subtract fee from amount
|
||||
@@ -187,7 +190,7 @@ class WalletTest(BitcoinTestFramework):
|
||||
self.sync_all([self.nodes[0:3]])
|
||||
node_2_bal -= Decimal('10')
|
||||
assert_equal(self.nodes[2].getbalance(), node_2_bal)
|
||||
node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, count_bytes(self.nodes[2].getrawtransaction(txid)))
|
||||
node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, self.get_vsize(self.nodes[2].getrawtransaction(txid)))
|
||||
|
||||
# Test ResendWalletTransactions:
|
||||
# Create a couple of transactions, then start up a fourth
|
||||
|
||||
Reference in New Issue
Block a user