erigon-pulse/trie/tapes.go
Igor Mandrigin 7fd4b0431b
refactor trie package a bit (#171)
* Refactor `structural*` files.

* some refactor

* dry hashbuilder a bit

* rename constants back to the magic rlp values
2019-11-15 17:50:16 +01:00

91 lines
2.7 KiB
Go

package trie
import (
"io"
"math/big"
"github.com/ledgerwatch/turbo-geth/common"
"github.com/ledgerwatch/turbo-geth/trie/rlphacks"
)
// BytesTape is an abstraction for an input tape that allows reading binary strings ([]byte) sequentially
// To be used for keys and binary string values
type BytesTape interface {
// Returned slice is only valid until the next invocation of NextBytes()
// i.e. the underlying array/slice may be shared between invocations
Next() ([]byte, error)
}
// Uint64Tape is an abstraction for an input tape that allows reading unsigned 64-bit integers sequentially
// To be used for nonces of the accounts
type Uint64Tape interface {
Next() (uint64, error)
}
// BigIntTape is an abstraction for an input tape that allows reading *big.Int values sequentially
// To be used for balances of the accounts
type BigIntTape interface {
// Returned pointer is only valid until the next invocation of NextBitInt()
// i.e. the underlying big.Int object may be shared between invocation
Next() (*big.Int, error)
}
// HashTape is an abstraction for an input table that allows reading 32-byte hashes (common.Hash) sequentially
// To be used for intermediate hashes in the Patricia Merkle tree
type HashTape interface {
Next() (common.Hash, error)
}
// RlpSerializableTape is an abstraction for a tape that allows reading a sequence of
// RlpSerializable values.
type RlpSerializableTape interface {
Next() (RlpSerializable, error)
}
// RlpSerializable is a value that can be double-RLP coded.
type RlpSerializable interface {
ToDoubleRLP(io.Writer) error
DoubleRLPLen() int
RawBytes() []byte
}
// RlpSerializableBytesTape is a wrapper on top of BytesTape that wraps every return value
// into RlpSerializableBytes, treating them as raw bytes.
type RlpSerializableBytesTape struct {
inner BytesTape
}
func NewRlpSerializableBytesTape(inner BytesTape) RlpSerializableTape {
return &RlpSerializableBytesTape{inner}
}
func (t *RlpSerializableBytesTape) Next() (RlpSerializable, error) {
value, err := t.inner.Next()
if err != nil {
return nil, err
}
return rlphacks.RlpSerializableBytes(value), nil
}
// RlpBytesTape is a wrapper on top of BytesTape that wraps every return value
// into RlpEncodedBytes, treating them as RLP-encode bytes.
// Hence, to get the double encoding we only need to encode once.
// Used when we know for sure that the data is already RLP encoded (accounts, tests, etc)
type RlpBytesTape struct {
inner BytesTape
}
func NewRlpEncodedBytesTape(inner BytesTape) RlpSerializableTape {
return &RlpBytesTape{inner}
}
func (t *RlpBytesTape) Next() (RlpSerializable, error) {
value, err := t.inner.Next()
if err != nil {
return nil, err
}
return rlphacks.RlpEncodedBytes(value), nil
}