def test_create_membership_proof():
    leaves = [b'a', b'b', b'c']
    merkle = FixedMerkle(2, leaves)
    proof_1 = merkle.create_membership_proof(b'a')
    proof_2 = merkle.create_membership_proof(b'c')
    assert merkle.check_membership(b'a', 0, proof_1) is True
    assert merkle.check_membership(b'c', 2, proof_2) is True
Example #2
0
    def withdraw(self, tx_id, oindex, exitor):
        transaction = self.transactions[tx_id]

        tx = transaction['tx']
        encoded_tx = rlp.encode(tx).hex()
        tx_bytes = rlp.encode(tx, UnsignedTransaction)
        sigs = tx.sig1 + tx.sig2 + transaction['confirm_sigs']

        blknum, txindex = self.child_chain.get_tx_pos(encoded_tx)
        utxo_pos = blknum * 1000000000 + txindex * 10000 + oindex * 1

        if transaction['is_deposit']:
            deposit_amount = tx.amount1

            self.root_chain.transact({
                'from': exitor['address']
            }).startDepositExit(utxo_pos + 1, NULL_ADDRESS_HEX, deposit_amount)
        else:
            output_block = self.child_chain.blocks[blknum]
            hashed_transaction_set = [transaction.merkle_hash for transaction in output_block.transaction_set]
            merkle = FixedMerkle(16, hashed_transaction_set, hashed=True)
            proof = merkle.create_membership_proof(tx.merkle_hash)

            self.root_chain.transact({
                'from': exitor['address']
            }).startExit(utxo_pos, tx_bytes, proof, sigs)
Example #3
0
 def start_standard_exit(self, output_id, key, bond=None):
     output_tx = self.child_chain.get_transaction(output_id)
     merkle = FixedMerkle(16, [output_tx.encoded])
     proof = merkle.create_membership_proof(output_tx.encoded)
     bond = bond if bond is not None else self.root_chain.standardExitBond()
     self.root_chain.startStandardExit(output_id,
                                       output_tx.encoded,
                                       proof,
                                       value=bond,
                                       sender=key)
Example #4
0
def test_challenge_exit(t, u, root_chain, assert_tx_failed):
    owner, value_1, key = t.a1, 100, t.k1
    tx1 = Transaction(0, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1,
                      NULL_ADDRESS, 0)
    deposit_tx_hash = get_deposit_hash(owner, NULL_ADDRESS, value_1)
    utxo_pos1 = encode_utxo_id(root_chain.getDepositBlock(), 0, 0)
    root_chain.deposit(value=value_1, sender=key)
    utxo_pos2 = encode_utxo_id(root_chain.getDepositBlock(), 0, 0)
    root_chain.deposit(value=value_1, sender=key)
    merkle = FixedMerkle(16, [deposit_tx_hash], True)
    proof = merkle.create_membership_proof(deposit_tx_hash)
    confirmSig1 = confirm_tx(tx1, root_chain.getPlasmaBlock(utxo_pos1)[0], key)
    sigs = tx1.sig1 + tx1.sig2 + confirmSig1
    root_chain.startDepositExit(utxo_pos1,
                                NULL_ADDRESS,
                                tx1.amount1,
                                sender=key)
    tx3 = Transaction(utxo_pos2, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1,
                      NULL_ADDRESS, 0)
    tx3.sign1(key)
    tx_bytes3 = rlp.encode(tx3, UnsignedTransaction)
    merkle = FixedMerkle(16, [tx3.merkle_hash], True)
    proof = merkle.create_membership_proof(tx3.merkle_hash)
    child_blknum = root_chain.currentChildBlock()
    root_chain.submitBlock(merkle.root)
    confirmSig = confirm_tx(tx3,
                            root_chain.getPlasmaBlock(child_blknum)[0], key)
    sigs = tx3.sig1 + tx3.sig2
    utxo_pos3 = encode_utxo_id(child_blknum, 0, 0)
    tx4 = Transaction(utxo_pos1, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1,
                      NULL_ADDRESS, 0)
    tx4.sign1(key)
    tx_bytes4 = rlp.encode(tx4, UnsignedTransaction)
    merkle = FixedMerkle(16, [tx4.merkle_hash], True)
    proof = merkle.create_membership_proof(tx4.merkle_hash)
    child_blknum = root_chain.currentChildBlock()
    root_chain.submitBlock(merkle.root)
    confirmSig = confirm_tx(tx4,
                            root_chain.getPlasmaBlock(child_blknum)[0], key)
    sigs = tx4.sig1 + tx4.sig2
    utxo_pos4 = encode_utxo_id(child_blknum, 0, 0)
    oindex1 = 0
    assert root_chain.exits(utxo_pos1) == [
        '0x' + owner.hex(), NULL_ADDRESS_HEX, 100
    ]
    # Fails if transaction after exit doesn't reference the utxo being exited
    assert_tx_failed(lambda: root_chain.challengeExit(
        utxo_pos3, oindex1, tx_bytes3, proof, sigs, confirmSig))
    # Fails if transaction proof is incorrect
    assert_tx_failed(lambda: root_chain.challengeExit(
        utxo_pos4, oindex1, tx_bytes4, proof[::-1], sigs, confirmSig))
    # Fails if transaction confirmation is incorrect
    assert_tx_failed(lambda: root_chain.challengeExit(
        utxo_pos4, oindex1, tx_bytes4, proof, sigs, confirmSig[::-1]))
    root_chain.challengeExit(utxo_pos4, oindex1, tx_bytes4, proof, sigs,
                             confirmSig)
    assert root_chain.exits(utxo_pos1) == [
        NULL_ADDRESS_HEX, NULL_ADDRESS_HEX, value_1
    ]
Example #5
0
 def start_standard_exit_with_tx_body(self,
                                      output_id,
                                      output_tx,
                                      key,
                                      bond=None):
     merkle = FixedMerkle(16, [output_tx.encoded])
     proof = merkle.create_membership_proof(output_tx.encoded)
     bond = bond if bond is not None else self.root_chain.standardExitBond()
     self.root_chain.startStandardExit(output_id,
                                       output_tx.encoded,
                                       proof,
                                       value=bond,
                                       sender=key)
Example #6
0
def test_initialize_with_leaves_more_than_depth_permits():
    depth = 1
    leaves = [b'dummy leaf'] * (2**depth + 1)
    with pytest.raises(ValueError) as e:
        FixedMerkle(depth, leaves, True)
    assert str(
        e.value) == 'num of leaves exceed max avaiable num with the depth'
Example #7
0
def test_initialize_with_too_many_leaves():
    depth = 1
    leaves = [b'asdf'] * (2**depth + 1)

    with pytest.raises(ValueError) as e:
        FixedMerkle(depth, leaves)

    assert str(e.value) == 'number of leaves should be at most depth ** 2'
Example #8
0
def test_initialize_with_leaves(num_leaves):
    depth = math.ceil(math.log(num_leaves, 2))
    leaves = [b'asdf'] * num_leaves

    hashed_leaves = [sha3(leaf) for leaf in leaves]
    empty_leaves = [sha3(NULL_HASH)] * (2**depth - num_leaves)

    assert FixedMerkle(depth, leaves).leaves == hashed_leaves + empty_leaves
def test_create_membership_proof():
    leaf = b'c'
    leaves = [b'a', b'b', leaf]
    proof = FixedMerkle(2, leaves).create_membership_proof(leaf)
    sibling_hash = sha3(LEAF_SALT + NULL_HASH)
    node_hash = sha3(NODE_SALT + sha3(LEAF_SALT + leaves[0]) +
                     sha3(LEAF_SALT + leaves[1]))
    assert proof == sibling_hash + node_hash
Example #10
0
def test_deposit_valid_values_should_succeed(ethtester, testlang):
    owner, amount = testlang.accounts[0], 100
    deposit_id = testlang.deposit(owner, amount)
    deposit_tx = testlang.child_chain.get_transaction(deposit_id)

    merkle = FixedMerkle(16, [deposit_tx.encoded])

    assert testlang.root_chain.blocks(1) == [merkle.root, ethtester.chain.head_state.timestamp]
    assert testlang.root_chain.nextDepositBlock() == 2
Example #11
0
 def start_standard_exit_with_tx_body(self,
                                      output_id,
                                      output_tx,
                                      account,
                                      bond=None,
                                      block=None):
     transactions = [output_tx]
     if block:
         transactions = block.transactions
     merkle = FixedMerkle(16, list(map(lambda tx: tx.encoded,
                                       transactions)))
     proof = merkle.create_membership_proof(output_tx.encoded)
     bond = bond if bond is not None else self.root_chain.standardExitBond()
     self.root_chain.startStandardExit(
         output_id, output_tx.encoded, proof, **{
             'value': bond,
             'from': account.address
         })
Example #12
0
    def challenge_exit(self, blknum, confirmSig, account):
        oindex = 0
        utxo_pos = blknum * 1000000000 + 10000 * 0 + oindex

        tx = self.get_transaction(utxo_pos)
        tx_bytes = rlp.encode(tx, UnsignedTransaction)

        merkle = FixedMerkle(16, [tx.merkle_hash], True)
        proof = merkle.create_membership_proof(tx.merkle_hash)

        sigs = tx.sig1 + tx.sig2

        return self.root_chain.challengeExit(utxo_pos,
                                             oindex,
                                             tx_bytes,
                                             proof,
                                             sigs,
                                             confirmSig,
                                             transact={
                                                 'from': account,
                                                 'gas': 40000000
                                             })
def test_check_membership(u):
    leaf_1 = b'\xff' * 31 + b'\x01'
    leaf_2 = b'\xff' * 31 + b'\x02'
    leaf_3 = b'\xff' * 31 + b'\x03'
    leaf_4 = b'\xff' * 31 + b'\x04'
    root = u.sha3(u.sha3(leaf_1 + leaf_2) + u.sha3(leaf_3 + leaf_4))
    zeros_hashes = get_empty_merkle_tree_hash(2)
    for _ in range(13):
        root = u.sha3(root + zeros_hashes[-32:])
        zeros_hashes += u.sha3(zeros_hashes[-32:] + zeros_hashes[-32:])
    left_proof = leaf_2 + u.sha3(leaf_3 + leaf_4) + zeros_hashes
    left_middle_proof = leaf_1 + u.sha3(leaf_3 + leaf_4) + zeros_hashes
    right_middle_proof = leaf_4 + u.sha3(leaf_1 + leaf_2) + zeros_hashes
    right_proof = leaf_3 + u.sha3(leaf_1 + leaf_2) + zeros_hashes
    fixed_merkle = FixedMerkle(16, [leaf_1, leaf_2, leaf_3, leaf_4], True)
    assert fixed_merkle.check_membership(leaf_1, 0, left_proof) is True
    assert fixed_merkle.check_membership(leaf_2, 1, left_middle_proof) is True
    assert fixed_merkle.check_membership(leaf_3, 2, right_middle_proof) is True
    assert fixed_merkle.check_membership(leaf_4, 3, right_proof) is True
Example #14
0
 def merkle_tree(self):
     hashed_transaction_set = [
         transaction.merkle_hash for transaction in self.transaction_set
     ]
     return FixedMerkle(16, hashed_transaction_set, hashed=True)
def test_non_member():
    leaves = [b'a', b'b', b'c']
    merkle = FixedMerkle(2, leaves, True)
    assert merkle.not_member(b'b') is False
    assert merkle.not_member(b'd') is True
def test_initial_state():
    assert FixedMerkle(2).leaves == [NULL_HASH] * 4
    assert FixedMerkle(3).leaves == [NULL_HASH] * 8
    assert FixedMerkle(12).leaves == [NULL_HASH] * (2**12)
Example #17
0
def test_initial_state(depth):
    assert FixedMerkle(depth).leaves == [sha3(NULL_HASH)] * (2**depth)
def test_initialize_with_leaves():
    leaves_1 = [b'a', b'c', b'c']
    leaves_2 = [b'a', b'c', b'c', b'd', b'e']
    assert FixedMerkle(2, leaves_1, True).leaves == leaves_1 + [NULL_HASH]
    assert FixedMerkle(3, leaves_2, True).leaves == leaves_2 + [NULL_HASH] * 3
def test_hash_empty_tree():
    root_1 = sha3(NULL_HASH + NULL_HASH)
    root_2 = sha3(root_1 + root_1)
    assert FixedMerkle(1, [], True).root == root_1
    assert FixedMerkle(2, [], True).root == root_2
    assert FixedMerkle(16, [], True).root == get_empty_merkle_tree_hash(16)
Example #20
0
def get_merkle_of_leaves(depth, leaves):
    return FixedMerkle(depth, leaves)
Example #21
0
def test_empty_tree(depth):
    assert FixedMerkle(depth).root == get_empty_tree_hash(depth)
Example #22
0
def test_create_membership_proof():
    leaves = [b'a', b'b', b'c']
    proof = FixedMerkle(2, leaves).create_membership_proof(leaves[2])
    assert proof == sha3(NULL_HASH) + sha3(sha3(leaves[0]) + sha3(leaves[1]))
Example #23
0
 def merklize_transaction_set(self):
     hashed_transaction_set = [
         transaction.merkle_hash for transaction in self.transaction_set
     ]
     self.merkle = FixedMerkle(16, hashed_transaction_set, hashed=True)
     return self.merkle.root
Example #24
0
def test_check_membership():
    leaves = [b'a', b'b', b'c']
    merkle = FixedMerkle(2, leaves)
    proof = merkle.create_membership_proof(leaves[2])
    assert merkle.check_membership(leaves[2], 2, proof)
Example #25
0
def test_start_exit(t, root_chain, assert_tx_failed):
    week_and_a_half = 60 * 60 * 24 * 13
    owner, value_1, key = t.a1, 100, t.k1
    tx1 = Transaction(0, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1,
                      NULL_ADDRESS, 0)
    deposit_tx_hash = get_deposit_hash(owner, NULL_ADDRESS, value_1)
    dep_blknum = root_chain.getDepositBlock()
    assert dep_blknum == 1
    root_chain.deposit(value=value_1, sender=key)
    merkle = FixedMerkle(16, [deposit_tx_hash], True)
    proof = merkle.create_membership_proof(deposit_tx_hash)
    confirmSig1 = tx1.confirm(root_chain.getChildChain(dep_blknum)[0], key)
    priority1 = dep_blknum * 1000000000 + 10000 * 0 + 1
    snapshot = t.chain.snapshot()
    sigs = tx1.sig1 + tx1.sig2 + confirmSig1
    utxoId = dep_blknum * 1000000000 + 10000 * 0 + 1
    # Deposit exit
    root_chain.startDepositExit(utxoId, NULL_ADDRESS, tx1.amount1, sender=key)

    t.chain.head_state.timestamp += week_and_a_half
    # Cannot exit twice off of the same utxo
    utxo_pos1 = dep_blknum * 1000000000 + 10000 * 0 + 1
    assert_tx_failed(lambda: root_chain.startExit(
        utxo_pos1, deposit_tx_hash, proof, sigs, sender=key))
    assert root_chain.getExit(priority1) == [
        address_to_hex(owner), NULL_ADDRESS_HEX, 100
    ]
    t.chain.revert(snapshot)

    tx2 = Transaction(dep_blknum, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1,
                      NULL_ADDRESS, 0)
    tx2.sign1(key)
    tx_bytes2 = rlp.encode(tx2, UnsignedTransaction)
    merkle = FixedMerkle(16, [tx2.merkle_hash], True)
    proof = merkle.create_membership_proof(tx2.merkle_hash)
    child_blknum = root_chain.currentChildBlock()
    assert child_blknum == 1000
    root_chain.submitBlock(merkle.root)
    confirmSig1 = tx2.confirm(root_chain.getChildChain(child_blknum)[0], key)
    priority2 = child_blknum * 1000000000 + 10000 * 0 + 0
    sigs = tx2.sig1 + tx2.sig2 + confirmSig1
    snapshot = t.chain.snapshot()
    # # Single input exit
    utxo_pos2 = child_blknum * 1000000000 + 10000 * 0 + 0
    root_chain.startExit(utxo_pos2, tx_bytes2, proof, sigs, sender=key)
    assert root_chain.getExit(priority2) == [
        address_to_hex(owner), NULL_ADDRESS_HEX, 100
    ]
    t.chain.revert(snapshot)
    dep2_blknum = root_chain.getDepositBlock()
    assert dep2_blknum == 1001
    root_chain.deposit(value=value_1, sender=key)
    tx3 = Transaction(child_blknum, 0, 0, dep2_blknum, 0, 0, NULL_ADDRESS,
                      owner, value_1, NULL_ADDRESS, 0, 0)
    tx3.sign1(key)
    tx3.sign2(key)
    tx_bytes3 = rlp.encode(tx3, UnsignedTransaction)
    merkle = FixedMerkle(16, [tx3.merkle_hash], True)
    proof = merkle.create_membership_proof(tx3.merkle_hash)
    child2_blknum = root_chain.currentChildBlock()
    assert child2_blknum == 2000
    root_chain.submitBlock(merkle.root)
    confirmSig1 = tx3.confirm(root_chain.getChildChain(child2_blknum)[0], key)
    confirmSig2 = tx3.confirm(root_chain.getChildChain(child2_blknum)[0], key)
    priority3 = child2_blknum * 1000000000 + 10000 * 0 + 0
    sigs = tx3.sig1 + tx3.sig2 + confirmSig1 + confirmSig2
    # Double input exit
    utxoPos3 = child2_blknum * 1000000000 + 10000 * 0 + 0
    root_chain.startExit(utxoPos3, tx_bytes3, proof, sigs, sender=key)
    assert root_chain.getExit(priority3) == [
        address_to_hex(owner), NULL_ADDRESS_HEX, 100
    ]
Example #26
0
def test_start_exit(t, root_chain, assert_tx_failed):
    week_and_a_half = 60 * 60 * 24 * 13
    owner, value_1, key = t.a1, 100, t.k1
    tx1 = Transaction(0, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1,
                      NULL_ADDRESS, 0)
    deposit_tx_hash = get_deposit_hash(owner, NULL_ADDRESS, value_1)
    dep_blknum = root_chain.getDepositBlock()
    assert dep_blknum == 1
    root_chain.deposit(value=value_1, sender=key)
    merkle = FixedMerkle(16, [deposit_tx_hash], True)
    proof = merkle.create_membership_proof(deposit_tx_hash)
    confirmSig1 = confirm_tx(tx1,
                             root_chain.getPlasmaBlock(dep_blknum)[0], key)
    snapshot = t.chain.snapshot()
    sigs = tx1.sig1 + tx1.sig2 + confirmSig1
    utxoId = encode_utxo_id(dep_blknum, 0, 0)
    # Deposit exit
    exit_bond = root_chain.EXIT_BOND()
    root_chain.startDepositExit(utxoId,
                                NULL_ADDRESS,
                                tx1.amount1,
                                sender=key,
                                value=exit_bond)

    t.chain.head_state.timestamp += week_and_a_half
    # Cannot exit twice off of the same utxo
    utxo_pos1 = encode_utxo_id(dep_blknum, 0, 0)
    assert_tx_failed(lambda: root_chain.startExit(
        utxo_pos1, deposit_tx_hash, proof, sigs, sender=key, value=exit_bond))
    assert root_chain.getExit(utxo_pos1) == [
        '0x' + owner.hex(), NULL_ADDRESS_HEX, 100
    ]
    t.chain.revert(snapshot)

    tx2 = Transaction(dep_blknum, 0, 0, 0, 0, 0, NULL_ADDRESS, owner, value_1,
                      NULL_ADDRESS, 0)
    tx2.sign1(key)
    tx_bytes2 = rlp.encode(tx2, UnsignedTransaction)
    merkle = FixedMerkle(16, [tx2.merkle_hash], True)
    proof = merkle.create_membership_proof(tx2.merkle_hash)
    child_blknum = root_chain.currentChildBlock()
    assert child_blknum == 1000
    root_chain.submitBlock(merkle.root)
    confirmSig1 = confirm_tx(tx2,
                             root_chain.getPlasmaBlock(child_blknum)[0], key)
    sigs = tx2.sig1 + tx2.sig2 + confirmSig1
    snapshot = t.chain.snapshot()
    # # Single input exit
    utxo_pos2 = encode_utxo_id(child_blknum, 0, 0)
    root_chain.startExit(utxo_pos2,
                         tx_bytes2,
                         proof,
                         sigs,
                         sender=key,
                         value=exit_bond)
    assert root_chain.getExit(utxo_pos2) == [
        '0x' + owner.hex(), NULL_ADDRESS_HEX, 100
    ]
    t.chain.revert(snapshot)
    dep2_blknum = root_chain.getDepositBlock()
    assert dep2_blknum == 1001
    root_chain.deposit(value=value_1, sender=key)
    tx3 = Transaction(child_blknum, 0, 0, dep2_blknum, 0, 0, NULL_ADDRESS,
                      owner, value_1, NULL_ADDRESS, 0, 0)
    tx3.sign1(key)
    tx3.sign2(key)
    tx_bytes3 = rlp.encode(tx3, UnsignedTransaction)
    merkle = FixedMerkle(16, [tx3.merkle_hash], True)
    proof = merkle.create_membership_proof(tx3.merkle_hash)
    child2_blknum = root_chain.currentChildBlock()
    assert child2_blknum == 2000
    root_chain.submitBlock(merkle.root)
    confirmSig1 = confirm_tx(tx3,
                             root_chain.getPlasmaBlock(child2_blknum)[0], key)
    confirmSig2 = confirm_tx(tx3,
                             root_chain.getPlasmaBlock(child2_blknum)[0], key)
    sigs = tx3.sig1 + tx3.sig2 + confirmSig1 + confirmSig2
    # Double input exit
    utxo_pos3 = encode_utxo_id(child2_blknum, 0, 0)
    root_chain.startExit(utxo_pos3,
                         tx_bytes3,
                         proof,
                         sigs,
                         sender=key,
                         value=exit_bond)
    assert root_chain.getExit(utxo_pos3) == [
        '0x' + owner.hex(), NULL_ADDRESS_HEX, 100
    ]
Example #27
0
 def merklized_transaction_set(self):
     encoded_transactions = [tx.encoded for tx in self.transactions]
     return FixedMerkle(16, encoded_transactions)
Example #28
0
 def merklized_transaction_set(self):
     hashed_transactions = [tx.merkle_hash for tx in self.transaction_set]
     return FixedMerkle(16, hashed_transactions, hashed=True)