|
|
|
from .rpc.request import (
|
|
|
|
rpc_request
|
|
|
|
)
|
|
|
|
|
|
|
|
from .exceptions import (
|
|
|
|
InvalidRPCReplyError
|
|
|
|
)
|
|
|
|
|
|
|
|
_default_endpoint = 'http://localhost:9500'
|
|
|
|
_default_timeout = 30
|
|
|
|
|
|
|
|
|
|
|
|
################
|
|
|
|
# Network RPCs #
|
|
|
|
################
|
|
|
|
def get_node_metadata(endpoint=_default_endpoint, timeout=_default_timeout) -> dict:
|
|
|
|
"""
|
|
|
|
Get config for the node
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
dict
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
"""
|
|
|
|
return rpc_request('hmy_getNodeMetadata', endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_shard(endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get config for the node
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Shard ID of node
|
|
|
|
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
InvalidRPCReplyError
|
|
|
|
If received unknown result from endpoint
|
|
|
|
"""
|
|
|
|
method = 'hmy_getNodeMetadata'
|
|
|
|
try:
|
|
|
|
return rpc_request(method, endpoint=endpoint, timeout=timeout)['result']['shard-id']
|
|
|
|
except KeyError as e:
|
|
|
|
raise InvalidRPCReplyError(method, endpoint) from e
|
|
|
|
|
|
|
|
|
|
|
|
def get_staking_epoch(endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get epoch number when blockchain switches to EPoS election
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Epoch at which blockchain switches to EPoS election
|
|
|
|
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
InvalidRPCReplyError
|
|
|
|
If received unknown result from endpoint
|
|
|
|
"""
|
|
|
|
method = 'hmy_getNodeMetadata'
|
|
|
|
data = rpc_request(method, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
try:
|
|
|
|
return int(data['chain-config']['staking-epoch'])
|
|
|
|
except (KeyError, TypeError) as e:
|
|
|
|
raise InvalidRPCReplyError(method, endpoint) from e
|
|
|
|
|
|
|
|
|
|
|
|
def get_prestaking_epoch(endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get epoch number when blockchain switches to allow staking features without election
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Epoch at which blockchain switches to allow staking features without election
|
|
|
|
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
InvalidRPCReplyError
|
|
|
|
If received unknown result from endpoint
|
|
|
|
"""
|
|
|
|
method = 'hmy_getNodeMetadata'
|
|
|
|
data = rpc_request(method, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
try:
|
|
|
|
return int(data['chain-config']['prestaking-epoch'])
|
|
|
|
except (KeyError, TypeError) as e:
|
|
|
|
raise InvalidRPCReplyError(method, endpoint) from e
|
|
|
|
|
|
|
|
|
|
|
|
def get_sharding_structure(endpoint=_default_endpoint, timeout=_default_timeout) -> list:
|
|
|
|
"""
|
|
|
|
Get network sharding structure
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
list
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
"""
|
|
|
|
return rpc_request('hmy_getShardingStructure', endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_leader_address(endpoint=_default_endpoint, timeout=_default_timeout) -> str:
|
|
|
|
"""
|
|
|
|
Get current leader one address
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
str
|
|
|
|
One address of current leader
|
|
|
|
"""
|
|
|
|
return rpc_request('hmy_getLeader', endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_block_number(endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get current block number
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Current block number
|
|
|
|
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
InvalidRPCReplyError
|
|
|
|
If received unknown result from endpoint
|
|
|
|
"""
|
|
|
|
method = 'hmy_blockNumber'
|
|
|
|
try:
|
|
|
|
return int(rpc_request(method, endpoint=endpoint, timeout=timeout)['result'], 16)
|
|
|
|
except TypeError as e:
|
|
|
|
raise InvalidRPCReplyError(method, endpoint) from e
|
|
|
|
|
|
|
|
|
|
|
|
def get_current_epoch(endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get current epoch number
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Current epoch number
|
|
|
|
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
InvalidRPCReplyError
|
|
|
|
If received unknown result from endpoint
|
|
|
|
"""
|
|
|
|
method = 'hmy_getEpoch'
|
|
|
|
try:
|
|
|
|
return int(rpc_request(method, endpoint=endpoint, timeout=timeout)['result'], 16)
|
|
|
|
except TypeError as e:
|
|
|
|
raise InvalidRPCReplyError(method, endpoint) from e
|
|
|
|
|
|
|
|
|
|
|
|
def get_gas_price(endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get network gas price
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Network gas price
|
|
|
|
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
InvalidRPCReplyError
|
|
|
|
If received unknown result from endpoint
|
|
|
|
"""
|
|
|
|
method = 'hmy_gasPrice'
|
|
|
|
try:
|
|
|
|
return int(rpc_request(method, endpoint=endpoint, timeout=timeout)['result'], 16)
|
|
|
|
except TypeError as e:
|
|
|
|
raise InvalidRPCReplyError(method, endpoint) from e
|
|
|
|
|
|
|
|
|
|
|
|
def get_num_peers(endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get number of peers connected to the node
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Number of connected peers
|
|
|
|
Raises
|
|
|
|
------
|
|
|
|
InvalidRPCReplyError
|
|
|
|
If received unknown result from endpoint
|
|
|
|
"""
|
|
|
|
method = 'net_peerCount'
|
|
|
|
try:
|
|
|
|
return int(rpc_request(method, endpoint=endpoint, timeout=timeout)['result'], 16)
|
|
|
|
except TypeError as e:
|
|
|
|
raise InvalidRPCReplyError(method, endpoint) from e
|
|
|
|
|
|
|
|
|
|
|
|
##############
|
|
|
|
# Block RPCs #
|
|
|
|
##############
|
|
|
|
def get_latest_header(endpoint=_default_endpoint, timeout=_default_timeout) -> dict:
|
|
|
|
"""
|
|
|
|
Get block header of latest block
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
dict
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
"""
|
|
|
|
return rpc_request('hmy_latestHeader', endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_latest_headers(endpoint=_default_endpoint, timeout=_default_timeout) -> dict:
|
|
|
|
"""
|
|
|
|
Get block header of latest block for beacon chain & shard chain
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
dict
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
"""
|
|
|
|
return rpc_request('hmy_getLatestChainHeaders', endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_block_by_number(block_num, endpoint=_default_endpoint, include_full_tx=False, timeout=_default_timeout) -> dict:
|
|
|
|
"""
|
|
|
|
Get block by number
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
block_num: int
|
|
|
|
Block number to fetch
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
include_full_tx: :obj:`bool`, optional
|
|
|
|
Include list of full transactions data for each block
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
dict
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
str(hex(block_num)),
|
|
|
|
include_full_tx
|
|
|
|
]
|
|
|
|
return rpc_request('hmy_getBlockByNumber', params=params, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_block_by_hash(block_hash, endpoint=_default_endpoint, include_full_tx=False, timeout=_default_timeout) -> dict:
|
|
|
|
"""
|
|
|
|
Get block by hash
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
block_hash: str
|
|
|
|
Block hash to fetch
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
include_full_tx: :obj:`bool`, optional
|
|
|
|
Include list of full transactions data for each block
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
dict
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
None if block hash is not found
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
block_hash,
|
|
|
|
include_full_tx
|
|
|
|
]
|
|
|
|
return rpc_request('hmy_getBlockByHash', params=params, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_block_transaction_count_by_number(block_num, endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get transaction count for specific block number
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
block_num: int
|
|
|
|
Block number to get transaction count for
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
include_full_tx: :obj:`bool`, optional
|
|
|
|
Include list of full transactions data for each block
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Number of transactions in the block
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
str(hex(block_num))
|
|
|
|
]
|
|
|
|
return int(rpc_request('hmy_getBlockTransactionCountByNumber', params=params,
|
|
|
|
endpoint=endpoint, timeout=timeout)['result'], 16
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def get_block_transaction_count_by_hash(block_hash, endpoint=_default_endpoint, timeout=_default_timeout) -> int:
|
|
|
|
"""
|
|
|
|
Get transaction count for specific block hash for
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
block_hash: str
|
|
|
|
Block hash to get transaction count
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
include_full_tx: :obj:`bool`, optional
|
|
|
|
Include list of full transactions data for each block
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
int
|
|
|
|
Number of transactions in the block
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
block_hash
|
|
|
|
]
|
|
|
|
return int(rpc_request('hmy_getBlockTransactionCountByHash', params=params,
|
|
|
|
endpoint=endpoint, timeout=timeout)['result'], 16
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def get_blocks(start_block, end_block, endpoint=_default_endpoint, include_full_tx=False,
|
|
|
|
include_signers=False, timeout=_default_timeout
|
|
|
|
) -> list:
|
|
|
|
"""
|
|
|
|
Get list of blocks from a range
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
start_block: int
|
|
|
|
First block to fetch (inclusive)
|
|
|
|
end_block: int
|
|
|
|
Last block to fetch (inclusive)
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
include_full_tx: :obj:`bool`, optional
|
|
|
|
Include list of full transactions data for each block
|
|
|
|
include_signers: :obj:`bool`, optional
|
|
|
|
Include list of signers for each block
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
list
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
str(hex(start_block)),
|
|
|
|
str(hex(end_block)),
|
|
|
|
{
|
|
|
|
'withSigners': include_signers,
|
|
|
|
'fullTx': include_full_tx,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
return rpc_request('hmy_getBlocks', params=params, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_block_signers(block_num, endpoint=_default_endpoint, timeout=_default_timeout) -> list:
|
|
|
|
"""
|
|
|
|
Get list of block signers for specific block number
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
block_num: int
|
|
|
|
Block number to get signers for
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
list
|
|
|
|
List of one addresses that signed the block
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
str(hex(block_num))
|
|
|
|
]
|
|
|
|
return rpc_request('hmy_getBlockSigners', params=params, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_block_signer_keys(block_num, endpoint=_default_endpoint, timeout=_default_timeout) -> list:
|
|
|
|
"""
|
|
|
|
Get list of block signer public bls keys for specific block number
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
block_num: int
|
|
|
|
Block number to get signer keys for
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
list
|
|
|
|
List of bls public keys that signed the block
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
str(hex(block_num))
|
|
|
|
]
|
|
|
|
return rpc_request('hmy_getBlockSignerKeys', params=params, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_validators(epoch, endpoint=_default_endpoint, timeout=_default_timeout) -> dict:
|
|
|
|
"""
|
|
|
|
Get list of validators for specific epoch number
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
epoch: int
|
|
|
|
Epoch to get list of validators for
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
dict
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
epoch
|
|
|
|
]
|
|
|
|
return rpc_request('hmy_getValidators', params=params, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_validator_keys(epoch, endpoint=_default_endpoint, timeout=_default_timeout) -> list:
|
|
|
|
"""
|
|
|
|
Get list of validator public bls keys for specific epoch number
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
epoch: int
|
|
|
|
Epoch to get list of validator keys for
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
list
|
|
|
|
List of bls public keys in the validator committee
|
|
|
|
"""
|
|
|
|
params = [
|
|
|
|
epoch
|
|
|
|
]
|
|
|
|
return rpc_request('hmy_getValidatorKeys', params=params, endpoint=endpoint, timeout=timeout)['result']
|
|
|
|
|
|
|
|
|
|
|
|
def get_bad_blocks(endpoint=_default_endpoint, timeout=_default_timeout) -> list:
|
|
|
|
"""
|
|
|
|
Get list of bad blocks in memory of specific node
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
endpoint: :obj:`str`, optional
|
|
|
|
Endpoint to send request to
|
|
|
|
timeout: :obj:`int`, optional
|
|
|
|
Timeout in seconds
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
list
|
|
|
|
# TODO: Add link to reference RPC documentation
|
|
|
|
"""
|
|
|
|
return rpc_request('hmy_getCurrentBadBlocks', endpoint=endpoint, timeout=timeout)['result']
|