-
Notifications
You must be signed in to change notification settings - Fork 203
Components
The Node offers REST endpoints which provide information about its current status and Network overview, as well as endpoints which accept requests to generate Transactions. A specific group of endpoints are used for debugging SmartContracts, and will not be enabled in production Nodes connected to the Network.
The endpoints in group /node
provide status information about the Node itself. Note that /node
(the group) is not an endpoint, so GET /node
will return 404 Not Found
.
Return the time-sorted list of Heartbeat messages received by the Node from the entire Network. This information is used to model the overall status of the Network, as reported by the Nodes themselves. The returned list can grow long with longer uptime, as the Node constantly receives Heartbeat messages (every X seconds). Code that mitigates this growth is currently being worked on.
Return aggregate information calculated by the Node itself with respect to: total number of Nodes, total number of Shards, current Block Nonce, current Round number, average rate of Transactions per second and others.
Return a detailed information on the status of the Node at the instant of the request. Includes information on resource usage (CPU, memory, network), contents of the Data Pools, synchronization status, its public keys for signing Blocks and Transactions, application version and other aspects.
The endpoints in group /address
provide Account information, such as current Balance and current Nonce.
Return information about the Account identified by :address
, such as its current Nonce, Balance, the SmartContract code if
any and the Root Hash of the SmartContract's storage trie (if the Account is a SmartContract).
Return the current balance of the Account identified by :address
. Does not provide information about the Nonce, SmartContract
code or any hashes corresponding to this Account (see endpoint /address/:address
for this).
The endpoints in group /transaction
accept requests to generate Transactions and propagate them throughout the Network for
execution.
Accept request to send a single Transaction. The request must contain the following fields:
{
"Sender" : // string
"Receiver" : // string
"Value" : // string
"Data" : // string
"Nonce" : // uint64
"GasPrice" : // uint64
"GasLimit" : // uint64
"Signature": // string
}
On success, a Transaction will be generated by the Node and propagated throughout the Network. Returns the hash of the generated Transaction.
Accept request to send multiple Transactions. This endpoint behaves just like /transaction/send
, but it accepts a JSON array
of individual requests for a single Transaction. See the endpoint /transaction/send
for details. Returns the number of valid
Transactions that could be generated and propagated throughout the Network.
Not implemented yet.
The endpoints in group /vm-values
are used to interrogate deployed SmartContracts and retrieve values from them. All endpoints
have the same behavior - the only difference between them is how they format the retrieved value and return it to the user.
These endpoints are only enabled for development purposes, as they present an opportunity for Denial-of-Service attacks.
Note that /vm-values
(the group) is not an endpoint, so GET /vm-values
will return 404 Not Found
.
The JSON request accepted by any of the endpoints in this group has the following form:
{
"ScAddress" : // string
"FuncName" : // string
"Args" : // string array
}
If there is a SmartContract to be found at ScAddress
, it will be loaded and its function FuncName
executed with the
arguments Args
. The function FuncName
must have been written to call special API functions provided by the Elrond Environment
Interface to be able to return values to the outside world.
The value returned by calling FuncName
is handled differently by each of the following endpoints.
Return the requested value from the SmartContract by treating it as raw bytes, then writing it in base 16 as a string.
Return the requested value from the SmartContract by treating it as a regular string.
Return the requested value from the SmartContract by treating it as an integer. Large integers are supported using Go's
big.Int
type.
Return the entire output produced by the Virtual Machine after executing the requested SmartContract function.
TODO
- ☐ Interceptors: Interceptors listen to channels based on the topology of the Network - there is a Topic & Interceptor for each pair of sender-receiver Shards
- ☐ Interceptors: there are dedicated Interceptors on consensus-specific topics
An Interceptor is the component that reacts to the arrival of a Message on a specific Topic. The main role of Interceptors is to add incoming information from the Network into the Data Pool. Note that Interceptors do not react to all Messages: they only react to valid Messages and to Message that arrive on Topics of interest. This means that no Interceptor will react to invalid or uninteresting Messages - such Messages will be automatically dropped.
Because Messages are propagated through the Network in a peer-to-peer manner,
Interceptors are invoked by the Messenger. This means that Interceptors must implement the interface
p2p.MessageProcessor
:
type MessageProcessor interface {
ProcessReceivedMessage(message p2p.MessageP2P) error
}
The function Interceptor.ProcessReceivedMessage()
must therefore perform all the handling required.
Where in the source code are Messages dropped due to being invalid or having uninteresting Topics?
[TODO add list of instantiated Interceptors directly from the Messenger structure at runtime]
- ☐ Resolvers: they send a reply back directly to the requesting Peer (the PeerID is in the Message containing the initial request)
- ☐ Data Pool: clarify that there's one Data Pool, with multiple sub-pools
- ☐ Notifier (inside Data Pools): reacts to the insertion of a certain piece of information into the Data Pool
- ☐ Notifier (inside Data Pools): if the Node was awaiting a reply with a specific info, it sets a Notifier which saves the newly inserted info into a "Requested info" Data Pool
The Data Pool is a heterogeneous container, present in each Node, which stores information that has arrived through valid Messages from the Network and awaits processing (see how Nodes communicate using Messages). Note that before having their contents stored in the Data Pool, all Messages that arrive from the Network to the Node must have already been validated by Interceptors.
A Node's Data Pool contains not only the information that is vehiculated through the Network and has somehow arrived at the Node, but it also contains information that the Node has requested from its Peers (and they responded).
Here's an example of how a transaction ends up in the Data Pool of a Node, after being propagated to the network:
- some user in the world wants to call a SmartContract
- this generates a transaction with a sum of ERD and containing a call to a SmartContract method (see Executing SmartContracts)
- the Transaction is propagated through the Network by broadcasting it to as many Nodes as possible - every Node, ideally (see the details of peer-to-peer Propagation of information)
- every Node that hears about this Transaction will store it in its Data Pool, after its Interceptors validate the Message that contains it
There are two types of Data Pools, which contain different types of information, depending on what kind of Node created it. These two types of Data Pools are Sharded Data Pool and Meta Data Pool. See below.
It is used by Nodes that are part of normal Shards (as opposed to Metashard Nodes).
type PoolsHolder interface {
Transactions() ShardedDataCacherNotifier
UnsignedTransactions() ShardedDataCacherNotifier
Headers() storage.Cacher
HeadersNonces() Uint64SyncMapCacher
MiniBlocks() storage.Cacher
PeerChangesBlocks() storage.Cacher
MetaBlocks() storage.Cacher
}
It is used by Nodes that are part of the Metashard (as opposed to Nodes in normal Shards)
type MetaPoolsHolder interface {
MetaChainBlocks() storage.Cacher
MiniBlockHashes() ShardedDataCacherNotifier
ShardHeaders() storage.Cacher
HeadersNonces() Uint64SyncMapCacher
}