def chain_fixture(scope="module"): # create a new account and fill it with some money ACCOUNT = Account.generate() ACCOUNT_1 = Account.generate() # used by for oracles # set the key folder as environment variables genesis = Account.from_private_key_string(PRIVATE_KEY) # Instantiate the node client for the tests NODE_CLI = NodeClient(Config( external_url=NODE_URL, internal_url=NODE_URL_DEBUG, # network_id=NETWORK_ID, blocking_mode=True, debug=True, )) NODE_CLI.spend(genesis, ACCOUNT.get_address(), 5000000000000000000000) # 5000AE a = NODE_CLI.get_account_by_pubkey(pubkey=ACCOUNT.get_address()) print(f"Test account is {ACCOUNT.get_address()} with balance {a.balance}") NODE_CLI.spend(genesis, ACCOUNT_1.get_address(), 5000000000000000000000) # 5000AE a = NODE_CLI.get_account_by_pubkey(pubkey=ACCOUNT_1.get_address()) print(f"Test account (1) is {ACCOUNT_1.get_address()} with balance {a.balance}") return namedtupled.map({"NODE_CLI": NODE_CLI, "ALICE": ACCOUNT, "BOB": ACCOUNT_1}, _nt_name="TestData")
def test_transaction_spend(chain_fixture): recipient_id = Account.generate().get_address() # account_id, recipient_id, amount, payload, fee, ttl, nonce tts = [ { "native": (chain_fixture.ACCOUNT.get_address(), recipient_id, 1000, "payload", 1, 100, 5555), "debug": (chain_fixture.ACCOUNT.get_address(), recipient_id, 1000, "payload", 1, 100, 5555), "match": True }, { "native": (chain_fixture.ACCOUNT.get_address(), recipient_id, 9845, "another payload", 1, 500, 1241), "debug": (chain_fixture.ACCOUNT.get_address(), recipient_id, 9845, "another payload", 1, 500, 1241), "match": True }, { "native": (chain_fixture.ACCOUNT.get_address(), recipient_id, 9845, "another payload", 1, 500, 32131), "debug": (chain_fixture.ACCOUNT.get_address(), Account.generate().get_address(), 9845, "another payload", 1, 500, 32131), "match": False }, { "native": (chain_fixture.ACCOUNT.get_address(), recipient_id, 410000, "another payload", 100, 500, 1241), "debug": (chain_fixture.ACCOUNT.get_address(), recipient_id, 410000, "another payload", 100, 500, 1241), "match": True }, ] for tt in tts: # get a native transaction txbn = transactions.TxBuilder() txn = txbn.tx_spend(tt["native"][0], tt["native"][1], tt["native"][2], tt["native"][3], tt["native"][4], tt["native"][5], tt["native"][6]) # get a debug transaction txbd = transactions.TxBuilder() txd = txbd.tx_spend(tt["debug"][0], tt["debug"][1], tt["debug"][2], tt["debug"][3], tt["debug"][4], tt["debug"][5], tt["debug"][6]) # theys should be the same if tt["match"]: assert txn == txd else: assert txn != txd
def test_tutorial_spend(chain_fixture): NODE_URL = os.environ.get('TEST_URL', 'https://testnet.aeternity.io') node_cli = NodeClient(Config( external_url=NODE_URL, blocking_mode=True, )) # generate ALICE account alice = Account.generate() # generate BOB account bob = Account.generate() # retrieve the balances for the accounts bob_balance = node_cli.get_balance(bob) alice_balance = node_cli.get_balance(alice) # print the balance of the two accounts print(f"Alice address is {alice.get_address()}") print(f"with balance {utils.format_amount(alice_balance)}") print(f"Bob address is {bob.get_address()}") print(f"with balance {utils.format_amount(bob_balance)}") # begin - tests execution section # top up the account from the test suite account, # outside the tests use the faucet to top_up an account tx = node_cli.spend(chain_fixture.ALICE, alice.get_address(), "5AE") # end - tests execution section #TODO pause the execution while using the faucet # execute the spend transaction tx = node_cli.spend(alice, bob.get_address(), "3AE") print(f"transaction hash: {tx.hash}") print(f"inspect transaction at {NODE_URL}/v2/transactions/{tx.hash}") # begin - tests execution section assert bob.get_address() == tx.data.tx.data.recipient_id assert alice.get_address() == tx.data.tx.data.sender_id # end - tests execution section # retrieve the balances for the accounts bob_balance = node_cli.get_balance(bob) alice_balance = node_cli.get_balance(alice) print(f"Alice balance is {utils.format_amount(alice_balance)}") print(f"Bob balance is {utils.format_amount(bob_balance)}") # begin - tests execution section assert bob_balance > 0 assert alice_balance > 0 assert alice_balance < bob_balance
def test_spend_by_name(chain_fixture): # claim a domain domain = random_domain( tld='chain' if chain_fixture.NODE_CLI.get_consensus_protocol_version() >= PROTOCOL_LIMA else 'test', length=20) print(f"domain is {domain}") name = chain_fixture.NODE_CLI.AEName(domain) print("Claim name ", domain) # generate a new address target_address = Account.generate().get_address() print(f"Target address {target_address}") name.full_claim_blocking(chain_fixture.ALICE, target_address) # domain claimed name.update_status() assert not chain_fixture.NODE_CLI.AEName( domain).is_available(), 'The name should be claimed now' name.update_status() print(f"domain is {name.domain} name_id {name.name_id}") print("pointers", name.pointers) tx = chain_fixture.NODE_CLI.spend(chain_fixture.ALICE, domain, '1AE') print("DATA ", tx) recipient_account = chain_fixture.NODE_CLI.get_account_by_pubkey( pubkey=target_address) print( f"recipient address {target_address}, balance {recipient_account.balance}" ) assert recipient_account.balance == 1000000000000000000
def test_cli_phases_spend(chain_fixture, tempdir): account_path = _account_path(tempdir, chain_fixture.ALICE) # generate a new address recipient_id = Account.generate().get_address() # step one, generate transaction nonce = chain_fixture.NODE_CLI.get_account_by_pubkey( pubkey=chain_fixture.ALICE.get_address()).nonce + 1 j = call_aecli('tx', 'spend', chain_fixture.ALICE.get_address(), recipient_id, '100', '--nonce', f'{nonce}') # assert chain_fixture.ALICE.get_address == j.get("Sender account") assert recipient_id == j.get("data", {}).get("recipient_id") # step 2, sign the transaction tx_unsigned = j.get("tx") s = call_aecli('account', 'sign', account_path, tx_unsigned, '--password', 'aeternity_bc', '--network-id', NETWORK_ID) tx_signed = s.get("tx") # recipient_account = chain_fixture.NODE_CLI.get_account_by_pubkey(pubkey=recipient_id) # assert recipient_account.balance == 0 # step 3 broadcast call_aecli('tx', 'broadcast', tx_signed, "--wait") # b.get("Transaction hash") # verify recipient_account = chain_fixture.NODE_CLI.get_account_by_pubkey( pubkey=recipient_id) assert recipient_account.balance == 100
def test_signing_keystore_save_load(tempdir): original_account = Account.generate() filename = original_account.save_to_keystore(tempdir, "whatever") path = os.path.join(tempdir, filename) print(f"\nAccount keystore is {path}") # now load again the same a = Account.from_keystore(path, "whatever") assert a.get_address() == original_account.get_address() ###### original_account = Account.generate() filename = "account_ks" filename = original_account.save_to_keystore(tempdir, "whatever") path = os.path.join(tempdir, filename) print(f"\nAccount keystore is {path}") # now load again the same a = Account.from_keystore(path, "whatever") assert a.get_address() == original_account.get_address()
def _test_node_spend(node_cli, sender_account): account = Account.generate().get_address() tx = node_cli.spend(sender_account, account, 100) assert account == tx.data.recipient_id assert sender_account.get_address() == tx.data.sender_id account = node_cli.get_account_by_pubkey(pubkey=account) balance = account.balance assert balance > 0
def test_signing_keystore_save_load_wrong_pwd(tempdir): original_account = Account.generate() filename = original_account.save_to_keystore(tempdir, "whatever") path = os.path.join(tempdir, filename) print(f"\nAccount keystore is {path}") # now load again the same with raises(ValueError): a = Account.from_keystore(path, "nononon") assert a.get_address() == original_account.get_address()
def test_transaction_spend(): recipient_id = Account.generate().get_address() tts = [ { "native": (recipient_id, 1000, 1, 100, "payload"), "debug": (recipient_id, 1000, 1, 100, "payload"), "match": True }, { "native": (recipient_id, 9845, 1, 500, "another payload"), "debug": (recipient_id, 9845, 1, 500, "another payload"), "match": True }, { "native": (recipient_id, 9845, 1, 500, "another payload"), "debug": (Account.generate().get_address(), 9845, 1, 500, "another payload"), "match": False }, ] for tt in tts: # get a native transaction txbn = transactions.TxBuilder(EPOCH_CLI, ACCOUNT, native=True) txn, sn, txhn = txbn.tx_spend(tt["native"][0], tt["native"][1], tt["native"][4], tt["native"][2], tt["native"][3]) # get a debug transaction txbd = transactions.TxBuilder(EPOCH_CLI, ACCOUNT, native=False) txd, sd, txhd = txbd.tx_spend(tt["debug"][0], tt["debug"][1], tt["debug"][4], tt["debug"][2], tt["debug"][3]) # theys should be the same if tt["match"]: assert txn == txd assert sn == sd assert txhn == txhd else: assert txn != txd assert sn != sd assert txhn != txhd
def test_cli_spend(account_path): # generate a new address recipient_address = Account.generate().get_address() # call the cli call_aecli('account', 'spend', account_path, recipient_address, "90", '--password', 'aeternity_bc') # test that the recipient account has the requested amount print(f"recipient address is {recipient_address}") recipient_account = EPOCH_CLI.get_account_by_pubkey(pubkey=recipient_address) print(f"recipient address {recipient_address}, balance {recipient_account.balance}") assert recipient_account.balance == 90
def test_hdwallet_keystore_save_load_wrong_type(tempdir): try: original_account = Account.generate() filename = original_account.save_to_keystore(tempdir, "whatever") path = os.path.join(tempdir, filename) print(f"\nAccount keystore is {path}") hdwallet_decrypted = HDWallet.from_keystore(path, "whatever") except Exception as e: assert str( e ) == "Invalid keystore. Expected keystore of type ed25519-bip39-mnemonic"
def test_cli_inspect_transaction_by_hash(): # fill the account from genesys na = Account.generate() amount = random.randint(50, 150) _, _, tx_hash = EPOCH_CLI.spend(ACCOUNT, na.get_address(), amount) # now inspect the transaction j = call_aecli('inspect', tx_hash) assert j.get("hash") == tx_hash assert j.get("block_height") > 0 assert j.get("tx", {}).get("recipient_id") == na.get_address() assert j.get("tx", {}).get("sender_id") == ACCOUNT.get_address() assert j.get("tx", {}).get("amount") == amount
def test_signing_create_transaction(): # generate a new account new_account = Account.generate() receiver_address = new_account.get_address() # create a spend transaction txb = TxBuilder(EPOCH_CLI, ACCOUNT) tx, sg, tx_hash = txb.tx_spend(receiver_address, 321, "test test ", TEST_FEE, TEST_TTL) # this call will fail if the hashes of the transaction do not match txb.post_transaction(tx, tx_hash) # make sure this works for very short block times spend_tx = EPOCH_CLI.get_transaction_by_hash(hash=tx_hash) assert spend_tx.signatures[0] == sg
def test_signing_create_transaction_signature(chain_fixture): # generate a new account new_account = Account.generate() receiver_address = new_account.get_address() # create a spend transaction nonce, ttl = chain_fixture.NODE_CLI._get_nonce_ttl(chain_fixture.ALICE.get_address(), TEST_TTL) tx = chain_fixture.NODE_CLI.tx_builder.tx_spend(chain_fixture.ALICE.get_address(), receiver_address, 321, "test test ", 0, ttl, nonce) tx_signed = chain_fixture.NODE_CLI.sign_transaction(chain_fixture.ALICE, tx) # this call will fail if the hashes of the transaction do not match chain_fixture.NODE_CLI.broadcast_transaction(tx_signed) # make sure this works for very short block times spend_tx = chain_fixture.NODE_CLI.get_transaction_by_hash(hash=tx_signed.hash) assert spend_tx.signatures[0] == tx_signed.get_signature(0)
def test_node_ga_meta_spend(chain_fixture, compiler_fixture): ae_cli = chain_fixture.NODE_CLI account = chain_fixture.ACCOUNT c_cli = compiler_fixture.COMPILER # make the account poa # transform the account # compile the contract ga_contract = c_cli.compile(blind_auth_contract).bytecode # now encode the call data init_calldata = c_cli.encode_calldata(blind_auth_contract, "init", [account.get_address()]).calldata # this will return an object # init_calldata.calldata # now we can execute the transaction tx = ae_cli.account_basic_to_ga(account, ga_contract, init_calldata=init_calldata, gas=500) print("ACCOUNT is now GA", account.get_address()) # retrieve the account data ga_account = ae_cli.get_account(account.get_address()) # create a dummy account recipient_id = Account.generate().get_address() # generate the spend transactions amount = 54321 payload = "ga spend tx" fee = defaults.FEE ttl = defaults.TX_TTL spend_tx = ae_cli.tx_builder.tx_spend(account.get_address(), recipient_id, amount, payload, fee, ttl, 0) # encode the call data for the transaction calldata = c_cli.encode_calldata(blind_auth_contract, ga_account.auth_fun, [hashing.randint()]).calldata # now we can sign the transaction (it will use the auth for do that) spend_tx = ae_cli.sign_transaction(ga_account, spend_tx.tx, auth_data=calldata) # broadcast tx_hash = ae_cli.broadcast_transaction(spend_tx.tx) print(f"GA_META_TX {tx_hash}") # check that the account received the tokens assert ae_cli.get_account_by_pubkey(pubkey=recipient_id).balance == amount
def test_cli_spend(chain_fixture, tempdir): account_path = _account_path(tempdir, chain_fixture.ALICE) # generate a new address recipient_address = Account.generate().get_address() # call the cli call_aecli('account', 'spend', account_path, recipient_address, "90", '--password', 'aeternity_bc', '--wait') # test that the recipient account has the requested amount print(f"recipient address is {recipient_address}") recipient_account = chain_fixture.NODE_CLI.get_account_by_pubkey( pubkey=recipient_address) print( f"recipient address {recipient_address}, balance {recipient_account.balance}" ) assert recipient_account.balance == 90
def test_cli_transfer_by_name(chain_fixture, tempdir): account_alice_path = _account_path(tempdir, chain_fixture.ALICE) # generate a new address recipient_address = Account.generate().get_address() domain = __fullclaim_domain(chain_fixture, tempdir, recipient_address) val = call_aecli('account', 'transfer', account_alice_path, domain, "0.01", '--password', 'aeternity_bc', '--wait') # test that the recipient account has the requested amount print(f"recipient domain is {domain}") recipient_account = chain_fixture.NODE_CLI.get_account_by_pubkey( pubkey=recipient_address) print( f"recipient address {recipient_address}, balance {recipient_account.balance}" ) assert recipient_account.balance == val['data']['tx']['data']['amount']
def _test_node_spend(node_cli, sender_account): account = Account.generate().get_address() # with numbers tx = node_cli.spend(sender_account, account, 100) print("DATA", tx) assert account == tx.data.tx.data.recipient_id assert sender_account.get_address() == tx.data.tx.data.sender_id account_balance = node_cli.get_account_by_pubkey(pubkey=account).balance assert account_balance == 100 # with strings tx = node_cli.spend(sender_account, account, "0.5ae") print("DATA", tx) assert account == tx.data.tx.data.recipient_id assert sender_account.get_address() == tx.data.tx.data.sender_id account_balance = node_cli.get_account_by_pubkey(pubkey=account).balance assert account_balance == 500000000000000100
def cmd_generate(args): try: if args.n > MAX_N_ACCOUNTS: print( f"Max number of accounts to generate is {MAX_N_ACCOUNTS}, requested: {args.n}" ) accounts = [] for i in range(args.n): a = Account.generate() accounts.append({ "index": i, "secret_key": a.get_secret_key(), "address": a.get_address() }) print(json.dumps(accounts, indent=2)) except Exception as e: print(f"Generation error: {e}")
def test_cli_inspect_transaction_by_hash(chain_fixture): # fill the account from genesys na = Account.generate() amount = random.randint(1, 1000000000000000000) tx = chain_fixture.NODE_CLI.spend(chain_fixture.ALICE, na.get_address(), amount) # now inspect the transaction j = call_aecli('inspect', tx.hash) assert j.get("hash") == tx.hash assert j.get("data", {}).get("block_height") > 0 assert j.get("data", {}).get("tx", {}).get("data", {}).get("recipient_id") == na.get_address() assert j.get("data", {}).get("tx", {}).get( "data", {}).get("sender_id") == chain_fixture.ALICE.get_address() assert j.get("data", {}).get("tx", {}).get("data", {}).get("amount") == amount
def test_api_get_block_by_hash(): has_kb, has_mb = False, False while not has_kb or not has_mb: # the latest block could be both micro or key block latest_block = EPOCH_CLI.get_top_block() has_mb = latest_block.hash.startswith( "mh_") or has_mb # check if is a microblock has_kb = latest_block.hash.startswith( "kh_") or has_kb # check if is a keyblock print(has_kb, has_mb, latest_block.hash) # create a transaction so the top block is going to be an micro block if not has_mb: account = Account.generate().get_address() EPOCH_CLI.spend(ACCOUNT, account, 100) # wait for the next block # client.wait_for_next_block() block = EPOCH_CLI.get_block_by_hash(hash=latest_block.hash) # assert block.hash == latest_block.hash assert block.height == latest_block.height
def test_node_spend_burst(chain_fixture): sender_account = chain_fixture.ALICE # make a new non blocking client ae_cli = chain_fixture.NODE_CLI ae_cli.config.blocking_mode = False # recipient account recipient_account = Account.generate().get_address() # send 50 consecutive spend ths = [] print(">>" * 20, "spend burst start") for i in range(50): tx = ae_cli.spend(sender_account, recipient_account, "1AE") ths.append(tx.hash) print("<<" * 20, "spend burst end") for th in ths: ae_cli.wait_for_transaction(th) assert (ae_cli.get_balance(recipient_account) == utils.amount_to_aettos( "50ae"))
def test_api_get_block_by_hash(chain_fixture): has_kb, has_mb = False, False while not has_kb or not has_mb: # the latest block could be both micro or key block latest_block = chain_fixture.NODE_CLI.get_top_block() has_mb = latest_block.hash.startswith( "mh_") or has_mb # check if is a microblock has_kb = latest_block.hash.startswith( "kh_") or has_kb # check if is a keyblock print(has_kb, has_mb, latest_block.hash) # create a transaction so the top block is going to be an micro block if not has_mb: account = Account.generate().get_address() chain_fixture.NODE_CLI.spend(chain_fixture.ALICE, account, '0.1AE') # wait for the next block block = chain_fixture.NODE_CLI.get_block_by_hash( hash=latest_block.hash) # assert block.hash == latest_block.hash assert block.height == latest_block.height
def test_node_spend_native(chain_fixture): node_cli = chain_fixture.NODE_CLI sender_account = chain_fixture.ALICE recipient_id = Account.generate().get_address() # with numbers tx = node_cli.spend(sender_account, recipient_id, 100) print("DATA", tx) assert recipient_id == tx.data.tx.data.recipient_id assert sender_account.get_address() == tx.data.tx.data.sender_id account_balance = node_cli.get_account_by_pubkey( pubkey=recipient_id).balance assert account_balance == 100 # spend some string tx = node_cli.spend(sender_account, recipient_id, "0.5ae") assert recipient_id == tx.data.tx.data.recipient_id assert sender_account.get_address() == tx.data.tx.data.sender_id account_balance = node_cli.get_account_by_pubkey( pubkey=recipient_id).balance assert account_balance == 500000000000000100
def test_name_transfer_ownership(): name = EPOCH_CLI.AEName(random_domain()) name.full_claim_blocking(ACCOUNT) assert name.status == AEName.Status.CLAIMED name.update_status() assert name.pointers[0]['id'] == ACCOUNT.get_address() assert name.pointers[0]['key'] == "account_pubkey" new_key_pair = Account.generate() # put some coins into the account so the account is in the state tree # otherwise it couldn't become the owner of an address. EPOCH_CLI.spend(ACCOUNT, new_key_pair.get_address(), 100) # now transfer the name to the other account name.transfer_ownership(ACCOUNT, new_key_pair.get_address()) assert name.status == AEName.Status.TRANSFERRED # try changing the target using that new account name.update_status() name.update(new_key_pair, new_key_pair.get_address()) name.update_status() assert len(name.pointers) > 0, 'Pointers should not be empty' assert name.pointers[0]['id'] == new_key_pair.get_address() assert name.pointers[0]['key'] == "account_pubkey"
def test_transaction_fee_calculation(): sender_id = Account.generate().get_address() recipient_id = Account.generate().get_address() # account_id, recipient_id, amount, payload, fee, ttl, nonce tts = [ { "native": (sender_id, recipient_id, 1000, "", 1, 0, 1), "field_fee_idx": 4, "match": False }, { "native": (sender_id, recipient_id, 9845, "another payload", 1, 500, 1241), "field_fee_idx": 4, "match": False }, { "native": (sender_id, recipient_id, 9845, "another payload", 1, 500, 32131), "field_fee_idx": 4, "match": False }, { "native": (sender_id, recipient_id, 410000, "this is a very long payload that is not good to have ", 100, 500, 1241), "field_fee_idx": 4, "match": False }, { "native": (sender_id, recipient_id, 410000, "another payload", 20000000000000, 10000000, 1241), "field_fee_idx": 4, "match": True }, { "native": (sender_id, recipient_id, 5000000000000000000, "Faucet TX", 20000000000000, 0, 1241), "field_fee_idx": 4, "match": True # 16920000000000 }, ] for tt in tts: # get a native transaction txbn = transactions.TxBuilder() txn = txbn.tx_spend(tt["native"][0], tt["native"][1], tt["native"][2], tt["native"][3], tt["native"][4], tt["native"][5], tt["native"][6]) print("=================") print(txn)
def test_cli_spend_invalid_amount(chain_fixture, tempdir): with pytest.raises(subprocess.CalledProcessError): account_path = _account_path(tempdir, chain_fixture.ALICE) receipient_address = Account.generate().get_address() call_aecli('account', 'spend', account_path, receipient_address, '-1', '--password', 'secret')
def create_wallet(): acc = Account.generate() pub_key = acc.get_address() priv_key = acc.get_secret_key() return priv_key, pub_key
def test_tutorial_offline_tx(chain_fixture): # Accounts addresses account = Account.generate() # --- hide --- override the account for tests account = chain_fixture.ALICE # /--- hide --- # instantiate the transactions builder build = TxBuilder() # we will be creating 5 transactions for later broadcast TODO: warn about the nonce limit txs = [] # each transaction is going to be a spend amount = utils.amount_to_aettos("0.05AE") payload = b'' for i in range(5): # increase the account nonce account.nonce = account.nonce + 1 # build the transaction tx = build.tx_spend( account.get_address(), # sender Account.generate().get_address(), # random generated recipient amount, payload, defaults.FEE, defaults.TX_TTL, account.nonce) # save the transaction txs.append(tx) # Sign the transactions # define the network_id network_id = identifiers.NETWORK_ID_TESTNET # --- hide --- override the network_id for tests network_id = chain_fixture.NODE_CLI.config.network_id # /--- hide --- # instantiate a transaction signer signer = TxSigner(account, network_id) # collect the signed tx for broadcast signed_txs = [] # sign all transactions for tx in txs: signature = signer.sign_transaction(tx) signed_tx = build.tx_signed([signature], tx) signed_txs.append(signed_tx) # Broadcast the transactions NODE_URL = os.environ.get('TEST_URL', 'https://testnet.aeternity.io') node_cli = NodeClient(Config( external_url=NODE_URL, blocking_mode=False, )) # broadcast all transactions for stx in signed_txs: node_cli.broadcast_transaction(stx) # verify that all transactions have been posted for stx in signed_txs: height = node_cli.wait_for_transaction(stx) assert (height > 0)
def test_epoch_spend(): account = Account.generate().get_address() EPOCH_CLI.spend(ACCOUNT, account, 100) account = EPOCH_CLI.get_account_by_pubkey(pubkey=account) balance = account.balance assert balance > 0