Changeset View
Changeset View
Standalone View
Standalone View
test/functional/p2p-fullblocktest.py
Show First 20 Lines • Show All 120 Lines • ▼ Show 20 Lines | def next_block(self, number, spend=None, additional_coinbase_value=0, script=CScript([OP_TRUE]), solve=True): | ||||
coinbase = create_coinbase(height, self.coinbase_pubkey) | coinbase = create_coinbase(height, self.coinbase_pubkey) | ||||
coinbase.vout[0].nValue += additional_coinbase_value | coinbase.vout[0].nValue += additional_coinbase_value | ||||
coinbase.rehash() | coinbase.rehash() | ||||
if spend == None: | if spend == None: | ||||
block = create_block(base_block_hash, coinbase, block_time) | block = create_block(base_block_hash, coinbase, block_time) | ||||
else: | else: | ||||
coinbase.vout[0].nValue += spend.tx.vout[ | coinbase.vout[0].nValue += spend.tx.vout[ | ||||
spend.n].nValue - 1 # all but one satoshi to fees | spend.n].nValue - 1 # all but one satoshi to fees | ||||
assert(coinbase.vout[0].nValue) | |||||
coinbase.rehash() | coinbase.rehash() | ||||
block = create_block(base_block_hash, coinbase, block_time) | block = create_block(base_block_hash, coinbase, block_time) | ||||
tx = create_transaction( | tx = create_transaction( | ||||
spend.tx, spend.n, b"", 1, script) # spend 1 satoshi | spend.tx, spend.n, b"", 1, script) # spend 1 satoshi | ||||
self.sign_tx(tx, spend.tx, spend.n) | self.sign_tx(tx, spend.tx, spend.n) | ||||
self.add_transactions_to_block(block, [tx]) | self.add_transactions_to_block(block, [tx]) | ||||
block.hashMerkleRoot = block.calc_merkle_root() | block.hashMerkleRoot = block.calc_merkle_root() | ||||
if solve: | if solve: | ||||
▲ Show 20 Lines • Show All 385 Lines • ▼ Show 20 Lines | def get_tests(self): | ||||
tx.rehash() | tx.rehash() | ||||
b39 = update_block(39, [tx]) | b39 = update_block(39, [tx]) | ||||
b39_outputs += 1 | b39_outputs += 1 | ||||
# Until block is full, add tx's with 1 satoshi to p2sh_script, the rest | # Until block is full, add tx's with 1 satoshi to p2sh_script, the rest | ||||
# to OP_TRUE | # to OP_TRUE | ||||
tx_new = None | tx_new = None | ||||
tx_last = tx | tx_last = tx | ||||
tx_last_n = len(tx.vout) - 1 | |||||
total_size = len(b39.serialize()) | total_size = len(b39.serialize()) | ||||
while(total_size < LEGACY_MAX_BLOCK_SIZE): | while(total_size < LEGACY_MAX_BLOCK_SIZE): | ||||
tx_new = create_tx(tx_last, 1, 1, p2sh_script) | tx_new = create_tx(tx_last, tx_last_n, 1, p2sh_script) | ||||
tx_new.vout.append( | tx_new.vout.append( | ||||
CTxOut(tx_last.vout[1].nValue - 1, CScript([OP_TRUE]))) | CTxOut(tx_last.vout[tx_last_n].nValue - 1, CScript([OP_TRUE]))) | ||||
tx_new.rehash() | tx_new.rehash() | ||||
total_size += len(tx_new.serialize()) | total_size += len(tx_new.serialize()) | ||||
if total_size >= LEGACY_MAX_BLOCK_SIZE: | if total_size >= LEGACY_MAX_BLOCK_SIZE: | ||||
break | break | ||||
b39.vtx.append(tx_new) # add tx to block | b39.vtx.append(tx_new) # add tx to block | ||||
tx_last = tx_new | tx_last = tx_new | ||||
tx_last_n = len(tx_new.vout) - 1 | |||||
b39_outputs += 1 | b39_outputs += 1 | ||||
b39 = update_block(39, []) | b39 = update_block(39, []) | ||||
yield accepted() | yield accepted() | ||||
save_spendable_output() | save_spendable_output() | ||||
# Test sigops in P2SH redeem scripts | # Test sigops in P2SH redeem scripts | ||||
# | # | ||||
Show All 22 Lines | def get_tests(self): | ||||
sighash = SignatureHashForkId( | sighash = SignatureHashForkId( | ||||
redeem_script, tx, 1, SIGHASH_ALL | SIGHASH_FORKID, | redeem_script, tx, 1, SIGHASH_ALL | SIGHASH_FORKID, | ||||
lastAmount) | lastAmount) | ||||
sig = self.coinbase_key.sign( | sig = self.coinbase_key.sign( | ||||
sighash) + bytes(bytearray([SIGHASH_ALL | SIGHASH_FORKID])) | sighash) + bytes(bytearray([SIGHASH_ALL | SIGHASH_FORKID])) | ||||
scriptSig = CScript([sig, redeem_script]) | scriptSig = CScript([sig, redeem_script]) | ||||
tx.vin[1].scriptSig = scriptSig | tx.vin[1].scriptSig = scriptSig | ||||
pad_tx(tx) | |||||
tx.rehash() | tx.rehash() | ||||
new_txs.append(tx) | new_txs.append(tx) | ||||
lastOutpoint = COutPoint(tx.sha256, 0) | lastOutpoint = COutPoint(tx.sha256, 0) | ||||
lastAmount = tx.vout[0].nValue | lastAmount = tx.vout[0].nValue | ||||
b40_sigops_to_fill = MAX_BLOCK_SIGOPS_PER_MB - \ | b40_sigops_to_fill = MAX_BLOCK_SIGOPS_PER_MB - \ | ||||
(numTxes * b39_sigops_per_output + sigops) + 1 | (numTxes * b39_sigops_per_output + sigops) + 1 | ||||
tx = CTransaction() | tx = CTransaction() | ||||
tx.vin.append(CTxIn(lastOutpoint, b'')) | tx.vin.append(CTxIn(lastOutpoint, b'')) | ||||
tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b40_sigops_to_fill))) | tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b40_sigops_to_fill))) | ||||
pad_tx(tx) | |||||
tx.rehash() | tx.rehash() | ||||
new_txs.append(tx) | new_txs.append(tx) | ||||
update_block(40, new_txs) | update_block(40, new_txs) | ||||
yield rejected(RejectResult(16, b'bad-blk-sigops')) | yield rejected(RejectResult(16, b'bad-blk-sigops')) | ||||
# same as b40, but one less sigop | # same as b40, but one less sigop | ||||
tip(39) | tip(39) | ||||
b41 = block(41, spend=None) | b41 = block(41, spend=None) | ||||
update_block(41, b40.vtx[1:-1]) | update_block(41, b40.vtx[1:-1]) | ||||
b41_sigops_to_fill = b40_sigops_to_fill - 1 | b41_sigops_to_fill = b40_sigops_to_fill - 1 | ||||
tx = CTransaction() | tx = CTransaction() | ||||
tx.vin.append(CTxIn(lastOutpoint, b'')) | tx.vin.append(CTxIn(lastOutpoint, b'')) | ||||
tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b41_sigops_to_fill))) | tx.vout.append(CTxOut(1, CScript([OP_CHECKSIG] * b41_sigops_to_fill))) | ||||
pad_tx(tx) | |||||
tx.rehash() | tx.rehash() | ||||
update_block(41, [tx]) | update_block(41, [tx]) | ||||
yield accepted() | yield accepted() | ||||
# Fork off of b39 to create a constant base again | # Fork off of b39 to create a constant base again | ||||
# | # | ||||
# b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) | # b23 (6) -> b30 (7) -> b31 (8) -> b33 (9) -> b35 (10) -> b39 (11) -> b42 (12) -> b43 (13) | ||||
# \-> b41 (12) | # \-> b41 (12) | ||||
▲ Show 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | def get_tests(self): | ||||
# tx with prevout.n out of range | # tx with prevout.n out of range | ||||
tip(57) | tip(57) | ||||
b58 = block(58, spend=out[17]) | b58 = block(58, spend=out[17]) | ||||
tx = CTransaction() | tx = CTransaction() | ||||
assert(len(out[17].tx.vout) < 42) | assert(len(out[17].tx.vout) < 42) | ||||
tx.vin.append( | tx.vin.append( | ||||
CTxIn(COutPoint(out[17].tx.sha256, 42), CScript([OP_TRUE]), 0xffffffff)) | CTxIn(COutPoint(out[17].tx.sha256, 42), CScript([OP_TRUE]), 0xffffffff)) | ||||
tx.vout.append(CTxOut(0, b"")) | tx.vout.append(CTxOut(0, b"")) | ||||
pad_tx(tx) | |||||
tx.calc_sha256() | tx.calc_sha256() | ||||
b58 = update_block(58, [tx]) | b58 = update_block(58, [tx]) | ||||
yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) | yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) | ||||
# tx with output value > input value out of range | # tx with output value > input value out of range | ||||
tip(57) | tip(57) | ||||
b59 = block(59) | b59 = block(59) | ||||
tx = create_and_sign_tx(out[17].tx, out[17].n, 51 * COIN) | tx = create_and_sign_tx(out[17].tx, out[17].n, 51 * COIN) | ||||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | def get_tests(self): | ||||
tip(69) | tip(69) | ||||
block(70, spend=out[21]) | block(70, spend=out[21]) | ||||
bogus_tx = CTransaction() | bogus_tx = CTransaction() | ||||
bogus_tx.sha256 = uint256_from_str( | bogus_tx.sha256 = uint256_from_str( | ||||
b"23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c") | b"23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c") | ||||
tx = CTransaction() | tx = CTransaction() | ||||
tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", 0xffffffff)) | tx.vin.append(CTxIn(COutPoint(bogus_tx.sha256, 0), b"", 0xffffffff)) | ||||
tx.vout.append(CTxOut(1, b"")) | tx.vout.append(CTxOut(1, b"")) | ||||
pad_tx(tx) | |||||
tx.rehash() | |||||
update_block(70, [tx]) | update_block(70, [tx]) | ||||
yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) | yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent')) | ||||
# Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks) | # Test accepting an invalid block which has the same hash as a valid one (via merkle tree tricks) | ||||
# | # | ||||
# -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21) | # -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20) -> b72 (21) | ||||
# \-> b71 (21) | # \-> b71 (21) | ||||
# | # | ||||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | |||||
# Reorg on/off blocks that have OP_RETURN in them (and try to spend them) | # Reorg on/off blocks that have OP_RETURN in them (and try to spend them) | ||||
# | # | ||||
# -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31) | # -> b81 (26) -> b82 (27) -> b83 (28) -> b84 (29) -> b87 (30) -> b88 (31) | ||||
# \-> b85 (29) -> b86 (30) \-> b89a (32) | # \-> b85 (29) -> b86 (30) \-> b89a (32) | ||||
# | # | ||||
# | # | ||||
b84 = block(84) | b84 = block(84) | ||||
tx1 = create_tx(out[29].tx, out[29].n, 0, CScript([OP_RETURN])) | tx1 = create_tx(out[29].tx, out[29].n, 0, CScript([OP_RETURN])) | ||||
vout_offset = len(tx1.vout) | |||||
tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) | tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) | ||||
tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) | tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) | ||||
tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) | tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) | ||||
tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) | tx1.vout.append(CTxOut(0, CScript([OP_TRUE]))) | ||||
tx1.calc_sha256() | tx1.calc_sha256() | ||||
self.sign_tx(tx1, out[29].tx, out[29].n) | self.sign_tx(tx1, out[29].tx, out[29].n) | ||||
tx1.rehash() | tx1.rehash() | ||||
tx2 = create_tx(tx1, 1, 0, CScript([OP_RETURN])) | tx2 = create_tx(tx1, vout_offset, 0, CScript([OP_RETURN])) | ||||
tx2.vout.append(CTxOut(0, CScript([OP_RETURN]))) | tx2.vout.append(CTxOut(0, CScript([OP_RETURN]))) | ||||
tx3 = create_tx(tx1, 2, 0, CScript([OP_RETURN])) | tx3 = create_tx(tx1, vout_offset + 1, 0, CScript([OP_RETURN])) | ||||
tx3.vout.append(CTxOut(0, CScript([OP_TRUE]))) | tx3.vout.append(CTxOut(0, CScript([OP_TRUE]))) | ||||
tx4 = create_tx(tx1, 3, 0, CScript([OP_TRUE])) | tx4 = create_tx(tx1, vout_offset + 2, 0, CScript([OP_TRUE])) | ||||
tx4.vout.append(CTxOut(0, CScript([OP_RETURN]))) | tx4.vout.append(CTxOut(0, CScript([OP_RETURN]))) | ||||
tx5 = create_tx(tx1, 4, 0, CScript([OP_RETURN])) | tx5 = create_tx(tx1, vout_offset + 3, 0, CScript([OP_RETURN])) | ||||
update_block(84, [tx1, tx2, tx3, tx4, tx5]) | update_block(84, [tx1, tx2, tx3, tx4, tx5]) | ||||
yield accepted() | yield accepted() | ||||
save_spendable_output() | save_spendable_output() | ||||
tip(83) | tip(83) | ||||
block(85, spend=out[29]) | block(85, spend=out[29]) | ||||
yield rejected() | yield rejected() | ||||
▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines |