Skip to content

Commit

Permalink
feat: add state content key
Browse files Browse the repository at this point in the history
  • Loading branch information
fearlessfe authored and GrapeBaBa committed Jun 22, 2024
1 parent 0f8632e commit 4e6a44f
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 4 deletions.
125 changes: 121 additions & 4 deletions portalnetwork/state/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (n *Nibbles) Deserialize(dr *codec.DecodingReader) error {
return err
}
flag, first := unpackNibblePair(firstByte)
nibbles := make([]byte, 1+2*len(packedNibbles))
nibbles := make([]byte, 0, 1+2*len(packedNibbles))

if flag == 0 {
if first != 0 {
Expand All @@ -77,10 +77,9 @@ func (n *Nibbles) Deserialize(dr *codec.DecodingReader) error {
return fmt.Errorf("nibbles: The highest 4 bits of the first byte must be 0 or 1, but was: %x", flag)
}

for i, b := range packedNibbles {
for _, b := range packedNibbles {
left, right := unpackNibblePair(b)
nibbles[1+2*i] = left
nibbles[1+2*i+1] = right
nibbles = append(nibbles, left, right)
}

unpackedNibbles, err := FromUnpackedNibbles(nibbles)
Expand Down Expand Up @@ -114,3 +113,121 @@ func FromUnpackedNibbles(nibbles []byte) (*Nibbles, error) {
func unpackNibblePair(pair byte) (byte, byte) {
return pair >> 4, pair & 0xf
}

// test data from
// https://github.com/ethereum/portal-network-specs/blob/master/state/state-network-test-vectors.md
type AccountTrieNodeKey struct {
Path Nibbles
NodeHash common.Bytes32
}

func (a *AccountTrieNodeKey) Deserialize(dr *codec.DecodingReader) error {
return dr.Container(
&a.Path,
&a.NodeHash,
)
}

func (a *AccountTrieNodeKey) Serialize(w *codec.EncodingWriter) error {
return w.Container(
&a.Path,
&a.NodeHash,
)
}

func (a *AccountTrieNodeKey) ByteLength(spec *common.Spec) uint64 {
return codec.ContainerLength(
&a.Path,
&a.NodeHash,
)
}

func (a *AccountTrieNodeKey) FixedLength(spec *common.Spec) uint64 {
return 0
}

func (a *AccountTrieNodeKey) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root {
return hFn.HashTreeRoot(
&a.Path,
&a.NodeHash,
)
}

type ContractStorageTrieNodeKey struct {
Address common.Eth1Address
Path Nibbles
NodeHash common.Bytes32
}

func (c *ContractStorageTrieNodeKey) Deserialize(dr *codec.DecodingReader) error {
return dr.Container(
&c.Address,
&c.Path,
&c.NodeHash,
)
}

func (c *ContractStorageTrieNodeKey) Serialize(w *codec.EncodingWriter) error {
return w.Container(
&c.Address,
&c.Path,
&c.NodeHash,
)
}

func (c *ContractStorageTrieNodeKey) ByteLength(spec *common.Spec) uint64 {
return codec.ContainerLength(
&c.Address,
&c.Path,
&c.NodeHash,
)
}

func (c *ContractStorageTrieNodeKey) FixedLength(spec *common.Spec) uint64 {
return 0
}

func (c *ContractStorageTrieNodeKey) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root {
return hFn.HashTreeRoot(
&c.Address,
&c.Path,
&c.NodeHash,
)
}

type ContractBytecodeKey struct {
Address common.Eth1Address
NodeHash common.Bytes32
}

func (c *ContractBytecodeKey) Deserialize(dr *codec.DecodingReader) error {
return dr.FixedLenContainer(
&c.Address,
&c.NodeHash,
)
}

func (c *ContractBytecodeKey) Serialize(w *codec.EncodingWriter) error {
return w.FixedLenContainer(
&c.Address,
&c.NodeHash,
)
}

func (c *ContractBytecodeKey) ByteLength(spec *common.Spec) uint64 {
return codec.ContainerLength(
&c.Address,
&c.NodeHash,
)
}

func (c *ContractBytecodeKey) FixedLength(spec *common.Spec) uint64 {
return 0
}

func (c *ContractBytecodeKey) HashTreeRoot(spec *common.Spec, hFn tree.HashFn) common.Root {
return hFn.HashTreeRoot(
&c.Address,
&c.NodeHash,
)
}
70 changes: 70 additions & 0 deletions portalnetwork/state/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"testing"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/protolambda/zrnt/eth2/beacon/common"
"github.com/protolambda/ztyp/codec"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNibblesEncodeDecode(t *testing.T) {
Expand Down Expand Up @@ -80,6 +82,11 @@ func TestNibblesEncodeDecode(t *testing.T) {
err = n.Serialize(codec.NewEncodingWriter(&tt.args.buf))
assert.NoError(t, err)
assert.Equal(t, tt.encodeds, hexutil.Encode(tt.args.buf.Bytes()))

newNibble := &Nibbles{}
err = newNibble.Deserialize(codec.NewDecodingReader(&tt.args.buf, uint64(len(tt.args.buf.Bytes()))))
require.NoError(t, err)
require.Equal(t, newNibble.Nibbles, n.Nibbles)
})
}
}
Expand Down Expand Up @@ -196,3 +203,66 @@ func initSlice(n int, v byte) []byte {
}
return s
}

func TestAccountTrieNode(t *testing.T) {
n, err := FromUnpackedNibbles([]byte{8, 6, 7, 9, 14, 8, 14, 13})
require.NoError(t, err)

accountTrieNode := &AccountTrieNodeKey{
Path: *n,
NodeHash: common.Bytes32(hexutil.MustDecode("0x6225fcc63b22b80301d9f2582014e450e91f9b329b7cc87ad16894722fff5296")),
}
var buf bytes.Buffer
err = accountTrieNode.Serialize(codec.NewEncodingWriter(&buf))
require.NoError(t, err)
hexStr := hexutil.Encode(buf.Bytes())
require.Equal(t, hexStr, "0x240000006225fcc63b22b80301d9f2582014e450e91f9b329b7cc87ad16894722fff5296008679e8ed")

newAccount := &AccountTrieNodeKey{}
err = newAccount.Deserialize(codec.NewDecodingReader(&buf, uint64(len(buf.Bytes()))))
require.NoError(t, err)
require.Equal(t, newAccount.NodeHash, accountTrieNode.NodeHash)
require.Equal(t, newAccount.Path.Nibbles, accountTrieNode.Path.Nibbles)
}

func TestContractStorageTrieNode(t *testing.T) {
path, err := FromUnpackedNibbles([]byte{4, 0, 5, 7, 8, 7})
require.NoError(t, err)
contractStorage := &ContractStorageTrieNodeKey{
Address: common.Eth1Address(hexutil.MustDecode("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")),
Path: *path,
NodeHash: common.Bytes32(hexutil.MustDecode("0xeb43d68008d216e753fef198cf51077f5a89f406d9c244119d1643f0f2b19011")),
}

var buf bytes.Buffer
err = contractStorage.Serialize(codec.NewEncodingWriter(&buf))
require.NoError(t, err)
hexStr := hexutil.Encode(buf.Bytes())
require.Equal(t, hexStr, "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc238000000eb43d68008d216e753fef198cf51077f5a89f406d9c244119d1643f0f2b1901100405787")

newContractStorage := &ContractStorageTrieNodeKey{}
err = newContractStorage.Deserialize(codec.NewDecodingReader(&buf, uint64(len(buf.Bytes()))))
require.NoError(t, err)
require.Equal(t, newContractStorage.NodeHash, contractStorage.NodeHash)
require.Equal(t, newContractStorage.Path.Nibbles, contractStorage.Path.Nibbles)
require.Equal(t, newContractStorage.Address, contractStorage.Address)
}

func TestContractBytecode(t *testing.T) {
bytecode := &ContractBytecodeKey{
Address: common.Eth1Address(hexutil.MustDecode("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2")),
NodeHash: common.Bytes32(hexutil.MustDecode("0xd0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23")),
}

var buf bytes.Buffer
err := bytecode.Serialize(codec.NewEncodingWriter(&buf))
require.NoError(t, err)
hexStr := hexutil.Encode(buf.Bytes())
require.Equal(t, hexStr, "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2d0a06b12ac47863b5c7be4185c2deaad1c61557033f56c7d4ea74429cbb25e23")

newBytecode := &ContractBytecodeKey{}
err = newBytecode.Deserialize(codec.NewDecodingReader(&buf, uint64(len(buf.Bytes()))))
require.NoError(t, err)
require.Equal(t, newBytecode.NodeHash, bytecode.NodeHash)
require.Equal(t, newBytecode.Address, bytecode.Address)
}

0 comments on commit 4e6a44f

Please sign in to comment.