waves_logo Docs
  • Why Waves
    Why Waves
  • Waves Basics
    Waves Basics
  • Account
    • Creating Account
      Creating Account
    • Address
      Address
    • Account Balance
      Account Balance
    • Account Data Storage
      Account Data Storage
    • Alias
      Alias
    • dApp and Smart Account
      dApp and Smart Account
    Account
  • Token (Asset)
    • Non-Fungible Token
      Non-Fungible Token
    • Smart Asset
      Smart Asset
    • Token ID
      Token ID
    • WAVES
      WAVES
    Token (Asset)
  • Transaction
    • Transaction Fee
      • Sponsored Fee
        Sponsored Fee
      Transaction Fee
    • Signature and Proofs
      Signature and Proofs
    • Transaction Types
      • Burn Transaction
        Burn Transaction
      • Create Alias Transaction
        Create Alias Transaction
      • Data Transaction
        Data Transaction
      • Exchange Transaction
        • Order
          Order
        Exchange Transaction
      • Genesis Transaction
        Genesis Transaction
      • Invoke Script Transaction
        Invoke Script Transaction
      • Issue Transaction
        Issue Transaction
      • Lease Cancel Transaction
        Lease Cancel Transaction
      • Lease Transaction
        Lease Transaction
      • Mass Transfer Transaction
        Mass Transfer Transaction
      • Reissue Transaction
        Reissue Transaction
      • Set Asset Script Transaction
        Set Asset Script Transaction
      • Set Script Transaction
        Set Script Transaction
      • Sponsor Fee Transaction
        Sponsor Fee Transaction
      • Transfer Transaction
        Transfer Transaction
      • Update Asset Info Transaction
        Update Asset Info Transaction
      • Ethereum-like Transaction
        Ethereum-like Transaction
      Transaction Types
    • Transaction Validation
      Transaction Validation
    Transaction
  • Block
    • Transactions Root Hash
      Transactions Root Hash
    • Genesis Block
      Genesis Block
    Block
  • Node
    • Leasing
      Leasing
    • Generator’s Income
      Generator’s Income
    • Monetary Policy
      Monetary Policy
    Node
  • Mainnet, Testnet, Stagenet
    Mainnet, Testnet, Stagenet
  • Unit Zero
    Unit Zero
  • Oracle
    Oracle
  • Protocols & Data formats
    • Cryptographic Practical Details
      Cryptographic Practical Details
    • Leased Proof of Stake
      Leased Proof of Stake
    • Waves-NG Solution
      Waves-NG Solution
    • Waves-NG Protocol
      Waves-NG Protocol
    • Waves 1.5
      Waves 1.5
    • Blockchain Data Types
      Blockchain Data Types
    • Binary Format
      • Address Binary Format
        Address Binary Format
      • Alias Binary Format
        Alias Binary Format
      • Block Binary Format
        Block Binary Format
      • Network Message Binary Format
        • Block Message Binary Format
          Block Message Binary Format
        • Checkpoint Message Binary Format
          Checkpoint Message Binary Format
        • Get Block Message Binary Format
          Get Block Message Binary Format
        • Get Peers Message Binary Format
          Get Peers Message Binary Format
        • Get Signatures Message Binary Format
          Get Signatures Message Binary Format
        • Handshake Message Binary Format
          Handshake Message Binary Format
        • Peers Message Binary Format
          Peers Message Binary Format
        • Score Message Binary Format
          Score Message Binary Format
        • Signatures Message Binary Format
          Signatures Message Binary Format
        • Transaction Message Message Binary Format
          Transaction Message Message Binary Format
        Network Message Binary Format
      • Order Binary Format
        Order Binary Format
      • Transaction Binary Format
        • Burn Transaction Binary Format
          Burn Transaction Binary Format
        • Create Alias Transaction Binary Format
          Create Alias Transaction Binary Format
        • Data Transaction Binary Format
          Data Transaction Binary Format
        • Exchange Transaction Binary Format
          Exchange Transaction Binary Format
        • Genesis Transaction Binary Format
          Genesis Transaction Binary Format
        • Invoke Script Transaction Binary Format
          Invoke Script Transaction Binary Format
        • Issue Transaction Binary Format
          Issue Transaction Binary Format
        • Lease Cancel Transaction Binary Format
          Lease Cancel Transaction Binary Format
        • Lease Transaction Binary Format
          Lease Transaction Binary Format
        • Mass Transfer Transaction Binary Format
          Mass Transfer Transaction Binary Format
        • Reissue Transaction Binary Format
          Reissue Transaction Binary Format
        • Set Asset Script Transaction Binary Format
          Set Asset Script Transaction Binary Format
        • Set Script Transaction Binary Format
          Set Script Transaction Binary Format
        • Sponsor Fee Transaction Binary Format
          Sponsor Fee Transaction Binary Format
        • Transfer Transaction Binary Format
          Transfer Transaction Binary Format
        • Update Asset Info Transaction Binary Format
          Update Asset Info Transaction Binary Format
        • Ethereum-like Transaction Binary Format
          Ethereum-like Transaction Binary Format
        Transaction Binary Format
      • Transaction Proof Binary Format
        Transaction Proof Binary Format
      Binary Format
    • Validation Rules
      Validation Rules
    Protocols & Data formats
  • Glossary
    Glossary
      • English
      • Русский
      On this page
        • Overview
        • Transaction State Snapshot
        • Block State Hash
        • Challenging State Hash
        • Counteracting Malicious Challenges
        • Elided Transactions
        • VRF
        • Schema Changes
        • Activation
      waves_logo Docs

          # Waves 1.5: Light Node

          # Overview

          Waves protocol version 1.5 introduces a mechanism for the generating node to produce and distribute final state snapshots for the blocks it forges. Other nodes can rely on these state snapshots to speed up transaction processing under heavy load. Other nodes can challenge state snapshot calculation results in cases when a malicious generator distributes invalid state snapshots to peers.

          # Transaction State Snapshot

          Blockchain state can be described as a mapping key => value which is needed to validate the subsequent transactions, including final account balances of WAVES, assets and leases, data entries, exchange order statuses, etc. Each transaction, in turn, changes the state somehow by creating, altering or removing some values from the state. Transaction state snapshot (TSS) is the set of all (key, value) pairs affected by the transaction. TSSs are encoded as TransactionStateSnapshot protobuf message at the network level.

          The generator produces a state snapshot for every transaction it includes in the block. Instead of validating transactions, nodes can sequentially apply transaction state snapshots to their local state, replacing local values for the given key with the new ones. Applying state snapshots instead of performing full transaction validation may significantly decrease block processing time. The state built by sequentially applying transaction state snapshots is identical to the one built by validating all the transactions.

          # Block State Hash

          A generator calculates the transaction state snapshot hash (TH) by building the list of binary strings si representing the state changes. These binary strings are sorted lexicographically and fed into Blake2b hash function. For the purpose of sorting, bytes are assumed to be unsigned. The resulting hash would be the transaction state snapshot hash.

          The following binary strings are built for the snapshot (|| is the string concatenation operator):

          • Waves balances: address || balance
          • Asset balances: address || asset_id || balance
          • Data entries: address || key || data_entry
          • Account script: sender_public_key || script || verifier_complexity). If the script is removed from the account, then only sender_public_key is hashed.
          • Asset script: asset_id || script
          • Lease balance: address || lease_in || lease_out
          • Lease details: lease_id || amount || sender_public_key || recipient
          • Lease status: lease_id || is_active
          • Sponsorship: asset_id || min_sponsored_fee
          • Alias: address || alias
          • Filled volume and fee: order_id || filled_volume || filled_fee
          • Static asset info: asset_id || issuer_public_key || decimals || is_nft. decimals is one byte.
          • Asset reissuability: asset_id || is_reissuable || total_quantity
          • Asset name and description: asset_id || name || description || change_height
          • Non-successful transaction application status: tx_id || application_status. Application status is one byte, either 0x01 (script execution failed) or 0x02 (elided; see below).

          Boolean flags (is_active, is_nft, is_reissuable) are encoded as one byte with 0x01 signifying true and 0x00 signifying false. All numeric fields are 8-byte big-endian values, unless otherwise specified.

          H0 is defined as the hash of an empty string, and Hi as a hash of the previous hash Hi-1 concatenated with THi. Hi is the hash of the blockchain state after applying the i-th transaction to the state:

          • TH = Blake2b(s1||s2||...||sm),
          • H0 = Blake2b('')
          • Hn = Blake2b(Hn–1 || THn)

          The generator does not include state snapshots in the block. To attest the authenticity of TSS, the generator includes the final Hn into the block header, where n is the sequence number of the last transaction in the block. Hn is called the block state hash.

          This algorithm works well for Waves-NG: no hashes need to be recalculated when the new microblock is appended to the state. Just like other mutable liquid block fields (e.g. transactions root), block state hash changes when new microblocks are appended.

          When receiving the state snapshot over the network, the nodes working in state snapshot application mode compute block state hash from the contents of the snapshot and check if the computed hash matches the hash from the block header. If the hashes don’t match, the node considers the state snapshot invalid and ignores it.

          Even though the nodes working in such mode still perform block consensus validation, they end up trusting state snapshot producers as they don’t check if the state snapshot does indeed correspond to the block contents.

          # Challenging State Hash

          When a node receives a block from the generator, it validates all the transactions from the block and computes the state hash of its own. If the resulting hash does not match the one calculated by the original generator, the node can challenge the results, if block generation is enabled in node’s settings, and the configured generating accounts have sufficient generating balance.

          • Challenger’s generating balance is combined with the original generator’s generating balance, and then block consensus parameters are recalculated. If the node has several generating accounts configured, consensus parameters (including block timestamp) are calculated for all accounts. The block is forged with the account which has the lowest block timestamp.
          • The node forges a new block with the transactions from the original block and the same reference.
          • Challenged block header is included in the new block header.
          • The block is signed and broadcast to other peers. Since block timestamp is also recalculated and is likely to change, the node might have to wait before broadcasting the block.

          This mechanism works for both ordinary blocks and microblocks: if state hash discrepancy is discovered in one of the microblocks, the node stops accepting subsequent microblocks from and immediately challenges this generator.

          When a node receives a block with a challenge, it validates both the challenged block and the challenge consensus. If the challenge is valid, the malicious generator’s effective balance (and hence the generating balance for the following 1000 blocks) is considered to be 0. Instead of the original generator, the successful challenger receives the block reward.

          Reduction of malicious generator’s generating balance helps to prevent them from re-attempting an attack. Resetting effective balance to 0 on the main chain will effectively disable the generator for the following 1000 blocks.

          # Counteracting Malicious Challenges

          Malicious generators may distribute invalid challenging blocks to their peers in several ways: broadcasting an alternative block at the top of the blockchain intending to replace a valid liquid block or providing a block in response to GetBlock request during synchronization. In both cases such invalid blocks will not be challenged by the generator and will be discarded instead. Only an original block (containing no challenge of its own) can be challenged.

          # Elided Transactions

          Since challenging block consensus information is different from the original block, some transactions from the original block may become invalid.

          • Suppose the original block generator’s account has the regular balance of 0 (i.e. all the generating balance comes from the incoming lease). The first transaction of the original block transfers the block reward from the generating account to a “safe”. Since the generator of the challenging block changes, this transaction will no longer be valid.
          • Block timestamp and generator address are accessible from Ride scripts. Changes to these fields may alter script execution results and either cause the Invoke Script transaction to fail, or even invalidate the entire transaction due to a verifier script returning false.

          In order to validate the transactions merkle root of the original block, the challenging block needs to include all of the transactions from the original block, so no transactions can be dropped, even though they may be invalid in the challenging block. Such invalid transactions are elided: they are included in the block, but produce an empty state snapshot. Elided transactions have the following properties:

          • may only appear in the challenging block (transactions in ordinary blocks can never be elided)
          • transaction ID uniqueness is still required
          • elided transactions have an applicationStatus of elided
          • /transactions/merkleProof API endpoint returns proofs for elided transactions
          • transactionHeightById(), transferTransactionById(), and transactionById() Ride built-in functions return unit for elided transactions.

          # VRF

          VRF plays a key role in both consensus and application layer. Since VRF is re-calculated in a challenging block, it’s important to ensure the challenger is unable to exploit the challenge mechanism. As mentioned above, only an account with a minimum of 1000 WAVES of generating balance is allowed to challenge invalid state hashes. This requirement makes it impossible to “mine” the specific VRF value which would be used to game a dApp.

          # Schema Changes

          Two new fields are added to the block header schema:

          bytes state_hash = 11;
          ChallengedHeader challenged_header = 12;
          

          The state_hash field contains the root state hash for the current block.

          The ChallengedHeader message contains values from the block header which is being challenged:

          message ChallengedHeader {
                  int64 base_target = 1;
                  bytes generation_signature = 2;
                  repeated uint32 feature_votes = 3;
                  int64 timestamp = 4;
                  int32 version = 5;
                  bytes generator = 6;
                  int64 reward_vote = 7;
                  bytes header_signature = 8;
          }
          

          The intention is to include all the fields required to reconstruct the original header, so that the signature could be validated and the authenticity of the header be established.

          # Activation

          The block schema has been changed after activation of feature #22 “Light Node”. Older nodes can not verify signatures of the newer blocks containing state hashes, and obviously can not append them. 1.4 nodes check for feature activation after the block had been appended. Since the new blocks are not appended, the nodes do not know the Light Node feature had already been activated, and can not shut down because of unsupported feature activation. This obvious problem could result in the 1.4 nodes being silently disconnected from the main chain.

          To ensure that 1.4 nodes indeed stop once the feature is activated, altering block structure was delayed until 1000 blocks after the activation: generators began including state hashes at (activation height + 1000). 1000 is larger than maximum rollback depth (100), so a node running in the sync mode can still append the entire extension and see that unsupported feature had been activated.

          Waves-NG Protocol
          Blockchain Data Types
          Waves-NG Protocol
          Blockchain Data Types