Skip to content

Commit

Permalink
Improve the fedpeg test with extra double claim tests
Browse files Browse the repository at this point in the history
- changes the expected behavior of claimpegin to fail on double spend
- adds extra test to make sure a block with a double spend is also not
  accepted:
  1. a tx with two identical pegin inputs (mempool & block)
  2. a tx claiming a pegin that another mempool tx also claims
  3. a tx claiming a pegin that a confirmed tx already claimed (mempool
     & block)
  • Loading branch information
stevenroose committed May 8, 2019
1 parent 48a82fa commit 52ef283
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions test/functional/feature_fedpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@
p2p_port,
assert_raises_rpc_error,
assert_equal,
bytes_to_hex_str,
)
from test_framework import util
from test_framework.messages import (
CBlock,
CTransaction,
CTxInWitness,
FromHex,
)
from test_framework.blocktools import (
add_witness_commitment,
)
from decimal import Decimal

def get_new_unconfidential_address(node, addr_type="p2sh-segwit"):
Expand Down Expand Up @@ -167,6 +173,7 @@ def run_test(self):
#parent2 = self.nodes[1]
sidechain = self.nodes[2]
sidechain2 = self.nodes[3]
util.node_fastmerkle = sidechain

parent.generate(101)
sidechain.generate(101)
Expand Down Expand Up @@ -214,6 +221,22 @@ def run_test(self):

# 12 confirms allows in mempool
parent.generate(1)

# Make sure that a tx with a duplicate pegin claim input gets rejected.
raw_pegin = sidechain.createrawpegin(raw, proof)["hex"]
raw_pegin = FromHex(CTransaction(), raw_pegin)
raw_pegin.vin.append(raw_pegin.vin[0]) # duplicate the pegin input
raw_pegin = sidechain.signrawtransactionwithwallet(raw_pegin.serialize().hex())["hex"]
assert_raises_rpc_error(-26, "bad-txns-inputs-duplicate", sidechain.sendrawtransaction, raw_pegin)
# Also try including this tx in a block manually and submitting it.
doublespendblock = FromHex(CBlock(), sidechain.getnewblockhex())
doublespendblock.vtx.append(FromHex(CTransaction(), raw_pegin))
doublespendblock.hashMerkleRoot = doublespendblock.calc_merkle_root()
add_witness_commitment(doublespendblock)
doublespendblock.solve()
block_hex = bytes_to_hex_str(doublespendblock.serialize(True))
assert_raises_rpc_error(-25, "bad-txns-inputs-duplicate", sidechain.testproposedblock, block_hex, True)

# Should succeed via wallet lookup for address match, and when given
raw_pegin = sidechain.createrawpegin(raw, proof)['hex']
signed_pegin = sidechain.signrawtransactionwithwallet(raw_pegin)
Expand All @@ -225,6 +248,9 @@ def run_test(self):
sample_pegin_witness = sample_pegin_struct.wit.vtxinwit[0].peginWitness

pegtxid1 = sidechain.claimpegin(raw, proof)
# Make sure a second pegin claim does not get accepted in the mempool when
# another mempool tx already claims that pegin.
assert_raises_rpc_error(-4, "txn-mempool-conflict", sidechain.claimpegin, raw, proof)

# Will invalidate the block that confirms this transaction later
self.sync_all(self.node_groups)
Expand Down Expand Up @@ -254,6 +280,21 @@ def run_test(self):
sidechain.invalidateblock(blockhash[0])
if sidechain.gettransaction(pegtxid1)["confirmations"] != 0:
raise Exception("Peg-in didn't unconfirm after invalidateblock call.")

# Create duplicate claim, put it in block along with current one in mempool
# to test duplicate-in-block claims between two txs that are in the same block.
raw_pegin = sidechain.createrawpegin(raw, proof)["hex"]
raw_pegin = sidechain.signrawtransactionwithwallet(raw_pegin)["hex"]
raw_pegin = FromHex(CTransaction(), raw_pegin)
doublespendblock = FromHex(CBlock(), sidechain.getnewblockhex())
assert(len(doublespendblock.vtx) == 2) # coinbase and pegin
doublespendblock.vtx.append(raw_pegin)
doublespendblock.hashMerkleRoot = doublespendblock.calc_merkle_root()
add_witness_commitment(doublespendblock)
doublespendblock.solve()
block_hex = bytes_to_hex_str(doublespendblock.serialize(True))
assert_raises_rpc_error(-25, "bad-txns-double-pegin", sidechain.testproposedblock, block_hex, True)

# Re-enters block
sidechain.generate(1)
if sidechain.gettransaction(pegtxid1)["confirmations"] != 1:
Expand All @@ -262,6 +303,19 @@ def run_test(self):
if sidechain.gettransaction(pegtxid1)["confirmations"] != 6:
raise Exception("Peg-in should be back to 6 confirms.")

# Now the pegin is already claimed in a confirmed tx.
# In that case, a duplicate claim should (1) not be accepted in the mempool
# and (2) not be accepted in a block.
assert_raises_rpc_error(-4, "pegin-already-claimed", sidechain.claimpegin, raw, proof)
# For case (2), manually craft a block and include the tx.
doublespendblock = FromHex(CBlock(), sidechain.getnewblockhex())
doublespendblock.vtx.append(raw_pegin)
doublespendblock.hashMerkleRoot = doublespendblock.calc_merkle_root()
add_witness_commitment(doublespendblock)
doublespendblock.solve()
block_hex = bytes_to_hex_str(doublespendblock.serialize(True))
assert_raises_rpc_error(-25, "bad-txns-double-pegin", sidechain.testproposedblock, block_hex, True)

# Do multiple claims in mempool
n_claims = 6

Expand Down

0 comments on commit 52ef283

Please sign in to comment.