From 90d3996453d5a8d3723b10571bac84a14df37ad2 Mon Sep 17 00:00:00 2001 From: Jakub Zajkowski Date: Tue, 29 Apr 2025 16:26:23 +0200 Subject: [PATCH 1/3] Introducing monitor-and-consume-events.md with contemporary SSE event examples, various fixes to errors in serialization documentation for v2.0.0 --- .../concepts/serialization/primitives.md | 2 +- .../concepts/serialization/structures.md | 119 ++-- .../concepts/serialization/types.md | 15 +- .../developers/cli/opcode-costs.md | 6 +- .../developers/json-rpc/types_chain.md | 2 +- .../developers/monitor-and-consume-events.md | 582 ++++++++++++++++++ 6 files changed, 674 insertions(+), 52 deletions(-) create mode 100644 versioned_docs/version-2.0.0/developers/monitor-and-consume-events.md diff --git a/versioned_docs/version-2.0.0/concepts/serialization/primitives.md b/versioned_docs/version-2.0.0/concepts/serialization/primitives.md index 77ef1bc41..14ae5799a 100644 --- a/versioned_docs/version-2.0.0/concepts/serialization/primitives.md +++ b/versioned_docs/version-2.0.0/concepts/serialization/primitives.md @@ -21,7 +21,7 @@ enum CLType { String, // e.g. "Hello, World!" URef, // unforgeable reference (see above) Key, // global state key (see above) - PublicKey // A Casper system PublicKey type + PublicKey, // A Casper system PublicKey type Option(CLType), // optional value of the given type List(CLType), // list of values of the given type (e.g. Vec in rust) ByteArray(CLType, u32), // same as `List` above, but number of elements diff --git a/versioned_docs/version-2.0.0/concepts/serialization/structures.md b/versioned_docs/version-2.0.0/concepts/serialization/structures.md index c3c018c2c..025f021de 100644 --- a/versioned_docs/version-2.0.0/concepts/serialization/structures.md +++ b/versioned_docs/version-2.0.0/concepts/serialization/structures.md @@ -17,25 +17,21 @@ An Account is a structure that represented a user on a legacy Casper network. Al ## AddressableEntity {#addressable-entity} An Addressable Entity is a structure that represents an entity on a Casper network. The addressable entity consists of the following fields: - - [`package_hash`](./types.md#package-hash) - [`byte_code_hash`](./types.md#byte-code-hash) -- [`entry_points`](./types.md#entrypoints) - - [`protocol_version`](./types.md#protocolversion) -- `main_purse`: The entity's main purse `URef`. You may find information on `URef` serialization [here](./primitives.md#clvalue-uref). +- [`main_purse`]: The entity's main purse `URef`. You may find information on `URef` serialization [here](./primitives.md#clvalue-uref). - [`associated_keys`](./types.md#associatedkey) - [`action_thresholds`](./types.md#entity-action-thresholds) -- [`message_topics`](./types.md#message-topics) - - [`entity_kind`](./types.md#entity-kind) + ## Block {#serialization-standard-block} A block is the core component of the Casper linear blockchain, used in two contexts: @@ -43,27 +39,26 @@ A block is the core component of the Casper linear blockchain, used in two conte 1. A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain. 2. A message that is exchanged between nodes containing the data structure as explained in (1). -Each block has a globally unique ID, achieved by hashing the contents of the block. - -Each block points to its parent. An exception is the first block, which has no parent. - -A block is structurally defined as follows: - -- `hash`: A hash over the header of the block. -- `header`: The header of the block that contains information about the contents of the block with additional metadata. -- `body`: The block's body contains the proposer of the block and hashes of deploys and transfers contained within it. +The block is a polymorphic structure that assumes one of the well-defined variants: +* `V1` which type is `BlockV1` (it has a binary `prefix` of 0) +* `V2` which type is `BlockV2` (it has a binary `prefix` of 1) -Further, a block may consist of one of the following types: +To byte-serialize a `Block` you first need to serialize it's binary prefix and then write the bytes of the byte-serialized representation of it's variant. -- `Version1`: A legacy block created prior to the Condor upgrade. +## BlockV1 {#block-v1} -- `Version2`: A modern block. +This type encapsulates block data that used to be produced in versions of the nodes prior to 2.0. +This type represents a historical block that was produced prior to 2.0 +Each block has a globally unique ID, achieved by hashing the contents of the block. +Each block points to its parent. An exception is the first block, which has no parent. -### BlockHash {#block-hash} +A block is structurally defined as follows: -The block hash is a `Digest` over the contents of the block Header. The `BlockHash` serializes as the byte representation of the hash itself. +- `hash`: A hash over the header of the block. It's type is `BlockHash` +- `header`: The header of the block that contains information about the contents of the block with additional metadata. It's type is `BlockHeaderV1`. +- `body`: The block's body contains the proposer of the block and hashes of deploys and transfers contained within it. It's type is `BlockBodyV1`. -### BlockHeader {#block-header} +### BlockHeaderV1 {#block-header-v1} The header portion of a block, structurally, is defined as follows: @@ -72,15 +67,13 @@ The header portion of a block, structurally, is defined as follows: - `body_hash` the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the `body_hash` is 32 bytes long. - `random_bit` is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0. - `accumulated_seed` is a seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the `accumulated_hash` is 32 bytes long. -- `era_end` contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as `None`, it serializes to _0_. The serialization of the other case is described in the EraEnd. +- `era_end` contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as `None`, it serializes to _0_. The serialization of the other case is described in the `EraEndV1`. - `timestamp` The timestamp from when the block was proposed. It serializes as a single `u64` value. The serialization of a `u64` value is described in the CLValues section. - `era_id` Era ID in which this block was created. It serializes as a single `u64` value. - `height` The height of this block, i.e., the number of ancestors. It serializes as a single `u64` value. - `protocol_version` The version of the Casper network when this block was proposed. It is 3-element tuple containing `u32` values. It serializes as a buffer containing the three `u32` serialized values. Refer to the CLValues section on how `u32` values are serialized. -Both `BlockHeaderV1` and `BlockHeaderV2` serialize in the same way. - -### EraEndV1 {#eraendV1} +#### EraEndV1 {#eraendV1} `EraEndV1` as represented within the block header, is a struct containing two fields. @@ -102,18 +95,6 @@ When serializing the overarching struct of `EraEndV1`, we first allocate a buffe Note that `EraEndV1` is an optional field. Thus the above scheme only applies if there is an `EraEndV1`; if there is no era end, the field simply serializes to _0_. -### EraEndV2 {#eraendV2} - -`EraEndV1` as represented within the block header, is a struct containing four fields. - -- `equivocators`: A vector of `PublicKey` listing equivocators for the era. -- `inactive_validators`: A list of inactive validators for the era. -- `next_era_validator_weights`: A map of validators and their weights for the era to follow. -- `rewards`: A Binary Tree Map of `PublicKey` and `u64`. -- `next_era_gas_price`: The next era's gas price as a `u8`. - -Note that `EraEndV2` is an optional field. Thus the above scheme only applies if there is an `EraEndV2`; if there is no era end, the field simply serializes to _0_. - ### BlockBodyV1 {#blockbodyV1} The body portion of a block, prior to the Condor upgrade, is structurally defined as: @@ -128,6 +109,52 @@ When we serialize the `BlockBodyV1`, we create a buffer that contains the serial - `deploy_hashes` serializes to the byte representation of all the deploy_hashes within the block header. Its length is `32 * n`, where n denotes the number of deploy hashes present within the body. - `transfer_hashes` serializes to the byte representation of all the deploy_hashes within the block header. Its length is `32 * n`, where n denotes the number of transfers present within the body. +## BlockV2 {#block-v2} + +This type represents a contemporary block that is produced by the network. A block is the core component of the Casper linear blockchain, used in two contexts: +1. A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain. +2. A message that is exchanged between nodes containing the data structure as explained in (1). + +Each block has a globally unique ID, achieved by hashing the contents of the block. + +Each block points to its parent. An exception is the first block, which has no parent. + +A block is structurally defined as follows: + +- `hash`: A hash over the header of the block. It's type is `BlockHash` +- `header`: The header of the block that contains information about the contents of the block with additional metadata. It's type is `BlockHeaderV2`. +- `body`: The block's body contains the proposer of the block and hashes of deploys and transfers contained within it. It's type is `BlockBodyV2`. + +### BlockHeaderV2 {#block-header-v2} + +The header portion of a block, structurally, is defined as follows: + +- `parent_hash` is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the `parent_hash` is 32 bytes long. +- `state_root_hash` is the global state root hash produced by executing this block's body. It serializes to the byte representation of the `state root hash`. The serialized buffer of the `state_root_hash` is 32 bytes long. +- `body_hash` the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the `body_hash` is 32 bytes long. +- `random_bit` is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0. +- `accumulated_seed` is a seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the `accumulated_hash` is 32 bytes long. +- `era_end` contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as `None`, it serializes to _0_. The serialization of the other case is described in the `EraEndV1`. +- `timestamp` The timestamp from when the block was proposed. It serializes as a single `u64` value. The serialization of a `u64` value is described in the CLValues section. +- `era_id` Era ID in which this block was created. It serializes as a single `u64` value. +- `height` The height of this block, i.e., the number of ancestors. It serializes as a single `u64` value. +- `protocol_version` The version of the Casper network when this block was proposed. It is 3-element tuple containing `u32` values. It serializes as a buffer containing the three `u32` serialized values. Refer to the CLValues section on how `u32` values are serialized. +- `proposer` public key of the proposer of the block. It's type is `PublicKey` +- `current_gas_price` gas price of the block. It is an unsigned 8 bit number. +- `last_switch_block_hash` it is an optional block hash pointing to the last switch block. It's type is `BlockHash`, but since it's optional, rules of serializing (optional fields)[./primitives.md#clvalue-option] apply. + +### EraEndV2 {#eraendV2} + +`EraEndV1` as represented within the block header, is a struct containing four fields. + +- `equivocators`: A vector of `PublicKey` listing equivocators for the era. +- `inactive_validators`: A list of inactive validators for the era. +- `next_era_validator_weights`: A map of validators and their weights for the era to follow. +- `rewards`: A Binary Tree Map of `PublicKey` and `u64`. +- `next_era_gas_price`: The next era's gas price as a `u8`. + +Note that `EraEndV2` is an optional field. Thus the above scheme only applies if there is an `EraEndV2`; if there is no era end, the field simply serializes to _0_. + ### BlockBodyV2 {blockbodyv2} A modern block is structurally defined as: @@ -136,6 +163,20 @@ A modern block is structurally defined as: - [`rewarded_signatures`](./types.md#rewarded-signatures): A list of identifiers for finality signatures for a particular past block. It serializes as a vector of `SingleBlockRewardedSignatures` which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on. + +## BlockHash {#block-hash} + +The block hash is a `Digest` over the contents of the block Header. The `BlockHash` serializes as the byte representation of the hash itself. + + +## ByteCodeAddr {#byte-code-addr} + +An address for ByteCode records stored in global state. Comes in one of three variants: +- `Empty`. It serializes as a `u8` tag of `0`. +- `V1CasperWasm`. It serializes as a `u8` tag of `1` followed by 32 bytes interpreted as hex-encoded address. +- `V2CasperWasm`. It serializes as a `u8` tag of `2` followed by 32 bytes interpreted as hex-encoded address. + + ## Contract {#contract} A contract struct containing the following fields: @@ -406,10 +447,6 @@ The scheduling mode of a transaction, serialized as a [`u8`](./primitives.md#clv - `Standard` serializes as a `0`. -- `FutureEra` serializes as a `1` followed by a future [`era_id`](./types.md#eraid). - -- `FutureTimestamp` serializes as a `2` followed by a future [`timestamp`](./types.md#timestamp). - ### TransactionInvocationTarget {#transactioninvocationtarget} The identifier of a `stored` transaction target, serialized as one of the following: diff --git a/versioned_docs/version-2.0.0/concepts/serialization/types.md b/versioned_docs/version-2.0.0/concepts/serialization/types.md index 37babce96..a833cfd46 100644 --- a/versioned_docs/version-2.0.0/concepts/serialization/types.md +++ b/versioned_docs/version-2.0.0/concepts/serialization/types.md @@ -214,7 +214,7 @@ Hex-encoded bytes serialized as a `u32` value describing the length of the bytes ## ByteCodeKind -The type of byte code, serialized as a single `u8` value. A `0` indicates empty byte code, while a `1` indicates a `V1CasperWasm` to be executed with the first version of the Casper execution engine. +The type of byte code, serialized as a single `u8` value. A `0` indicates empty byte code. `1` indicates a `V1CasperWasm` to be executed with the first version of the Casper execution engine. `2` indicates a `V2CasperWasm` to be executed with the first version of the Casper execution engine ## Caller {#caller} @@ -252,6 +252,9 @@ ChainspecRegistry is a unique key variant which contains a mapping of file names The checksum registry. It serializes as a `BTreeMap` where the first 4 bytes represent a `u32` value describing the number of checksum names as strings and [digests](#digest) held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. +## ContractRuntimeTag {#contract-runtime-tag} +A tag for the contracts runtime tag, serialized as a single `u8` tag of 0 for `VmCasperV1`, 1 for `VmCasperV2`. + ## Delegator {#delegator} Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields: @@ -368,7 +371,7 @@ An `enum` specifying who pays for the invocation and execution of an entry point - `Caller`: Serializes as a 0 and indicates that the caller must cover the cost. -- `SelfOnly`: Serializes as a 1 and indicates that the contract will pay the cost to execute itself, but no subsequent invoked contracts. +- `DirectInvocationOnly`: Serializes as a 1 and indicates that the contract will pay the cost to execute itself, but no subsequent invoked contracts. - `SelfOnward`: Serializes as a 2 and indicates that the contract will pay for executing itself and any subsequent invocations. @@ -378,9 +381,9 @@ The context of method execution. It serializes as one of the following: - `Caller`: Serializes as a single `u8`, `0b00000000` -- `Called`: Serializes as a single `u8`, `0b00000001` +- `DirectInvocationOnly`: Serializes as a single `u8`, `0b00000001` -- `Factory`: Serializes as a single `u8`, `0b10000000` +- `SelfOnward`: Serializes as a single `u8`, `0b10000000` ## EntrypointV2 @@ -770,9 +773,9 @@ Entity types for system contracts, serialized as a single `u8` tag identifying t | Tag | System Contract | | --- | --------------- | | 0 | `Mint` | -| 1 | `Auction` | +| 1 | `HandlePayment` | | 2 | `StandardPayment` | -| 3 | `HandlePayment` | +| 3 | `Auction` | ## TimeDiff {#timediff} diff --git a/versioned_docs/version-2.0.0/developers/cli/opcode-costs.md b/versioned_docs/version-2.0.0/developers/cli/opcode-costs.md index 0795f7c68..be56aeb00 100644 --- a/versioned_docs/version-2.0.0/developers/cli/opcode-costs.md +++ b/versioned_docs/version-2.0.0/developers/cli/opcode-costs.md @@ -14,13 +14,13 @@ All costs in this table are in [motes](/concepts/glossary/M/#motes), not CSPR, a ::: -## Storage Costs +## StorageCosts |Attribute |Description | Cost | |----------------- |-----------------------------------------------|-----------------| |gas_per_byte | Gas charged per byte stored in global state. | 1_117_587| -## OpCode Costs +## OpCodeCosts |Attribute |Description | Cost | |----------------- |-----------------------------------------------|-----------------| @@ -40,7 +40,7 @@ All costs in this table are in [motes](/concepts/glossary/M/#motes), not CSPR, a |current_memory | Get the current memory operation multiplier. | 290| |grow_memory | Grow memory cost per page (64 kB). | 240_000| -## Control Flow Operation Costs +## ControlFlowCost |Attribute |Description | Cost | |----------------- |-----------------------------------------------|-----------------| diff --git a/versioned_docs/version-2.0.0/developers/json-rpc/types_chain.md b/versioned_docs/version-2.0.0/developers/json-rpc/types_chain.md index 90c229b9c..eb9654203 100644 --- a/versioned_docs/version-2.0.0/developers/json-rpc/types_chain.md +++ b/versioned_docs/version-2.0.0/developers/json-rpc/types_chain.md @@ -423,7 +423,7 @@ Required Parameters: ## ByteCodeHash -The hex-encoded address of a smart contract [`AddressableEntity`](#addressableentity). +A type wrapping a `HashAddr` which is the raw bytes of the ByteCodeHash. Serializes as `HashAddr` ## ByteCodeKind diff --git a/versioned_docs/version-2.0.0/developers/monitor-and-consume-events.md b/versioned_docs/version-2.0.0/developers/monitor-and-consume-events.md new file mode 100644 index 000000000..1de48214d --- /dev/null +++ b/versioned_docs/version-2.0.0/developers/monitor-and-consume-events.md @@ -0,0 +1,582 @@ +import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; + +# Monitoring and Consuming Events + +The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data. + +Each Casper node streams events through the SSE (Server Sent Event) server via the port specified as the `event_stream_server.address` in the node's _config.toml_. This port is by default `9999` for nodes on [Testnet](https://testnet.cspr.live/tools/peers) and [Mainnet](https://cspr.live/tools/peers). + +Events in `2.0` are all emitted via the firehose `http://:/events` endpoint. Bear in mind that a node is not obligated to have the sse server turned on to operate in the network. + +:::note + +An `ApiVersion` event is always emitted when a new client connects to a node's SSE server, informing the client of the node's software version. + +::: + +## Listening to the Event Stream + +Applications can listen for such events for a specific account during a particular era, containing certain data. Then, they can parse the data and discard what they do not need. To consume the event stream, you need to set up an event listener in your dApp. Here are example code snippets doing that: + + + + + +```javascript +import { SseClient, EventName } from "casper-js-sdk"; + +const sseClient = new SseClient("http://:9999/events"); + +sseClient.subscribe(EventName.BlockAddedEventType, (rawEvent) => { + try { + const parsedEvent = rawEvent.parseAsBlockAddedEvent(); + console.log(`Block hash: ${parsedEvent.BlockAdded.blockHash}`); + } catch (error) { + console.error("Error processing event:", error); + } +}); + +// Start the client with the last known event ID ( Optional ) +const lastEventID = 1234; + +sseClient.start(lastEventID); +``` + +For more in-depth explanation of features of the SSE client of js-sdk, plese refer to it's (repository and documentation)[https://github.com/casper-ecosystem/casper-js-sdk/blob/dev/src/sse/README.md]. + + + + +```bash +curl -s http://NODE_ADDRESS:9999/events/CHANNEL +``` + + + + + +You can find node addresses of active online peers to replace `NODE_ADDRESS`, by navigating to [cspr.live](https://cspr.live/tools/peers) for Mainnet and [testnet.cspr.live](https://testnet.cspr.live/tools/peers) for Testnet. + +You will find a list with all the possible event types below. + +## Event Types + +### ApiVersion + +The `ApiVersion` event is always the first event emitted when a new client connects to a node's SSE server. It specifies the protocol version of a node on the Casper platform. The following example contains the JSON representation of the `ApiVersion` event structure. + +```bash +data:{"ApiVersion":"2.0.0"} +``` + +### BlockAdded + +A `BlockAdded` event is emitted when a new block is added to the blockchain and stored locally in the node. The `BlockAdded` can be in either a `Version1` (1.x compliant) or `Version2` (2.x compliant) variants. + +
+Expand to see example of a Version1 BlockAdded + +```json +{ + "BlockAdded": { + "block_hash": "9571b9b27dacbed06e048cb656829128e4cab06a45ffe84a5ffff88f919f99b1", + "block": { + "Version1": { + "hash": "4fb7be0031f4dc0d107061065c603d79d3691c37f769e9e3285c73357ae952fa", + "header": { + "parent_hash": "50fdb9b02e429283ef1ff94c5317185a081eaf56a163f4de0f581eefe999e7b7", + "state_root_hash": "ec741f31e84de97db9a1f8d3ed1c48f5448656970a59f9b2267430124ab93fb1", + "body_hash": "7a38b4cf9fb5b1ad88724e67a16ae92fc1b76f8647b8aab0585c683ba3008a2f", + "random_bit": true, + "accumulated_seed": "f6167f91fe62d37fb601cb17dd7ec822f49a31c3da10ff8def194a8d118c4389", + "era_end": null, + "timestamp": "2025-04-28T10:12:51.985Z", + "era_id": 100, + "height": 555, + "protocol_version": "2.0.0" + }, + "body": { + "proposer": "02027ee0d7fdab27eeab089f292d64d78af865c8e79800f9b376e6ce68a3d5f41f5f", + "deploy_hashes": [ + "040dd42480760133c25ca33b394395c115090f40577c4792cc3c58c5c7c812fb", + "3f9f0f42b4e548693598e7b0ecd969ae7851087c66e6c9733161ad137d75fddf", + "8dadb644ca8d6e5678a619c14c7994b832a2d5cfbc222f0ddae6f18ccc61f3f6" + ], + "transfer_hashes": [] + } + } + } + } +} +``` + +- [block_hash](../concepts/serialization/structures.md#block-hash) - The cryptographic hash that identifies a block. +- [block](../concepts/serialization/structures.md#serialization-standard-block) - The JSON representation of the block. + +
+ +
+Expand to see example of a Version2 BlockAdded + +```json +{ + "BlockAdded": { + "block_hash": "290eb1ecd5c4e8bda94dae647fb9c21aeb531fe817467abb60f7c12be6a672eb", + "block": { + "Version2": { + "hash": "290eb1ecd5c4e8bda94dae647fb9c21aeb531fe817467abb60f7c12be6a672eb", + "header": { + "parent_hash": "3236c683ec5f220c1936a25a0be96b976cfbe784f06d2319933b432f2a1fe1eb", + "state_root_hash": "89ba71746096011be36cda29fdf1d1bd8067af51a0ea7eaf65e90666a35bcbf6", + "body_hash": "11b6c10321aea27c2fc4d292f570a93b32488759c16cf9ee22e747c35c3873fc", + "random_bit": true, + "accumulated_seed": "e376199ca38015a57760e9431fc6723e9500ab3f18c93a26830b5b4ccc9f6a29", + "era_end": null, + "timestamp": "2025-04-28T10:12:52.090Z", + "era_id": 246749, + "height": 2467498, + "protocol_version": "1.0.0", + "proposer": "0203c5ecdb1ad56b65cbc7dbbf99ea492e7566a6b2259191f9ab604c58b19d2a01f3", + "current_gas_price": 1, + "last_switch_block_hash": "0808080808080808080808080808080808080808080808080808080808080808" + }, + "body": { + "transactions": { + "0": [], + "1": [ + { + "Version1": "1f3b12822cfa6ef26d8f1e369ffbab37fa0e963385d124db5ab09ba22d2ec452" + }, + { + "Version1": "a13c6a737a926562a02e88f62bf84c3811f2fe20bcc6a9b1454802640dfc730d" + } + ], + "2": [], + "3": [ + { + "Deploy": "5825b4fcdb6e180bd80f83d743910b16e6217dd4e74d1147ac0eb656214ab5d4" + }, + { + "Deploy": "e83a459beef99015de50e3c33ba0acbe658aea8f0b72f0f55599889dc3025b68" + } + ], + "4": [], + "5": [] + }, + "rewarded_signatures": [] + } + } + } + } +} +``` + +- [block_hash](../concepts/serialization/structures.md#block-hash) - The cryptographic hash that identifies a block. +- [block](../concepts/serialization/structures.md#serialization-standard-block) - The JSON representation of the block. + +
+ +### TransactionAccepted + +`TransactionAccepted` events are emitted when a node on the network receives a transaction. This event will be produced in both cases - if a transaction is of variant Deploy and TransactionV1. + +
+Expand to view example of Transaction::Version1 + +```json +{ + "TransactionAccepted": { + "Version1": { + "hash": "942785a412289a5aaffdb01d58ee91478bb0cc6b68646519531f4e859ed80566", + "payload": { + "initiator_addr": { + "PublicKey": "02020707086bf373174af44dd96ff43cf73ee4ed01d5a563c97926d880acfda55476" + }, + "timestamp": "2020-08-07T01:30:31.750Z", + "ttl": "1h 56m 52s 389ms", + "chain_name": "xyz", + "pricing_mode": { + "Fixed": { + "additional_computation_factor": 0, + "gas_price_tolerance": 5 + } + }, + "fields": { + "args": { + "Named": [ + [ + "delegator", + { + "cl_type": "PublicKey", + "bytes": "01714f5b526d0ce966b0c7d7a6a7eda7fb5b8b10e8b0b18cfe085e8fe7abc0ab66", + "parsed": "01714f5b526d0ce966b0c7d7a6a7eda7fb5b8b10e8b0b18cfe085e8fe7abc0ab66" + } + ], + [ + "validator", + { + "cl_type": "PublicKey", + "bytes": "01fb60a66cdb914e7448b48213d247edacadc1b17cb2180fbc432460f2fcce497f", + "parsed": "01fb60a66cdb914e7448b48213d247edacadc1b17cb2180fbc432460f2fcce497f" + } + ], + [ + "amount", + { + "cl_type": "U512", + "bytes": "088063df0de89d7c06", + "parsed": "467422081330406272" + } + ] + ] + }, + "entry_point": "Undelegate", + "scheduling": "Standard", + "target": "Native" + } + }, + "approvals": [ + { + "signer": "02020707086bf373174af44dd96ff43cf73ee4ed01d5a563c97926d880acfda55476", + "signature": "02b049620953b7f2b828d8e435d37608e7b4dfe203056016a66228b0ffd933d1861dcbeeceab8cfc457a381ce4763734bf3cd1ecb912033a3c340c657d436ebe50" + } + ] + } + } +} +``` + +- [Version1.hash](../concepts/serialization/hash-types.md) - The blake2b hash of the Transaction. +- [Version1.payload](../concepts/serialization/serialization-standard.md#serialization-standard-account) - Internal data of the Version1 Transaction. +- [Version1.approvals](../concepts/serialization/types_chain.md#approval) - The signer's hexadecimal-encoded public key and signature. + +
+ +
+Expand to view example of Transaction::Deploy + +```json +{ + "TransactionAccepted": { + "Deploy": { + "hash": "916ab2344cdf29581221d9ff6b9947b683f955b4687455cd8a0f6f63d33b36f6", + "header": { + "account": "01800075cc557e3270b686784b2ea3a45bf6e6a7f88f9cc3d17a9c60c96ff16dbd", + "timestamp": "2020-08-07T01:20:22.509Z", + "ttl": "4m 12s", + "gas_price": 22, + "body_hash": "bc45450393b656a1fb3ee570f0345116dbc5ff1c18a9825955d2387cf62142b5", + "dependencies": [], + "chain_name": "casper-example" + }, + "payment": { + "StoredContractByName": { + "name": "casper-example", + "entry_point": "example-entry-point", + "args": [ + [ + "amount", + { + "cl_type": "U512", + "bytes": "0400f90295", + "parsed": "2500000000" + } + ] + ] + } + }, + "session": { + "ModuleBytes": { + "module_bytes": "6f49f3fc98c1514dd815ddef8ef20de772e72a3f523f562b8b47369e1d5cb4462f7644f8dab833228262b7ce4cbf42554edf98a0e4cc24aa1e77cd76506b922c7d281ffd0769f18e29e0080972b7036468463dde97cf73c11e3f86aa924fbe", + "args": [ + [ + "l2w4NZKZvxezK52Xb3I6", + { + "cl_type": { "List": "U8" }, + "bytes": "05000000f72c275005", + "parsed": [247, 44, 39, 80, 5] + } + ] + ] + } + }, + "approvals": [ + { + "signer": "01800075cc557e3270b686784b2ea3a45bf6e6a7f88f9cc3d17a9c60c96ff16dbd", + "signature": "016a1ae5c57d233baec536920a9c4dcf712f32456d07b3a5e669f624ffdd2281e9438780a73fca2fed154e9028b2d9fae118298457d03b232250a3cdbd71625603" + } + ] + } + } +} +``` + +- [Deploy.hash](../concepts/serialization/structures.md#deploy-hash) - The blake2b hash of the Deploy. +- [Deploy.body_hash](../concepts/serialization/hash-types.md) - The blake2b hash of the Deploy body. +- [Deploy.session](./developers/writing-onchain-code/contract-hash-vs-package-hash.md#what-is-session-code) - The session logic defining the Deploy's functionality. +- [Deploy.approvals](../json-rpc/types_chain.md#approval) - The signer's hexadecimal-encoded public key and signature. + +
+ +For details on custom serializations, check the [Serialization Standard](../../concepts/serialization-standard.md). Also, the [Types](../json-rpc/types_chain.md) page defines the terms used in the event stream output. + +### TransactionProcessed + +A `TransactionProcessed` event is emitted when a given Deploy has been executed. + +
+Expand to view output + +```json +{ + "TransactionProcessed": { + "transaction_hash": { + "Version1": "25329c14a4f9307830f2b4b6b529b0c3fd618dec65af7456ad9f9e2c7ba1ff4a" + }, + "initiator_addr": { + "PublicKey": "02024e2b994a52bcf4c0cc112512c4be04853c4e824203a8e627c107a8d595707801" + }, + "timestamp": "2020-08-07T01:30:33.119Z", + "ttl": "54m 11s 767ms", + "block_hash": "315210f005e7d2d7130004f0178c29cf7e4718d8b642f3f832a35a028ed094cf", + "execution_result": { + "Version1": { + "Success": { + "effect": { + "operations": [], + "transforms": [ + { + "key": "12730438218135504636", + "transform": { + "AddUInt256": "16420226327505839383" + } + }, + { + "key": "10696215255214620472", + "transform": { + "AddUInt256": "14018730981435988852" + } + }, + { + "key": "15638241704090226222", + "transform": { + "AddUInt256": "2486508393436959391" + } + } + ] + }, + "transfers": [], + "cost": "2379796918402242989" + } + } + }, + "messages": [ + { + "entity_addr": "entity-contract-a8648307789543cbf38afb24c970844e755654d462a25624edd775219d0cdacf", + "message": { + "String": "Sax8BEJtXE6vRPXMqOruOhyDxar7N70OeiyPVtfYqiOVNzvHThJwennWwoOs3HHd" + }, + "topic_name": "PTgw4HZ6CPRhYmSSBbXsI0rnMOcQXgrr", + "topic_name_hash": "54a3c9afacf3d475ed69af9de5d4f5496798af12d914aa7f5f8b5cec9935096f", + "topic_index": 4003932854, + "block_index": 2261021254199878090 + } + ] + } +} +``` + +- [transaction_hash](../concepts/serialization/structures.md#transaction-hash) - The cryptographic hash of a Deploy. +- [initiator_addr](../concepts/serialization/types.md#initiatoraddr) - Representation of the address that initiated this transaction. +- [timestamp](../concepts/serialization/types.md#timestamp) - A timestamp type representing a concrete moment in time. +- [block_hash](../concepts/serialization/structures.md#block-hash) - A cryptographic hash identifying a Block. +- [execution_result](../concepts/serialization/types.md#execution-result) - The execution status of the transaction. It is a polymorphic type that can be either `Deploy` or `Version1`. + +
+ +### TransactionExpired + +A `TransactionExpired` event is emitted when the Deploy is no longer valid for processing or being added to a block due to its time to live (TTL) having expired. + +
+Expand to view output + +```json +{ + "TransactionExpired": { + "transaction_hash": { + "Version1": "fa1bf753a9b361316531f691db06e0798e4cb29e70724e2c7bf8619b8066be8c" + } + } +} +``` + +- [transaction_hash](../concepts/serialization/types.md#transactionhash) - The cryptographic hash of a Transaction. + +
+ +### Fault + +The `Fault` event is emitted if there is a validator error. + +
+Expand the below section to view the Fault event details: + +```json +{ + "Fault": { + "era_id": 4591448806312642600, + "public_key": "013da85eb06279da42e28530e1116be04bfd2aa25ed8d63401ebff4d9153a609a9", + "timestamp": "2023-01-01T01:26:58.364Z" + } +} +``` + +- [era_id](../concepts/serialization/types.md#eraid) - A period of time during which the validator set does not change. +- [public_key](../concepts/serialization/types.md#publickey) - The hexadecimal-encoded public key of the validator that caused the fault. +- [timestamp](../concepts/serialization/types.md#timestamp) - A timestamp representing the moment the validator faulted. + +
+ +### FinalitySignature + +This event indicates validators have signed the final approvals and further alterations to the block will not be allowed. Refer to the [consensus reached](../concepts/transactions-and-transaction-lifecycle.md#consensus-reached) and [block finality](../concepts/glossary/B.md#block-finality) sections to learn more about finality signatures. The body of `FinalitySignature` is polymorphic - it will either hold `V1` or `V2` field. The content of `V1` is to support compatibility with the payload of 1.x node `FinalitySignature` event + +
+Expand to view example of FinalitySignature::V1 + +```json +{ + "FinalitySignature": { + "V1": { + "block_hash": "92be2255d4d47cc236b037b761ee1d2a92b94c5bbac12e43982b1a8736dad97a", + "era_id": 878101, + "signature": "02f9c63d28dc1ffb6555de629358d9e784e73f612a7a78bc918b2e7a5e0a67b195162d6606f01069aa2f23e1198268b15e483b0b63a29746f56205d977a0aedf26", + "public_key": "020355c10a87a7fa97ca0b9b4dad262d8eed977a25e2c4a9dcb85bd954476b496d6f" + } + } +} +``` + +- [block_hash](../concepts/serialization/structures.md#block-hash) - A cryptographic hash identifying a Block. +- [era_id](../concepts/serialization/types.md#eraid) - A period of time during which the validator set does not change. +- [signature](../concepts/serialization/types.md#signature) - Serialized bytes representing the validator's signature. +- [public_key](../concepts/serialization/types.md#publickey) - The hexadecimal-encoded public key of the validator. + +
+ +
+Expand to view example of FinalitySignature::V2 + +```json +{ + "FinalitySignature": { + "V2": { + "block_hash": "75420adf11cc23a52fd45a9a843cce770ce0e7056dd37943584625d97cdac31c", + "block_height": 15850176021194416983, + "era_id": 724437, + "chain_name_hash": "63803374d60b19e25baa34d306a74c19fc09866df48d9dd5a4e645b7cb26026c", + "signature": "015b88427cffd2d7d58833d09378323d65dec72e2e0a8a9c53991024c53a0bebfe836bcf233f4233bcf63f22f3025b68efb2b00226700bc5d49293cce3a98edc00", + "public_key": "01a792c3e2db14a130676d2498f70acf15e33aa22945d9b300f3f35021acaeb3cf" + } + } +} +``` + +- [block_hash](../concepts/serialization/structures.md#block-hash) - A cryptographic hash identifying a Block. +- [block_height](../concepts/serialization/primitives.md#clvalue-numeric) - A cryptographic hash identifying a Block. +- [era_id](../concepts/serialization/types.md#eraid) - A period of time during which the validator set does not change. +- [signature](../concepts/serialization/types.md#signature) - Serialized bytes representing the validator's signature. +- [public_key](../concepts/serialization/types.md#publickey) - The hexadecimal-encoded public key of the validator. + +
+ +### Step + +The `Step` event is emitted at the end of every era and contains the execution effects produced by running the auction contract's `step` function. + +
+Expand to view output: + +```json +{ + "Step": { + "era_id": 1245, + "execution_effects": [ + { + "key": "account-hash-0909090909090909090909090909090909090909090909090909090909090909", + "kind": "Identity" + }, + { + "key": "withdraw-0909090909090909090909090909090909090909090909090909090909090909", + "kind": { + "AddInt32": 543 + } + } + ] + } +} +``` + +- [era_id](../concepts/serialization/types.md#eraid) - A period of time during which the validator set does not change. +- [execution_effect](../concepts/serialization/types.md#effects) - The journal of execution effects. + +
+ +### Shutdown + +The `Shutdown` event is emitted when the node is about to shut down, usually for an upgrade, causing a termination of the event stream. + +
+Expand the below section to view the Shutdown event details: + +```bash +"Shutdown" +``` + +- Shutdown - The "Shutdown" text notifies the event listener that a shutdown will occur. + +
+ +## Replaying the Event Stream + +This command will replay the event stream from an old event onward. Replace the `NODE_ADDRESS`, `CHANNEL`, and `ID` fields with the values of your scenario. + + + + + +```bash +curl -sN http://NODE_ADDRESS:9999/events/CHANNEL?start_from=ID +``` + +_Example:_ + +```bash +curl -sN http://65.21.235.219:9999/events/main?start_from=29267508 +``` + + + + + +Each URL can have a query string added to the form `?start_from=ID`, where ID is an integer representing an old event ID. With this query, you can replay the event stream from that old event onward. If you specify an event ID already purged from the cache, the server will replay all the cached events. + +:::note + +The server keeps only a limited number of events cached to allow replaying the stream to clients using the `?start_from=` query string. The cache size can be set differently on each node using the `event_stream_buffer_length` value in the _config.toml_. By default, it is only 5000. +The intended use case is to allow a client consuming the event stream that loses its connection to reconnect and catch up with events that were emitted while it was disconnected. + +::: + +# 1.5 vs 2.x compatibility note + +The SSE events serve went through significant, backwards incompatible changes. Here are the most important ones of them that need to be taken into consideration: + +1. 2.0 SSE supports the firehose `/events` endpoint which channels all the beforementioned events. +1. `DeployAccepted`, `DeployProcessed`, `DeployExpired` +1. `BlockAdded` has a 1.5 incompatible structure +1. `TransactionAccepted` is an event analogous to `DeployAccepted`, but there is no backwards-compatibility guarantee - their structure differs. +1. `TransactionProcessed` is an event analogous to `DeployProcessed`, but there is no backwards-compatibility guarantee - their structure differs. +1. `TransactionExpired` is an event analogous to `DeployExpired`, but there is no backwards-compatibility guarantee - their structure differs. +1. `FinalitySignature` has a 1.5 incompatible structure. From e531d7815ab732bc3fbb6005600b94c48fd6cec4 Mon Sep 17 00:00:00 2001 From: Jakub Zajkowski Date: Wed, 30 Apr 2025 15:28:33 +0200 Subject: [PATCH 2/3] Added mention of sidecar in version-2.0.0/developers/monitor-and-consume-events.md --- .../version-2.0.0/developers/monitor-and-consume-events.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/versioned_docs/version-2.0.0/developers/monitor-and-consume-events.md b/versioned_docs/version-2.0.0/developers/monitor-and-consume-events.md index 1de48214d..fee68aebe 100644 --- a/versioned_docs/version-2.0.0/developers/monitor-and-consume-events.md +++ b/versioned_docs/version-2.0.0/developers/monitor-and-consume-events.md @@ -569,7 +569,7 @@ The intended use case is to allow a client consuming the event stream that loses ::: -# 1.5 vs 2.x compatibility note +## 1.5 vs 2.x compatibility note The SSE events serve went through significant, backwards incompatible changes. Here are the most important ones of them that need to be taken into consideration: @@ -580,3 +580,7 @@ The SSE events serve went through significant, backwards incompatible changes. H 1. `TransactionProcessed` is an event analogous to `DeployProcessed`, but there is no backwards-compatibility guarantee - their structure differs. 1. `TransactionExpired` is an event analogous to `DeployExpired`, but there is no backwards-compatibility guarantee - their structure differs. 1. `FinalitySignature` has a 1.5 incompatible structure. + +## Sidecar and SSE events + +The Sidecar App offers some benefits and extensions to how the SSE of the node itself works. For instance it allows to store events to drive and query them with a separate REST API. It also allows the nodes SSE endpoint to be not-public since Sidecar has the ability to republish SSE events. For details on how it works please consult (Sidecar documentation)[https://github.com/casper-network/casper-sidecar/blob/dev/README.md] From 8b57f1ba27b3cbe4ae489729b52cf361ecae5738 Mon Sep 17 00:00:00 2001 From: Jakub Zajkowski Date: Sun, 4 May 2025 15:43:09 +0200 Subject: [PATCH 3/3] Applied CR remarks --- .../concepts/serialization/structures.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/versioned_docs/version-2.0.0/concepts/serialization/structures.md b/versioned_docs/version-2.0.0/concepts/serialization/structures.md index 025f021de..38f7e1954 100644 --- a/versioned_docs/version-2.0.0/concepts/serialization/structures.md +++ b/versioned_docs/version-2.0.0/concepts/serialization/structures.md @@ -2,7 +2,7 @@ ## Account {#serialization-standard-account} -An Account is a structure that represented a user on a legacy Casper network. Alongside the Condor protocol release, `Accounts` were replaced with `AddressableEntities` of the type `Account`. The account structure consists of the following fields: +An Account is a structure that represented a user on a legacy Casper network. Alongside the Casper 2.0 protocol release, `Accounts` were replaced with `AddressableEntities` of the type `Account`. The account structure consists of the following fields: - [`account_hash`](./types.md#account-hash) @@ -47,10 +47,12 @@ To byte-serialize a `Block` you first need to serialize it's binary prefix and t ## BlockV1 {#block-v1} -This type encapsulates block data that used to be produced in versions of the nodes prior to 2.0. -This type represents a historical block that was produced prior to 2.0 -Each block has a globally unique ID, achieved by hashing the contents of the block. -Each block points to its parent. An exception is the first block, which has no parent. +This type: +* encapsulates block data that used to be produced in versions of the nodes prior to 2.0. +* represents a historical block that was produced prior to 2.0 +Each block: +* has a globally unique ID, achieved by hashing the contents of the block. +* points to its parent. An exception is the first block, which has no parent. A block is structurally defined as follows: @@ -97,7 +99,7 @@ Note that `EraEndV1` is an optional field. Thus the above scheme only applies if ### BlockBodyV1 {#blockbodyV1} -The body portion of a block, prior to the Condor upgrade, is structurally defined as: +The body portion of a block, prior to the Casper 2.0 upgrade, is structurally defined as: - `proposer`: The PublicKey which proposed this block. - `deploy_hashes`: Is a vector of hex-encoded hashes identifying Deploys included in this block. @@ -134,7 +136,7 @@ The header portion of a block, structurally, is defined as follows: - `body_hash` the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the `body_hash` is 32 bytes long. - `random_bit` is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0. - `accumulated_seed` is a seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the `accumulated_hash` is 32 bytes long. -- `era_end` contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as `None`, it serializes to _0_. The serialization of the other case is described in the `EraEndV1`. +- `era_end` contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as `None`, it serializes to _0_. The serialization of the other case is described in the `EraEndV2`. - `timestamp` The timestamp from when the block was proposed. It serializes as a single `u64` value. The serialization of a `u64` value is described in the CLValues section. - `era_id` Era ID in which this block was created. It serializes as a single `u64` value. - `height` The height of this block, i.e., the number of ancestors. It serializes as a single `u64` value. @@ -145,7 +147,7 @@ The header portion of a block, structurally, is defined as follows: ### EraEndV2 {#eraendV2} -`EraEndV1` as represented within the block header, is a struct containing four fields. +`EraEndV2` as represented within the block header, is a struct containing four fields. - `equivocators`: A vector of `PublicKey` listing equivocators for the era. - `inactive_validators`: A list of inactive validators for the era.