Bugs in Enum_virtual_ops from account_history API
While doing some functional testing of account_history API in testnet I noticed suspicious behaviors of enum_virtual_ops
method.
First abnormality happens when include_reversible
argument is set on true (we want to list operations in reversible blocks) and limit
is defined, method actually limits number of blocks, not operations, which is incorrect. Number of operations should be limited by limit
argument. Test case which indicated this behavior:
- get actual block number
- create 15 new accounts in single transaction
- wait 1 block
- get actual block number
- use method with
block_range_begin
set to the one before creating accounts,block_range_end
set to one after creating accounts,include_reversible=True
,limit = 2
andgroup_by_block: True
.
Sent JSON:
{'jsonrpc': '2.0', 'id': 1, 'method': 'account_history_api.enum_virtual_ops', 'params': {'block_range_begin': 3, 'block_range_end': 8, 'include_reversible': True, 'group_by_block': True, 'limit': 2}}
Response:
{
'ops': [],
'ops_by_block': [
{
'block': 2,
'irreversible': False,
'timestamp': '2022-12-08T09: 10: 30',
'ops': [
{
'trx_id': '0000000000000000000000000000000000000000',
'block': 2,
'trx_in_block': 4294967295,
'op_in_trx': 1,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'producer_reward_operation',
'value': {
'producer': 'initminer',
'vesting_shares': {
'amount': '43067',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': '18446744069414584321'
}
]
},
{
'block': 3,
'irreversible': False,
'timestamp': '2022-12-08T09: 10: 30',
'ops': [
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 1,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-0',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 1
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 3,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-1',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 3
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 5,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-2',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 5
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 7,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-3',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 7
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 9,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-4',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 9
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 11,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-5',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 11
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 13,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-6',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 13
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 15,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-7',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 15
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 17,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-8',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 17
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 19,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-9',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 19
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 21,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-10',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 21
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 23,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-11',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 23
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,As shown above, number of blocks is limited, not number of operations. If blocks are irreversible, everything works as intended.
'op_in_trx': 25,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-12',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 25
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 27,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-13',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 27
},
{
'trx_id': '13b7d2ea7243d08faa7b78d070950e677f365f65',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 29,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 30',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-14',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 29
},
{
'trx_id': '0000000000000000000000000000000000000000',
'block': 3,
'trx_in_block': 4294967295,
'op_in_trx': 1,
'virtual_op': True,
'timestamp': '2022-12-08T09: 10: 33',
'op': {
'type': 'producer_reward_operation',
'value': {
'producer': 'initminer',
'vesting_shares': {
'amount': '32630',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': '18446744069414584321'
}
]
}
],
'next_block_range_begin': 0,
'next_operation_begin': 0
}
As shown above, number of blocks is limited, not number of operations. If blocks are irreversible, everything works as intended.
Second suspicious behaviour of method is when operation_id
assigned to operation_begin
is higher than last operation_id
included in block_range_begin
. In this situation method starts listing from last operation included in block_range_begin
number (no matter if transaction is reversible or irreversible) which has obviously operation_id
which we don't want to see.
Example:
Block with number 2 has two virtual operations with operation_id
35 and 37.
Block with number 3 has also two virtual operations with operation_id
39 and 41.
Message sent:
{
"jsonrpc": "2.0",
"id": 1,
"method": "account_history_api.enum_virtual_ops",
"params": {
"block_range_begin": 2,
"block_range_end": 4,
"operation_begin": 39
}
}
Response:
{
'ops': [
{
'trx_id': '89cf7f4aed491c020fda2aca6b3c489c0db66bd4',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 1,
'virtual_op': True,
'timestamp': '2022-12-16T11: 30: 45',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-0',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 37
},
{
'trx_id': '89cf7f4aed491c020fda2aca6b3c489c0db66bd4',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 3,
'virtual_op': True,
'timestamp': '2022-12-16T11: 30: 45',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-1',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 39
},
{
'trx_id': '89cf7f4aed491c020fda2aca6b3c489c0db66bd4',
'block': 3,
'trx_in_block': 0,
'op_in_trx': 5,
'virtual_op': True,
'timestamp': '2022-12-16T11: 30: 45',
'op': {
'type': 'account_created_operation',
'value': {
'new_account_name': 'account-2',
'creator': 'initminer',
'initial_vesting_shares': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
},
'initial_delegation': {
'amount': '0',
'precision': 6,
'nai': '@@000000037'
}
}
},
'operation_id': 41
}
],
'ops_by_block': [],
'next_block_range_begin': 0,
'next_operation_begin': 0
}
As shown above listing starts from transaction with id 37, not 39 as wanted.