Exemple #1
0
    def lithium_instance(self, run_event, rpc_from, rpc_to, from_account,
                         to_account, lock, link, batch_size):
        ionlock = rpc_from.proxy("abi/IonLock.abi", lock, from_account)
        batch = []

        prev_root = merkle_hash("merkle-tree-extra")

        print("Starting block iterator")
        print("Latest Block: ", ionlock.LatestBlock)

        for is_latest, block_group in self.iter_blocks(run_event, rpc_from,
                                                       ionlock.LatestBlock()):
            items, group_tx_count, group_log_count, transfers = self.process_block_group(
                rpc_from, block_group)
            if items:
                for value in items:
                    self.leaves.append(value)

                pack_items(self.leaves)
                print("blocks %d-%d (%d tx, %d events)" %
                      (min(block_group), max(block_group), group_tx_count,
                       group_log_count))
                tree, root = merkle_tree(self.leaves)
                batch.append((block_group[0], root, transfers[0]))

                if is_latest or len(batch) >= batch_size:
                    print("Submitting batch of", len(batch), "blocks")
                    prev_root = self.lithium_submit(batch, prev_root, rpc_to,
                                                    link, to_account,
                                                    self.checkpoints,
                                                    self.leaves)
                    batch = []
        return 0
Exemple #2
0
def api_proof():
    """
        POST:   Arguments: JSON with leaf, blockid in the form {'leaf': <some_leaf>, 'blockid': <some_blockid>}
                Return: If passed valid information returns merkle proof to supplied leaf of relevant blockid
    """
    if request.method == 'POST':
        json = request.get_json()
        leaf = json[u'leaf']
        blockid = json[u'blockid']
    else:
        return "Please POST leaf data."

    if leaf is not None and blockid is not None:
        nleaves = app.lithium.checkpoints[blockid]
        tree, root = merkle_tree(app.lithium.leaves[:nleaves])

        hex_leaf = leaf.decode('hex')

        path = merkle_path(hex_leaf, tree)

        string_path = [str(x) for x in path]
        dict = {u'proof': string_path}
        return jsonify(dict)
    else:
        return "No valid leaf received."
Exemple #3
0
def api_root():
    """
        GET:    Return: The root for the merkle tree of all leaves
    """
    byte_leaves = app.lithium.leaves
    tree, root = merkle_tree(byte_leaves)
    dict = {u'root': root}
    return jsonify(dict)
Exemple #4
0
 def test_merkle_tree(self):
     """
     Test merkle tree generation
     """
     print("\nTest: Merkle tree generation")
     tree, root = merkle_tree(TEST_DATA)
     self.assertTrue(tree == EXPECTED_TREE)
     self.assertTrue(root == EXPECTED_ROOT)
     print("Test: Merkle tree generation success")
Exemple #5
0
def api_verify_proof():
    """
        POST:   Arguments: JSON with leaf, proof, blockid in the form {'leaf': <some_leaf>, 'proof': [<array_of_path>] 'blockid': <some_blockid>}
                Return: If passed valid information returns a boolean verifying in the supplied leaf is part of the merkle tree
    """
    if request.method == 'POST':
        json = dict(request.get_json())
        leaf = json[u'leaf']
        proof = json[u'proof']
        blockid = json[u'blockid']
    else:
        return "Please POST leaf and path data."

    if leaf is not None and proof is not None and blockid is not None:
        nleaves = app.lithium.checkpoints[blockid]
        leaves = app.lithium.leaves[0:nleaves]
        tree, root = merkle_tree(leaves)

        hex_leaf = leaf.decode('hex')
        proof = merkle_proof(hex_leaf, proof, root)

        return jsonify({"verified": proof})
    else:
        return "No valid leaf or path provided."
Exemple #6
0
    def test_integration(self):
        print("\nTest: Integration")

        totalSupply_a = 1000
        totalSupply_b = 1000
        value_a = 10
        value_b = 10
        rawRef_a = 'Hello world!'
        rawRef_b = 'Hello world!'

        # Assert that both testrpc A and B are live
        sockA = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sockA.settimeout(2)
        self.assertFalse(sockA.connect_ex(('127.0.0.1', 8545)),
                         "Please run testrpc on 127.0.0.1:8545")
        sockB = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sockB.settimeout(2)
        self.assertFalse(sockB.connect_ex(('127.0.0.1', 8546)),
                         "Please run testrpc on 127.0.0.1:8546")

        # First iteration of block
        rpc_a = arg_ethrpc(None, None, '127.0.0.1:8545')
        rpc_b = arg_ethrpc(None, None, '127.0.0.1:8546')
        ionlock_a = rpc_a.proxy("abi/IonLock.abi", lock, owner)
        ionlock_b = rpc_b.proxy("abi/IonLock.abi", lock, owner)
        ionlink_a = rpc_a.proxy("abi/IonLink.abi", link, owner)
        ionlink_b = rpc_b.proxy("abi/IonLink.abi", link, owner)
        token_a = rpc_a.proxy("abi/Token.abi", tokAddr, send)
        token_b = rpc_b.proxy("abi/Token.abi", tokAddr, recv)
        batch_a = []
        batch_b = []
        transfers = []
        prev_root = merkle_hash("merkle-tree-extra")

        ################################################################################
        print("Starting block iterator: rpc_a")
        print("latest Block rpc_a: ", ionlock_a.LatestBlock())
        # Note this is the un-wound infinite loop of iter_blocks
        start = rpc_a.eth_blockNumber()

        # Now deploy the tokens on the networks
        token_a.mint(totalSupply_a)
        token_a.metadataTransfer(lock, value_a, rawRef_a)

        obh = min(start + 1, max(1, rpc_a.eth_blockNumber() - 0))
        print("Starting block header  rpc_a: ", start)
        print("Previous block header  rpc_a: ", obh)
        self.assertEqual(start, 8)
        obh -= obh % 1
        blocks = []
        is_latest = False

        # Pack the blocks into batches
        bh = rpc_a.eth_blockNumber() + 1
        print("Current block header rpc_a: ", bh)
        for i in range(obh, bh):
            # XXX TODO: I think this is why the latest block info is not always in sync with geth
            if i == (bh - 1):
                is_latest = True
            blocks.append(i)
        obh = bh

        # Show the blocks to work on and then rename just to keep convention from lithium.py
        block_group = blocks
        self.assertEqual(len(blocks), 2)

        # Process the block on chain A
        items, group_tx_count, group_log_count, transfers = lithium_process_block_group(
            rpc_a, block_group)
        item_tree_a, root = merkle_tree(items)

        for i in range(0, len(block_group)):
            batch_a.append((block_group[i], root, transfers[i]))

        prev_root = lithium_submit(batch_a, prev_root, rpc_b, link, owner)
        latestBlockB = ionlink_b.GetLatestBlock()
        path_a = merkle_path(items[1], item_tree_a)

        leafHashB = sha3(items[1])
        reference_a = sha3(rawRef_a)

        ionlock_b = rpc_b.proxy("abi/IonLock.abi", lock, send)
        # print(ionlink_b.Verify(latestBlockB, leafHashB, path_a))

        ################################################################################
        print("Starting block iterator: rpc_b")
        print("latest Block rpc_b: ", ionlock_b.LatestBlock())
        # Note this is the un-wound infinite loop of iter_blocks
        start = rpc_b.eth_blockNumber()

        # Now deploy the tokens on the networks
        token_b.mint(totalSupply_b)
        token_b.metadataTransfer(lock, value_b, rawRef_b)

        obh = min(start + 1, max(1, rpc_b.eth_blockNumber() - 0))
        print("Starting block header  rpc_b: ", start)
        print("Previous block header  rpc_b: ", obh)
        self.assertEqual(start, 9)
        obh -= obh % 1
        blocks = []
        is_latest = False

        # Pack the blocks into batches
        bh = rpc_b.eth_blockNumber() + 1
        print("Current block header rpc_b: ", bh)
        for i in range(obh, bh):
            # XXX TODO: I think this is why the latest block info is not always in sync with geth
            if i == (bh - 1):
                is_latest = True
            blocks.append(i)
        obh = bh

        # Show the blocks to work on and then rename just to keep convention from lithium.py
        block_group = blocks
        self.assertEqual(len(blocks), 2)

        # Process the block on chain B
        items, group_tx_count, group_log_count, transfers = lithium_process_block_group(
            rpc_b, block_group)

        item_tree_b, root = merkle_tree(items)

        for i in range(0, len(block_group)):
            batch_b.append((block_group[i], root, transfers[i]))

        prev_root = lithium_submit(batch_b, prev_root, rpc_a, link, owner)
        latestBlockA = ionlink_a.GetLatestBlock()
        path_b = merkle_path(items[1], item_tree_b)

        leafHashA = sha3(items[1])
        reference_b = sha3(rawRef_b)

        ionlock_a = rpc_a.proxy("abi/IonLock.abi", lock, recv)

        ################################################################################

        self.assertEqual(token_a.balanceOf(lock), value_a)
        self.assertEqual(token_b.balanceOf(lock), value_b)
        self.assertEqual(token_a.balanceOf(recv), 0)
        self.assertEqual(token_b.balanceOf(send), 0)

        ionlock_b.Withdraw(value_a, reference_a, latestBlockB, path_a)
        ionlock_a.Withdraw(value_b, reference_b, latestBlockA, path_b)
        self.assertEqual(token_a.balanceOf(lock), 0)
        self.assertEqual(token_b.balanceOf(lock), 0)
        self.assertEqual(token_a.balanceOf(recv), value_a)
        self.assertEqual(token_b.balanceOf(send), value_b)