2019-11-13 09:52:43 +00:00
|
|
|
package trie
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"math/big"
|
|
|
|
|
|
|
|
"github.com/ledgerwatch/turbo-geth/common"
|
2019-11-15 16:50:16 +00:00
|
|
|
"github.com/ledgerwatch/turbo-geth/trie/rlphacks"
|
2019-11-13 09:52:43 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
2019-11-15 16:50:16 +00:00
|
|
|
// RlpSerializableTape is an abstraction for a tape that allows reading a sequence of
|
|
|
|
// RlpSerializable values.
|
2019-11-13 09:52:43 +00:00
|
|
|
type RlpSerializableTape interface {
|
|
|
|
Next() (RlpSerializable, error)
|
|
|
|
}
|
|
|
|
|
2019-11-15 16:50:16 +00:00
|
|
|
// RlpSerializable is a value that can be double-RLP coded.
|
2019-11-13 09:52:43 +00:00
|
|
|
type RlpSerializable interface {
|
|
|
|
ToDoubleRLP(io.Writer) error
|
|
|
|
DoubleRLPLen() int
|
|
|
|
RawBytes() []byte
|
|
|
|
}
|
|
|
|
|
2019-11-15 16:50:16 +00:00
|
|
|
// RlpSerializableBytesTape is a wrapper on top of BytesTape that wraps every return value
|
|
|
|
// into RlpSerializableBytes, treating them as raw bytes.
|
2019-11-13 09:52:43 +00:00
|
|
|
type RlpSerializableBytesTape struct {
|
|
|
|
inner BytesTape
|
|
|
|
}
|
|
|
|
|
2019-11-15 16:50:16 +00:00
|
|
|
func NewRlpSerializableBytesTape(inner BytesTape) RlpSerializableTape {
|
|
|
|
return &RlpSerializableBytesTape{inner}
|
|
|
|
}
|
|
|
|
|
2019-11-13 09:52:43 +00:00
|
|
|
func (t *RlpSerializableBytesTape) Next() (RlpSerializable, error) {
|
|
|
|
value, err := t.inner.Next()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-11-15 16:50:16 +00:00
|
|
|
return rlphacks.RlpSerializableBytes(value), nil
|
2019-11-13 09:52:43 +00:00
|
|
|
}
|
|
|
|
|
2019-11-15 16:50:16 +00:00
|
|
|
// 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)
|
2019-11-13 09:52:43 +00:00
|
|
|
type RlpBytesTape struct {
|
|
|
|
inner BytesTape
|
|
|
|
}
|
|
|
|
|
2019-11-15 16:50:16 +00:00
|
|
|
func NewRlpEncodedBytesTape(inner BytesTape) RlpSerializableTape {
|
|
|
|
return &RlpBytesTape{inner}
|
|
|
|
}
|
|
|
|
|
2019-11-13 09:52:43 +00:00
|
|
|
func (t *RlpBytesTape) Next() (RlpSerializable, error) {
|
|
|
|
value, err := t.inner.Next()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-11-15 16:50:16 +00:00
|
|
|
return rlphacks.RlpEncodedBytes(value), nil
|
2019-11-13 09:52:43 +00:00
|
|
|
}
|