[−][src]Module exonum::runtime
Common building blocks for creating runtimes for the Exonum blockchain.
Each runtime contains specific services to execute transactions, process events, provide user APIs, etc. A unified dispatcher redirects all the calls and requests to the appropriate runtime environment. Thus, a blockchain interacts with the dispatcher, and not with specific runtime instances.
Artifacts
Each runtime has its own artifacts registry from which users can create a service. The artifact identifier is required by the runtime to construct service instances. In other words, an artifact identifier is similar to a class name, and a specific service instance - to a class instance. A single artifact may be used to instantiate zero or more services.
The format of an artifact ID is uniform across runtimes (it is essentially a string), but the runtime may customize artifact deployment via runtime-specific deployment arguments.
Artifact Lifecycle
-
An artifact is assembled in a way specific to the runtime. For example, the artifact may be compiled from sources and packaged using an automated build system.
-
The artifact with the service is deployed on the blockchain. The decision to deploy the artifact and the deployment spec are usually performed by the blockchain administrators. The corresponding logic is customizable via a supervisor service. What deployment entails depends on the runtime; e.g., the artifact may be downloaded by each Exonum node, verified for integrity and then added into the execution environment.
-
For each node, an artifact may be deployed either asynchronously or synchronously / in a blocking manner. The supervisor usually first commands a node to deploy the artifact asynchronously via
Mailbox
once the decision to start deployment is reached by the blockchain administrators. Async deployment speed and outcome may differ among nodes. -
The supervisor translates local deployment outcomes into a consensus-agreed result. For example, the supervisor may collect confirmations from the validator nodes that have successfully deployed the artifact, and once all the validator nodes have sent their confirmations, the artifact is committed. Being part of the service logic, artifact commitment is completely deterministic, agreed via consensus, and occurs at the same blockchain height for all nodes in the network.
-
Once the artifact is committed, every node in the network is required to have it deployed in order to continue functioning. If a node has not deployed the artifact previously, deployment becomes blocking; the node does not participate in consensus or block processing until the deployment is completed successfully. If the deployment is unsuccessful, the node stops indefinitely. Due to deployment confirmation mechanics built into the supervisor, it is reasonable to assume that a deployment failure at this stage is local to the node and could be fixed by the node admin.
Service Lifecycle
-
Once the artifact is committed, it is possible to instantiate a corresponding service. Each instantiation request contains an ID of a previously deployed artifact, a string instance ID, and instantiation arguments in a binary encoding (by convention, Protobuf). As with the artifacts, the logic controlling instantiation is encapsulated in the supervisor service.
-
During instantiation, the service is assigned a numeric ID, which is used to reference the service in transactions. The runtime can execute initialization logic defined in the service artifact; e.g., the service may store some initial data in the storage, check service dependencies, etc. The service (or the enclosing runtime) may signal that the initialization failed, in which case the service is considered not instantiated.
-
Once the service is instantiated, it can process transactions and interact with the external users in other ways. Different services instantiated from the same artifact are independent and have separate blockchain storages. Users can distinguish services by their IDs; both numeric and string IDs are unique within a blockchain.
Warning: state hash of the block is not affected by services, instantiated within it. The only exception is the genesis block where object hashes of builtin services are included to the resulting block state hash. This behavior difference will be unified in next release.
Dispatcher
is responsible for persisting artifacts and services across node restarts.
Transaction Lifecycle
-
An Exonum client creates a transaction message which includes
CallInfo
information about the corresponding method to call and serialized method parameters as a payload. The client then signs the message using the Ed25519 signature system. -
The client transmits the message to one of the Exonum nodes in the network.
-
The node verifies correctness of the transaction signature and retransmits it to the other network nodes if it is correct.
-
When the consensus algorithm run by Exonum nodes finds a feasible candidate for the next block of transactions, transactions in the block are passed to the
Dispatcher
for execution. -
The dispatcher uses a lookup table to find the corresponding
Runtime
for the transaction by theinstance_id
recorded in the message. If the corresponding runtime is found, the dispatcher passes the transaction into this runtime for immediate execution. -
After execution the transaction execution status is written into the blockchain.
Supervisor Service
A supervisor service is a service that has additional privileges. This service allows to deploy artifacts and instantiate new services after the blockchain is launched and running. Other than that, it looks like an ordinary service. The supervisor should be present during the blockchain start, otherwise no new artifacts / services could ever be added to the blockchain.
The supervisor service is distinguished by its numerical ID, which must be set
to SUPERVISOR_INSTANCE_ID
. Services may assume that transactions originating from
the supervisor service are authorized by the blockchain administrators. This can be used
in services: if a certain transaction originates from a service with SUPERVISOR_INSTANCE_ID
,
it is authorized by the administrators.
Re-exports
pub use self::error::ErrorKind; |
pub use self::error::ExecutionError; |
Modules
error | The set of errors for the Runtime module. |
rust | The current runtime is for running native services written in Rust. |
Structs
AnyTx | Transaction with the information required for the call. |
ArtifactId | The artifact identifier is required by the runtime to construct service instances. In other words, an artifact identifier is similar to a class name, and a specific service instance is similar to a class instance. |
ArtifactSpec | Exhaustive artifact specification. |
ArtifactState | Current state of artifact in dispatcher. |
BlockchainData | Provides access to blockchain data for the executing service. |
CallInfo | Information for calling the service method. |
Dispatcher | A collection of |
DispatcherSchema | Schema of the dispatcher, used to store information about pending artifacts / service instances, and to reload artifacts / instances on node restart. |
ExecutionContext | Provide the current state of the blockchain and the caller information in respect of the transaction which is being executed. |
InstanceDescriptor | Instance descriptor contains information to access running service instance. |
InstanceSpec | Exhaustive service instance specification. |
InstanceState | Current state of service instance in dispatcher. |
Mailbox | Mailbox accumulating |
RuntimeInstance | Instance of |
StateHashAggregator | An accessory structure that aggregates root object hashes of the service information schemas of the runtime with the root hash of the runtime information schema itself. |
Enums
ArtifactStatus | Status of an artifact deployment. |
Caller | The initiator of the method execution. |
DispatcherError | List of possible dispatcher errors. |
InstanceQuery | Allows to query a service instance by either of the two identifiers. |
InstanceStatus | Status of a service instance. |
RuntimeIdentifier | List of predefined runtimes. |
Constants
SUPERVISOR_INSTANCE_ID | Persistent identifier of supervisor service instance. |
Traits
Runtime | Runtime environment for Exonum services. |
SnapshotExt | Extension trait for |
WellKnownRuntime | Specifies system identifier for a |
Type Definitions
InstanceId | Unique service instance identifier. |
MethodId | Identifier of the method in the service interface required for the call. |