mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-26 21:47:18 +00:00
97 lines
2.5 KiB
Markdown
97 lines
2.5 KiB
Markdown
# Block Witness Format
|
|
|
|
Each block witness consists of a header followed by a list of operators.
|
|
|
|
There is no length of witness specified anywhere, the code expects to just reach `EOF`.
|
|
|
|
Witness: `[HEADER, OP1, OP2, ..., OPn-1, OPn, EOF]`
|
|
|
|
## Encoding
|
|
|
|
### Keys
|
|
|
|
key nibbles are encoded in a following way `[FLAGS NIBBLE1+NIBBLE2 NIBBLE3+NIBBLE4 NIBBLE5... ]`
|
|
|
|
*FLAGS*
|
|
* bit 0 -- 1 if the number of nibbles were odd
|
|
* bit 1 -- 1 if the nibbles end with 0x10
|
|
|
|
## Header
|
|
|
|
format: `version:byte`
|
|
|
|
encoded as `[ version ]`
|
|
|
|
the current version is 1.
|
|
|
|
## Operators
|
|
|
|
Each operator starts with an opcode (see [`witness_operators.go`](../../trie/witness_operators.go) for exact values).
|
|
|
|
Then it might contain some data.
|
|
|
|
### `OpEmptyRoot`
|
|
|
|
puts empty trie root to on the stack
|
|
|
|
format: `OpEmptyRoot`
|
|
|
|
encoded as `[ 0x06 ]`
|
|
|
|
### `OpHash`
|
|
|
|
puts a single hash on the stack
|
|
|
|
format: `OpHash hash:[32]byte`
|
|
|
|
encoded as `[ 0x03 hash_byte_1 ... hash_byte_32 ]`
|
|
|
|
### `OpBranch`
|
|
|
|
pops N values from the stack and adds them as the children; pushes the result to the stack; N is the number of 1's in the *mask* field.
|
|
|
|
format: `OpBranch mask:uint32`
|
|
|
|
*mask* defines which children are present
|
|
(e.g. `0000000000001011` means that children 0, 1 and 3 are present and the other ones are not)
|
|
|
|
encoded as `[ 0x02 CBOR(mask)...]`
|
|
|
|
### `OpCode`
|
|
|
|
pushes a code to the stack
|
|
|
|
format: `OpCode code:[]byte`
|
|
|
|
encoded as `[ 0x04 CBOR(code)... ]`
|
|
|
|
### `OpExtension`
|
|
|
|
pushes an extension node with a specified key on the stack
|
|
|
|
format: `OpExtension key:[]byte`
|
|
|
|
encoded as `[ 0x01 CBOR(key)... ]`
|
|
|
|
### `OpLeaf`
|
|
|
|
pushes a leaf with specified key and value to the stack
|
|
|
|
format: `OpLeaf key:[]byte value:[]byte`
|
|
|
|
encoded as `[ 0x00 CBOR(key)... CBOR(value)... ]`
|
|
|
|
### `OpAccountLeaf`
|
|
|
|
pushes a leaf with specified parameters to the stack; if flags show, before that pops 1 or 2 values from the stack;
|
|
|
|
format: `OpAccountLeaf key:[]byte flags [nonce:uint64] [balance:[]byte]`
|
|
|
|
encoded as `[ 0x05 CBOR(key|[]byte)... flags /CBOR(nonce).../ /CBOR(balance).../ ]`
|
|
|
|
*flags* is a bitset encoded in a single bit (see [`witness_operators_test.go`](../../trie/witness_operators_test.go) to see flags in action).
|
|
* bit 0 defines if **code** is present; if set to 1 it assumes that either `OpCode` or `OpHash` already put something on the stack;
|
|
* bit 1 defines if **storage** is present; if set to 1, the operators preceeding `OpAccountLeaf` will reconstruct a storage trie;
|
|
* bit 2 defines if **nonce** is not 0; if set to 0, *nonce* field is not encoded;
|
|
* bit 3 defines if **balance** is not 0; if set to 0, *balance* field is not encoded;
|