Пример #1
0
def test_start_exit_invalid_proof_should_fail(testlang):
    owner, amount = testlang.accounts[0], 100

    # Create a deposit
    deposit_blknum = testlang.deposit(owner, amount)
    deposit_utxo_position = encode_utxo_position(deposit_blknum, 0, 0)

    # Spend the deposit and submit the block
    spend_utxo_position = testlang.spend_utxo(deposit_utxo_position, owner,
                                              amount, owner)
    testlang.confirm(spend_utxo_position, 0, owner)

    # Start an exit
    bond = testlang.root_chain.EXIT_BOND()
    proof = b''  # Using empty proof
    (encoded_tx, _, signatures,
     confirmations) = testlang.get_exit_proof(spend_utxo_position)
    with pytest.raises(TransactionFailed):
        testlang.root_chain.startExit(
            *decode_utxo_position(spend_utxo_position),
            encoded_tx,
            proof,
            signatures,
            confirmations,
            value=bond)
Пример #2
0
def test_challenge_exit_invalid_confirmation_signatures_should_fail(testlang):
    (exiting_utxo_position, spending_utxo_position) = start_exit_spend(testlang)

    # Exit should fail
    confirmation_signature = b''  # Using empty confirmation signatures
    (encoded_tx, _) = testlang.get_challenge_proof(exiting_utxo_position, spending_utxo_position)
    with pytest.raises(TransactionFailed):
        testlang.root_chain.challengeExit(*decode_utxo_position(exiting_utxo_position),
                                          encoded_tx,
                                          confirmation_signature)
Пример #3
0
def test_challenge_exit_invalid_tx_should_fail(testlang):
    (exiting_utxo_position, spending_utxo_position) = start_exit_spend(testlang)

    # Exit should fail
    encoded_tx = testlang.child_chain.get_transaction(exiting_utxo_position).encoded  # Using the wrong tx
    (_, confirmation_signature) = testlang.get_challenge_proof(exiting_utxo_position, spending_utxo_position)
    with pytest.raises(TransactionFailed):
        testlang.root_chain.challengeExit(*decode_utxo_position(exiting_utxo_position),
                                          encoded_tx,
                                          confirmation_signature)
    def get_transaction(self, transaction_position):
        """Returns the transaction at a given position.

        Args:
            transaction_position (int): Transaction position to query.

        Returns:
            Transaction: Corresponding transaction object.
        """

        (blknum, txindex, _) = decode_utxo_position(transaction_position)
        return self.blocks[blknum].transactions[txindex]
    def challenge_exit(self, exiting_utxo_position, spending_tx_position):
        """Challenges an exit with a double spend.

        Args:
            exiting_utxo_position (int): Position of the UTXO being exited.
            spending_tx_position (int): Position of the transaction that spent the UTXO.
        """

        proof_data = self.get_challenge_proof(exiting_utxo_position,
                                              spending_tx_position)
        self.root_chain.challengeExit(
            *decode_utxo_position(exiting_utxo_position), *proof_data)
    def start_exit(self, owner, utxo_position):
        """Starts a standard exit.

        Args:
            owner (EthereumAccount): Account to attempt the exit.
            utxo_position (int): Position of the UTXO to be exited.
        """

        bond = self.root_chain.EXIT_BOND()
        self.root_chain.startExit(*decode_utxo_position(utxo_position),
                                  *self.get_exit_proof(utxo_position),
                                  sender=owner.key,
                                  value=bond)
Пример #7
0
    def get_challenge_proof(self, exiting_utxo_position, spending_tx_position):
        """Returns information required to submit a challenge.

        Args:
            exiting_utxo_position (int): Position of the UTXO being exited.
            spending_tx_position (int): Position of the transaction that spent the UTXO.

        Returns:
            bytes, bytes: Information necessary to create a challenge proof.
        """

        spend_tx = self.child_chain.get_transaction(spending_tx_position)
        (_, _, oindex) = decode_utxo_position(spending_tx_position)
        confirmation_signature = spend_tx.confirmations[oindex]
        return (spend_tx.encoded, confirmation_signature)
Пример #8
0
    def get_exit_proof(self, utxo_position):
        """Returns information required to exit

        Args:
            utxo_position (int): Position of the UTXO to be exited.
        
        Returns:
            bytes, bytes, bytes, bytes: Information necessary to exit the UTXO.
        """

        (blknum, _, _) = decode_utxo_position(utxo_position)
        block = self.child_chain.get_block(blknum)

        spend_tx = self.child_chain.get_transaction(utxo_position)
        encoded_tx = spend_tx.encoded
        proof = block.merkle.create_membership_proof(spend_tx.encoded)
        signatures = spend_tx.joined_signatures
        confirmation_signatures = spend_tx.joined_confirmations
        return (encoded_tx, proof, signatures, confirmation_signatures)
Пример #9
0
def test_start_exit_wrong_bond_value_should_fail(testlang):
    owner, amount = testlang.accounts[0], 100

    # Create a deposit
    deposit_blknum = testlang.deposit(owner, amount)
    deposit_utxo_position = encode_utxo_position(deposit_blknum, 0, 0)

    # Spend the deposit and submit the block
    spend_utxo_position = testlang.spend_utxo(deposit_utxo_position, owner,
                                              amount, owner)
    testlang.confirm(spend_utxo_position, 0, owner)

    # Start an exit
    bond = 0  # Using wrong bond value
    with pytest.raises(TransactionFailed):
        testlang.root_chain.startExit(
            *decode_utxo_position(spend_utxo_position),
            *testlang.get_exit_proof(spend_utxo_position),
            value=bond)
Пример #10
0
    def spend_utxo(self, utxo_position, new_owner, amount, signer):
        """Creates a spending transaction and inserts it into the chain.

        Args:
            utxo_position (int): Identifier of the UTXO to spend.
            new_owner (EthereumAccount): Account to own the output of this spend.
            amount (int): Amount to spend.
            signer (EthereumAccount): Account to sign this transaction.

        Returns:
            int: Unique identifier of the spend.
        """

        spend_tx = Transaction(inputs=[decode_utxo_position(utxo_position)],
                               outputs=[(new_owner.address, amount)])
        spend_tx.sign(0, signer.key)

        blknum = self.root_chain.currentPlasmaBlockNumber()
        block = Block(transactions=[spend_tx], number=blknum)
        self.commit_plasma_block_root(block)
        return encode_utxo_position(blknum, 0, 0)