Protocol rules

From Bytecoin Wiki
Jump to: navigation, search
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
in this document are to be interpreted as described in RFC 2119.




  • Blockchain: all known valid blocks
  • Concurrent branch: blockchain branch with max cummulative diff (may be > 1)
  • Main branch: one of concurrent branches, the node mines on top of it (only one)
  • Side branch: not main branch (but may be concurrent)
  • Current block: a block the node is working on
  • New block: a block the node is trying to add on top of main branch (after solving current or receiving from the net)
  • Orphan block: a block in a side branch
  • TxMemPool: set of all tx, which can be included in next blocks of main branch (not necessary together -- i.e. they may contradict each other)
  • TxWorkPool: set of all tx, which are being included in the current block (don't contradict each other)
  • TxUsed: set of all txs in main branch
  • ImagesUsed: set of used key_images in main branch
  • ImagesWork: set of key_images in WorkPool
  • TmpTxStorage, TmpTxWork: auxiliary tx sets for reorganizing


  • MAX_BLOCK_SIZE = 2 * median(size of last 400 blocks)
  • MIN_GEN_TX_SIZE: constant, minimal coinbase tx size
  • blk_size = blob_size(coinbase tx) + blob_size(all txs) (i.e. blk_size doesn't include block header)




TX is VALID if all rules are successfully verified. TX is INVALID if any rule's verification fails.

Nodes SHOULD relay all txes considered VALID according to this specification. Nodes MUST NOT relay any tx considered as INVALID.

TR1. syntactic
1.1. CURR_TX_VER >= "version" > 0
1.2. txin_count > 0 (tx without outs MUST be considered as valid, can be accepted and relayed)
1.3. txins' type is not txin_gen (we don't relay or verify coinbase tx without block)
// Note: currently only txin_to_key are considered as valid input type (everything else isn't implemented)
1.4. each txins' field is not empty (TODO: details needed)
1.5. sum(txin.amount) and sum(txout.amount) don't overflow
1.6. sum(txin.amount) >= sum(txout.amount) // lite (noDB) check is possible only with txin_to_key
1.7. tx_pub_key is correct
1.8. sig_count = txin_count
1.9. tx_size <= MAX_TX_SIZE (we don't have to relay tx if it can't be included into block in the near future)
TR2. semantic
2.1. for each txin_to_key a key_image not in ImagesUsed // Note: this implies "tx has not already been mined"
2.2. for each txin_to_key.offset a corresponding txout_to_key exists
2.3. for each txin a corresponding signature is valid
// if passed -- tx may be included in main branch (not necessary current block)
// if tx can be included ONLY in side branch -- it fails


Nodes SHOULD mine all txes considered VALID according to this specification. Nodes MUST NOT mine any tx considered as INVALID.

TM1. tx is valid for relay
TM2. for each txin_to_key a key_image not in ImagesWork
TM3. for each txin_to_key.offset a corresponding txout_to_key is spendable (see unlock_time)
// if passed -- tx can be included in current block



BR1. syntactic
1.1. CURR_BLK_VER >= "version" > 0 // see also Versioning
1.2. "timestamp" is in legal range // see also Timestamping
1.3. blk_size <= MAX_BLOCK_SIZE
BR2. semantic
2.1. prev_id is known
// next rules are applied to a local branch of the blockchain (i.e. ending in prev_id).
2.2. block hash satisfies difficulty // this step includes merkle_root computation
2.3. generating tx is valid // NB: check syntax, reward, unicity
2.4. all txs are valid to be mined (and together) //NB: hard to check if in alt-branch


BM1. block is valid for relay
BM2. prev_id is the top of concurrent branch



  1. check if tx is new
  2. check if tx is valid for relay; reject if failed
  3. here additional checks can be performed in order to protect network from DDOS. These verifications are to be defined by local node's policy.
  4. relay
  5. check if tx is valid to be mined
    1. yes -- add tx to TxWorkPool, add key_image to ImagesWork
    2. no -- add tx to TxMemPool // NB: we don't consider sum(fee) for now


  1. check if block is new
  2. check all syntactic block rules BR1.x; reject if failed
  3. check BR2.1 // if failed -- reject
  4. if prev_id is the top of main brach:
    1. check BR2.2, BR2.3; reject if failed
    2. copy TxWorkPool to TxLocalPool, clean TxWorkPool; same with ImagesWork -> ImagesLocal
    3. find all txs which are both in TxLocalPool and NewBlock, move them to TxWorkPool, update ImagesWork
    4. check if the rest txs from NewBlock are valid to be mined; reject if any failed // if any tx only valid for relay -- add it to TxMemPool?
    5. add NewBlock to blockchain, relay block
    6. update indexes, update sets:
      1. move TxWorkPool -> TxUsed
      2. move ImagesWork -> ImagesUsed
      3. check TR2.1 for the rest of TxLocalPool: move to TxWorkPool (and update ImagesWork) or reject
      4. check TR2.1,TM2,TM3 for TxMemPool: move to TxWorkPool (and update ImagesWork), reject or leave
  5. if prev_id is not in concurrent branch:
    1. skip all if block is too deep // TODO: How many blocks?
    2. check BR2.2, BR2.3; reject if failed
    3. treat unknown txs as new
    4. save block index
  6. if prev_id is concurrent branch, but not in main one (reorganize)
    1. disassemble new orphans blocks in reverse order:
      1. move all txs from TxUsed to TmpTxStorage, tag them "valid for block index X" // an object can have multiple tags
      2. update ImagesUsed
    2. move TxWorkPool to TmpTxWork, tag them "valid for height H", flush ImageWork //Note: we never work on the same height in different branches! every reorg. increases height
    3. add new blocks in straight order. check if any tx of new block is in TmpTxStorage with "valid for block index X":
      1. yes -- add the whole block w/out checks, update all sets // that means that we are reorganizing BACK
      2. no -- check BR4
    4. if all blocks OK:
      1. clean TxMemPool from invalidated (for relay) txs // rapid reorganizings may lead to "forgeting" many "good" txs
      2. fill in TxWorkPool from TmpTxStorage, TmpTxWork, TxMemPool (check TR2.x,TM2,TM3) // NB: sig is correct IFF no txout (regards to its offset index) changed! // So we need to keep smth like "txout ids snapshot" of the txin and check its consistency instead of TR2.2 and "heavy" TR2.3
    5. if any block fails:
      1. mark it and all his successor as invalid
      2. disassemble just added blocks (do 6.1.x)
      3. restore previously disassembled blocks, copy txs from TmpTxStorage with corresponding tags to TxUsed, update ImagesUsed
      4. restore TxWorkPool from TmpTxWork by corresponding tag
      5. reject the just received block from other node
      6. treat unknown txs from invalid blocks as new
  7. if height increased, clean TmpTxStorage, and TmpTxWork from txs with OLD tags
Personal tools