Exemple #1
0
def test_contract_create():
    test_settings = settings["test_contract_create"]
    (node, (root_dir, external_api,
            top)) = setup_node_with_tokens(test_settings, "node")
    internal_api = common.internal_api(node)

    private_key = keys.new_private()
    public_key = keys.public_key(private_key)

    alice_address = keys.address(public_key)

    test_settings["alice"]["pubkey"] = alice_address
    send_tokens_to_user("alice", test_settings, external_api, internal_api)
    encoded_tx, contract_address = get_unsigned_contract_create(
        alice_address, test_settings["create_contract"], external_api)

    print("Unsigned encoded transaction: " + encoded_tx)
    print("Contract address: " + contract_address)
    unsigned_tx = common.base58_decode(encoded_tx)
    tx = common.decode_unsigned_tx(unsigned_tx)
    print("Unsigned decoded transaction: " + str(tx))

    # make sure same tx
    assert_equals(tx['type'], 'contract_create_tx')
    assert_equals(tx['owner'],
                  common.base58_decode(test_settings["alice"]["pubkey"]))
    assert_equals(tx['vm_version'],
                  test_settings["create_contract"]["vm_version"])
    assert_equals(tx['deposit'], test_settings["create_contract"]["deposit"])
    assert_equals(tx['amount'], test_settings["create_contract"]["amount"])
    assert_equals(tx['gas'], test_settings["create_contract"]["gas"])
    assert_equals(tx['gas_price'],
                  test_settings["create_contract"]["gas_price"])
    assert_equals(tx['fee'], test_settings["create_contract"]["fee"])

    signed = keys.sign_verify_encode_tx(unsigned_tx, private_key, public_key)
    print("Signed transaction " + signed)

    alice_balance0 = common.get_account_balance(external_api,
                                                internal_api,
                                                pub_key=alice_address).balance
    tx_object = Tx(tx=signed)
    external_api.post_tx(tx_object)

    top = external_api.get_top_block()
    common.wait_until_height(external_api, top.height + 3)
    alice_balance = common.get_account_balance(external_api,
                                               internal_api,
                                               pub_key=alice_address).balance

    assert_equals(
        alice_balance0,
        alice_balance + test_settings["create_contract"]["fee"] +
        test_settings["create_contract"]["gas_used"] +
        test_settings["create_contract"]["deposit"] +
        test_settings["create_contract"]["amount"])

    print("Fee was consumed, transaction is part of the chain")

    cleanup(node, root_dir)
Exemple #2
0
def setup_test(test):
    import common
    import keys
    test_settings = _test_settings_(test)
    node = test_settings['miner_node']
    beneficiary = common.setup_beneficiary()

    node_root_dir = _setup_node_(node, beneficiary,
                                 test_settings['blocks_to_mine'])
    ext_api = common.external_api(node)
    int_api = common.internal_api(node)

    users = {
        k: {
            'encoded_pub_key': v['key_pair']['enc_pubk'],
            'pub_key': v['key_pair']['pubk'],
            'priv_key': v['key_pair']['privk']
        }
        for (k, v) in _setup_users_(beneficiary, test_settings['users'],
                                    test_settings['min_spend_tx_fee'], ext_api,
                                    int_api).items()
    }
    test.globs['epoch_node'] = {
        '_root_dir_': node_root_dir,
        'external_api': ext_api,
        'internal_api': int_api
    }
    test.globs['users'] = users
Exemple #3
0
def test_send_by_name():
    # Bob registers a name 'bob.aet'
    # Alice should be able to send tokens to Bob using that name
    test_settings = settings["test_send_by_name"]
    (node, (root_dir, ext_api, top)) = setup_node_with_tokens(test_settings, "miner")
    int_api = common.internal_api(node)

    alice_private_key = keys.new_private()
    alice_public_key = keys.public_key(alice_private_key)
    alice_address = keys.address(alice_public_key)

    bob_private_key = keys.new_private()
    bob_public_key = keys.public_key(bob_private_key)
    bob_address = keys.address(bob_public_key)

    # initial balances - amounts that the miner should send them
    alice_init_balance = test_settings["send_tokens"]["alice"]
    bob_init_balance = test_settings["send_tokens"]["bob"]

    # populate accounts with tokens
    miner_send_tokens(alice_address, alice_init_balance, int_api, ext_api)
    miner_send_tokens(bob_address, bob_init_balance, int_api, ext_api)

    # validate balances
    alice_balance0 = common.get_account_balance(ext_api, int_api, pub_key=alice_address).balance
    bob_balance0 = common.get_account_balance(ext_api, int_api, pub_key=bob_address).balance

    assert_equals(alice_balance0, alice_init_balance)
    assert_equals(bob_balance0, bob_init_balance)
    print("Alice balance is " + str(alice_balance0))
    print("Bob balance is " + str(bob_balance0))
    print("Bob address is " + bob_address)

    bob_name = test_settings["name_register"]["name"]
    register_name(bob_name, bob_address, ext_api, bob_private_key)

    print("Bob has registered " + bob_name)
    bob_balance1 = common.get_account_balance(ext_api, int_api, pub_key=bob_address).balance
    print("Bob balance is " + str(bob_balance1))

    tokens_to_send = test_settings["spend_tx"]["amount"]
    print("Alice is about to send " + str(tokens_to_send) + " to " + bob_name)
    send_tokens_to_name(bob_name, tokens_to_send, alice_address, alice_private_key, ext_api)

    # validate balances
    alice_balance2 = common.get_account_balance(ext_api, int_api, pub_key=alice_address).balance
    bob_balance2 = common.get_account_balance(ext_api, int_api, pub_key=bob_address).balance

    print("Alice balance is " + str(alice_balance2))
    print("Bob balance is " + str(bob_balance2))

    # Alice's balance should be decresed by the amount being send and the fee (1)
    assert_equals(alice_balance2, alice_balance0 - tokens_to_send - 1)

    # Bob's balance should be incresed by the amount being send
    assert_equals(bob_balance2, bob_balance1 + tokens_to_send)

    # stop node
    common.stop_node(node)
    shutil.rmtree(root_dir)
Exemple #4
0
def test_spend():
    test_settings = settings["test_spend"]
    (root_dir, node, external_api,
     top) = setup_node_with_tokens(test_settings, "node")
    internal_api = common.internal_api(node)

    private_key = keys.new_private()
    public_key = keys.public_key(private_key)

    alice_address = keys.address(public_key)
    bob_address = test_settings["spend_tx"]["recipient"]

    test_settings["alice"]["pubkey"] = alice_address
    send_tokens_to_user("alice", test_settings, internal_api, external_api)

    spend_data_obj = SpendTx(sender=alice_address,
                             recipient_pubkey=bob_address,
                             amount=test_settings["spend_tx"]["amount"],
                             fee=test_settings["spend_tx"]["fee"])
    unsigned_spend_obj = external_api.post_spend(spend_data_obj)
    unsigned_spend_enc = unsigned_spend_obj.tx
    tx_hash = unsigned_spend_obj.tx_hash
    unsigned_tx = common.base58_decode(unsigned_spend_enc)
    unpacked_tx = common.unpack_tx(unsigned_tx)
    print("Tx " + str(common.parse_tx(unpacked_tx)))

    alice_balance0 = common.get_account_balance(internal_api,
                                                pub_key=alice_address).balance
    bob_balance0 = common.get_account_balance(internal_api,
                                              pub_key=bob_address).balance

    signed = keys.sign_verify_encode_tx(unsigned_tx, unpacked_tx, private_key,
                                        public_key)
    print("Signed transaction " + signed)
    print("Tx hash " + tx_hash)

    tx_object = Tx(tx=signed)
    external_api.post_tx(tx_object)

    top = external_api.get_top()
    common.wait_until_height(external_api, top.height + 3)
    alice_balance = common.get_account_balance(internal_api,
                                               pub_key=alice_address).balance
    bob_balance = common.get_account_balance(internal_api,
                                             pub_key=bob_address).balance
    tx = external_api.get_tx(
        tx_hash=tx_hash)  # it is there - either in mempool or in a block

    print("Alice balance now is " + str(alice_balance))
    print("Bob balance now is " + str(bob_balance))
    print("Balances are updated, transaction has been executed")

    assert_equals(
        alice_balance0, alice_balance + test_settings["spend_tx"]["fee"] +
        test_settings["spend_tx"]["amount"])

    assert_equals(bob_balance0,
                  bob_balance - test_settings["spend_tx"]["amount"])
    cleanup(node, root_dir)
Exemple #5
0
def test_contract_create():
    test_settings = settings["test_contract_create"]
    (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node") 
    internal_api = common.internal_api(node)

    send_tokens_to_user("alice", test_settings, internal_api, external_api)

    encoded_tx = get_unsigned_contract_create(test_settings["alice"]["pubkey"], test_settings["create_contract"], external_api)

    print("Unsigned encoded transaction: " + encoded_tx)
    unsigned_tx = common.base58_decode(encoded_tx)
    unpacked_tx = common.unpack_tx(unsigned_tx)
    tx = common.parse_tx(unpacked_tx)
    print("Unsigned decoded transaction: " + str(tx))

    # make sure same tx
    assert_equals(tx['type'], 'contract_create')
    assert_equals(tx['owner'], common.base58_decode(test_settings["alice"]["pubkey"]))
    assert_equals(tx['vm_version'], test_settings["create_contract"]["vm_version"])
    assert_equals(tx['deposit'], test_settings["create_contract"]["deposit"])
    assert_equals(tx['amount'], test_settings["create_contract"]["amount"])
    assert_equals(tx['gas'], test_settings["create_contract"]["gas"])
    assert_equals(tx['gas_price'], test_settings["create_contract"]["gas_price"])
    assert_equals(tx['fee'], test_settings["create_contract"]["fee"])

    code = bytearray.fromhex(test_settings["create_contract"]["code"][2:]) # without 0x
    assert_equals(tx['code'], code)

    call_data = bytearray.fromhex(test_settings["create_contract"]["call_data"][2:]) # without 0x
    assert_equals(tx['call_data'], call_data)

    signature = bytearray(list(map(int, test_settings["create_contract"]["signature"].split(","))))
    signed = common.encode_signed_tx(unpacked_tx, [signature]) 
    print("Signed transaction " + signed)

    alice_balance0 = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance
    tx_object = Tx(tx=signed)
    external_api.post_tx(tx_object)

    top = external_api.get_top()
    common.wait_until_height(external_api, top.height + 3)
    alice_balance = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance

    assert_equals(alice_balance0, alice_balance + test_settings["create_contract"]["fee"])

    cleanup(node, root_dir)
Exemple #6
0
def test_compile_and_call_id():
    # Alice should be able to compile a sophia contract with an identity
    # function into bytecode and call it.
    test_settings = settings["test_compile_and_call_id"]
    (root_dir, node, external_api) = setup_node(test_settings, "alice")
    internal_api = common.internal_api(node)

    bytecode = read_id_contract(internal_api)

    # Call contract bytecode
    call_input = ContractCallInput("sophia", bytecode, "main", "42")
    call_result = internal_api.call_contract(call_input)
    assert_regexp_matches(call_result.out, '0x.*')

    # stop node
    common.stop_node(node)
    shutil.rmtree(root_dir)
Exemple #7
0
def test_contract_on_chain_call_off_chain():
    test_settings = settings["test_contract_call"]
    create_settings = settings["test_contract_create"]
    beneficiary = common.setup_beneficiary()
    (node, (root_dir, external_api,
            top)) = setup_node_with_tokens(test_settings, beneficiary, "node")
    internal_api = common.internal_api(node)

    private_key = keys.new_private()
    public_key = keys.public_key(private_key)

    alice_address = keys.address(public_key)

    test_settings["alice"]["pubkey"] = alice_address
    send_tokens_to_user(beneficiary, "alice", test_settings, external_api,
                        internal_api)

    ## create contract
    encoded_tx, encoded_contract_id = get_unsigned_contract_create(
        alice_address, create_settings["create_contract"], external_api,
        internal_api)
    unsigned_tx = common.base58_decode(encoded_tx)

    signed = keys.sign_verify_encode_tx(unsigned_tx, private_key, public_key)

    alice_balance0 = common.get_account_balance(external_api,
                                                internal_api,
                                                pub_key=alice_address).balance
    tx_object = Tx(tx=signed)
    external_api.post_transaction(tx_object)

    top = external_api.get_top_block()
    common.wait_until_height(external_api, top.height + 3)

    call_contract = test_settings["contract_call"]
    call_input = ContractCallInput("sophia-address", encoded_contract_id,\
                                   call_contract["data"]["function"],\
                                   call_contract["data"]["argument"])
    result = internal_api.call_contract(call_input)

    assert_equals(
        '0x000000000000000000000000000000000000000000000000000000000000002a',
        result.out)

    cleanup(node, root_dir)
Exemple #8
0
def test_id_call():
    # Alice should be able to call the id function in
    # an Id contract.

    test_settings = settings["test_id_call"]
    (root_dir, node, external_api) = setup_node(test_settings, "alice")
    internal_api = common.internal_api(node)

    bytecode = read_id_contract(internal_api)

    call_input = ContractCallInput("sophia", bytecode, "main", "42")
    result = internal_api.call_contract(call_input)
    print(result)

    retval = '0x000000000000000000000000000000000000000000000000000000000000002a'
    assert_equals(result.out, retval)
    # stop node
    common.stop_node(node)
    shutil.rmtree(root_dir)
Exemple #9
0
def test_encode_id_call():
    # Alice should be able to encode a call to a function in
    # a sophia contract.

    test_settings = settings["test_encode_id_call"]
    (root_dir, node, external_api) = setup_node(test_settings, "alice")
    internal_api = common.internal_api(node)

    bytecode = read_id_contract(internal_api)

    call_input = ContractCallInput("sophia", bytecode, "main", "42")
    result = internal_api.encode_calldata(call_input)

    calldata = '0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000046d61696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a'
    assert_equals(result.calldata, calldata)

    # stop node
    common.stop_node(node)
    shutil.rmtree(root_dir)
Exemple #10
0
def test_solidity_greeter():
    # Alice should be able to initialize
    # the gretee Solidity contract.

    test_settings = settings["test_id_call"]
    (root_dir, node, api) = setup_node(test_settings, "alice")
    internal_api = common.internal_api(node)

    bytecode = greeter_code()


    call_input = ContractCallInput("evm", bytecode, "", "0x00")
    result = internal_api.call_contract(call_input)
    print(result)

    generatedcode = greeter_generated_code()

    assert_equals(result.out, generatedcode)
    # stop node
    common.stop_node(node)
    shutil.rmtree(root_dir)
Exemple #11
0
def test_call_solidity_greeter():
    # Alice should be able to call the greet function in
    # an greete Solidity contract.

    test_settings = settings["test_id_call"]
    (root_dir, node, api) = setup_node(test_settings, "alice")
    internal_api = common.internal_api(node)

    bytecode = greeter_generated_code()

    setGreeting = "0xa4136862"
    HelloWorld = "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d48656c6c6c6f20576f726c642100000000000000000000000000000000000000"
    call_input = ContractCallInput("evm", bytecode, "", setGreeting + HelloWorld)
    result = internal_api.call_contract(call_input)
    print(result)

    generatedcode = greeter_generated_code()

    # assert_equals(result.out, generatedcode)
    # stop node
    common.stop_node(node)
    shutil.rmtree(root_dir)
Exemple #12
0
def test_not_enough_tokens():
    # Bob should not be able to send more tokens than he has
    #
    # Let's say Bob has 100 tokens. He should not be able to send more than
    # 100 tokens to Alice.
    #
    # If there's an incoming but unconfirmed deposit into Bob's account then Bob
    # should not be able to use the incoming tokens until the spend transaction
    # they are in is confirmed.
    test_settings = settings["test_not_enough_tokens"]
    coinbase_reward = common.coinbase_reward()
    (root_dir, bob_node, bob_api,
     bob_top) = setup_node_with_tokens(test_settings, "bob")
    bob_internal_api = common.internal_api(bob_node)

    def get_bob_balance(height):
        return common.get_account_balance_at_height(bob_api, bob_internal_api,
                                                    height)

    def get_alice_balance(height):
        k = test_settings["spend_tx"]["alice_pubkey"]
        return common.get_account_balance_at_height(bob_api,
                                                    bob_internal_api,
                                                    height,
                                                    pub_key=k)

    spend_tx_amt = test_settings["spend_tx"]["amount"]
    spend_tx_fee = test_settings["spend_tx"]["fee"]
    bob_balance = get_bob_balance(bob_top.height)
    bob_has_not_enough_tokens = bob_balance.balance < spend_tx_amt + spend_tx_fee
    assert_equals(bob_has_not_enough_tokens, True)
    print("Bob initial balance is " + str(bob_balance.balance) +
          " and he will try to spend " + str(spend_tx_amt + spend_tx_fee))

    alice_balance0 = get_alice_balance(bob_top.height)

    # Bob tries to send some tokens to Alice
    spend_tx_obj = SpendTx(
        recipient_pubkey=test_settings["spend_tx"]["alice_pubkey"],
        amount=spend_tx_amt,
        fee=spend_tx_fee)
    print("Bob's spend_tx is " + str(spend_tx_obj))
    bob_internal_api.post_spend_tx(spend_tx_obj)
    print("Transaction sent")
    bob_top_after_tx = bob_api.get_top()

    print("Waiting for a few blocks to be mined")
    checked_height = bob_top_after_tx.height + 3
    common.wait_until_height(bob_api, checked_height)

    # ensure Alice balance had not changed
    alice_balance1 = get_alice_balance(checked_height)
    print("Alice's balance is now " + str(alice_balance1.balance))
    assert_equals(alice_balance1.balance, alice_balance0.balance)

    # ensure Bob not debited
    # Since Bob had mined the block he is receiving the coinbase_reward
    blocks_mined = checked_height - bob_top.height
    print("Coinbase reward is " + str(coinbase_reward) + ", had mined " +
          str(blocks_mined) + " blocks")
    expected_balance = bob_balance.balance + coinbase_reward * blocks_mined
    bob_new_balance = get_bob_balance(checked_height)
    print("Bob's balance (with coinbase rewards) is now " +
          str(bob_new_balance.balance))
    assert_equals(bob_new_balance.balance, expected_balance)

    # stop node
    common.stop_node(bob_node)
    shutil.rmtree(root_dir)
Exemple #13
0
def test_node_discovery_from_common_friend():
    """
    Test node discovery (from common friend peer)
    Assuming Carol's node only knows about Bob upon startup and that Alice's
    node knows Bob, Carol's node should be able to discover Alice and
    sync with her node.
    """
    test_settings = settings["test_node_discovery_from_common_friend"]
    alice_node = test_settings["nodes"]["alice"]
    bob_node = test_settings["nodes"]["bob"]
    carol_node = test_settings["nodes"]["carol"]

    # prepare a dir to hold the configs
    root_dir = tempfile.mkdtemp()

    # Alice's config: only peer is Bob
    alice_peers = """\
peers:
    - "aenode://pp$28uQUgsPcsy7TQwnRxhF8GMKU4ykFLKsgf4TwDwPMNaSCXwWV8@localhost:3025"
"""
    alice_user_config = make_peers_user_config(root_dir, "alice_epoch.yaml",
                                               "node1", "3015", alice_peers,
                                               "true")
    # Bob's config: no peers
    bob_peers = "peers: []"
    bob_user_config = make_peers_user_config(root_dir, "bob_epoch.yaml",
                                             "node2", "3025", bob_peers,
                                             "false")
    # Carol's config: only peer is Bob
    carol_peers = """\
peers:
    - "aenode://pp$28uQUgsPcsy7TQwnRxhF8GMKU4ykFLKsgf4TwDwPMNaSCXwWV8@localhost:3025"
"""
    carol_user_config = make_peers_user_config(root_dir, "carol_epoch.yaml",
                                               "node3", "3035", carol_peers,
                                               "false")

    # start Alice's node
    common.start_node(alice_node, alice_user_config)
    alice_api = common.external_api(alice_node)

    # Insert some blocks in Alice's chain
    blocks_to_mine = test_settings["blocks_to_mine"]
    common.wait_until_height(alice_api, blocks_to_mine)
    alice_top = alice_api.get_top_block()
    assert_true(alice_top.height >= blocks_to_mine)
    # Now Alice has at least blocks_to_mine blocks

    # start the other nodes
    common.start_node(bob_node, bob_user_config)
    common.start_node(carol_node, carol_user_config)

    # Check that Carol syncs with Alice's chain
    carol_api = common.external_api(carol_node)
    common.wait_until_height(carol_api, alice_top.height)
    assert_equals(
        carol_api.get_block_by_hash(alice_top.hash).height, alice_top.height)

    # Check that Carol discovers Alice as a peer
    carol_int_api = common.internal_api(carol_node)
    wait(
        lambda:
        'aenode://[email protected]:3015'
        in get_peers(carol_int_api),
        timeout_seconds=20,
        sleep_seconds=1)

    # cleanup
    common.stop_node(alice_node)
    common.stop_node(bob_node)
    common.stop_node(carol_node)

    shutil.rmtree(root_dir)
Exemple #14
0
def test_successful():
    # Alice should be able to create a spend transaction to send tokens to
    # Bob. In a controlled environment, Alice should see her transaction
    # appear in the next block or two that are added to the blockchain.
    #
    # Once that happens, Alice should see her account debited and Bob's
    # account credited with the same number of tokens.
    #
    # The debit/credit should not happen until the transaction is confirmed,
    # e.g. included in at least one block in the chain.
    test_settings = settings["test_successful"]
    coinbase_reward = common.coinbase_reward()
    (root_dir, alice_node, alice_api,
     alice_top) = setup_node_with_tokens(test_settings, "alice")
    alice_internal_api = common.internal_api(alice_node)

    spend_tx_amt = test_settings["spend_tx"]["amount"]
    spend_tx_fee = test_settings["spend_tx"]["fee"]
    alice_balance = common.get_account_balance(alice_internal_api)
    alice_has_enough_tokens = alice_balance.balance >= spend_tx_amt + spend_tx_fee
    assert_equals(alice_has_enough_tokens, True)
    print("Alice initial balance is " + str(alice_balance.balance))

    bob_balance0 = common.get_account_balance(
        alice_internal_api, pub_key=test_settings["spend_tx"]["bob_pubkey"])
    # Alice sends some tokens to Bob
    alice_internal_api = common.internal_api(alice_node)
    spend_tx_obj = SpendTx(
        recipient_pubkey=test_settings["spend_tx"]["bob_pubkey"],
        amount=spend_tx_amt,
        fee=spend_tx_fee)
    print("Alice's spend_tx is " + str(spend_tx_obj))
    alice_internal_api.post_spend_tx(spend_tx_obj)
    print("Transaction sent")

    # ensure Alice balance had not changed
    alice_balance1 = common.get_account_balance(alice_internal_api)
    assert_equals(alice_balance.balance, alice_balance1.balance)

    # ensure Bob balance had not changed
    bob_balance1 = common.get_account_balance(
        alice_internal_api, pub_key=test_settings["spend_tx"]["bob_pubkey"])
    assert_equals(bob_balance1.balance, bob_balance0.balance)

    # wait for a block to be mined
    print("Waiting for a next block to be mined")
    common.wait_until_height(alice_api, alice_top.height + 1)

    alice_new_top = alice_api.get_top()
    alice_new_balance = common.get_account_balance(alice_internal_api)

    blocks_mined = alice_new_top.height - alice_top.height

    # Since Alice had mined the block she is receiving the fee and the
    # coinbase_reward
    # Alice should have
    # tokens = old_balance - spent_amt - spend_tx + spent_fee + coinbase_reward
    expected_balance = alice_balance.balance - spend_tx_amt + coinbase_reward * blocks_mined
    assert_equals(alice_new_balance.balance, expected_balance)

    bob_balance = common.get_account_balance(
        alice_internal_api, pub_key=test_settings["spend_tx"]["bob_pubkey"])
    print("Coinbase reward is " + str(coinbase_reward) + ", had mined " +
          str(blocks_mined) + " blocks")
    print("Alice's balance (with a coinbase reward) is now " +
          str(alice_new_balance.balance))
    print("Bob's balance is now " + str(bob_balance.balance))
    assert_equals(bob_balance.balance, spend_tx_amt)
    # stop node
    common.stop_node(alice_node)
    shutil.rmtree(root_dir)
Exemple #15
0
def test_node_discovery():
    """
    Test node discovery
    Assuming Carol's node only knows about Bob upon startup and that Bob's
    node knows Alice, Carol's node should be able to discover Alice and
    sync with her node.
    """
    test_settings = settings["test_node_discovery"]
    alice_node = test_settings["nodes"]["alice"]
    bob_node = test_settings["nodes"]["bob"]
    carol_node = test_settings["nodes"]["carol"]

    alice_peer_url = node_peer_url(alice_node)
    bob_peer_url = node_peer_url(bob_node)
    carol_peer_url = node_peer_url(carol_node)

    # prepare a dir to hold the configs
    root_dir = tempfile.mkdtemp()

    # Alice's config: no peers
    alice_sys_config = make_peers_config(root_dir,
                                         "alice.config",
                                         alice_peer_url,
                                         "node1",
                                         "3015",
                                         '{peers, []},',
                                         mining=True)
    print("\nAlice has address " + alice_peer_url + " and no peers")
    # Bob's config: only peer is Alice
    bob_peers = ' {peers, [<<"aenode://pp$HdcpgTX2C1aZ5sjGGysFEuup67K9XiFsWqSPJs4RahEcSyF7X@localhost:3015">>]}, '
    bob_sys_config = make_peers_config(root_dir,
                                       "bob.config",
                                       bob_peer_url,
                                       "node2",
                                       "3025",
                                       bob_peers,
                                       mining=False)
    print("Bob has address " + bob_peer_url + " and peers [" + alice_peer_url +
          "]")
    # Carol's config: only peer is Bob
    carol_peers = ' {peers, [<<"aenode://pp$28uQUgsPcsy7TQwnRxhF8GMKU4ykFLKsgf4TwDwPMNaSCXwWV8@localhost:3025">>]}, '
    carol_sys_config = make_peers_config(root_dir,
                                         "carol.config",
                                         carol_peer_url,
                                         "node3",
                                         "3035",
                                         carol_peers,
                                         mining=False)
    print("Carol has address " + carol_peer_url + " and peers [" +
          bob_peer_url + "]")

    # start Alice's node
    common.start_node(alice_node, alice_sys_config)
    alice_api = common.external_api(alice_node)

    # Insert some blocks in Alice's chain
    blocks_to_mine = test_settings["blocks_to_mine"]
    common.wait_until_height(alice_api, blocks_to_mine)
    alice_top = alice_api.get_top()
    assert_true(alice_top.height >= blocks_to_mine)
    # Now Alice has at least blocks_to_mine blocks

    # start the other nodes
    common.start_node(bob_node, bob_sys_config)
    common.start_node(carol_node, carol_sys_config)

    # Check that Carol syncs with Alice's chain
    carol_api = common.external_api(carol_node)
    common.wait_until_height(carol_api, alice_top.height)
    assert_equals(
        carol_api.get_block_by_hash(alice_top.hash).height, alice_top.height)

    # Check that Carol discovers Alice as a peer
    carol_int_api = common.internal_api(carol_node)

    def carol_peers():
        peers = carol_int_api.get_peers().peers
        print("Peers: " + str(peers))
        return peers

    wait(
        lambda:
        'aenode://pp$HdcpgTX2C1aZ5sjGGysFEuup67K9XiFsWqSPJs4RahEcSyF7X@localhost:3015'
        in carol_peers(),
        timeout_seconds=20,
        sleep_seconds=1)

    # cleanup
    common.stop_node(alice_node)
    common.stop_node(bob_node)
    common.stop_node(carol_node)

    shutil.rmtree(root_dir)
Exemple #16
0
def test_spend():
    # Alice should be able to create a spend transaction to send tokens to
    # Bob. In a controlled environment, Alice should see her transaction
    # appear in the next block or two that are added to the blockchain.
    #
    # Once that happens, Alice should see her account debited and Bob's
    # account credited with the same number of tokens.
    #
    # The debit/credit should not happen until the transaction is confirmed,
    # e.g. included in at least one block in the chain.

    # Setup
    test_settings = settings["test_spend"]
    (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node")
    internal_api = common.internal_api(node)

    private_key = keys.new_private()
    public_key = keys.public_key(private_key)

    alice_address = keys.address(public_key)
    bob_address = test_settings["spend_tx"]["recipient"]

    test_settings["alice"]["pubkey"] = alice_address
    send_tokens_to_user("alice", test_settings, external_api, internal_api)

    alice_balance0 = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance
    bob_balance0 = common.get_account_balance(external_api, internal_api, pub_key=bob_address).balance

    # Alice creates spend tx
    spend_data_obj = SpendTx(
            sender=alice_address,
            recipient_pubkey=bob_address,
            amount=test_settings["spend_tx"]["amount"],
            fee=test_settings["spend_tx"]["fee"],
            ttl=100,
            payload="foo")
    unsigned_spend_obj = external_api.post_spend(spend_data_obj)
    unsigned_spend_enc = unsigned_spend_obj.tx
    unsigned_tx = common.base58_decode(unsigned_spend_enc)

    # Alice signs spend tx
    signed = keys.sign_verify_encode_tx(unsigned_tx, private_key, public_key)
    tx_hash = keys.tx_hash_from_signed_encoded(signed)
    print("Tx hash " + tx_hash)
    print("Signed transaction " + signed)

    # Alice posts spend tx
    tx_object = Tx(tx=signed)
    external_api.post_tx(tx_object)
    _ = external_api.get_tx(tx_hash=tx_hash) # it is there - either in mempool or in a block

    # Wait until spend tx is mined
    wait(lambda: common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance < alice_balance0,
         timeout_seconds=120, sleep_seconds=0.25)
    _ = external_api.get_tx(tx_hash=tx_hash) # it is there - shall be in a block
    print("Tx in chain ")

    # Check that Alice was debited and Bob was credited
    alice_balance = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance
    bob_balance = common.get_account_balance(external_api, internal_api, pub_key=bob_address).balance
    print("Alice balance now is " + str(alice_balance))
    print("Bob balance now is " + str(bob_balance))
    assert_equals(alice_balance0, alice_balance + test_settings["spend_tx"]["fee"] + test_settings["spend_tx"]["amount"])
    assert_equals(bob_balance0, bob_balance - test_settings["spend_tx"]["amount"])

    # Cleanup
    cleanup(node, root_dir)
Exemple #17
0
def test_contract_call():
    test_settings = settings["test_contract_call"]
    create_settings = settings["test_contract_create"]
    (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node")
    internal_api = common.internal_api(node)

    private_key = keys.new_private()
    public_key = keys.public_key(private_key)

    alice_address = keys.address(public_key)

    test_settings["alice"]["pubkey"] = alice_address
    send_tokens_to_user("alice", test_settings, external_api, internal_api)

    ## create contract
    encoded_tx, encoded_contract_address = get_unsigned_contract_create(alice_address, create_settings["create_contract"], external_api)
    unsigned_tx = common.base58_decode(encoded_tx)

    signed = keys.sign_verify_encode_tx(unsigned_tx, private_key, public_key)

    alice_balance0 = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance
    tx_object = Tx(tx=signed)
    external_api.post_tx(tx_object)

    top = external_api.get_top()
    common.wait_until_height(external_api, top.height + 3)
    alice_balance = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance

    # assert contract created:
    call_contract = test_settings["contract_call"]
    assert_equals(alice_balance0,
                  alice_balance
                  + create_settings["create_contract"]["fee"]
                  + create_settings["create_contract"]["gas_used"]
                  + create_settings["create_contract"]["deposit"]
                  + create_settings["create_contract"]["amount"])

    call_input = ContractCallInput("sophia", create_settings["create_contract"]["code"],\
                                             call_contract["data"]["function"],\
                                             call_contract["data"]["argument"])
    result = external_api.call_contract(call_input)
    contract_call_obj = ContractCallData(
        caller=test_settings["alice"]["pubkey"],
        contract=encoded_contract_address,
        vm_version=call_contract["vm_version"],
        fee=call_contract["fee"],
        ttl=100,
        amount=call_contract["amount"],
        gas=call_contract["gas"],
        gas_price=call_contract["gas_price"],
        call_data=result.out)


    call_tx_obj = external_api.post_contract_call(contract_call_obj)
    encoded_call_tx = call_tx_obj.tx

    print("Unsigned encoded transaction: " + encoded_call_tx)
    unsigned_call_tx = common.base58_decode(encoded_call_tx)

    signed_call = keys.sign_verify_encode_tx(unsigned_call_tx, private_key, public_key)

    print("Signed transaction: " + signed_call)
    alice_balance0 = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance
    tx_object = Tx(tx=signed_call)
    external_api.post_tx(tx_object)

    top = external_api.get_top()
    common.wait_until_height(external_api, top.height + 3)
    alice_balance = common.get_account_balance(external_api, internal_api, pub_key=alice_address).balance

    # The call runs out of gas and all gas is consumed
    # assert contract called:
    assert_equals(alice_balance0, alice_balance
                  + test_settings["contract_call"]["fee"]
                  + test_settings["contract_call"]["gas"]
                  + test_settings["contract_call"]["amount"])
    print("Fee and gas was consumed, transaction is part of the chain")

    cleanup(node, root_dir)
Exemple #18
0
def test_contract_call():
    test_settings = settings["test_contract_call"]
    create_settings = settings["test_contract_create"]
    (root_dir, node, external_api, top) = setup_node_with_tokens(test_settings, "node") 
    internal_api = common.internal_api(node)

    send_tokens_to_user("alice", test_settings, internal_api, external_api)

    ## create contract
    encoded_tx = get_unsigned_contract_create(test_settings["alice"]["pubkey"], create_settings["create_contract"], external_api)
    unsigned_tx = common.base58_decode(encoded_tx)
    unpacked_tx = common.unpack_tx(unsigned_tx)
    signature = bytearray(list(map(int, create_settings["create_contract"]["signature"].split(","))))
    signed = common.encode_signed_tx(unpacked_tx,[signature]) 

    alice_balance0 = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance
    tx_object = Tx(tx=signed)
    external_api.post_tx(tx_object)

    top = external_api.get_top()
    common.wait_until_height(external_api, top.height + 3)
    alice_balance = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance

    # assert contract created:
    call_contract = test_settings["contract_call"]
    assert_equals(alice_balance0, alice_balance + create_settings["create_contract"]["fee"])

    call_input = ContractCallInput("ring", create_settings["create_contract"]["code"],\
                                           call_contract["data"]["function"],\
                                           call_contract["data"]["argument"])
    result = external_api.call_contract(call_input)
    contract_call_obj = ContractCallData(
        caller=test_settings["alice"]["pubkey"],
        contract=call_contract["contract"],
        vm_version=call_contract["vm_version"],
        fee=call_contract["fee"],
        amount=call_contract["amount"],
        gas=call_contract["gas"],
        gas_price=call_contract["gas_price"],
        call_data=result.out)


    call_tx_obj = external_api.post_contract_call(contract_call_obj)
    encoded_call_tx = call_tx_obj.tx

    print("Unsigned encoded transaction: " + encoded_call_tx)
    unsigned_call_tx = common.base58_decode(encoded_call_tx)
    unpacked_call_tx = common.unpack_tx(unsigned_call_tx)
    tx = common.parse_tx(unpacked_call_tx)
    print("Unsigned decoded transaction: " + str(tx))

    signature = bytearray(list(map(int, test_settings["contract_call"]["signature"].split(","))))

    signed = common.encode_signed_tx(unpacked_call_tx,[signature]) 

    print("Signed transaction: " + signed)
    alice_balance0 = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance
    tx_object = Tx(tx=signed)
    external_api.post_tx(tx_object)

    top = external_api.get_top()
    common.wait_until_height(external_api, top.height + 3)
    alice_balance = common.get_account_balance(internal_api, pub_key=test_settings["alice"]["pubkey"]).balance

    print("BALANCE0 " + str(alice_balance0))
    print("BALANCE " + str(alice_balance))
    # assert contract created:
    assert_equals(alice_balance0, alice_balance + test_settings["contract_call"]["fee"])



    cleanup(node, root_dir)