Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: rosetta zero balance accounts tests #8833

Merged
merged 6 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 13 additions & 13 deletions chain/rosetta-rpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "near-rosetta-rpc"
version = "0.0.0"
authors.workspace = true
publish = false
edition.workspace = true
name = "near-rosetta-rpc"
publish = false
version = "0.0.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand All @@ -24,19 +24,19 @@ thiserror.workspace = true
tokio.workspace = true
validator.workspace = true

near-primitives = { path = "../../core/primitives" }
near-account-id = { path = "../../core/account-id" }
near-crypto = { path = "../../core/crypto" }
near-chain-configs = { path = "../../core/chain-configs" }
near-client = { path = "../client" }
near-client-primitives = { path = "../client-primitives" }
near-network = { path = "../network" }
near-o11y = { path = "../../core/o11y" }

near-account-id = {path = "../../core/account-id"}
near-chain-configs = {path = "../../core/chain-configs"}
near-client = {path = "../client"}
near-client-primitives = {path = "../client-primitives"}
near-crypto = {path = "../../core/crypto"}
near-network = {path = "../network"}
near-o11y = {path = "../../core/o11y"}
near-primitives = {path = "../../core/primitives"}
node-runtime = {path = "../../runtime/runtime"}

[dev-dependencies]
insta = "1"
near-actix-test-utils = { path = "../../test-utils/actix-test-utils" }
near-actix-test-utils = {path = "../../test-utils/actix-test-utils"}

[features]
nightly = []
2 changes: 1 addition & 1 deletion chain/rosetta-rpc/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ where

/// Zero-balance account (NEP-448)
fn is_zero_balance_account(account: &near_primitives::account::Account) -> bool {
account.storage_usage() <= 770
account.storage_usage() <= node_runtime::ZERO_BALANCE_ACCOUNT_STORAGE_LIMIT
}

/// Tokens not locked due to staking (=liquid) but reserved for state.
Expand Down
171 changes: 104 additions & 67 deletions pytest/tests/sanity/rosetta.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
BlockIdentifier = typing.Union[str, int, JsonDict]
TxIdentifier = typing.Union[str, JsonDict]

def account_identifier(account_id: str) -> JsonDict:
return {'address': account_id}

def block_identifier(block_id: BlockIdentifier) -> JsonDict:
if isinstance(block_id, int):
Expand Down Expand Up @@ -261,6 +263,39 @@ def transfer(self, *, src: key.Key, dst: key.Key, amount: int,
},
}, **kw)

def add_full_access_key(self, account: key.Key, public_key_hex: str, **kw) -> RosettaExecResult:
return self.exec_operations(
account,
{
"operation_identifier": {
"index": 0
},
"type": "INITIATE_ADD_KEY",
"account": {
"address": account.account_id
}
},
{
"operation_identifier": {
"index": 1
},
"related_operations": [
{
"index": 0
}
],
"type": "ADD_KEY",
"account": {
"address": account.account_id
},
"metadata": {
"public_key": {
"hex_bytes": public_key_hex,
"curve_type": "edwards25519"
}
}
}, **kw)

def delete_account(self, account: key.Key, refund_to: key.Key,
**kw) -> RosettaExecResult:
return self.exec_operations(
Expand Down Expand Up @@ -325,6 +360,11 @@ def get_transaction(self, *, block_id: BlockIdentifier,
transaction_identifier=tx_identifier(tx_id))
return res['transaction']

def get_account_balances(self, *, account_id: str) -> JsonDict:
res = self.rpc('/account/balance',
account_identifier=account_identifier(account_id))
return res['balances']


class RosettaTestCase(unittest.TestCase):
node = None
Expand All @@ -350,6 +390,65 @@ def setUpClass(cls) -> None:
def tearDownClass(cls) -> None:
cls.node.cleanup()

def test_zero_balance_account(self) -> None:
test_amount = 10**22
encody marked this conversation as resolved.
Show resolved Hide resolved
key_space_cost = 41964925000000000000
validator = self.node.validator_key
implicit = key.Key.implicit_account()

result = self.rosetta.transfer(src=validator,
dst=implicit,
amount=test_amount)

block = result.block()
tx = result.transaction()
json_res = self.node.get_tx(result.near_hash, implicit.account_id)
json_res = json_res['result']
receipt_ids = json_res['transaction_outcome']['outcome']['receipt_ids']
receipt_id = {'hash': 'receipt:' + receipt_ids[0]}

# Fetch the receipt through Rosetta RPC.
result = RosettaExecResult(self.rosetta, block, receipt_id)
related = result.related(0)

balances = self.rosetta.get_account_balances(account_id=implicit.account_id)

self.assertEqual(balances, [{
'value': str(test_amount),
'currency': {
'symbol': 'NEAR',
'decimals': 24
}
}])

# add 6 keys to go over the zero-balance account free storage allowance
public_keys_hex = [
"17595386a67d36afc73872e60916f83217d789dc60b5d037563998e6651111cf",
"7940aac79a425f194621ab5c4e38b7841dddae90b20eaf28f7f78caec911bcf4",
"0554fffef36614d7c49b3088c4c1fb66613ff05fb30927b582b43aed0b25b549",
"09d36e25c5a3ac440a798252982dd92b67d8de60894df3177cb4ff30a890cafd",
"e0ca119be7211f3dfed1768fc9ab235b6af06a205077ef23166dd1cbfd2ac7fc",
"98f1a49296fb7156980d325a25e1bfeb4f123dd98c90fa0492699c55387f7ef3",
]
for pk in public_keys_hex:
result = self.rosetta.add_full_access_key(implicit, pk)

block = result.block()
tx = result.transaction()
json_res = self.node.get_tx(result.near_hash, implicit.account_id)
json_res = json_res['result']
receipt_ids = json_res['transaction_outcome']['outcome']['receipt_ids']
receipt_id = {'hash': 'receipt:' + receipt_ids[0]}

# Fetch the receipt through Rosetta RPC.
result = RosettaExecResult(self.rosetta, block, receipt_id)
related = result.related(0)

balances = self.rosetta.get_account_balances(account_id=implicit.account_id)

# no longer a zero-balance account
self.assertEqual(test_amount - key_space_cost * len(public_keys_hex), int(balances[0]['value']))

def test_get_block(self) -> None:
"""Tests getting blocks and transactions.

Expand All @@ -375,32 +474,13 @@ def test_get_block(self) -> None:
'decimals': 24,
'symbol': 'NEAR'
},
'value': '999999999998180000000000000000000'
'value': '1000000000000000000000000000000000'
},
'operation_identifier': {
'index': 0
},
'status': 'SUCCESS',
'type': 'TRANSFER'
}, {
'account': {
'address': 'near',
'sub_account': {
'address': 'LIQUID_BALANCE_FOR_STORAGE'
}
},
'amount': {
'currency': {
'decimals': 24,
'symbol': 'NEAR'
},
'value': '1820000000000000000000'
},
'operation_identifier': {
'index': 1
},
'status': 'SUCCESS',
'type': 'TRANSFER'
}, {
'account': {
'address': 'test0'
Expand All @@ -413,7 +493,7 @@ def test_get_block(self) -> None:
'value': '950000000000000000000000000000000'
},
'operation_identifier': {
'index': 2
'index': 1
},
'status': 'SUCCESS',
'type': 'TRANSFER'
Expand All @@ -432,7 +512,7 @@ def test_get_block(self) -> None:
'value': '50000000000000000000000000000000'
},
'operation_identifier': {
'index': 3
'index': 2
},
'status': 'SUCCESS',
'type': 'TRANSFER'
Expand Down Expand Up @@ -666,31 +746,7 @@ def test_implicit_account(self) -> None:
'address': implicit.account_id,
},
'amount': {
'value': '8180000000000000000000',
'currency': {
'symbol': 'NEAR',
'decimals': 24
}
}
}, {
'operation_identifier': {
'index': 1
},
'type': 'TRANSFER',
'status': 'SUCCESS',
'metadata': {
'predecessor_id': {
'address': 'test0'
}
},
'account': {
'address': implicit.account_id,
'sub_account': {
'address': 'LIQUID_BALANCE_FOR_STORAGE'
}
},
'amount': {
'value': '1820000000000000000000',
'value': '10000000000000000000000',
'currency': {
'symbol': 'NEAR',
'decimals': 24
Expand Down Expand Up @@ -808,32 +864,13 @@ def test_implicit_account(self) -> None:
'decimals': 24,
'symbol': 'NEAR'
},
'value': '-8128890300000000000000'
'value': '-9948890300000000000000'
},
'operation_identifier': {
'index': 0
},
'status': 'SUCCESS',
'type': 'TRANSFER'
}, {
'account': {
'address': implicit.account_id,
'sub_account': {
'address': 'LIQUID_BALANCE_FOR_STORAGE'
}
},
'amount': {
'currency': {
'decimals': 24,
'symbol': 'NEAR'
},
'value': '-1820000000000000000000'
},
'operation_identifier': {
'index': 1
},
'status': 'SUCCESS',
'type': 'TRANSFER'
}],
'related_transactions': [{
'direction': 'forward',
Expand Down