mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2025-01-05 18:42:19 +00:00
abd93fe9c9
* commitment: implemented semi-working bin patricia trie * commitment: added initialize function to select commitment implementation * deleted reference implementation of binary trie * added branch merge function selection in accordance with current commitment type * smarter branch prefix convolution to reduce disk usage * implemented DELETE update * commitment/bin-trie: fixed merge processing and storage encoding * added changed hex to bin patricia trie * fixed trie variant select * allocate if bufPos larger than buf size * added tracing code * Fix lint * Skip test Co-authored-by: Alexey Sharp <alexeysharp@Alexeys-iMac.local>
127 lines
2.9 KiB
Go
127 lines
2.9 KiB
Go
package commitment
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"fmt"
|
|
|
|
"github.com/holiman/uint256"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/common/length"
|
|
)
|
|
|
|
// Trie represents commitment variant.
|
|
type Trie interface {
|
|
ProcessUpdates(plainKeys, hashedKeys [][]byte, updates []Update) (branchNodeUpdates map[string][]byte, err error)
|
|
|
|
// RootHash produces root hash of the trie
|
|
RootHash() (hash []byte, err error)
|
|
|
|
// Variant returns commitment trie variant
|
|
Variant() TrieVariant
|
|
|
|
// Reset Drops everything from the trie
|
|
Reset()
|
|
|
|
ResetFns(
|
|
branchFn func(prefix []byte) ([]byte, error),
|
|
accountFn func(plainKey []byte, cell *Cell) error,
|
|
storageFn func(plainKey []byte, cell *Cell) error,
|
|
)
|
|
|
|
// Makes trie more verbose
|
|
SetTrace(bool)
|
|
}
|
|
|
|
type TrieVariant string
|
|
|
|
const (
|
|
// HexPatriciaHashed used as default commitment approach
|
|
VariantHexPatriciaTrie TrieVariant = "hex-patricia-hashed"
|
|
VariantReducedHexPatriciaTrie TrieVariant = "modified-hex-patricia-hashed"
|
|
// Experimental mode with binary key representation
|
|
VariantBinPatriciaTrie TrieVariant = "bin-patricia-hashed"
|
|
)
|
|
|
|
func InitializeTrie(tv TrieVariant) Trie {
|
|
switch tv {
|
|
case VariantBinPatriciaTrie:
|
|
return NewBinaryPatriciaTrie()
|
|
case VariantReducedHexPatriciaTrie:
|
|
return NewBinHashed(length.Addr, nil, nil, nil)
|
|
case VariantHexPatriciaTrie:
|
|
fallthrough
|
|
default:
|
|
return NewHexPatriciaHashed(length.Addr, nil, nil, nil)
|
|
}
|
|
}
|
|
|
|
type Account struct {
|
|
CodeHash []byte // hash of the bytecode
|
|
Nonce uint64
|
|
Balance uint256.Int
|
|
}
|
|
|
|
func (a *Account) String() string {
|
|
return fmt.Sprintf("Account{Nonce: %d, Balance: %s, CodeHash: %x}", a.Nonce, a.Balance.String(), a.CodeHash)
|
|
}
|
|
|
|
func (a *Account) decode(buffer []byte) *Account {
|
|
var pos int
|
|
if buffer[pos] < 128 {
|
|
a.Nonce = uint64(buffer[pos])
|
|
pos++
|
|
} else {
|
|
var nonce uint64
|
|
sizeBytes := int(buffer[pos] - 128)
|
|
pos++
|
|
nonce, n := binary.Uvarint(buffer[pos : pos+sizeBytes])
|
|
a.Nonce = nonce
|
|
pos += n
|
|
}
|
|
|
|
if buffer[pos] < 128 {
|
|
b := uint256.NewInt(uint64(buffer[pos]))
|
|
a.Balance = *b
|
|
pos++
|
|
} else {
|
|
bc := int(buffer[pos] - 128)
|
|
pos++
|
|
a.Balance.SetBytes(buffer[pos : pos+bc])
|
|
pos += bc
|
|
}
|
|
|
|
codeSize := int(buffer[pos] - 128)
|
|
if codeSize > 0 {
|
|
pos++
|
|
a.CodeHash = make([]byte, codeSize)
|
|
copy(a.CodeHash, buffer[pos:pos+codeSize])
|
|
}
|
|
return a
|
|
}
|
|
|
|
func (a *Account) encode(bb []byte) []byte {
|
|
buffer := bytes.NewBuffer(bb)
|
|
|
|
// Encoding nonce
|
|
if a.Nonce < 128 && a.Nonce != 0 {
|
|
buffer.WriteByte(byte(a.Nonce))
|
|
} else {
|
|
aux := [binary.MaxVarintLen64]byte{}
|
|
n := binary.PutUvarint(aux[:], a.Nonce)
|
|
buffer.WriteByte(byte(128 + n))
|
|
buffer.Write(aux[:n])
|
|
}
|
|
|
|
// Encoding balance
|
|
if a.Balance.LtUint64(128) && !a.Balance.IsZero() {
|
|
buffer.WriteByte(byte(a.Balance.Uint64()))
|
|
} else {
|
|
buffer.WriteByte(byte(128 + a.Balance.ByteLen()))
|
|
buffer.Write(a.Balance.Bytes())
|
|
}
|
|
buffer.WriteByte(byte(128 + len(a.CodeHash)))
|
|
buffer.Write(a.CodeHash)
|
|
return buffer.Bytes()
|
|
}
|