diff --git a/beacon-chain/state/state-native/custom-types/BUILD.bazel b/beacon-chain/state/state-native/custom-types/BUILD.bazel index 1ab81516fa..3c19f0a126 100644 --- a/beacon-chain/state/state-native/custom-types/BUILD.bazel +++ b/beacon-chain/state/state-native/custom-types/BUILD.bazel @@ -5,6 +5,7 @@ go_library( srcs = [ "block_roots.go", "byte32.go", + "historical_roots.go", "randao_mixes.go", "state_roots.go", ], @@ -21,9 +22,13 @@ go_test( srcs = [ "block_roots_test.go", "byte32_test.go", + "historical_roots_test.go", "randao_mixes_test.go", "state_roots_test.go", ], embed = [":go_default_library"], - deps = ["//config/fieldparams:go_default_library"], + deps = [ + "//config/fieldparams:go_default_library", + "//testing/assert:go_default_library", + ], ) diff --git a/beacon-chain/state/state-native/custom-types/block_roots.go b/beacon-chain/state/state-native/custom-types/block_roots.go index df492bdf02..1a3c154741 100644 --- a/beacon-chain/state/state-native/custom-types/block_roots.go +++ b/beacon-chain/state/state-native/custom-types/block_roots.go @@ -67,3 +67,16 @@ func (r *BlockRoots) MarshalSSZ() ([]byte, error) { func (_ *BlockRoots) SizeSSZ() int { return fieldparams.BlockRootsLength * 32 } + +// Slice converts a customtypes.BlockRoots object into a 2D byte slice. +func (r *BlockRoots) Slice() [][]byte { + if r == nil { + return nil + } + bRoots := make([][]byte, len(r)) + for i, root := range r { + tmp := root + bRoots[i] = tmp[:] + } + return bRoots +} diff --git a/beacon-chain/state/state-native/custom-types/block_roots_test.go b/beacon-chain/state/state-native/custom-types/block_roots_test.go index 045c27421b..1bd756b710 100644 --- a/beacon-chain/state/state-native/custom-types/block_roots_test.go +++ b/beacon-chain/state/state-native/custom-types/block_roots_test.go @@ -5,6 +5,7 @@ import ( "testing" fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" + "github.com/prysmaticlabs/prysm/testing/assert" ) func TestBlockRoots_Casting(t *testing.T) { @@ -90,3 +91,15 @@ func TestBlockRoots_SizeSSZ(t *testing.T) { t.Errorf("Wrong SSZ size. Expected %v vs actual %v", fieldparams.BlockRootsLength*32, d.SizeSSZ()) } } + +func TestBlockRoots_Slice(t *testing.T) { + a, b, c := [32]byte{'a'}, [32]byte{'b'}, [32]byte{'c'} + roots := BlockRoots{} + roots[1] = a + roots[10] = b + roots[100] = c + slice := roots.Slice() + assert.DeepEqual(t, a[:], slice[1]) + assert.DeepEqual(t, b[:], slice[10]) + assert.DeepEqual(t, c[:], slice[100]) +} diff --git a/beacon-chain/state/state-native/custom-types/historical_roots.go b/beacon-chain/state/state-native/custom-types/historical_roots.go new file mode 100644 index 0000000000..aea021fc44 --- /dev/null +++ b/beacon-chain/state/state-native/custom-types/historical_roots.go @@ -0,0 +1,81 @@ +package customtypes + +import ( + "fmt" + + fssz "github.com/ferranbt/fastssz" +) + +var _ fssz.HashRoot = (HistoricalRoots)([][32]byte{}) +var _ fssz.Marshaler = (*HistoricalRoots)(nil) +var _ fssz.Unmarshaler = (*HistoricalRoots)(nil) + +// Byte32 represents a 32 bytes HistoricalRoots object in Ethereum beacon chain consensus. +type HistoricalRoots [][32]byte + +// HashTreeRoot returns calculated hash root. +func (r HistoricalRoots) HashTreeRoot() ([32]byte, error) { + return fssz.HashWithDefaultHasher(r) +} + +// HashTreeRootWith hashes a HistoricalRoots object with a Hasher from the default HasherPool. +func (r HistoricalRoots) HashTreeRootWith(hh *fssz.Hasher) error { + index := hh.Index() + for _, sRoot := range r { + hh.Append(sRoot[:]) + } + hh.Merkleize(index) + return nil +} + +// UnmarshalSSZ deserializes the provided bytes buffer into the HistoricalRoots object. +func (r *HistoricalRoots) UnmarshalSSZ(buf []byte) error { + if len(buf) != r.SizeSSZ() { + return fmt.Errorf("expected buffer of length %d received %d", r.SizeSSZ(), len(buf)) + } + + mixes := make([][32]byte, len(buf)/32) + for i := range mixes { + copy(mixes[i][:], buf[i*32:(i+1)*32]) + } + *r = mixes + return nil +} + +// MarshalSSZTo marshals HistoricalRoots with the provided byte slice. +func (r *HistoricalRoots) MarshalSSZTo(dst []byte) ([]byte, error) { + marshalled, err := r.MarshalSSZ() + if err != nil { + return nil, err + } + return append(dst, marshalled...), nil +} + +// MarshalSSZ marshals HistoricalRoots into a serialized object. +func (r *HistoricalRoots) MarshalSSZ() ([]byte, error) { + marshalled := make([]byte, len(*r)*32) + for i, r32 := range *r { + for j, rr := range r32 { + marshalled[i*32+j] = rr + } + } + return marshalled, nil +} + +// SizeSSZ returns the size of the serialized object. +func (r *HistoricalRoots) SizeSSZ() int { + return len(*r) * 32 +} + +// Slice converts a customtypes.HistoricalRoots object into a 2D byte slice. +func (r *HistoricalRoots) Slice() [][]byte { + if r == nil { + return nil + } + hRoots := make([][]byte, len(*r)) + for i, root := range *r { + tmp := root + hRoots[i] = tmp[:] + } + return hRoots +} diff --git a/beacon-chain/state/state-native/custom-types/historical_roots_test.go b/beacon-chain/state/state-native/custom-types/historical_roots_test.go new file mode 100644 index 0000000000..462a3fd011 --- /dev/null +++ b/beacon-chain/state/state-native/custom-types/historical_roots_test.go @@ -0,0 +1,102 @@ +package customtypes + +import ( + "reflect" + "testing" + + "github.com/prysmaticlabs/prysm/testing/assert" +) + +func TestHistoricalRoots_Casting(t *testing.T) { + b := make([][32]byte, 4) + d := HistoricalRoots(b) + if !reflect.DeepEqual([][32]byte(d), b) { + t.Errorf("Unequal: %v = %v", d, b) + } +} + +func TestHistoricalRoots_UnmarshalSSZ(t *testing.T) { + t.Run("Ok", func(t *testing.T) { + d := HistoricalRoots(make([][32]byte, 2)) + b := make([][32]byte, 2) + b[0] = [32]byte{'f', 'o', 'o'} + b[1] = [32]byte{'b', 'a', 'r'} + bb := make([]byte, 2*32) + for i, elem32 := range b { + for j, elem := range elem32 { + bb[i*32+j] = elem + } + } + err := d.UnmarshalSSZ(bb) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !reflect.DeepEqual(b, [][32]byte(d)) { + t.Errorf("Unequal: %v = %v", b, [][32]byte(d)) + } + }) + + t.Run("Wrong slice length", func(t *testing.T) { + d := HistoricalRoots(make([][32]byte, 2)) + b := make([][16]byte, 2) + b[0] = [16]byte{'f', 'o', 'o'} + b[1] = [16]byte{'b', 'a', 'r'} + bb := make([]byte, 2*16) + for i, elem16 := range b { + for j, elem := range elem16 { + bb[i*16+j] = elem + } + } + err := d.UnmarshalSSZ(bb) + if err == nil { + t.Error("Expected error") + } + }) +} + +func TestHistoricalRoots_MarshalSSZTo(t *testing.T) { + d := HistoricalRoots(make([][32]byte, 1)) + d[0] = [32]byte{'f', 'o', 'o'} + dst := []byte("bar") + b, err := d.MarshalSSZTo(dst) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + expected := []byte{'b', 'a', 'r', 'f', 'o', 'o'} + actual := []byte{b[0], b[1], b[2], b[3], b[4], b[5]} + if !reflect.DeepEqual(expected, actual) { + t.Errorf("Unequal: %v = %v", expected, actual) + } +} + +func TestHistoricalRoots_MarshalSSZ(t *testing.T) { + d := HistoricalRoots(make([][32]byte, 2)) + d[0] = [32]byte{'f', 'o', 'o'} + d[1] = [32]byte{'b', 'a', 'r'} + b, err := d.MarshalSSZ() + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + if !reflect.DeepEqual(d[0][:], b[0:32]) { + t.Errorf("Unequal: %v = %v", d[0], b[0:32]) + } + if !reflect.DeepEqual(d[1][:], b[32:64]) { + t.Errorf("Unequal: %v = %v", d[0], b[32:64]) + } +} + +func TestHistoricalRoots_SizeSSZ(t *testing.T) { + d := HistoricalRoots(make([][32]byte, 2)) + if d.SizeSSZ() != 2*32 { + t.Errorf("Wrong SSZ size. Expected %v vs actual %v", 2*32, d.SizeSSZ()) + } +} + +func TestHistoricalRoots_Slice(t *testing.T) { + a, b, c := [32]byte{'a'}, [32]byte{'b'}, [32]byte{'c'} + roots := HistoricalRoots{a, b, c} + slice := roots.Slice() + assert.DeepEqual(t, a[:], slice[0]) + assert.DeepEqual(t, b[:], slice[1]) + assert.DeepEqual(t, c[:], slice[2]) +} diff --git a/beacon-chain/state/state-native/custom-types/randao_mixes.go b/beacon-chain/state/state-native/custom-types/randao_mixes.go index a0921ecba3..e4d7435c34 100644 --- a/beacon-chain/state/state-native/custom-types/randao_mixes.go +++ b/beacon-chain/state/state-native/custom-types/randao_mixes.go @@ -11,7 +11,7 @@ var _ fssz.HashRoot = (RandaoMixes)([fieldparams.RandaoMixesLength][32]byte{}) var _ fssz.Marshaler = (*RandaoMixes)(nil) var _ fssz.Unmarshaler = (*RandaoMixes)(nil) -// Byte32 represents a 32 bytes RandaoMixes object in Ethereum beacon chain consensus. +// RandaoMixes represents RANDAO mixes of the beacon state. type RandaoMixes [fieldparams.RandaoMixesLength][32]byte // HashTreeRoot returns calculated hash root. @@ -68,63 +68,15 @@ func (_ *RandaoMixes) SizeSSZ() int { return fieldparams.RandaoMixesLength * 32 } -var _ fssz.HashRoot = (HistoricalRoots)([][32]byte{}) -var _ fssz.Marshaler = (*HistoricalRoots)(nil) -var _ fssz.Unmarshaler = (*HistoricalRoots)(nil) - -// Byte32 represents a 32 bytes HistoricalRoots object in Ethereum beacon chain consensus. -type HistoricalRoots [][32]byte - -// HashTreeRoot returns calculated hash root. -func (r HistoricalRoots) HashTreeRoot() ([32]byte, error) { - return fssz.HashWithDefaultHasher(r) -} - -// HashTreeRootWith hashes a HistoricalRoots object with a Hasher from the default HasherPool. -func (r HistoricalRoots) HashTreeRootWith(hh *fssz.Hasher) error { - index := hh.Index() - for _, sRoot := range r { - hh.Append(sRoot[:]) +// Slice converts a customtypes.RandaoMixes object into a 2D byte slice. +func (r *RandaoMixes) Slice() [][]byte { + if r == nil { + return nil } - hh.Merkleize(index) - return nil -} - -// UnmarshalSSZ deserializes the provided bytes buffer into the HistoricalRoots object. -func (r *HistoricalRoots) UnmarshalSSZ(buf []byte) error { - if len(buf) != r.SizeSSZ() { - return fmt.Errorf("expected buffer of length %d received %d", r.SizeSSZ(), len(buf)) + mixes := make([][]byte, len(r)) + for i, root := range r { + tmp := root + mixes[i] = tmp[:] } - - mixes := make([][32]byte, len(buf)/32) - for i := range mixes { - copy(mixes[i][:], buf[i*32:(i+1)*32]) - } - *r = mixes - return nil -} - -// MarshalSSZTo marshals HistoricalRoots with the provided byte slice. -func (r *HistoricalRoots) MarshalSSZTo(dst []byte) ([]byte, error) { - marshalled, err := r.MarshalSSZ() - if err != nil { - return nil, err - } - return append(dst, marshalled...), nil -} - -// MarshalSSZ marshals HistoricalRoots into a serialized object. -func (r *HistoricalRoots) MarshalSSZ() ([]byte, error) { - marshalled := make([]byte, len(*r)*32) - for i, r32 := range *r { - for j, rr := range r32 { - marshalled[i*32+j] = rr - } - } - return marshalled, nil -} - -// SizeSSZ returns the size of the serialized object. -func (r *HistoricalRoots) SizeSSZ() int { - return len(*r) * 32 + return mixes } diff --git a/beacon-chain/state/state-native/custom-types/randao_mixes_test.go b/beacon-chain/state/state-native/custom-types/randao_mixes_test.go index f969f6fa89..9e94581da7 100644 --- a/beacon-chain/state/state-native/custom-types/randao_mixes_test.go +++ b/beacon-chain/state/state-native/custom-types/randao_mixes_test.go @@ -5,6 +5,7 @@ import ( "testing" fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" + "github.com/prysmaticlabs/prysm/testing/assert" ) func TestRandaoMixes_Casting(t *testing.T) { @@ -91,87 +92,14 @@ func TestRandaoMixes_SizeSSZ(t *testing.T) { } } -func TestHistoricalRoots_Casting(t *testing.T) { - b := make([][32]byte, 4) - d := HistoricalRoots(b) - if !reflect.DeepEqual([][32]byte(d), b) { - t.Errorf("Unequal: %v = %v", d, b) - } -} - -func TestHistoricalRoots_UnmarshalSSZ(t *testing.T) { - t.Run("Ok", func(t *testing.T) { - d := HistoricalRoots(make([][32]byte, 2)) - b := make([][32]byte, 2) - b[0] = [32]byte{'f', 'o', 'o'} - b[1] = [32]byte{'b', 'a', 'r'} - bb := make([]byte, 2*32) - for i, elem32 := range b { - for j, elem := range elem32 { - bb[i*32+j] = elem - } - } - err := d.UnmarshalSSZ(bb) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if !reflect.DeepEqual(b, [][32]byte(d)) { - t.Errorf("Unequal: %v = %v", b, [][32]byte(d)) - } - }) - - t.Run("Wrong slice length", func(t *testing.T) { - d := HistoricalRoots(make([][32]byte, 2)) - b := make([][16]byte, 2) - b[0] = [16]byte{'f', 'o', 'o'} - b[1] = [16]byte{'b', 'a', 'r'} - bb := make([]byte, 2*16) - for i, elem16 := range b { - for j, elem := range elem16 { - bb[i*16+j] = elem - } - } - err := d.UnmarshalSSZ(bb) - if err == nil { - t.Error("Expected error") - } - }) -} - -func TestHistoricalRoots_MarshalSSZTo(t *testing.T) { - d := HistoricalRoots(make([][32]byte, 1)) - d[0] = [32]byte{'f', 'o', 'o'} - dst := []byte("bar") - b, err := d.MarshalSSZTo(dst) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - expected := []byte{'b', 'a', 'r', 'f', 'o', 'o'} - actual := []byte{b[0], b[1], b[2], b[3], b[4], b[5]} - if !reflect.DeepEqual(expected, actual) { - t.Errorf("Unequal: %v = %v", expected, actual) - } -} - -func TestHistoricalRoots_MarshalSSZ(t *testing.T) { - d := HistoricalRoots(make([][32]byte, 2)) - d[0] = [32]byte{'f', 'o', 'o'} - d[1] = [32]byte{'b', 'a', 'r'} - b, err := d.MarshalSSZ() - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - if !reflect.DeepEqual(d[0][:], b[0:32]) { - t.Errorf("Unequal: %v = %v", d[0], b[0:32]) - } - if !reflect.DeepEqual(d[1][:], b[32:64]) { - t.Errorf("Unequal: %v = %v", d[0], b[32:64]) - } -} - -func TestHistoricalRoots_SizeSSZ(t *testing.T) { - d := HistoricalRoots(make([][32]byte, 2)) - if d.SizeSSZ() != 2*32 { - t.Errorf("Wrong SSZ size. Expected %v vs actual %v", 2*32, d.SizeSSZ()) - } +func TestRandaoMixes_Slice(t *testing.T) { + a, b, c := [32]byte{'a'}, [32]byte{'b'}, [32]byte{'c'} + roots := RandaoMixes{} + roots[1] = a + roots[10] = b + roots[100] = c + slice := roots.Slice() + assert.DeepEqual(t, a[:], slice[1]) + assert.DeepEqual(t, b[:], slice[10]) + assert.DeepEqual(t, c[:], slice[100]) } diff --git a/beacon-chain/state/state-native/custom-types/state_roots.go b/beacon-chain/state/state-native/custom-types/state_roots.go index eca42c0afe..4c544b8b7b 100644 --- a/beacon-chain/state/state-native/custom-types/state_roots.go +++ b/beacon-chain/state/state-native/custom-types/state_roots.go @@ -67,3 +67,16 @@ func (r *StateRoots) MarshalSSZ() ([]byte, error) { func (_ *StateRoots) SizeSSZ() int { return fieldparams.StateRootsLength * 32 } + +// Slice converts a customtypes.StateRoots object into a 2D byte slice. +func (r *StateRoots) Slice() [][]byte { + if r == nil { + return nil + } + sRoots := make([][]byte, len(r)) + for i, root := range r { + tmp := root + sRoots[i] = tmp[:] + } + return sRoots +} diff --git a/beacon-chain/state/state-native/custom-types/state_roots_test.go b/beacon-chain/state/state-native/custom-types/state_roots_test.go index fade730cc7..d37c6c2676 100644 --- a/beacon-chain/state/state-native/custom-types/state_roots_test.go +++ b/beacon-chain/state/state-native/custom-types/state_roots_test.go @@ -5,6 +5,7 @@ import ( "testing" fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" + "github.com/prysmaticlabs/prysm/testing/assert" ) func TestStateRoots_Casting(t *testing.T) { @@ -90,3 +91,15 @@ func TestStateRoots_SizeSSZ(t *testing.T) { t.Errorf("Wrong SSZ size. Expected %v vs actual %v", fieldparams.StateRootsLength*32, d.SizeSSZ()) } } + +func TestStateRoots_Slice(t *testing.T) { + a, b, c := [32]byte{'a'}, [32]byte{'b'}, [32]byte{'c'} + roots := StateRoots{} + roots[1] = a + roots[10] = b + roots[100] = c + slice := roots.Slice() + assert.DeepEqual(t, a[:], slice[1]) + assert.DeepEqual(t, b[:], slice[10]) + assert.DeepEqual(t, c[:], slice[100]) +} diff --git a/beacon-chain/state/state-native/v1/BUILD.bazel b/beacon-chain/state/state-native/v1/BUILD.bazel index 5a0cd4ed5d..52ec97dc7f 100644 --- a/beacon-chain/state/state-native/v1/BUILD.bazel +++ b/beacon-chain/state/state-native/v1/BUILD.bazel @@ -1,4 +1,6 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test") +load("//proto:ssz_proto_library.bzl", "ssz_proto_files") +load("//tools:ssz.bzl", "SSZ_DEPS", "ssz_gen_marshal") go_library( name = "go_default_library", @@ -27,7 +29,11 @@ go_library( "types.go", "unsupported_getters.go", "unsupported_setters.go", - ], + ":ssz_generated_files", # keep + ] + select({ + "//config:mainnet": ["beacon_state_mainnet.go"], + "//config:minimal": ["beacon_state_minimal.go"], + }), importpath = "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/v1", visibility = [ "//beacon-chain:__subpackages__", @@ -46,6 +52,7 @@ go_library( ], deps = [ "//beacon-chain/state:go_default_library", + "//beacon-chain/state/state-native/custom-types:go_default_library", "//beacon-chain/state/state-native/fieldtrie:go_default_library", "//beacon-chain/state/stateutil:go_default_library", "//beacon-chain/state/types:go_default_library", @@ -58,6 +65,7 @@ go_library( "//encoding/ssz:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//runtime/version:go_default_library", + "@com_github_ferranbt_fastssz//:go_default_library", "@com_github_pkg_errors//:go_default_library", "@com_github_prysmaticlabs_eth2_types//:go_default_library", "@com_github_prysmaticlabs_go_bitfield//:go_default_library", @@ -81,7 +89,10 @@ go_test( "state_test.go", "state_trie_test.go", "types_test.go", - ], + ] + select({ + "//config:mainnet": ["beacon_state_mainnet_test.go"], + "//config:minimal": ["beacon_state_minimal_test.go"], + }), embed = [":go_default_library"], deps = [ "//beacon-chain/state:go_default_library", @@ -103,3 +114,20 @@ go_test( "@org_golang_google_protobuf//proto:go_default_library", ], ) + +ssz_gen_marshal( + name = "ssz_generated_files", + srcs = select({ + "//config:mainnet": ["beacon_state_mainnet.go"], + "//config:minimal": ["beacon_state_minimal.go"], + }), + includes = [ + "//beacon-chain/state/state-native/custom-types:go_default_library", + "//config/fieldparams:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", + "@com_github_prysmaticlabs_eth2_types//:go_default_library", + ], + objs = [ + "BeaconState[no-htr]", + ], +) diff --git a/beacon-chain/state/state-native/v1/beacon_state_mainnet.go b/beacon-chain/state/state-native/v1/beacon_state_mainnet.go new file mode 100644 index 0000000000..c476a0adc9 --- /dev/null +++ b/beacon-chain/state/state-native/v1/beacon_state_mainnet.go @@ -0,0 +1,50 @@ +// +build !minimal + +package v1 + +import ( + "sync" + + eth2types "github.com/prysmaticlabs/eth2-types" + "github.com/prysmaticlabs/go-bitfield" + customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types" + "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/fieldtrie" + "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" + "github.com/prysmaticlabs/prysm/beacon-chain/state/types" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" +) + +// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining +// getters and setters for its respective values and helpful functions such as HashTreeRoot(). +type BeaconState struct { + genesisTime uint64 `ssz-gen:"true"` + genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"` + slot eth2types.Slot `ssz-gen:"true"` + fork *ethpb.Fork `ssz-gen:"true"` + latestBlockHeader *ethpb.BeaconBlockHeader `ssz-gen:"true"` + blockRoots *customtypes.BlockRoots `ssz-gen:"true" ssz-size:"8192,32"` + stateRoots *customtypes.StateRoots `ssz-gen:"true" ssz-size:"8192,32"` + historicalRoots customtypes.HistoricalRoots `ssz-gen:"true" ssz-size:"?,32" ssz-max:"16777216"` + eth1Data *ethpb.Eth1Data `ssz-gen:"true"` + eth1DataVotes []*ethpb.Eth1Data `ssz-gen:"true" ssz-max:"2048"` + eth1DepositIndex uint64 `ssz-gen:"true"` + validators []*ethpb.Validator `ssz-gen:"true" ssz-max:"1099511627776"` + balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"` + randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"65536,32"` + slashings []uint64 `ssz-gen:"true" ssz-size:"8192"` + previousEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"4096"` + currentEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"4096"` + justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"` + previousJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"` + currentJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"` + finalizedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"` + + lock sync.RWMutex + dirtyFields map[types.FieldIndex]bool + dirtyIndices map[types.FieldIndex][]uint64 + stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie + rebuildTrie map[types.FieldIndex]bool + valMapHandler *stateutil.ValidatorMapHandler + merkleLayers [][][]byte + sharedFieldReferences map[types.FieldIndex]*stateutil.Reference +} diff --git a/beacon-chain/state/state-native/v1/beacon_state_mainnet_test.go b/beacon-chain/state/state-native/v1/beacon_state_mainnet_test.go new file mode 100644 index 0000000000..a273b3637e --- /dev/null +++ b/beacon-chain/state/state-native/v1/beacon_state_mainnet_test.go @@ -0,0 +1,81 @@ +// +build !minimal + +package v1 + +import ( + "reflect" + "strconv" + "testing" + + fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" + "github.com/prysmaticlabs/prysm/testing/assert" + "github.com/prysmaticlabs/prysm/testing/require" +) + +func TestMainnetSszValuesAgainstFieldParams(t *testing.T) { + // Casting needed to avoid lock copy analyzer issue. + bs := (interface{})(BeaconState{}) + bsType := reflect.TypeOf(bs) + + f, ok := bsType.FieldByName("genesisValidatorsRoot") + require.Equal(t, true, ok, "Required field not found") + v := f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.RootLength), v) + + f, ok = bsType.FieldByName("blockRoots") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.BlockRootsLength)+","+strconv.Itoa(fieldparams.RootLength), v) + + f, ok = bsType.FieldByName("stateRoots") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.StateRootsLength)+","+strconv.Itoa(fieldparams.RootLength), v) + + f, ok = bsType.FieldByName("historicalRoots") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, "?,"+strconv.Itoa(fieldparams.RootLength), v) + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.HistoricalRootsLength), v) + + f, ok = bsType.FieldByName("eth1DataVotes") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.Eth1DataVotesLength), v) + + f, ok = bsType.FieldByName("validators") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v) + + f, ok = bsType.FieldByName("balances") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v) + + f, ok = bsType.FieldByName("randaoMixes") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.RandaoMixesLength)+","+strconv.Itoa(fieldparams.RootLength), v) + + f, ok = bsType.FieldByName("slashings") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.SlashingsLength), v) + + f, ok = bsType.FieldByName("previousEpochAttestations") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.PreviousEpochAttestationsLength), v) + + f, ok = bsType.FieldByName("currentEpochAttestations") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.CurrentEpochAttestationsLength), v) + + f, ok = bsType.FieldByName("justificationBits") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, "1", v) +} diff --git a/beacon-chain/state/state-native/v1/beacon_state_minimal.go b/beacon-chain/state/state-native/v1/beacon_state_minimal.go new file mode 100644 index 0000000000..9aac004cda --- /dev/null +++ b/beacon-chain/state/state-native/v1/beacon_state_minimal.go @@ -0,0 +1,50 @@ +// +build minimal + +package v1 + +import ( + "sync" + + eth2types "github.com/prysmaticlabs/eth2-types" + "github.com/prysmaticlabs/go-bitfield" + customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types" + "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/fieldtrie" + "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" + "github.com/prysmaticlabs/prysm/beacon-chain/state/types" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" +) + +// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining +// getters and setters for its respective values and helpful functions such as HashTreeRoot(). +type BeaconState struct { + genesisTime uint64 `ssz-gen:"true"` + genesisValidatorsRoot customtypes.Byte32 `ssz-gen:"true" ssz-size:"32"` + slot eth2types.Slot `ssz-gen:"true"` + fork *ethpb.Fork `ssz-gen:"true"` + latestBlockHeader *ethpb.BeaconBlockHeader `ssz-gen:"true"` + blockRoots *customtypes.BlockRoots `ssz-gen:"true" ssz-size:"64,32"` + stateRoots *customtypes.StateRoots `ssz-gen:"true" ssz-size:"64,32"` + historicalRoots customtypes.HistoricalRoots `ssz-gen:"true" ssz-size:"?,32" ssz-max:"16777216"` + eth1Data *ethpb.Eth1Data `ssz-gen:"true"` + eth1DataVotes []*ethpb.Eth1Data `ssz-gen:"true" ssz-max:"32"` + eth1DepositIndex uint64 `ssz-gen:"true"` + validators []*ethpb.Validator `ssz-gen:"true" ssz-max:"1099511627776"` + balances []uint64 `ssz-gen:"true" ssz-max:"1099511627776"` + randaoMixes *customtypes.RandaoMixes `ssz-gen:"true" ssz-size:"64,32"` + slashings []uint64 `ssz-gen:"true" ssz-size:"64"` + previousEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"1024"` + currentEpochAttestations []*ethpb.PendingAttestation `ssz-gen:"true" ssz-max:"1024"` + justificationBits bitfield.Bitvector4 `ssz-gen:"true" ssz-size:"1"` + previousJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"` + currentJustifiedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"` + finalizedCheckpoint *ethpb.Checkpoint `ssz-gen:"true"` + + lock sync.RWMutex + dirtyFields map[types.FieldIndex]bool + dirtyIndices map[types.FieldIndex][]uint64 + stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie + rebuildTrie map[types.FieldIndex]bool + valMapHandler *stateutil.ValidatorMapHandler + merkleLayers [][][]byte + sharedFieldReferences map[types.FieldIndex]*stateutil.Reference +} diff --git a/beacon-chain/state/state-native/v1/beacon_state_minimal_test.go b/beacon-chain/state/state-native/v1/beacon_state_minimal_test.go new file mode 100644 index 0000000000..24ca41fac4 --- /dev/null +++ b/beacon-chain/state/state-native/v1/beacon_state_minimal_test.go @@ -0,0 +1,81 @@ +// +build minimal + +package v1 + +import ( + "reflect" + "strconv" + "testing" + + fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" + "github.com/prysmaticlabs/prysm/testing/assert" + "github.com/prysmaticlabs/prysm/testing/require" +) + +func TestMinimalSszValuesAgainstFieldParams(t *testing.T) { + // Casting needed to avoid lock copy analyzer issue. + bs := (interface{})(BeaconState{}) + bsType := reflect.TypeOf(bs) + + f, ok := bsType.FieldByName("genesisValidatorsRoot") + require.Equal(t, true, ok, "Required field not found") + v := f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.RootLength), v) + + f, ok = bsType.FieldByName("blockRoots") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.BlockRootsLength)+","+strconv.Itoa(fieldparams.RootLength), v) + + f, ok = bsType.FieldByName("stateRoots") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.StateRootsLength)+","+strconv.Itoa(fieldparams.RootLength), v) + + f, ok = bsType.FieldByName("historicalRoots") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, "?,"+strconv.Itoa(fieldparams.RootLength), v) + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.HistoricalRootsLength), v) + + f, ok = bsType.FieldByName("eth1DataVotes") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.Eth1DataVotesLength), v) + + f, ok = bsType.FieldByName("validators") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v) + + f, ok = bsType.FieldByName("balances") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.ValidatorRegistryLimit), v) + + f, ok = bsType.FieldByName("randaoMixes") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.RandaoMixesLength)+","+strconv.Itoa(fieldparams.RootLength), v) + + f, ok = bsType.FieldByName("slashings") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, strconv.Itoa(fieldparams.SlashingsLength), v) + + f, ok = bsType.FieldByName("previousEpochAttestations") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.PreviousEpochAttestationsLength), v) + + f, ok = bsType.FieldByName("currentEpochAttestations") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-max") + assert.Equal(t, strconv.Itoa(fieldparams.CurrentEpochAttestationsLength), v) + + f, ok = bsType.FieldByName("justificationBits") + require.Equal(t, true, ok, "Required field not found") + v = f.Tag.Get("ssz-size") + assert.Equal(t, "1", v) +} diff --git a/beacon-chain/state/state-native/v1/generated.ssz.go b/beacon-chain/state/state-native/v1/generated.ssz.go new file mode 100644 index 0000000000..8991c00440 --- /dev/null +++ b/beacon-chain/state/state-native/v1/generated.ssz.go @@ -0,0 +1,493 @@ +// Code generated by fastssz. DO NOT EDIT. +// Hash: 6de36f732d72b5c4c0c967bc0edcc752b7afdd337e829486954eb6affda84da8 +package v1 + +import ( + ssz "github.com/ferranbt/fastssz" + eth2types "github.com/prysmaticlabs/eth2-types" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" +) + +// MarshalSSZ ssz marshals the BeaconState object +func (b *BeaconState) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(b) +} + +// MarshalSSZTo ssz marshals the BeaconState object to a target array +func (b *BeaconState) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + offset := int(2687377) + + // Field (0) 'genesisTime' + dst = ssz.MarshalUint64(dst, b.genesisTime) + + // Field (1) 'genesisValidatorsRoot' + dst = append(dst, b.genesisValidatorsRoot[:]...) + + // Field (2) 'slot' + dst = ssz.MarshalUint64(dst, uint64(b.slot)) + + // Field (3) 'fork' + if b.fork == nil { + b.fork = new(ethpb.Fork) + } + if dst, err = b.fork.MarshalSSZTo(dst); err != nil { + return + } + + // Field (4) 'latestBlockHeader' + if b.latestBlockHeader == nil { + b.latestBlockHeader = new(ethpb.BeaconBlockHeader) + } + if dst, err = b.latestBlockHeader.MarshalSSZTo(dst); err != nil { + return + } + + // Field (5) 'blockRoots' + for ii := 0; ii < 8192; ii++ { + dst = append(dst, b.blockRoots[ii][:]...) + } + + // Field (6) 'stateRoots' + for ii := 0; ii < 8192; ii++ { + dst = append(dst, b.stateRoots[ii][:]...) + } + + // Offset (7) 'historicalRoots' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.historicalRoots) * 32 + + // Field (8) 'eth1Data' + if b.eth1Data == nil { + b.eth1Data = new(ethpb.Eth1Data) + } + if dst, err = b.eth1Data.MarshalSSZTo(dst); err != nil { + return + } + + // Offset (9) 'eth1DataVotes' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.eth1DataVotes) * 72 + + // Field (10) 'eth1DepositIndex' + dst = ssz.MarshalUint64(dst, b.eth1DepositIndex) + + // Offset (11) 'validators' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.validators) * 121 + + // Offset (12) 'balances' + dst = ssz.WriteOffset(dst, offset) + offset += len(b.balances) * 8 + + // Field (13) 'randaoMixes' + for ii := 0; ii < 65536; ii++ { + dst = append(dst, b.randaoMixes[ii][:]...) + } + + // Field (14) 'slashings' + if len(b.slashings) != 8192 { + err = ssz.ErrVectorLength + return + } + for ii := 0; ii < 8192; ii++ { + dst = ssz.MarshalUint64(dst, b.slashings[ii]) + } + + // Offset (15) 'previousEpochAttestations' + dst = ssz.WriteOffset(dst, offset) + for ii := 0; ii < len(b.previousEpochAttestations); ii++ { + offset += 4 + offset += b.previousEpochAttestations[ii].SizeSSZ() + } + + // Offset (16) 'currentEpochAttestations' + dst = ssz.WriteOffset(dst, offset) + for ii := 0; ii < len(b.currentEpochAttestations); ii++ { + offset += 4 + offset += b.currentEpochAttestations[ii].SizeSSZ() + } + + // Field (17) 'justificationBits' + if len(b.justificationBits) != 1 { + err = ssz.ErrBytesLength + return + } + dst = append(dst, b.justificationBits...) + + // Field (18) 'previousJustifiedCheckpoint' + if b.previousJustifiedCheckpoint == nil { + b.previousJustifiedCheckpoint = new(ethpb.Checkpoint) + } + if dst, err = b.previousJustifiedCheckpoint.MarshalSSZTo(dst); err != nil { + return + } + + // Field (19) 'currentJustifiedCheckpoint' + if b.currentJustifiedCheckpoint == nil { + b.currentJustifiedCheckpoint = new(ethpb.Checkpoint) + } + if dst, err = b.currentJustifiedCheckpoint.MarshalSSZTo(dst); err != nil { + return + } + + // Field (20) 'finalizedCheckpoint' + if b.finalizedCheckpoint == nil { + b.finalizedCheckpoint = new(ethpb.Checkpoint) + } + if dst, err = b.finalizedCheckpoint.MarshalSSZTo(dst); err != nil { + return + } + + // Field (7) 'historicalRoots' + if len(b.historicalRoots) > 16777216 { + err = ssz.ErrListTooBig + return + } + for ii := 0; ii < len(b.historicalRoots); ii++ { + dst = append(dst, b.historicalRoots[ii][:]...) + } + + // Field (9) 'eth1DataVotes' + if len(b.eth1DataVotes) > 2048 { + err = ssz.ErrListTooBig + return + } + for ii := 0; ii < len(b.eth1DataVotes); ii++ { + if dst, err = b.eth1DataVotes[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (11) 'validators' + if len(b.validators) > 1099511627776 { + err = ssz.ErrListTooBig + return + } + for ii := 0; ii < len(b.validators); ii++ { + if dst, err = b.validators[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (12) 'balances' + if len(b.balances) > 1099511627776 { + err = ssz.ErrListTooBig + return + } + for ii := 0; ii < len(b.balances); ii++ { + dst = ssz.MarshalUint64(dst, b.balances[ii]) + } + + // Field (15) 'previousEpochAttestations' + if len(b.previousEpochAttestations) > 4096 { + err = ssz.ErrListTooBig + return + } + { + offset = 4 * len(b.previousEpochAttestations) + for ii := 0; ii < len(b.previousEpochAttestations); ii++ { + dst = ssz.WriteOffset(dst, offset) + offset += b.previousEpochAttestations[ii].SizeSSZ() + } + } + for ii := 0; ii < len(b.previousEpochAttestations); ii++ { + if dst, err = b.previousEpochAttestations[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + // Field (16) 'currentEpochAttestations' + if len(b.currentEpochAttestations) > 4096 { + err = ssz.ErrListTooBig + return + } + { + offset = 4 * len(b.currentEpochAttestations) + for ii := 0; ii < len(b.currentEpochAttestations); ii++ { + dst = ssz.WriteOffset(dst, offset) + offset += b.currentEpochAttestations[ii].SizeSSZ() + } + } + for ii := 0; ii < len(b.currentEpochAttestations); ii++ { + if dst, err = b.currentEpochAttestations[ii].MarshalSSZTo(dst); err != nil { + return + } + } + + return +} + +// UnmarshalSSZ ssz unmarshals the BeaconState object +func (b *BeaconState) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size < 2687377 { + return ssz.ErrSize + } + + tail := buf + var o7, o9, o11, o12, o15, o16 uint64 + + // Field (0) 'genesisTime' + b.genesisTime = ssz.UnmarshallUint64(buf[0:8]) + + // Field (1) 'genesisValidatorsRoot' + copy(b.genesisValidatorsRoot[:], buf[8:40]) + + // Field (2) 'slot' + b.slot = eth2types.Slot(ssz.UnmarshallUint64(buf[40:48])) + + // Field (3) 'fork' + if b.fork == nil { + b.fork = new(ethpb.Fork) + } + if err = b.fork.UnmarshalSSZ(buf[48:64]); err != nil { + return err + } + + // Field (4) 'latestBlockHeader' + if b.latestBlockHeader == nil { + b.latestBlockHeader = new(ethpb.BeaconBlockHeader) + } + if err = b.latestBlockHeader.UnmarshalSSZ(buf[64:176]); err != nil { + return err + } + + // Field (5) 'blockRoots' + + for ii := 0; ii < 8192; ii++ { + copy(b.blockRoots[ii][:], buf[176:262320][ii*32:(ii+1)*32]) + } + + // Field (6) 'stateRoots' + + for ii := 0; ii < 8192; ii++ { + copy(b.stateRoots[ii][:], buf[262320:524464][ii*32:(ii+1)*32]) + } + + // Offset (7) 'historicalRoots' + if o7 = ssz.ReadOffset(buf[524464:524468]); o7 > size { + return ssz.ErrOffset + } + + if o7 < 2687377 { + return ssz.ErrInvalidVariableOffset + } + + // Field (8) 'eth1Data' + if b.eth1Data == nil { + b.eth1Data = new(ethpb.Eth1Data) + } + if err = b.eth1Data.UnmarshalSSZ(buf[524468:524540]); err != nil { + return err + } + + // Offset (9) 'eth1DataVotes' + if o9 = ssz.ReadOffset(buf[524540:524544]); o9 > size || o7 > o9 { + return ssz.ErrOffset + } + + // Field (10) 'eth1DepositIndex' + b.eth1DepositIndex = ssz.UnmarshallUint64(buf[524544:524552]) + + // Offset (11) 'validators' + if o11 = ssz.ReadOffset(buf[524552:524556]); o11 > size || o9 > o11 { + return ssz.ErrOffset + } + + // Offset (12) 'balances' + if o12 = ssz.ReadOffset(buf[524556:524560]); o12 > size || o11 > o12 { + return ssz.ErrOffset + } + + // Field (13) 'randaoMixes' + + for ii := 0; ii < 65536; ii++ { + copy(b.randaoMixes[ii][:], buf[524560:2621712][ii*32:(ii+1)*32]) + } + + // Field (14) 'slashings' + b.slashings = ssz.ExtendUint64(b.slashings, 8192) + for ii := 0; ii < 8192; ii++ { + b.slashings[ii] = ssz.UnmarshallUint64(buf[2621712:2687248][ii*8 : (ii+1)*8]) + } + + // Offset (15) 'previousEpochAttestations' + if o15 = ssz.ReadOffset(buf[2687248:2687252]); o15 > size || o12 > o15 { + return ssz.ErrOffset + } + + // Offset (16) 'currentEpochAttestations' + if o16 = ssz.ReadOffset(buf[2687252:2687256]); o16 > size || o15 > o16 { + return ssz.ErrOffset + } + + // Field (17) 'justificationBits' + if cap(b.justificationBits) == 0 { + b.justificationBits = make([]byte, 0, len(buf[2687256:2687257])) + } + b.justificationBits = append(b.justificationBits, buf[2687256:2687257]...) + + // Field (18) 'previousJustifiedCheckpoint' + if b.previousJustifiedCheckpoint == nil { + b.previousJustifiedCheckpoint = new(ethpb.Checkpoint) + } + if err = b.previousJustifiedCheckpoint.UnmarshalSSZ(buf[2687257:2687297]); err != nil { + return err + } + + // Field (19) 'currentJustifiedCheckpoint' + if b.currentJustifiedCheckpoint == nil { + b.currentJustifiedCheckpoint = new(ethpb.Checkpoint) + } + if err = b.currentJustifiedCheckpoint.UnmarshalSSZ(buf[2687297:2687337]); err != nil { + return err + } + + // Field (20) 'finalizedCheckpoint' + if b.finalizedCheckpoint == nil { + b.finalizedCheckpoint = new(ethpb.Checkpoint) + } + if err = b.finalizedCheckpoint.UnmarshalSSZ(buf[2687337:2687377]); err != nil { + return err + } + + // Field (7) 'historicalRoots' + { + buf = tail[o7:o9] + num, err := ssz.DivideInt2(len(buf), 32, 16777216) + if err != nil { + return err + } + b.historicalRoots = make([][32]byte, num) + for ii := 0; ii < num; ii++ { + copy(b.historicalRoots[ii][:], buf[ii*32:(ii+1)*32]) + } + } + + // Field (9) 'eth1DataVotes' + { + buf = tail[o9:o11] + num, err := ssz.DivideInt2(len(buf), 72, 2048) + if err != nil { + return err + } + b.eth1DataVotes = make([]*ethpb.Eth1Data, num) + for ii := 0; ii < num; ii++ { + if b.eth1DataVotes[ii] == nil { + b.eth1DataVotes[ii] = new(ethpb.Eth1Data) + } + if err = b.eth1DataVotes[ii].UnmarshalSSZ(buf[ii*72 : (ii+1)*72]); err != nil { + return err + } + } + } + + // Field (11) 'validators' + { + buf = tail[o11:o12] + num, err := ssz.DivideInt2(len(buf), 121, 1099511627776) + if err != nil { + return err + } + b.validators = make([]*ethpb.Validator, num) + for ii := 0; ii < num; ii++ { + if b.validators[ii] == nil { + b.validators[ii] = new(ethpb.Validator) + } + if err = b.validators[ii].UnmarshalSSZ(buf[ii*121 : (ii+1)*121]); err != nil { + return err + } + } + } + + // Field (12) 'balances' + { + buf = tail[o12:o15] + num, err := ssz.DivideInt2(len(buf), 8, 1099511627776) + if err != nil { + return err + } + b.balances = ssz.ExtendUint64(b.balances, num) + for ii := 0; ii < num; ii++ { + b.balances[ii] = ssz.UnmarshallUint64(buf[ii*8 : (ii+1)*8]) + } + } + + // Field (15) 'previousEpochAttestations' + { + buf = tail[o15:o16] + num, err := ssz.DecodeDynamicLength(buf, 4096) + if err != nil { + return err + } + b.previousEpochAttestations = make([]*ethpb.PendingAttestation, num) + err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) { + if b.previousEpochAttestations[indx] == nil { + b.previousEpochAttestations[indx] = new(ethpb.PendingAttestation) + } + if err = b.previousEpochAttestations[indx].UnmarshalSSZ(buf); err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + } + + // Field (16) 'currentEpochAttestations' + { + buf = tail[o16:] + num, err := ssz.DecodeDynamicLength(buf, 4096) + if err != nil { + return err + } + b.currentEpochAttestations = make([]*ethpb.PendingAttestation, num) + err = ssz.UnmarshalDynamic(buf, num, func(indx int, buf []byte) (err error) { + if b.currentEpochAttestations[indx] == nil { + b.currentEpochAttestations[indx] = new(ethpb.PendingAttestation) + } + if err = b.currentEpochAttestations[indx].UnmarshalSSZ(buf); err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + } + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the BeaconState object +func (b *BeaconState) SizeSSZ() (size int) { + size = 2687377 + + // Field (7) 'historicalRoots' + size += len(b.historicalRoots) * 32 + + // Field (9) 'eth1DataVotes' + size += len(b.eth1DataVotes) * 72 + + // Field (11) 'validators' + size += len(b.validators) * 121 + + // Field (12) 'balances' + size += len(b.balances) * 8 + + // Field (15) 'previousEpochAttestations' + for ii := 0; ii < len(b.previousEpochAttestations); ii++ { + size += 4 + size += b.previousEpochAttestations[ii].SizeSSZ() + } + + // Field (16) 'currentEpochAttestations' + for ii := 0; ii < len(b.currentEpochAttestations); ii++ { + size += 4 + size += b.currentEpochAttestations[ii].SizeSSZ() + } + + return +} diff --git a/beacon-chain/state/state-native/v1/getters_attestation.go b/beacon-chain/state/state-native/v1/getters_attestation.go index e7e3bd6901..a76ad5accb 100644 --- a/beacon-chain/state/state-native/v1/getters_attestation.go +++ b/beacon-chain/state/state-native/v1/getters_attestation.go @@ -6,50 +6,36 @@ import ( // PreviousEpochAttestations corresponding to blocks on the beacon chain. func (b *BeaconState) PreviousEpochAttestations() ([]*ethpb.PendingAttestation, error) { - if !b.hasInnerState() { - return nil, nil - } - if b.state.PreviousEpochAttestations == nil { + if b.previousEpochAttestations == nil { return nil, nil } b.lock.RLock() defer b.lock.RUnlock() - return b.previousEpochAttestations(), nil + return b.previousEpochAttestationsVal(), nil } -// previousEpochAttestations corresponding to blocks on the beacon chain. +// previousEpochAttestationsVal corresponding to blocks on the beacon chain. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) previousEpochAttestations() []*ethpb.PendingAttestation { - if !b.hasInnerState() { - return nil - } - - return ethpb.CopyPendingAttestationSlice(b.state.PreviousEpochAttestations) +func (b *BeaconState) previousEpochAttestationsVal() []*ethpb.PendingAttestation { + return ethpb.CopyPendingAttestationSlice(b.previousEpochAttestations) } // CurrentEpochAttestations corresponding to blocks on the beacon chain. func (b *BeaconState) CurrentEpochAttestations() ([]*ethpb.PendingAttestation, error) { - if !b.hasInnerState() { - return nil, nil - } - if b.state.CurrentEpochAttestations == nil { + if b.currentEpochAttestations == nil { return nil, nil } b.lock.RLock() defer b.lock.RUnlock() - return b.currentEpochAttestations(), nil + return b.currentEpochAttestationsVal(), nil } // currentEpochAttestations corresponding to blocks on the beacon chain. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) currentEpochAttestations() []*ethpb.PendingAttestation { - if !b.hasInnerState() { - return nil - } - - return ethpb.CopyPendingAttestationSlice(b.state.CurrentEpochAttestations) +func (b *BeaconState) currentEpochAttestationsVal() []*ethpb.PendingAttestation { + return ethpb.CopyPendingAttestationSlice(b.currentEpochAttestations) } diff --git a/beacon-chain/state/state-native/v1/getters_block.go b/beacon-chain/state/state-native/v1/getters_block.go index 64baa623cb..0fd7ce3575 100644 --- a/beacon-chain/state/state-native/v1/getters_block.go +++ b/beacon-chain/state/state-native/v1/getters_block.go @@ -1,47 +1,42 @@ package v1 import ( - "github.com/prysmaticlabs/prysm/encoding/bytesutil" + "fmt" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" ) // LatestBlockHeader stored within the beacon state. func (b *BeaconState) LatestBlockHeader() *ethpb.BeaconBlockHeader { - if !b.hasInnerState() { - return nil - } - if b.state.LatestBlockHeader == nil { + if b.latestBlockHeader == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.latestBlockHeader() + return b.latestBlockHeaderVal() } -// latestBlockHeader stored within the beacon state. +// latestBlockHeaderVal stored within the beacon state. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) latestBlockHeader() *ethpb.BeaconBlockHeader { - if !b.hasInnerState() { - return nil - } - if b.state.LatestBlockHeader == nil { +func (b *BeaconState) latestBlockHeaderVal() *ethpb.BeaconBlockHeader { + if b.latestBlockHeader == nil { return nil } hdr := ðpb.BeaconBlockHeader{ - Slot: b.state.LatestBlockHeader.Slot, - ProposerIndex: b.state.LatestBlockHeader.ProposerIndex, + Slot: b.latestBlockHeader.Slot, + ProposerIndex: b.latestBlockHeader.ProposerIndex, } - parentRoot := make([]byte, len(b.state.LatestBlockHeader.ParentRoot)) - bodyRoot := make([]byte, len(b.state.LatestBlockHeader.BodyRoot)) - stateRoot := make([]byte, len(b.state.LatestBlockHeader.StateRoot)) + parentRoot := make([]byte, len(b.latestBlockHeader.ParentRoot)) + bodyRoot := make([]byte, len(b.latestBlockHeader.BodyRoot)) + stateRoot := make([]byte, len(b.latestBlockHeader.StateRoot)) - copy(parentRoot, b.state.LatestBlockHeader.ParentRoot) - copy(bodyRoot, b.state.LatestBlockHeader.BodyRoot) - copy(stateRoot, b.state.LatestBlockHeader.StateRoot) + copy(parentRoot, b.latestBlockHeader.ParentRoot) + copy(bodyRoot, b.latestBlockHeader.BodyRoot) + copy(stateRoot, b.latestBlockHeader.StateRoot) hdr.ParentRoot = parentRoot hdr.BodyRoot = bodyRoot hdr.StateRoot = stateRoot @@ -50,50 +45,39 @@ func (b *BeaconState) latestBlockHeader() *ethpb.BeaconBlockHeader { // BlockRoots kept track of in the beacon state. func (b *BeaconState) BlockRoots() [][]byte { - if !b.hasInnerState() { - return nil - } - if b.state.BlockRoots == nil { + if b.blockRoots == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.blockRoots() -} - -// blockRoots kept track of in the beacon state. -// This assumes that a lock is already held on BeaconState. -func (b *BeaconState) blockRoots() [][]byte { - if !b.hasInnerState() { - return nil - } - return bytesutil.SafeCopy2dBytes(b.state.BlockRoots) + return b.blockRoots.Slice() } // BlockRootAtIndex retrieves a specific block root based on an // input index value. func (b *BeaconState) BlockRootAtIndex(idx uint64) ([]byte, error) { - if !b.hasInnerState() { - return nil, ErrNilInnerState - } - if b.state.BlockRoots == nil { - return nil, nil + if b.blockRoots == nil { + return []byte{}, nil } b.lock.RLock() defer b.lock.RUnlock() - return b.blockRootAtIndex(idx) + r, err := b.blockRootAtIndex(idx) + if err != nil { + return nil, err + } + return r[:], nil } // blockRootAtIndex retrieves a specific block root based on an // input index value. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) blockRootAtIndex(idx uint64) ([]byte, error) { - if !b.hasInnerState() { - return nil, ErrNilInnerState +func (b *BeaconState) blockRootAtIndex(idx uint64) ([32]byte, error) { + if uint64(len(b.blockRoots)) <= idx { + return [32]byte{}, fmt.Errorf("index %d out of range", idx) } - return bytesutil.SafeCopyRootAtIndex(b.state.BlockRoots, idx) + return b.blockRoots[idx], nil } diff --git a/beacon-chain/state/state-native/v1/getters_block_test.go b/beacon-chain/state/state-native/v1/getters_block_test.go index aee36ec9b0..4edea0c75a 100644 --- a/beacon-chain/state/state-native/v1/getters_block_test.go +++ b/beacon-chain/state/state-native/v1/getters_block_test.go @@ -3,6 +3,7 @@ package v1 import ( "testing" + fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" "github.com/prysmaticlabs/prysm/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/testing/require" @@ -29,9 +30,21 @@ func TestBeaconState_BlockRoots(t *testing.T) { s, err := InitializeFromProto(ðpb.BeaconState{}) require.NoError(t, err) got := s.BlockRoots() - require.DeepEqual(t, ([][]byte)(nil), got) + want := make([][]byte, fieldparams.BlockRootsLength) + for i := range want { + want[i] = make([]byte, 32) + } + require.DeepEqual(t, want, got) - want := [][]byte{{'a'}} + want = make([][]byte, fieldparams.BlockRootsLength) + for i := range want { + if i == 0 { + want[i] = bytesutil.PadTo([]byte{'a'}, 32) + } else { + want[i] = make([]byte, 32) + } + + } s, err = InitializeFromProto(ðpb.BeaconState{BlockRoots: want}) require.NoError(t, err) got = s.BlockRoots() @@ -47,10 +60,15 @@ func TestBeaconState_BlockRootAtIndex(t *testing.T) { require.NoError(t, err) got, err := s.BlockRootAtIndex(0) require.NoError(t, err) - require.DeepEqual(t, ([]byte)(nil), got) + require.DeepEqual(t, bytesutil.PadTo([]byte{}, 32), got) - r := [][]byte{{'a'}} - s, err = InitializeFromProto(ðpb.BeaconState{BlockRoots: r}) + r := [fieldparams.BlockRootsLength][32]byte{{'a'}} + bRoots := make([][]byte, len(r)) + for i, root := range r { + tmp := root + bRoots[i] = tmp[:] + } + s, err = InitializeFromProto(ðpb.BeaconState{BlockRoots: bRoots}) require.NoError(t, err) got, err = s.BlockRootAtIndex(0) require.NoError(t, err) diff --git a/beacon-chain/state/state-native/v1/getters_checkpoint.go b/beacon-chain/state/state-native/v1/getters_checkpoint.go index 70f6237303..c2ab62b70a 100644 --- a/beacon-chain/state/state-native/v1/getters_checkpoint.go +++ b/beacon-chain/state/state-native/v1/getters_checkpoint.go @@ -10,151 +10,115 @@ import ( // JustificationBits marking which epochs have been justified in the beacon chain. func (b *BeaconState) JustificationBits() bitfield.Bitvector4 { - if !b.hasInnerState() { - return nil - } - if b.state.JustificationBits == nil { + if b.justificationBits == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.justificationBits() + return b.justificationBitsVal() } -// justificationBits marking which epochs have been justified in the beacon chain. +// justificationBitsVal marking which epochs have been justified in the beacon chain. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) justificationBits() bitfield.Bitvector4 { - if !b.hasInnerState() { - return nil - } - if b.state.JustificationBits == nil { +func (b *BeaconState) justificationBitsVal() bitfield.Bitvector4 { + if b.justificationBits == nil { return nil } - res := make([]byte, len(b.state.JustificationBits.Bytes())) - copy(res, b.state.JustificationBits.Bytes()) + res := make([]byte, len(b.justificationBits.Bytes())) + copy(res, b.justificationBits.Bytes()) return res } // PreviousJustifiedCheckpoint denoting an epoch and block root. func (b *BeaconState) PreviousJustifiedCheckpoint() *ethpb.Checkpoint { - if !b.hasInnerState() { - return nil - } - if b.state.PreviousJustifiedCheckpoint == nil { + if b.previousJustifiedCheckpoint == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.previousJustifiedCheckpoint() + return b.previousJustifiedCheckpointVal() } -// previousJustifiedCheckpoint denoting an epoch and block root. +// previousJustifiedCheckpointVal denoting an epoch and block root. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) previousJustifiedCheckpoint() *ethpb.Checkpoint { - if !b.hasInnerState() { - return nil - } - - return ethpb.CopyCheckpoint(b.state.PreviousJustifiedCheckpoint) +func (b *BeaconState) previousJustifiedCheckpointVal() *ethpb.Checkpoint { + return ethpb.CopyCheckpoint(b.previousJustifiedCheckpoint) } // CurrentJustifiedCheckpoint denoting an epoch and block root. func (b *BeaconState) CurrentJustifiedCheckpoint() *ethpb.Checkpoint { - if !b.hasInnerState() { - return nil - } - if b.state.CurrentJustifiedCheckpoint == nil { + if b.currentJustifiedCheckpoint == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.currentJustifiedCheckpoint() + return b.currentJustifiedCheckpointVal() } -// currentJustifiedCheckpoint denoting an epoch and block root. +// currentJustifiedCheckpointVal denoting an epoch and block root. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) currentJustifiedCheckpoint() *ethpb.Checkpoint { - if !b.hasInnerState() { - return nil - } - - return ethpb.CopyCheckpoint(b.state.CurrentJustifiedCheckpoint) +func (b *BeaconState) currentJustifiedCheckpointVal() *ethpb.Checkpoint { + return ethpb.CopyCheckpoint(b.currentJustifiedCheckpoint) } // MatchCurrentJustifiedCheckpoint returns true if input justified checkpoint matches // the current justified checkpoint in state. func (b *BeaconState) MatchCurrentJustifiedCheckpoint(c *ethpb.Checkpoint) bool { - if !b.hasInnerState() { - return false - } - if b.state.CurrentJustifiedCheckpoint == nil { + if b.currentJustifiedCheckpoint == nil { return false } - if c.Epoch != b.state.CurrentJustifiedCheckpoint.Epoch { + if c.Epoch != b.currentJustifiedCheckpoint.Epoch { return false } - return bytes.Equal(c.Root, b.state.CurrentJustifiedCheckpoint.Root) + return bytes.Equal(c.Root, b.currentJustifiedCheckpoint.Root) } // MatchPreviousJustifiedCheckpoint returns true if the input justified checkpoint matches // the previous justified checkpoint in state. func (b *BeaconState) MatchPreviousJustifiedCheckpoint(c *ethpb.Checkpoint) bool { - if !b.hasInnerState() { - return false - } - if b.state.PreviousJustifiedCheckpoint == nil { + if b.previousJustifiedCheckpoint == nil { return false } - if c.Epoch != b.state.PreviousJustifiedCheckpoint.Epoch { + if c.Epoch != b.previousJustifiedCheckpoint.Epoch { return false } - return bytes.Equal(c.Root, b.state.PreviousJustifiedCheckpoint.Root) + return bytes.Equal(c.Root, b.previousJustifiedCheckpoint.Root) } // FinalizedCheckpoint denoting an epoch and block root. func (b *BeaconState) FinalizedCheckpoint() *ethpb.Checkpoint { - if !b.hasInnerState() { - return nil - } - if b.state.FinalizedCheckpoint == nil { + if b.finalizedCheckpoint == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.finalizedCheckpoint() + return b.finalizedCheckpointVal() } -// finalizedCheckpoint denoting an epoch and block root. +// finalizedCheckpointVal denoting an epoch and block root. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) finalizedCheckpoint() *ethpb.Checkpoint { - if !b.hasInnerState() { - return nil - } - - return ethpb.CopyCheckpoint(b.state.FinalizedCheckpoint) +func (b *BeaconState) finalizedCheckpointVal() *ethpb.Checkpoint { + return ethpb.CopyCheckpoint(b.finalizedCheckpoint) } // FinalizedCheckpointEpoch returns the epoch value of the finalized checkpoint. func (b *BeaconState) FinalizedCheckpointEpoch() types.Epoch { - if !b.hasInnerState() { - return 0 - } - if b.state.FinalizedCheckpoint == nil { + if b.finalizedCheckpoint == nil { return 0 } b.lock.RLock() defer b.lock.RUnlock() - return b.state.FinalizedCheckpoint.Epoch + return b.finalizedCheckpoint.Epoch } diff --git a/beacon-chain/state/state-native/v1/getters_eth1.go b/beacon-chain/state/state-native/v1/getters_eth1.go index 4f1ad84d12..35c0dea3ef 100644 --- a/beacon-chain/state/state-native/v1/getters_eth1.go +++ b/beacon-chain/state/state-native/v1/getters_eth1.go @@ -6,62 +6,50 @@ import ( // Eth1Data corresponding to the proof-of-work chain information stored in the beacon state. func (b *BeaconState) Eth1Data() *ethpb.Eth1Data { - if !b.hasInnerState() { - return nil - } - if b.state.Eth1Data == nil { + if b.eth1Data == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.eth1Data() + return b.eth1DataVal() } -// eth1Data corresponding to the proof-of-work chain information stored in the beacon state. +// eth1DataVal corresponding to the proof-of-work chain information stored in the beacon state. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) eth1Data() *ethpb.Eth1Data { - if !b.hasInnerState() { - return nil - } - if b.state.Eth1Data == nil { +func (b *BeaconState) eth1DataVal() *ethpb.Eth1Data { + if b.eth1Data == nil { return nil } - return ethpb.CopyETH1Data(b.state.Eth1Data) + return ethpb.CopyETH1Data(b.eth1Data) } // Eth1DataVotes corresponds to votes from Ethereum on the canonical proof-of-work chain // data retrieved from eth1. func (b *BeaconState) Eth1DataVotes() []*ethpb.Eth1Data { - if !b.hasInnerState() { - return nil - } - if b.state.Eth1DataVotes == nil { + if b.eth1DataVotes == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.eth1DataVotes() + return b.eth1DataVotesVal() } -// eth1DataVotes corresponds to votes from Ethereum on the canonical proof-of-work chain +// eth1DataVotesVal corresponds to votes from Ethereum on the canonical proof-of-work chain // data retrieved from eth1. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) eth1DataVotes() []*ethpb.Eth1Data { - if !b.hasInnerState() { - return nil - } - if b.state.Eth1DataVotes == nil { +func (b *BeaconState) eth1DataVotesVal() []*ethpb.Eth1Data { + if b.eth1DataVotes == nil { return nil } - res := make([]*ethpb.Eth1Data, len(b.state.Eth1DataVotes)) + res := make([]*ethpb.Eth1Data, len(b.eth1DataVotes)) for i := 0; i < len(res); i++ { - res[i] = ethpb.CopyETH1Data(b.state.Eth1DataVotes[i]) + res[i] = ethpb.CopyETH1Data(b.eth1DataVotes[i]) } return res } @@ -69,23 +57,8 @@ func (b *BeaconState) eth1DataVotes() []*ethpb.Eth1Data { // Eth1DepositIndex corresponds to the index of the deposit made to the // validator deposit contract at the time of this state's eth1 data. func (b *BeaconState) Eth1DepositIndex() uint64 { - if !b.hasInnerState() { - return 0 - } - b.lock.RLock() defer b.lock.RUnlock() - return b.eth1DepositIndex() -} - -// eth1DepositIndex corresponds to the index of the deposit made to the -// validator deposit contract at the time of this state's eth1 data. -// This assumes that a lock is already held on BeaconState. -func (b *BeaconState) eth1DepositIndex() uint64 { - if !b.hasInnerState() { - return 0 - } - - return b.state.Eth1DepositIndex + return b.eth1DepositIndex } diff --git a/beacon-chain/state/state-native/v1/getters_misc.go b/beacon-chain/state/state-native/v1/getters_misc.go index b7c9cec335..0be0a90079 100644 --- a/beacon-chain/state/state-native/v1/getters_misc.go +++ b/beacon-chain/state/state-native/v1/getters_misc.go @@ -2,62 +2,24 @@ package v1 import ( types "github.com/prysmaticlabs/eth2-types" - "github.com/prysmaticlabs/prysm/config/params" - "github.com/prysmaticlabs/prysm/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/runtime/version" ) // GenesisTime of the beacon state as a uint64. func (b *BeaconState) GenesisTime() uint64 { - if !b.hasInnerState() { - return 0 - } - b.lock.RLock() defer b.lock.RUnlock() - return b.genesisTime() -} - -// genesisTime of the beacon state as a uint64. -// This assumes that a lock is already held on BeaconState. -func (b *BeaconState) genesisTime() uint64 { - if !b.hasInnerState() { - return 0 - } - - return b.state.GenesisTime + return b.genesisTime } // GenesisValidatorRoot of the beacon state. func (b *BeaconState) GenesisValidatorRoot() []byte { - if !b.hasInnerState() { - return nil - } - if b.state.GenesisValidatorsRoot == nil { - return params.BeaconConfig().ZeroHash[:] - } - b.lock.RLock() defer b.lock.RUnlock() - return b.genesisValidatorRoot() -} - -// genesisValidatorRoot of the beacon state. -// This assumes that a lock is already held on BeaconState. -func (b *BeaconState) genesisValidatorRoot() []byte { - if !b.hasInnerState() { - return nil - } - if b.state.GenesisValidatorsRoot == nil { - return params.BeaconConfig().ZeroHash[:] - } - - root := make([]byte, 32) - copy(root, b.state.GenesisValidatorsRoot) - return root + return b.genesisValidatorsRoot[:] } // Version of the beacon state. This method @@ -69,95 +31,60 @@ func (_ *BeaconState) Version() int { // Slot of the current beacon chain state. func (b *BeaconState) Slot() types.Slot { - if !b.hasInnerState() { - return 0 - } - b.lock.RLock() defer b.lock.RUnlock() - return b.slot() -} - -// slot of the current beacon chain state. -// This assumes that a lock is already held on BeaconState. -func (b *BeaconState) slot() types.Slot { - if !b.hasInnerState() { - return 0 - } - - return b.state.Slot + return b.slot } // Fork version of the beacon chain. func (b *BeaconState) Fork() *ethpb.Fork { - if !b.hasInnerState() { - return nil - } - if b.state.Fork == nil { + if b.fork == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.fork() + return b.forkVal() } -// fork version of the beacon chain. +// forkVal version of the beacon chain. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) fork() *ethpb.Fork { - if !b.hasInnerState() { - return nil - } - if b.state.Fork == nil { +func (b *BeaconState) forkVal() *ethpb.Fork { + if b.fork == nil { return nil } - prevVersion := make([]byte, len(b.state.Fork.PreviousVersion)) - copy(prevVersion, b.state.Fork.PreviousVersion) - currVersion := make([]byte, len(b.state.Fork.CurrentVersion)) - copy(currVersion, b.state.Fork.CurrentVersion) + prevVersion := make([]byte, len(b.fork.PreviousVersion)) + copy(prevVersion, b.fork.PreviousVersion) + currVersion := make([]byte, len(b.fork.CurrentVersion)) + copy(currVersion, b.fork.CurrentVersion) return ðpb.Fork{ PreviousVersion: prevVersion, CurrentVersion: currVersion, - Epoch: b.state.Fork.Epoch, + Epoch: b.fork.Epoch, } } // HistoricalRoots based on epochs stored in the beacon state. func (b *BeaconState) HistoricalRoots() [][]byte { - if !b.hasInnerState() { - return nil - } - if b.state.HistoricalRoots == nil { + if b.historicalRoots == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.historicalRoots() -} - -// historicalRoots based on epochs stored in the beacon state. -// This assumes that a lock is already held on BeaconState. -func (b *BeaconState) historicalRoots() [][]byte { - if !b.hasInnerState() { - return nil - } - return bytesutil.SafeCopy2dBytes(b.state.HistoricalRoots) + return b.historicalRoots.Slice() } // balancesLength returns the length of the balances slice. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) balancesLength() int { - if !b.hasInnerState() { - return 0 - } - if b.state.Balances == nil { + if b.balances == nil { return 0 } - return len(b.state.Balances) + return len(b.balances) } diff --git a/beacon-chain/state/state-native/v1/getters_randao.go b/beacon-chain/state/state-native/v1/getters_randao.go index b222ceb36b..c22abceb08 100644 --- a/beacon-chain/state/state-native/v1/getters_randao.go +++ b/beacon-chain/state/state-native/v1/getters_randao.go @@ -1,67 +1,51 @@ package v1 import ( - "github.com/prysmaticlabs/prysm/encoding/bytesutil" + "fmt" ) // RandaoMixes of block proposers on the beacon chain. func (b *BeaconState) RandaoMixes() [][]byte { - if !b.hasInnerState() { - return nil - } - if b.state.RandaoMixes == nil { + if b.randaoMixes == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.randaoMixes() -} - -// randaoMixes of block proposers on the beacon chain. -// This assumes that a lock is already held on BeaconState. -func (b *BeaconState) randaoMixes() [][]byte { - if !b.hasInnerState() { - return nil - } - - return bytesutil.SafeCopy2dBytes(b.state.RandaoMixes) + return b.randaoMixes.Slice() } // RandaoMixAtIndex retrieves a specific block root based on an // input index value. func (b *BeaconState) RandaoMixAtIndex(idx uint64) ([]byte, error) { - if !b.hasInnerState() { - return nil, ErrNilInnerState - } - if b.state.RandaoMixes == nil { + if b.randaoMixes == nil { return nil, nil } b.lock.RLock() defer b.lock.RUnlock() - return b.randaoMixAtIndex(idx) + m, err := b.randaoMixAtIndex(idx) + if err != nil { + return nil, err + } + return m[:], nil } // randaoMixAtIndex retrieves a specific block root based on an // input index value. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) randaoMixAtIndex(idx uint64) ([]byte, error) { - if !b.hasInnerState() { - return nil, ErrNilInnerState +func (b *BeaconState) randaoMixAtIndex(idx uint64) ([32]byte, error) { + if uint64(len(b.randaoMixes)) <= idx { + return [32]byte{}, fmt.Errorf("index %d out of range", idx) } - - return bytesutil.SafeCopyRootAtIndex(b.state.RandaoMixes, idx) + return b.randaoMixes[idx], nil } // RandaoMixesLength returns the length of the randao mixes slice. func (b *BeaconState) RandaoMixesLength() int { - if !b.hasInnerState() { - return 0 - } - if b.state.RandaoMixes == nil { + if b.randaoMixes == nil { return 0 } @@ -74,12 +58,9 @@ func (b *BeaconState) RandaoMixesLength() int { // randaoMixesLength returns the length of the randao mixes slice. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) randaoMixesLength() int { - if !b.hasInnerState() { - return 0 - } - if b.state.RandaoMixes == nil { + if b.randaoMixes == nil { return 0 } - return len(b.state.RandaoMixes) + return len(b.randaoMixes) } diff --git a/beacon-chain/state/state-native/v1/getters_state.go b/beacon-chain/state/state-native/v1/getters_state.go index 20c435480a..4ce4e11fe1 100644 --- a/beacon-chain/state/state-native/v1/getters_state.go +++ b/beacon-chain/state/state-native/v1/getters_state.go @@ -1,115 +1,119 @@ package v1 import ( + "fmt" + "github.com/pkg/errors" - "github.com/prysmaticlabs/prysm/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" ) -// InnerStateUnsafe returns the pointer value of the underlying +// ToProtoUnsafe returns the pointer value of the underlying // beacon state proto object, bypassing immutability. Use with care. -func (b *BeaconState) InnerStateUnsafe() interface{} { +func (b *BeaconState) ToProtoUnsafe() interface{} { if b == nil { return nil } - return b.state + + gvrCopy := b.genesisValidatorsRoot + + return ðpb.BeaconState{ + GenesisTime: b.genesisTime, + GenesisValidatorsRoot: gvrCopy[:], + Slot: b.slot, + Fork: b.fork, + LatestBlockHeader: b.latestBlockHeader, + BlockRoots: b.blockRoots.Slice(), + StateRoots: b.stateRoots.Slice(), + HistoricalRoots: b.historicalRoots.Slice(), + Eth1Data: b.eth1Data, + Eth1DataVotes: b.eth1DataVotes, + Eth1DepositIndex: b.eth1DepositIndex, + Validators: b.validators, + Balances: b.balances, + RandaoMixes: b.randaoMixes.Slice(), + Slashings: b.slashings, + PreviousEpochAttestations: b.previousEpochAttestations, + CurrentEpochAttestations: b.currentEpochAttestations, + JustificationBits: b.justificationBits, + PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint, + CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint, + FinalizedCheckpoint: b.finalizedCheckpoint, + } } -// CloneInnerState the beacon state into a protobuf for usage. -func (b *BeaconState) CloneInnerState() interface{} { - if b == nil || b.state == nil { +// ToProto the beacon state into a protobuf for usage. +func (b *BeaconState) ToProto() interface{} { + if b == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return ðpb.BeaconState{ - GenesisTime: b.genesisTime(), - GenesisValidatorsRoot: b.genesisValidatorRoot(), - Slot: b.slot(), - Fork: b.fork(), - LatestBlockHeader: b.latestBlockHeader(), - BlockRoots: b.blockRoots(), - StateRoots: b.stateRoots(), - HistoricalRoots: b.historicalRoots(), - Eth1Data: b.eth1Data(), - Eth1DataVotes: b.eth1DataVotes(), - Eth1DepositIndex: b.eth1DepositIndex(), - Validators: b.validators(), - Balances: b.balances(), - RandaoMixes: b.randaoMixes(), - Slashings: b.slashings(), - PreviousEpochAttestations: b.previousEpochAttestations(), - CurrentEpochAttestations: b.currentEpochAttestations(), - JustificationBits: b.justificationBits(), - PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint(), - CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint(), - FinalizedCheckpoint: b.finalizedCheckpoint(), - } -} -// hasInnerState detects if the internal reference to the state data structure -// is populated correctly. Returns false if nil. -func (b *BeaconState) hasInnerState() bool { - return b != nil && b.state != nil + gvrCopy := b.genesisValidatorsRoot + + return ðpb.BeaconState{ + GenesisTime: b.genesisTime, + GenesisValidatorsRoot: gvrCopy[:], + Slot: b.slot, + Fork: b.forkVal(), + LatestBlockHeader: b.latestBlockHeaderVal(), + BlockRoots: b.blockRoots.Slice(), + StateRoots: b.stateRoots.Slice(), + HistoricalRoots: b.historicalRoots.Slice(), + Eth1Data: b.eth1DataVal(), + Eth1DataVotes: b.eth1DataVotesVal(), + Eth1DepositIndex: b.eth1DepositIndex, + Validators: b.validatorsVal(), + Balances: b.balancesVal(), + RandaoMixes: b.randaoMixes.Slice(), + Slashings: b.slashingsVal(), + PreviousEpochAttestations: b.previousEpochAttestationsVal(), + CurrentEpochAttestations: b.currentEpochAttestationsVal(), + JustificationBits: b.justificationBitsVal(), + PreviousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(), + CurrentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(), + FinalizedCheckpoint: b.finalizedCheckpointVal(), + } } // StateRoots kept track of in the beacon state. func (b *BeaconState) StateRoots() [][]byte { - if !b.hasInnerState() { - return nil - } - if b.state.StateRoots == nil { + if b.stateRoots == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.stateRoots() -} - -// StateRoots kept track of in the beacon state. -// This assumes that a lock is already held on BeaconState. -func (b *BeaconState) stateRoots() [][]byte { - if !b.hasInnerState() { - return nil - } - return bytesutil.SafeCopy2dBytes(b.state.StateRoots) + return b.stateRoots.Slice() } // StateRootAtIndex retrieves a specific state root based on an // input index value. func (b *BeaconState) StateRootAtIndex(idx uint64) ([]byte, error) { - if !b.hasInnerState() { - return nil, ErrNilInnerState - } - if b.state.StateRoots == nil { + if b.stateRoots == nil { return nil, nil } b.lock.RLock() defer b.lock.RUnlock() - return b.stateRootAtIndex(idx) + r, err := b.stateRootAtIndex(idx) + if err != nil { + return nil, err + } + return r[:], nil } // stateRootAtIndex retrieves a specific state root based on an // input index value. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) stateRootAtIndex(idx uint64) ([]byte, error) { - if !b.hasInnerState() { - return nil, ErrNilInnerState +func (b *BeaconState) stateRootAtIndex(idx uint64) ([32]byte, error) { + if uint64(len(b.stateRoots)) <= idx { + return [32]byte{}, fmt.Errorf("index %d out of range", idx) } - return bytesutil.SafeCopyRootAtIndex(b.state.StateRoots, idx) -} - -// MarshalSSZ marshals the underlying beacon state to bytes. -func (b *BeaconState) MarshalSSZ() ([]byte, error) { - if !b.hasInnerState() { - return nil, errors.New("nil beacon state") - } - return b.state.MarshalSSZ() + return b.stateRoots[idx], nil } // ProtobufBeaconState transforms an input into beacon state in the form of protobuf. @@ -121,3 +125,14 @@ func ProtobufBeaconState(s interface{}) (*ethpb.BeaconState, error) { } return pbState, nil } + +// InnerStateUnsafe returns the pointer value of the underlying +// beacon state proto object, bypassing immutability. Use with care. +func (b *BeaconState) InnerStateUnsafe() interface{} { + return b.ToProtoUnsafe() +} + +// CloneInnerState the beacon state into a protobuf for usage. +func (b *BeaconState) CloneInnerState() interface{} { + return b.ToProto() +} diff --git a/beacon-chain/state/state-native/v1/getters_test.go b/beacon-chain/state/state-native/v1/getters_test.go index 2de87fc41a..014db4e1aa 100644 --- a/beacon-chain/state/state-native/v1/getters_test.go +++ b/beacon-chain/state/state-native/v1/getters_test.go @@ -1,7 +1,6 @@ package v1 import ( - "runtime/debug" "sync" "testing" @@ -30,54 +29,6 @@ func TestBeaconState_SlotDataRace(t *testing.T) { wg.Wait() } -func TestNilState_NoPanic(t *testing.T) { - var st *BeaconState - defer func() { - if r := recover(); r != nil { - t.Errorf("Method panicked when it was not supposed to: %v\n%v\n", r, string(debug.Stack())) - } - }() - // retrieve elements from nil state - _ = st.GenesisTime() - _ = st.GenesisValidatorRoot() - _ = st.GenesisValidatorRoot() - _ = st.Slot() - _ = st.Fork() - _ = st.LatestBlockHeader() - _ = st.BlockRoots() - _, err := st.BlockRootAtIndex(0) - _ = err - _ = st.StateRoots() - _ = st.HistoricalRoots() - _ = st.Eth1Data() - _ = st.Eth1DataVotes() - _ = st.Eth1DepositIndex() - _, err = st.ValidatorAtIndex(0) - _ = err - _, err = st.ValidatorAtIndexReadOnly(0) - _ = err - _, _ = st.ValidatorIndexByPubkey([fieldparams.BLSPubkeyLength]byte{}) - _ = st.PubkeyAtIndex(0) - _ = st.NumValidators() - _ = st.Balances() - _, err = st.BalanceAtIndex(0) - _ = err - _ = st.BalancesLength() - _ = st.RandaoMixes() - _, err = st.RandaoMixAtIndex(0) - _ = err - _ = st.RandaoMixesLength() - _ = st.Slashings() - _, err = st.PreviousEpochAttestations() - require.NoError(t, err) - _, err = st.CurrentEpochAttestations() - require.NoError(t, err) - _ = st.JustificationBits() - _ = st.PreviousJustifiedCheckpoint() - _ = st.CurrentJustifiedCheckpoint() - _ = st.FinalizedCheckpoint() -} - func TestBeaconState_MatchCurrentJustifiedCheckpt(t *testing.T) { c1 := ðpb.Checkpoint{Epoch: 1} c2 := ðpb.Checkpoint{Epoch: 2} @@ -87,8 +38,6 @@ func TestBeaconState_MatchCurrentJustifiedCheckpt(t *testing.T) { require.Equal(t, false, beaconState.MatchCurrentJustifiedCheckpoint(c2)) require.Equal(t, false, beaconState.MatchPreviousJustifiedCheckpoint(c1)) require.Equal(t, false, beaconState.MatchPreviousJustifiedCheckpoint(c2)) - beaconState.state = nil - require.Equal(t, false, beaconState.MatchCurrentJustifiedCheckpoint(c1)) } func TestBeaconState_MatchPreviousJustifiedCheckpt(t *testing.T) { @@ -101,16 +50,6 @@ func TestBeaconState_MatchPreviousJustifiedCheckpt(t *testing.T) { require.Equal(t, false, beaconState.MatchCurrentJustifiedCheckpoint(c2)) require.Equal(t, true, beaconState.MatchPreviousJustifiedCheckpoint(c1)) require.Equal(t, false, beaconState.MatchPreviousJustifiedCheckpoint(c2)) - beaconState.state = nil - require.Equal(t, false, beaconState.MatchPreviousJustifiedCheckpoint(c1)) -} - -func TestBeaconState_MarshalSSZ_NilState(t *testing.T) { - s, err := InitializeFromProto(ðpb.BeaconState{}) - require.NoError(t, err) - s.state = nil - _, err = s.MarshalSSZ() - require.ErrorContains(t, "nil beacon state", err) } func TestBeaconState_ValidatorByPubkey(t *testing.T) { diff --git a/beacon-chain/state/state-native/v1/getters_validator.go b/beacon-chain/state/state-native/v1/getters_validator.go index 746bd20303..343b70801b 100644 --- a/beacon-chain/state/state-native/v1/getters_validator.go +++ b/beacon-chain/state/state-native/v1/getters_validator.go @@ -31,32 +31,26 @@ func (e *ValidatorIndexOutOfRangeError) Error() string { // Validators participating in consensus on the beacon chain. func (b *BeaconState) Validators() []*ethpb.Validator { - if !b.hasInnerState() { - return nil - } - if b.state.Validators == nil { + if b.validators == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.validators() + return b.validatorsVal() } -// validators participating in consensus on the beacon chain. +// validatorsVal participating in consensus on the beacon chain. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) validators() []*ethpb.Validator { - if !b.hasInnerState() { - return nil - } - if b.state.Validators == nil { +func (b *BeaconState) validatorsVal() []*ethpb.Validator { + if b.validators == nil { return nil } - res := make([]*ethpb.Validator, len(b.state.Validators)) + res := make([]*ethpb.Validator, len(b.validators)) for i := 0; i < len(res); i++ { - val := b.state.Validators[i] + val := b.validators[i] if val == nil { continue } @@ -69,16 +63,13 @@ func (b *BeaconState) validators() []*ethpb.Validator { // This assumes that a lock is already held on BeaconState. This does not // copy fully and instead just copies the reference. func (b *BeaconState) validatorsReferences() []*ethpb.Validator { - if !b.hasInnerState() { - return nil - } - if b.state.Validators == nil { + if b.validators == nil { return nil } - res := make([]*ethpb.Validator, len(b.state.Validators)) + res := make([]*ethpb.Validator, len(b.validators)) for i := 0; i < len(res); i++ { - validator := b.state.Validators[i] + validator := b.validators[i] if validator == nil { continue } @@ -90,13 +81,10 @@ func (b *BeaconState) validatorsReferences() []*ethpb.Validator { // ValidatorAtIndex is the validator at the provided index. func (b *BeaconState) ValidatorAtIndex(idx types.ValidatorIndex) (*ethpb.Validator, error) { - if !b.hasInnerState() { - return nil, ErrNilInnerState - } - if b.state.Validators == nil { + if b.validators == nil { return ðpb.Validator{}, nil } - if uint64(len(b.state.Validators)) <= uint64(idx) { + if uint64(len(b.validators)) <= uint64(idx) { e := NewValidatorIndexOutOfRangeError(idx) return nil, &e } @@ -104,20 +92,17 @@ func (b *BeaconState) ValidatorAtIndex(idx types.ValidatorIndex) (*ethpb.Validat b.lock.RLock() defer b.lock.RUnlock() - val := b.state.Validators[idx] + val := b.validators[idx] return ethpb.CopyValidator(val), nil } // ValidatorAtIndexReadOnly is the validator at the provided index. This method // doesn't clone the validator. func (b *BeaconState) ValidatorAtIndexReadOnly(idx types.ValidatorIndex) (state.ReadOnlyValidator, error) { - if !b.hasInnerState() { - return nil, ErrNilInnerState - } - if b.state.Validators == nil { + if b.validators == nil { return nil, state.ErrNilValidatorsInState } - if uint64(len(b.state.Validators)) <= uint64(idx) { + if uint64(len(b.validators)) <= uint64(idx) { e := NewValidatorIndexOutOfRangeError(idx) return nil, &e } @@ -125,7 +110,7 @@ func (b *BeaconState) ValidatorAtIndexReadOnly(idx types.ValidatorIndex) (state. b.lock.RLock() defer b.lock.RUnlock() - return NewValidator(b.state.Validators[idx]) + return NewValidator(b.validators[idx]) } // ValidatorIndexByPubkey returns a given validator by its 48-byte public key. @@ -135,7 +120,7 @@ func (b *BeaconState) ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]by } b.lock.RLock() defer b.lock.RUnlock() - numOfVals := len(b.state.Validators) + numOfVals := len(b.validators) idx, ok := b.valMapHandler.Get(key) if ok && numOfVals <= int(idx) { @@ -147,43 +132,34 @@ func (b *BeaconState) ValidatorIndexByPubkey(key [fieldparams.BLSPubkeyLength]by // PubkeyAtIndex returns the pubkey at the given // validator index. func (b *BeaconState) PubkeyAtIndex(idx types.ValidatorIndex) [fieldparams.BLSPubkeyLength]byte { - if !b.hasInnerState() { - return [fieldparams.BLSPubkeyLength]byte{} - } - if uint64(idx) >= uint64(len(b.state.Validators)) { + if uint64(idx) >= uint64(len(b.validators)) { return [fieldparams.BLSPubkeyLength]byte{} } b.lock.RLock() defer b.lock.RUnlock() - if b.state.Validators[idx] == nil { + if b.validators[idx] == nil { return [fieldparams.BLSPubkeyLength]byte{} } - return bytesutil.ToBytes48(b.state.Validators[idx].PublicKey) + return bytesutil.ToBytes48(b.validators[idx].PublicKey) } // NumValidators returns the size of the validator registry. func (b *BeaconState) NumValidators() int { - if !b.hasInnerState() { - return 0 - } b.lock.RLock() defer b.lock.RUnlock() - return len(b.state.Validators) + return len(b.validators) } // ReadFromEveryValidator reads values from every validator and applies it to the provided function. // Warning: This method is potentially unsafe, as it exposes the actual validator registry. func (b *BeaconState) ReadFromEveryValidator(f func(idx int, val state.ReadOnlyValidator) error) error { - if !b.hasInnerState() { - return ErrNilInnerState - } - if b.state.Validators == nil { + if b.validators == nil { return errors.New("nil validators in state") } b.lock.RLock() - validators := b.state.Validators + validators := b.validators b.lock.RUnlock() for i, v := range validators { @@ -200,58 +176,46 @@ func (b *BeaconState) ReadFromEveryValidator(f func(idx int, val state.ReadOnlyV // Balances of validators participating in consensus on the beacon chain. func (b *BeaconState) Balances() []uint64 { - if !b.hasInnerState() { - return nil - } - if b.state.Balances == nil { + if b.balances == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.balances() + return b.balancesVal() } // balances of validators participating in consensus on the beacon chain. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) balances() []uint64 { - if !b.hasInnerState() { - return nil - } - if b.state.Balances == nil { +func (b *BeaconState) balancesVal() []uint64 { + if b.balances == nil { return nil } - res := make([]uint64, len(b.state.Balances)) - copy(res, b.state.Balances) + res := make([]uint64, len(b.balances)) + copy(res, b.balances) return res } // BalanceAtIndex of validator with the provided index. func (b *BeaconState) BalanceAtIndex(idx types.ValidatorIndex) (uint64, error) { - if !b.hasInnerState() { - return 0, ErrNilInnerState - } - if b.state.Balances == nil { + if b.balances == nil { return 0, nil } b.lock.RLock() defer b.lock.RUnlock() - if uint64(len(b.state.Balances)) <= uint64(idx) { + if uint64(len(b.balances)) <= uint64(idx) { return 0, fmt.Errorf("index of %d does not exist", idx) } - return b.state.Balances[idx], nil + return b.balances[idx], nil } // BalancesLength returns the length of the balances slice. func (b *BeaconState) BalancesLength() int { - if !b.hasInnerState() { - return 0 - } - if b.state.Balances == nil { + if b.balances == nil { return 0 } @@ -263,30 +227,24 @@ func (b *BeaconState) BalancesLength() int { // Slashings of validators on the beacon chain. func (b *BeaconState) Slashings() []uint64 { - if !b.hasInnerState() { - return nil - } - if b.state.Slashings == nil { + if b.slashings == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() - return b.slashings() + return b.slashingsVal() } // slashings of validators on the beacon chain. // This assumes that a lock is already held on BeaconState. -func (b *BeaconState) slashings() []uint64 { - if !b.hasInnerState() { - return nil - } - if b.state.Slashings == nil { +func (b *BeaconState) slashingsVal() []uint64 { + if b.slashings == nil { return nil } - res := make([]uint64, len(b.state.Slashings)) - copy(res, b.state.Slashings) + res := make([]uint64, len(b.slashings)) + copy(res, b.slashings) return res } diff --git a/beacon-chain/state/state-native/v1/proofs.go b/beacon-chain/state/state-native/v1/proofs.go index 5a69f8bcd5..1bbf360974 100644 --- a/beacon-chain/state/state-native/v1/proofs.go +++ b/beacon-chain/state/state-native/v1/proofs.go @@ -39,7 +39,7 @@ func (b *BeaconState) FinalizedRootProof(ctx context.Context) ([][]byte, error) if err := b.recomputeDirtyFields(ctx); err != nil { return nil, err } - cpt := b.state.FinalizedCheckpoint + cpt := b.finalizedCheckpoint // The epoch field of a finalized checkpoint is the neighbor // index of the finalized root field in its Merkle tree representation // of the checkpoint. This neighbor is the first element added to the proof. diff --git a/beacon-chain/state/state-native/v1/references_test.go b/beacon-chain/state/state-native/v1/references_test.go index 6feb76de3d..5b099347a3 100644 --- a/beacon-chain/state/state-native/v1/references_test.go +++ b/beacon-chain/state/state-native/v1/references_test.go @@ -64,14 +64,14 @@ func TestStateReferenceCopy_NoUnexpectedRootsMutation(t *testing.T) { assertRefCount(t, a, stateRoots, 2) assertRefCount(t, b, blockRoots, 2) assertRefCount(t, b, stateRoots, 2) - assert.Equal(t, 1, len(b.state.GetBlockRoots()), "No block roots found") - assert.Equal(t, 1, len(b.state.GetStateRoots()), "No state roots found") + assert.Equal(t, 8192, len(b.BlockRoots()), "Wrong number of block roots found") + assert.Equal(t, 8192, len(b.StateRoots()), "Wrong number of state roots found") // Assert shared state. - blockRootsA := a.state.GetBlockRoots() - stateRootsA := a.state.GetStateRoots() - blockRootsB := b.state.GetBlockRoots() - stateRootsB := b.state.GetStateRoots() + blockRootsA := a.BlockRoots() + stateRootsA := a.StateRoots() + blockRootsB := b.BlockRoots() + stateRootsB := b.StateRoots() if len(blockRootsA) != len(blockRootsB) || len(blockRootsA) < 1 { t.Errorf("Unexpected number of block roots, want: %v", 1) } @@ -88,20 +88,20 @@ func TestStateReferenceCopy_NoUnexpectedRootsMutation(t *testing.T) { require.NoError(t, a.UpdateStateRootAtIndex(0, root2)) // Assert no shared state mutation occurred only on state a (copy on write). - assertValNotFound(t, a.state.GetBlockRoots(), root1[:]) - assertValNotFound(t, a.state.GetStateRoots(), root1[:]) - assertValFound(t, a.state.GetBlockRoots(), root2[:]) - assertValFound(t, a.state.GetStateRoots(), root2[:]) - assertValFound(t, b.state.GetBlockRoots(), root1[:]) - assertValFound(t, b.state.GetStateRoots(), root1[:]) + assertValNotFound(t, a.BlockRoots(), root1[:]) + assertValNotFound(t, a.StateRoots(), root1[:]) + assertValFound(t, a.BlockRoots(), root2[:]) + assertValFound(t, a.StateRoots(), root2[:]) + assertValFound(t, b.BlockRoots(), root1[:]) + assertValFound(t, b.StateRoots(), root1[:]) if len(blockRootsA) != len(blockRootsB) || len(blockRootsA) < 1 { t.Errorf("Unexpected number of block roots, want: %v", 1) } if len(stateRootsA) != len(stateRootsB) || len(stateRootsA) < 1 { t.Errorf("Unexpected number of state roots, want: %v", 1) } - assert.DeepEqual(t, root2[:], a.state.GetBlockRoots()[0], "Expected mutation not found") - assert.DeepEqual(t, root2[:], a.state.GetStateRoots()[0], "Expected mutation not found") + assert.DeepEqual(t, root2[:], a.BlockRoots()[0], "Expected mutation not found") + assert.DeepEqual(t, root2[:], a.StateRoots()[0], "Expected mutation not found") assert.DeepEqual(t, root1[:], blockRootsB[0], "Unexpected mutation found") assert.DeepEqual(t, root1[:], stateRootsB[0], "Unexpected mutation found") @@ -114,7 +114,7 @@ func TestStateReferenceCopy_NoUnexpectedRootsMutation(t *testing.T) { func TestStateReferenceCopy_NoUnexpectedRandaoMutation(t *testing.T) { - val1, val2 := []byte("foo"), []byte("bar") + val1, val2 := bytesutil.PadTo([]byte("foo"), 32), bytesutil.PadTo([]byte("bar"), 32) a, err := InitializeFromProtoUnsafe(ðpb.BeaconState{ RandaoMixes: [][]byte{ val1, @@ -129,11 +129,10 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation(t *testing.T) { require.Equal(t, true, ok) assertRefCount(t, a, randaoMixes, 2) assertRefCount(t, b, randaoMixes, 2) - assert.Equal(t, 1, len(b.state.GetRandaoMixes()), "No randao mixes found") // Assert shared state. - mixesA := a.state.GetRandaoMixes() - mixesB := b.state.GetRandaoMixes() + mixesA := a.RandaoMixes() + mixesB := b.RandaoMixes() if len(mixesA) != len(mixesB) || len(mixesA) < 1 { t.Errorf("Unexpected number of mix values, want: %v", 1) } @@ -147,13 +146,13 @@ func TestStateReferenceCopy_NoUnexpectedRandaoMutation(t *testing.T) { if len(mixesA) != len(mixesB) || len(mixesA) < 1 { t.Errorf("Unexpected number of mix values, want: %v", 1) } - assertValFound(t, a.state.GetRandaoMixes(), val2) - assertValNotFound(t, a.state.GetRandaoMixes(), val1) - assertValFound(t, b.state.GetRandaoMixes(), val1) - assertValNotFound(t, b.state.GetRandaoMixes(), val2) + assertValFound(t, a.RandaoMixes(), val2) + assertValNotFound(t, a.RandaoMixes(), val1) + assertValFound(t, b.RandaoMixes(), val1) + assertValNotFound(t, b.RandaoMixes(), val2) assertValFound(t, mixesB, val1) assertValNotFound(t, mixesB, val2) - assert.DeepEqual(t, val2, a.state.GetRandaoMixes()[0], "Expected mutation not found") + assert.DeepEqual(t, val2, a.RandaoMixes()[0], "Expected mutation not found") assert.DeepEqual(t, val1, mixesB[0], "Unexpected mutation found") // Copy on write happened, reference counters are reset. @@ -208,14 +207,26 @@ func TestStateReferenceCopy_NoUnexpectedAttestationsMutation(t *testing.T) { assertRefCount(t, a, currentEpochAttestations, 2) assertRefCount(t, b, previousEpochAttestations, 2) assertRefCount(t, b, currentEpochAttestations, 2) - assert.Equal(t, 1, len(b.state.GetPreviousEpochAttestations()), "Unexpected number of attestations") - assert.Equal(t, 1, len(b.state.GetCurrentEpochAttestations()), "Unexpected number of attestations") + bPrevEpochAtts, err := b.PreviousEpochAttestations() + require.NoError(t, err) + bCurrEpochAtts, err := b.CurrentEpochAttestations() + require.NoError(t, err) + assert.Equal(t, 1, len(bPrevEpochAtts), "Unexpected number of attestations") + assert.Equal(t, 1, len(bCurrEpochAtts), "Unexpected number of attestations") // Assert shared state. - curAttsA := a.state.GetCurrentEpochAttestations() - prevAttsA := a.state.GetPreviousEpochAttestations() - curAttsB := b.state.GetCurrentEpochAttestations() - prevAttsB := b.state.GetPreviousEpochAttestations() + aCurrEpochAtts, err := a.CurrentEpochAttestations() + require.NoError(t, err) + curAttsA := aCurrEpochAtts + aPrevEpochAtts, err := a.PreviousEpochAttestations() + require.NoError(t, err) + prevAttsA := aPrevEpochAtts + bCurrEpochAtts, err = b.CurrentEpochAttestations() + require.NoError(t, err) + curAttsB := bCurrEpochAtts + bPrevEpochAtts, err = b.PreviousEpochAttestations() + require.NoError(t, err) + prevAttsB := bPrevEpochAtts if len(curAttsA) != len(curAttsB) || len(curAttsA) < 1 { t.Errorf("Unexpected number of attestations, want: %v", 1) } @@ -236,52 +247,72 @@ func TestStateReferenceCopy_NoUnexpectedAttestationsMutation(t *testing.T) { preAtt, err = a.PreviousEpochAttestations() require.NoError(t, err) assert.Equal(t, 2, len(preAtt), "Unexpected number of attestations") - assertAttFound(a.state.GetCurrentEpochAttestations(), 1) - assertAttFound(a.state.GetPreviousEpochAttestations(), 1) - assertAttFound(a.state.GetCurrentEpochAttestations(), 2) - assertAttFound(a.state.GetPreviousEpochAttestations(), 2) - assertAttFound(b.state.GetCurrentEpochAttestations(), 1) - assertAttFound(b.state.GetPreviousEpochAttestations(), 1) - assertAttNotFound(b.state.GetCurrentEpochAttestations(), 2) - assertAttNotFound(b.state.GetPreviousEpochAttestations(), 2) + aCurrEpochAtts, err = a.CurrentEpochAttestations() + require.NoError(t, err) + aPrevEpochAtts, err = a.PreviousEpochAttestations() + require.NoError(t, err) + bCurrEpochAtts, err = b.CurrentEpochAttestations() + require.NoError(t, err) + bPrevEpochAtts, err = b.PreviousEpochAttestations() + require.NoError(t, err) + assertAttFound(aCurrEpochAtts, 1) + assertAttFound(aPrevEpochAtts, 1) + assertAttFound(aCurrEpochAtts, 2) + assertAttFound(aPrevEpochAtts, 2) + assertAttFound(bCurrEpochAtts, 1) + assertAttFound(bPrevEpochAtts, 1) + assertAttNotFound(bCurrEpochAtts, 2) + assertAttNotFound(bPrevEpochAtts, 2) // Mutator should only affect calling state: a. - applyToEveryAttestation := func(state *ethpb.BeaconState) { + applyToEveryAttestation := func(state *BeaconState) { // One MUST copy on write. - atts = make([]*ethpb.PendingAttestation, len(state.CurrentEpochAttestations)) - copy(atts, state.CurrentEpochAttestations) - state.CurrentEpochAttestations = atts - for i := range state.GetCurrentEpochAttestations() { - att := ethpb.CopyPendingAttestation(state.CurrentEpochAttestations[i]) + atts = make([]*ethpb.PendingAttestation, len(state.currentEpochAttestations)) + copy(atts, state.currentEpochAttestations) + state.currentEpochAttestations = atts + currEpochAtts, err := state.CurrentEpochAttestations() + require.NoError(t, err) + for i := range currEpochAtts { + att := ethpb.CopyPendingAttestation(state.currentEpochAttestations[i]) att.AggregationBits = bitfield.NewBitlist(3) - state.CurrentEpochAttestations[i] = att + state.currentEpochAttestations[i] = att } - atts = make([]*ethpb.PendingAttestation, len(state.PreviousEpochAttestations)) - copy(atts, state.PreviousEpochAttestations) - state.PreviousEpochAttestations = atts - for i := range state.GetPreviousEpochAttestations() { - att := ethpb.CopyPendingAttestation(state.PreviousEpochAttestations[i]) + atts = make([]*ethpb.PendingAttestation, len(state.previousEpochAttestations)) + copy(atts, state.previousEpochAttestations) + state.previousEpochAttestations = atts + prevEpochAtts, err := state.PreviousEpochAttestations() + require.NoError(t, err) + for i := range prevEpochAtts { + att := ethpb.CopyPendingAttestation(state.previousEpochAttestations[i]) att.AggregationBits = bitfield.NewBitlist(3) - state.PreviousEpochAttestations[i] = att + state.previousEpochAttestations[i] = att } } - applyToEveryAttestation(a.state) + applyToEveryAttestation(a) + aCurrEpochAtts, err = a.CurrentEpochAttestations() + require.NoError(t, err) + aPrevEpochAtts, err = a.PreviousEpochAttestations() + require.NoError(t, err) + bCurrEpochAtts, err = b.CurrentEpochAttestations() + require.NoError(t, err) + bPrevEpochAtts, err = b.PreviousEpochAttestations() + require.NoError(t, err) // Assert no shared state mutation occurred only on state a (copy on write). - assertAttFound(a.state.GetCurrentEpochAttestations(), 3) - assertAttFound(a.state.GetPreviousEpochAttestations(), 3) - assertAttNotFound(a.state.GetCurrentEpochAttestations(), 1) - assertAttNotFound(a.state.GetPreviousEpochAttestations(), 1) - assertAttNotFound(a.state.GetCurrentEpochAttestations(), 2) - assertAttNotFound(a.state.GetPreviousEpochAttestations(), 2) + assertAttFound(aCurrEpochAtts, 3) + assertAttFound(aPrevEpochAtts, 3) + assertAttNotFound(aCurrEpochAtts, 1) + assertAttNotFound(aPrevEpochAtts, 1) + assertAttNotFound(aCurrEpochAtts, 2) + assertAttNotFound(aPrevEpochAtts, 2) // State b must be unaffected. - assertAttNotFound(b.state.GetCurrentEpochAttestations(), 3) - assertAttNotFound(b.state.GetPreviousEpochAttestations(), 3) - assertAttFound(b.state.GetCurrentEpochAttestations(), 1) - assertAttFound(b.state.GetPreviousEpochAttestations(), 1) - assertAttNotFound(b.state.GetCurrentEpochAttestations(), 2) - assertAttNotFound(b.state.GetPreviousEpochAttestations(), 2) + assertAttNotFound(bCurrEpochAtts, 3) + assertAttNotFound(bPrevEpochAtts, 3) + assertAttFound(bCurrEpochAtts, 1) + assertAttFound(bPrevEpochAtts, 1) + assertAttNotFound(bCurrEpochAtts, 2) + assertAttNotFound(bPrevEpochAtts, 2) // Copy on write happened, reference counters are reset. assertRefCount(t, a, currentEpochAttestations, 1) @@ -310,7 +341,7 @@ func TestValidatorReferences_RemainsConsistent(t *testing.T) { // Update First Validator. assert.NoError(t, a.UpdateValidatorAtIndex(0, ðpb.Validator{PublicKey: []byte{'Z'}})) - assert.DeepNotEqual(t, a.state.Validators[0], b.state.Validators[0], "validators are equal when they are supposed to be different") + assert.DeepNotEqual(t, a.Validators()[0], b.Validators()[0], "validators are equal when they are supposed to be different") // Modify all validators from copied state. assert.NoError(t, b.ApplyToEveryValidator(func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error) { return true, ðpb.Validator{PublicKey: []byte{'V'}}, nil diff --git a/beacon-chain/state/state-native/v1/setters_attestation.go b/beacon-chain/state/state-native/v1/setters_attestation.go index 7b3fd41e53..45d36b7167 100644 --- a/beacon-chain/state/state-native/v1/setters_attestation.go +++ b/beacon-chain/state/state-native/v1/setters_attestation.go @@ -11,13 +11,10 @@ import ( // RotateAttestations sets the previous epoch attestations to the current epoch attestations and // then clears the current epoch attestations. func (b *BeaconState) RotateAttestations() error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.setPreviousEpochAttestations(b.currentEpochAttestations()) + b.setPreviousEpochAttestations(b.currentEpochAttestationsVal()) b.setCurrentEpochAttestations([]*ethpb.PendingAttestation{}) return nil } @@ -26,7 +23,7 @@ func (b *BeaconState) setPreviousEpochAttestations(val []*ethpb.PendingAttestati b.sharedFieldReferences[previousEpochAttestations].MinusRef() b.sharedFieldReferences[previousEpochAttestations] = stateutil.NewRef(1) - b.state.PreviousEpochAttestations = val + b.previousEpochAttestations = val b.markFieldAsDirty(previousEpochAttestations) b.rebuildTrie[previousEpochAttestations] = true } @@ -35,7 +32,7 @@ func (b *BeaconState) setCurrentEpochAttestations(val []*ethpb.PendingAttestatio b.sharedFieldReferences[currentEpochAttestations].MinusRef() b.sharedFieldReferences[currentEpochAttestations] = stateutil.NewRef(1) - b.state.CurrentEpochAttestations = val + b.currentEpochAttestations = val b.markFieldAsDirty(currentEpochAttestations) b.rebuildTrie[currentEpochAttestations] = true } @@ -43,13 +40,10 @@ func (b *BeaconState) setCurrentEpochAttestations(val []*ethpb.PendingAttestatio // AppendCurrentEpochAttestations for the beacon state. Appends the new value // to the the end of list. func (b *BeaconState) AppendCurrentEpochAttestations(val *ethpb.PendingAttestation) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - atts := b.state.CurrentEpochAttestations + atts := b.currentEpochAttestations max := uint64(fieldparams.CurrentEpochAttestationsLength) if uint64(len(atts)) >= max { return fmt.Errorf("current pending attestation exceeds max length %d", max) @@ -57,42 +51,39 @@ func (b *BeaconState) AppendCurrentEpochAttestations(val *ethpb.PendingAttestati if b.sharedFieldReferences[currentEpochAttestations].Refs() > 1 { // Copy elements in underlying array by reference. - atts = make([]*ethpb.PendingAttestation, len(b.state.CurrentEpochAttestations)) - copy(atts, b.state.CurrentEpochAttestations) + atts = make([]*ethpb.PendingAttestation, len(b.currentEpochAttestations)) + copy(atts, b.currentEpochAttestations) b.sharedFieldReferences[currentEpochAttestations].MinusRef() b.sharedFieldReferences[currentEpochAttestations] = stateutil.NewRef(1) } - b.state.CurrentEpochAttestations = append(atts, val) + b.currentEpochAttestations = append(atts, val) b.markFieldAsDirty(currentEpochAttestations) - b.addDirtyIndices(currentEpochAttestations, []uint64{uint64(len(b.state.CurrentEpochAttestations) - 1)}) + b.addDirtyIndices(currentEpochAttestations, []uint64{uint64(len(b.currentEpochAttestations) - 1)}) return nil } // AppendPreviousEpochAttestations for the beacon state. Appends the new value // to the the end of list. func (b *BeaconState) AppendPreviousEpochAttestations(val *ethpb.PendingAttestation) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - atts := b.state.PreviousEpochAttestations + atts := b.previousEpochAttestations max := uint64(fieldparams.PreviousEpochAttestationsLength) if uint64(len(atts)) >= max { return fmt.Errorf("previous pending attestation exceeds max length %d", max) } if b.sharedFieldReferences[previousEpochAttestations].Refs() > 1 { - atts = make([]*ethpb.PendingAttestation, len(b.state.PreviousEpochAttestations)) - copy(atts, b.state.PreviousEpochAttestations) + atts = make([]*ethpb.PendingAttestation, len(b.previousEpochAttestations)) + copy(atts, b.previousEpochAttestations) b.sharedFieldReferences[previousEpochAttestations].MinusRef() b.sharedFieldReferences[previousEpochAttestations] = stateutil.NewRef(1) } - b.state.PreviousEpochAttestations = append(atts, val) + b.previousEpochAttestations = append(atts, val) b.markFieldAsDirty(previousEpochAttestations) - b.addDirtyIndices(previousEpochAttestations, []uint64{uint64(len(b.state.PreviousEpochAttestations) - 1)}) + b.addDirtyIndices(previousEpochAttestations, []uint64{uint64(len(b.previousEpochAttestations) - 1)}) return nil } diff --git a/beacon-chain/state/state-native/v1/setters_attestation_test.go b/beacon-chain/state/state-native/v1/setters_attestation_test.go index 46fcd3d3e6..51984098c6 100644 --- a/beacon-chain/state/state-native/v1/setters_attestation_test.go +++ b/beacon-chain/state/state-native/v1/setters_attestation_test.go @@ -1,14 +1,10 @@ package v1 import ( - "context" "testing" types "github.com/prysmaticlabs/eth2-types" - stateTypes "github.com/prysmaticlabs/prysm/beacon-chain/state/types" - "github.com/prysmaticlabs/prysm/config/params" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" - "github.com/prysmaticlabs/prysm/testing/assert" "github.com/prysmaticlabs/prysm/testing/require" ) @@ -21,52 +17,6 @@ func TestBeaconState_RotateAttestations(t *testing.T) { require.NoError(t, err) require.NoError(t, st.RotateAttestations()) - require.Equal(t, 0, len(st.currentEpochAttestations())) - require.Equal(t, types.Slot(456), st.previousEpochAttestations()[0].Data.Slot) -} - -func TestAppendBeyondIndicesLimit(t *testing.T) { - zeroHash := params.BeaconConfig().ZeroHash - mockblockRoots := make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot) - for i := 0; i < len(mockblockRoots); i++ { - mockblockRoots[i] = zeroHash[:] - } - - mockstateRoots := make([][]byte, params.BeaconConfig().SlotsPerHistoricalRoot) - for i := 0; i < len(mockstateRoots); i++ { - mockstateRoots[i] = zeroHash[:] - } - mockrandaoMixes := make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector) - for i := 0; i < len(mockrandaoMixes); i++ { - mockrandaoMixes[i] = zeroHash[:] - } - st, err := InitializeFromProto(ðpb.BeaconState{ - Slot: 1, - CurrentEpochAttestations: []*ethpb.PendingAttestation{{Data: ðpb.AttestationData{Slot: 456}}}, - PreviousEpochAttestations: []*ethpb.PendingAttestation{{Data: ðpb.AttestationData{Slot: 123}}}, - Validators: []*ethpb.Validator{}, - Eth1Data: ðpb.Eth1Data{}, - BlockRoots: mockblockRoots, - StateRoots: mockstateRoots, - RandaoMixes: mockrandaoMixes, - }) - require.NoError(t, err) - _, err = st.HashTreeRoot(context.Background()) - require.NoError(t, err) - for i := stateTypes.FieldIndex(0); i < stateTypes.FieldIndex(params.BeaconConfig().BeaconStateFieldCount); i++ { - st.dirtyFields[i] = true - } - _, err = st.HashTreeRoot(context.Background()) - require.NoError(t, err) - for i := 0; i < 10; i++ { - assert.NoError(t, st.AppendValidator(ðpb.Validator{})) - } - assert.Equal(t, false, st.rebuildTrie[validators]) - assert.NotEqual(t, len(st.dirtyIndices[validators]), 0) - - for i := 0; i < indicesLimit; i++ { - assert.NoError(t, st.AppendValidator(ðpb.Validator{})) - } - assert.Equal(t, true, st.rebuildTrie[validators]) - assert.Equal(t, len(st.dirtyIndices[validators]), 0) + require.Equal(t, 0, len(st.currentEpochAttestationsVal())) + require.Equal(t, types.Slot(456), st.previousEpochAttestationsVal()[0].Data.Slot) } diff --git a/beacon-chain/state/state-native/v1/setters_block.go b/beacon-chain/state/state-native/v1/setters_block.go index 78195cc372..f76c2b7825 100644 --- a/beacon-chain/state/state-native/v1/setters_block.go +++ b/beacon-chain/state/state-native/v1/setters_block.go @@ -3,19 +3,18 @@ package v1 import ( "fmt" + customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types" "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" + fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" ) // SetLatestBlockHeader in the beacon state. func (b *BeaconState) SetLatestBlockHeader(val *ethpb.BeaconBlockHeader) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.LatestBlockHeader = ethpb.CopyBeaconBlockHeader(val) + b.latestBlockHeader = ethpb.CopyBeaconBlockHeader(val) b.markFieldAsDirty(latestBlockHeader) return nil } @@ -23,16 +22,18 @@ func (b *BeaconState) SetLatestBlockHeader(val *ethpb.BeaconBlockHeader) error { // SetBlockRoots for the beacon state. Updates the entire // list to a new value by overwriting the previous one. func (b *BeaconState) SetBlockRoots(val [][]byte) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() b.sharedFieldReferences[blockRoots].MinusRef() b.sharedFieldReferences[blockRoots] = stateutil.NewRef(1) - b.state.BlockRoots = val + var rootsArr [fieldparams.BlockRootsLength][32]byte + for i := 0; i < len(rootsArr); i++ { + copy(rootsArr[i][:], val[i]) + } + roots := customtypes.BlockRoots(rootsArr) + b.blockRoots = &roots b.markFieldAsDirty(blockRoots) b.rebuildTrie[blockRoots] = true return nil @@ -41,26 +42,24 @@ func (b *BeaconState) SetBlockRoots(val [][]byte) error { // UpdateBlockRootAtIndex for the beacon state. Updates the block root // at a specific index to a new value. func (b *BeaconState) UpdateBlockRootAtIndex(idx uint64, blockRoot [32]byte) error { - if !b.hasInnerState() { - return ErrNilInnerState - } - if uint64(len(b.state.BlockRoots)) <= idx { + if uint64(len(b.blockRoots)) <= idx { return fmt.Errorf("invalid index provided %d", idx) } b.lock.Lock() defer b.lock.Unlock() - r := b.state.BlockRoots + r := b.blockRoots if ref := b.sharedFieldReferences[blockRoots]; ref.Refs() > 1 { // Copy elements in underlying array by reference. - r = make([][]byte, len(b.state.BlockRoots)) - copy(r, b.state.BlockRoots) + roots := *b.blockRoots + rootsCopy := roots + r = &rootsCopy ref.MinusRef() b.sharedFieldReferences[blockRoots] = stateutil.NewRef(1) } - r[idx] = blockRoot[:] - b.state.BlockRoots = r + r[idx] = blockRoot + b.blockRoots = r b.markFieldAsDirty(blockRoots) b.addDirtyIndices(blockRoots, []uint64{idx}) diff --git a/beacon-chain/state/state-native/v1/setters_checkpoint.go b/beacon-chain/state/state-native/v1/setters_checkpoint.go index bf84053ee3..66730692eb 100644 --- a/beacon-chain/state/state-native/v1/setters_checkpoint.go +++ b/beacon-chain/state/state-native/v1/setters_checkpoint.go @@ -7,52 +7,40 @@ import ( // SetJustificationBits for the beacon state. func (b *BeaconState) SetJustificationBits(val bitfield.Bitvector4) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.JustificationBits = val + b.justificationBits = val b.markFieldAsDirty(justificationBits) return nil } // SetPreviousJustifiedCheckpoint for the beacon state. func (b *BeaconState) SetPreviousJustifiedCheckpoint(val *ethpb.Checkpoint) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.PreviousJustifiedCheckpoint = val + b.previousJustifiedCheckpoint = val b.markFieldAsDirty(previousJustifiedCheckpoint) return nil } // SetCurrentJustifiedCheckpoint for the beacon state. func (b *BeaconState) SetCurrentJustifiedCheckpoint(val *ethpb.Checkpoint) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.CurrentJustifiedCheckpoint = val + b.currentJustifiedCheckpoint = val b.markFieldAsDirty(currentJustifiedCheckpoint) return nil } // SetFinalizedCheckpoint for the beacon state. func (b *BeaconState) SetFinalizedCheckpoint(val *ethpb.Checkpoint) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.FinalizedCheckpoint = val + b.finalizedCheckpoint = val b.markFieldAsDirty(finalizedCheckpoint) return nil } diff --git a/beacon-chain/state/state-native/v1/setters_eth1.go b/beacon-chain/state/state-native/v1/setters_eth1.go index 53a5683668..ce3d6af567 100644 --- a/beacon-chain/state/state-native/v1/setters_eth1.go +++ b/beacon-chain/state/state-native/v1/setters_eth1.go @@ -7,13 +7,10 @@ import ( // SetEth1Data for the beacon state. func (b *BeaconState) SetEth1Data(val *ethpb.Eth1Data) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.Eth1Data = val + b.eth1Data = val b.markFieldAsDirty(eth1Data) return nil } @@ -21,16 +18,13 @@ func (b *BeaconState) SetEth1Data(val *ethpb.Eth1Data) error { // SetEth1DataVotes for the beacon state. Updates the entire // list to a new value by overwriting the previous one. func (b *BeaconState) SetEth1DataVotes(val []*ethpb.Eth1Data) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() b.sharedFieldReferences[eth1DataVotes].MinusRef() b.sharedFieldReferences[eth1DataVotes] = stateutil.NewRef(1) - b.state.Eth1DataVotes = val + b.eth1DataVotes = val b.markFieldAsDirty(eth1DataVotes) b.rebuildTrie[eth1DataVotes] = true return nil @@ -38,13 +32,10 @@ func (b *BeaconState) SetEth1DataVotes(val []*ethpb.Eth1Data) error { // SetEth1DepositIndex for the beacon state. func (b *BeaconState) SetEth1DepositIndex(val uint64) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.Eth1DepositIndex = val + b.eth1DepositIndex = val b.markFieldAsDirty(eth1DepositIndex) return nil } @@ -52,23 +43,20 @@ func (b *BeaconState) SetEth1DepositIndex(val uint64) error { // AppendEth1DataVotes for the beacon state. Appends the new value // to the the end of list. func (b *BeaconState) AppendEth1DataVotes(val *ethpb.Eth1Data) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - votes := b.state.Eth1DataVotes + votes := b.eth1DataVotes if b.sharedFieldReferences[eth1DataVotes].Refs() > 1 { // Copy elements in underlying array by reference. - votes = make([]*ethpb.Eth1Data, len(b.state.Eth1DataVotes)) - copy(votes, b.state.Eth1DataVotes) + votes = make([]*ethpb.Eth1Data, len(b.eth1DataVotes)) + copy(votes, b.eth1DataVotes) b.sharedFieldReferences[eth1DataVotes].MinusRef() b.sharedFieldReferences[eth1DataVotes] = stateutil.NewRef(1) } - b.state.Eth1DataVotes = append(votes, val) + b.eth1DataVotes = append(votes, val) b.markFieldAsDirty(eth1DataVotes) - b.addDirtyIndices(eth1DataVotes, []uint64{uint64(len(b.state.Eth1DataVotes) - 1)}) + b.addDirtyIndices(eth1DataVotes, []uint64{uint64(len(b.eth1DataVotes) - 1)}) return nil } diff --git a/beacon-chain/state/state-native/v1/setters_misc.go b/beacon-chain/state/state-native/v1/setters_misc.go index e6b89626b3..8331f84876 100644 --- a/beacon-chain/state/state-native/v1/setters_misc.go +++ b/beacon-chain/state/state-native/v1/setters_misc.go @@ -6,7 +6,9 @@ import ( "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" stateTypes "github.com/prysmaticlabs/prysm/beacon-chain/state/types" "github.com/prysmaticlabs/prysm/config/features" + fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" "github.com/prysmaticlabs/prysm/crypto/hash" + "github.com/prysmaticlabs/prysm/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" "google.golang.org/protobuf/proto" ) @@ -44,7 +46,7 @@ func (b *BeaconState) SetGenesisTime(val uint64) error { b.lock.Lock() defer b.lock.Unlock() - b.state.GenesisTime = val + b.genesisTime = val b.markFieldAsDirty(genesisTime) return nil } @@ -54,29 +56,26 @@ func (b *BeaconState) SetGenesisValidatorRoot(val []byte) error { b.lock.Lock() defer b.lock.Unlock() - b.state.GenesisValidatorsRoot = val + if len(val) != fieldparams.RootLength { + return errors.New("incorrect validator root length") + } + b.genesisValidatorsRoot = bytesutil.ToBytes32(val) b.markFieldAsDirty(genesisValidatorRoot) return nil } // SetSlot for the beacon state. func (b *BeaconState) SetSlot(val types.Slot) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.Slot = val + b.slot = val b.markFieldAsDirty(slot) return nil } // SetFork version for the beacon chain. func (b *BeaconState) SetFork(val *ethpb.Fork) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() @@ -84,7 +83,7 @@ func (b *BeaconState) SetFork(val *ethpb.Fork) error { if !ok { return errors.New("proto.Clone did not return a fork proto") } - b.state.Fork = fk + b.fork = fk b.markFieldAsDirty(fork) return nil } @@ -92,16 +91,17 @@ func (b *BeaconState) SetFork(val *ethpb.Fork) error { // SetHistoricalRoots for the beacon state. Updates the entire // list to a new value by overwriting the previous one. func (b *BeaconState) SetHistoricalRoots(val [][]byte) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() b.sharedFieldReferences[historicalRoots].MinusRef() b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1) - b.state.HistoricalRoots = val + roots := make([][32]byte, len(val)) + for i, r := range val { + copy(roots[i][:], r) + } + b.historicalRoots = roots b.markFieldAsDirty(historicalRoots) return nil } @@ -109,21 +109,18 @@ func (b *BeaconState) SetHistoricalRoots(val [][]byte) error { // AppendHistoricalRoots for the beacon state. Appends the new value // to the the end of list. func (b *BeaconState) AppendHistoricalRoots(root [32]byte) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - roots := b.state.HistoricalRoots + roots := b.historicalRoots if b.sharedFieldReferences[historicalRoots].Refs() > 1 { - roots = make([][]byte, len(b.state.HistoricalRoots)) - copy(roots, b.state.HistoricalRoots) + roots = make([][32]byte, len(b.historicalRoots)) + copy(roots, b.historicalRoots) b.sharedFieldReferences[historicalRoots].MinusRef() b.sharedFieldReferences[historicalRoots] = stateutil.NewRef(1) } - b.state.HistoricalRoots = append(roots, root[:]) + b.historicalRoots = append(roots, root) b.markFieldAsDirty(historicalRoots) return nil } diff --git a/beacon-chain/state/state-native/v1/setters_randao.go b/beacon-chain/state/state-native/v1/setters_randao.go index 1f1f337b17..12f5112d36 100644 --- a/beacon-chain/state/state-native/v1/setters_randao.go +++ b/beacon-chain/state/state-native/v1/setters_randao.go @@ -2,22 +2,27 @@ package v1 import ( "github.com/pkg/errors" + customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types" "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" + fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" + "github.com/prysmaticlabs/prysm/encoding/bytesutil" ) // SetRandaoMixes for the beacon state. Updates the entire // randao mixes to a new value by overwriting the previous one. func (b *BeaconState) SetRandaoMixes(val [][]byte) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() b.sharedFieldReferences[randaoMixes].MinusRef() b.sharedFieldReferences[randaoMixes] = stateutil.NewRef(1) - b.state.RandaoMixes = val + var mixesArr [fieldparams.RandaoMixesLength][32]byte + for i := 0; i < len(mixesArr); i++ { + copy(mixesArr[i][:], val[i]) + } + mixes := customtypes.RandaoMixes(mixesArr) + b.randaoMixes = &mixes b.markFieldAsDirty(randaoMixes) b.rebuildTrie[randaoMixes] = true return nil @@ -26,26 +31,24 @@ func (b *BeaconState) SetRandaoMixes(val [][]byte) error { // UpdateRandaoMixesAtIndex for the beacon state. Updates the randao mixes // at a specific index to a new value. func (b *BeaconState) UpdateRandaoMixesAtIndex(idx uint64, val []byte) error { - if !b.hasInnerState() { - return ErrNilInnerState - } - if uint64(len(b.state.RandaoMixes)) <= idx { + if uint64(len(b.randaoMixes)) <= idx { return errors.Errorf("invalid index provided %d", idx) } b.lock.Lock() defer b.lock.Unlock() - mixes := b.state.RandaoMixes + mixes := b.randaoMixes if refs := b.sharedFieldReferences[randaoMixes].Refs(); refs > 1 { // Copy elements in underlying array by reference. - mixes = make([][]byte, len(b.state.RandaoMixes)) - copy(mixes, b.state.RandaoMixes) + m := *b.randaoMixes + mCopy := m + mixes = &mCopy b.sharedFieldReferences[randaoMixes].MinusRef() b.sharedFieldReferences[randaoMixes] = stateutil.NewRef(1) } - mixes[idx] = val - b.state.RandaoMixes = mixes + mixes[idx] = bytesutil.ToBytes32(val) + b.randaoMixes = mixes b.markFieldAsDirty(randaoMixes) b.addDirtyIndices(randaoMixes, []uint64{idx}) diff --git a/beacon-chain/state/state-native/v1/setters_state.go b/beacon-chain/state/state-native/v1/setters_state.go index 1a7d93fad7..b30803957b 100644 --- a/beacon-chain/state/state-native/v1/setters_state.go +++ b/beacon-chain/state/state-native/v1/setters_state.go @@ -2,22 +2,26 @@ package v1 import ( "github.com/pkg/errors" + customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types" "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" + fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" ) // SetStateRoots for the beacon state. Updates the state roots // to a new value by overwriting the previous value. func (b *BeaconState) SetStateRoots(val [][]byte) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() b.sharedFieldReferences[stateRoots].MinusRef() b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1) - b.state.StateRoots = val + var rootsArr [fieldparams.StateRootsLength][32]byte + for i := 0; i < len(rootsArr); i++ { + copy(rootsArr[i][:], val[i]) + } + roots := customtypes.StateRoots(rootsArr) + b.stateRoots = &roots b.markFieldAsDirty(stateRoots) b.rebuildTrie[stateRoots] = true return nil @@ -26,12 +30,8 @@ func (b *BeaconState) SetStateRoots(val [][]byte) error { // UpdateStateRootAtIndex for the beacon state. Updates the state root // at a specific index to a new value. func (b *BeaconState) UpdateStateRootAtIndex(idx uint64, stateRoot [32]byte) error { - if !b.hasInnerState() { - return ErrNilInnerState - } - b.lock.RLock() - if uint64(len(b.state.StateRoots)) <= idx { + if uint64(len(b.stateRoots)) <= idx { b.lock.RUnlock() return errors.Errorf("invalid index provided %d", idx) } @@ -41,17 +41,18 @@ func (b *BeaconState) UpdateStateRootAtIndex(idx uint64, stateRoot [32]byte) err defer b.lock.Unlock() // Check if we hold the only reference to the shared state roots slice. - r := b.state.StateRoots + r := b.stateRoots if ref := b.sharedFieldReferences[stateRoots]; ref.Refs() > 1 { // Copy elements in underlying array by reference. - r = make([][]byte, len(b.state.StateRoots)) - copy(r, b.state.StateRoots) + roots := *b.stateRoots + rootsCopy := roots + r = &rootsCopy ref.MinusRef() b.sharedFieldReferences[stateRoots] = stateutil.NewRef(1) } - r[idx] = stateRoot[:] - b.state.StateRoots = r + r[idx] = stateRoot + b.stateRoots = r b.markFieldAsDirty(stateRoots) b.addDirtyIndices(stateRoots, []uint64{idx}) diff --git a/beacon-chain/state/state-native/v1/setters_validator.go b/beacon-chain/state/state-native/v1/setters_validator.go index 598c278408..aafa0136b6 100644 --- a/beacon-chain/state/state-native/v1/setters_validator.go +++ b/beacon-chain/state/state-native/v1/setters_validator.go @@ -11,29 +11,23 @@ import ( // SetValidators for the beacon state. Updates the entire // to a new value by overwriting the previous one. func (b *BeaconState) SetValidators(val []*ethpb.Validator) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - b.state.Validators = val + b.validators = val b.sharedFieldReferences[validators].MinusRef() b.sharedFieldReferences[validators] = stateutil.NewRef(1) b.markFieldAsDirty(validators) b.rebuildTrie[validators] = true - b.valMapHandler = stateutil.NewValMapHandler(b.state.Validators) + b.valMapHandler = stateutil.NewValMapHandler(b.validators) return nil } // ApplyToEveryValidator applies the provided callback function to each validator in the // validator registry. func (b *BeaconState) ApplyToEveryValidator(f func(idx int, val *ethpb.Validator) (bool, *ethpb.Validator, error)) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() - v := b.state.Validators + v := b.validators if ref := b.sharedFieldReferences[validators]; ref.Refs() > 1 { v = b.validatorsReferences() ref.MinusRef() @@ -55,7 +49,7 @@ func (b *BeaconState) ApplyToEveryValidator(f func(idx int, val *ethpb.Validator b.lock.Lock() defer b.lock.Unlock() - b.state.Validators = v + b.validators = v b.markFieldAsDirty(validators) b.addDirtyIndices(validators, changedVals) @@ -65,16 +59,13 @@ func (b *BeaconState) ApplyToEveryValidator(f func(idx int, val *ethpb.Validator // UpdateValidatorAtIndex for the beacon state. Updates the validator // at a specific index to a new value. func (b *BeaconState) UpdateValidatorAtIndex(idx types.ValidatorIndex, val *ethpb.Validator) error { - if !b.hasInnerState() { - return ErrNilInnerState - } - if uint64(len(b.state.Validators)) <= uint64(idx) { + if uint64(len(b.validators)) <= uint64(idx) { return errors.Errorf("invalid index provided %d", idx) } b.lock.Lock() defer b.lock.Unlock() - v := b.state.Validators + v := b.validators if ref := b.sharedFieldReferences[validators]; ref.Refs() > 1 { v = b.validatorsReferences() ref.MinusRef() @@ -82,7 +73,7 @@ func (b *BeaconState) UpdateValidatorAtIndex(idx types.ValidatorIndex, val *ethp } v[idx] = val - b.state.Validators = v + b.validators = v b.markFieldAsDirty(validators) b.addDirtyIndices(validators, []uint64{uint64(idx)}) @@ -92,16 +83,13 @@ func (b *BeaconState) UpdateValidatorAtIndex(idx types.ValidatorIndex, val *ethp // SetBalances for the beacon state. Updates the entire // list to a new value by overwriting the previous one. func (b *BeaconState) SetBalances(val []uint64) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() b.sharedFieldReferences[balances].MinusRef() b.sharedFieldReferences[balances] = stateutil.NewRef(1) - b.state.Balances = val + b.balances = val b.markFieldAsDirty(balances) b.rebuildTrie[balances] = true return nil @@ -110,24 +98,21 @@ func (b *BeaconState) SetBalances(val []uint64) error { // UpdateBalancesAtIndex for the beacon state. This method updates the balance // at a specific index to a new value. func (b *BeaconState) UpdateBalancesAtIndex(idx types.ValidatorIndex, val uint64) error { - if !b.hasInnerState() { - return ErrNilInnerState - } - if uint64(len(b.state.Balances)) <= uint64(idx) { + if uint64(len(b.balances)) <= uint64(idx) { return errors.Errorf("invalid index provided %d", idx) } b.lock.Lock() defer b.lock.Unlock() - bals := b.state.Balances + bals := b.balances if b.sharedFieldReferences[balances].Refs() > 1 { - bals = b.balances() + bals = b.balancesVal() b.sharedFieldReferences[balances].MinusRef() b.sharedFieldReferences[balances] = stateutil.NewRef(1) } bals[idx] = val - b.state.Balances = bals + b.balances = bals b.markFieldAsDirty(balances) b.addDirtyIndices(balances, []uint64{uint64(idx)}) return nil @@ -136,16 +121,13 @@ func (b *BeaconState) UpdateBalancesAtIndex(idx types.ValidatorIndex, val uint64 // SetSlashings for the beacon state. Updates the entire // list to a new value by overwriting the previous one. func (b *BeaconState) SetSlashings(val []uint64) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() b.sharedFieldReferences[slashings].MinusRef() b.sharedFieldReferences[slashings] = stateutil.NewRef(1) - b.state.Slashings = val + b.slashings = val b.markFieldAsDirty(slashings) return nil } @@ -153,25 +135,22 @@ func (b *BeaconState) SetSlashings(val []uint64) error { // UpdateSlashingsAtIndex for the beacon state. Updates the slashings // at a specific index to a new value. func (b *BeaconState) UpdateSlashingsAtIndex(idx, val uint64) error { - if !b.hasInnerState() { - return ErrNilInnerState - } - if uint64(len(b.state.Slashings)) <= idx { + if uint64(len(b.slashings)) <= idx { return errors.Errorf("invalid index provided %d", idx) } b.lock.Lock() defer b.lock.Unlock() - s := b.state.Slashings + s := b.slashings if b.sharedFieldReferences[slashings].Refs() > 1 { - s = b.slashings() + s = b.slashingsVal() b.sharedFieldReferences[slashings].MinusRef() b.sharedFieldReferences[slashings] = stateutil.NewRef(1) } s[idx] = val - b.state.Slashings = s + b.slashings = s b.markFieldAsDirty(slashings) return nil @@ -180,13 +159,10 @@ func (b *BeaconState) UpdateSlashingsAtIndex(idx, val uint64) error { // AppendValidator for the beacon state. Appends the new value // to the the end of list. func (b *BeaconState) AppendValidator(val *ethpb.Validator) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - vals := b.state.Validators + vals := b.validators if b.sharedFieldReferences[validators].Refs() > 1 { vals = b.validatorsReferences() b.sharedFieldReferences[validators].MinusRef() @@ -194,8 +170,8 @@ func (b *BeaconState) AppendValidator(val *ethpb.Validator) error { } // append validator to slice - b.state.Validators = append(vals, val) - valIdx := types.ValidatorIndex(len(b.state.Validators) - 1) + b.validators = append(vals, val) + valIdx := types.ValidatorIndex(len(b.validators) - 1) b.valMapHandler.Set(bytesutil.ToBytes48(val.PublicKey), valIdx) @@ -207,21 +183,18 @@ func (b *BeaconState) AppendValidator(val *ethpb.Validator) error { // AppendBalance for the beacon state. Appends the new value // to the the end of list. func (b *BeaconState) AppendBalance(bal uint64) error { - if !b.hasInnerState() { - return ErrNilInnerState - } b.lock.Lock() defer b.lock.Unlock() - bals := b.state.Balances + bals := b.balances if b.sharedFieldReferences[balances].Refs() > 1 { - bals = b.balances() + bals = b.balancesVal() b.sharedFieldReferences[balances].MinusRef() b.sharedFieldReferences[balances] = stateutil.NewRef(1) } - b.state.Balances = append(bals, bal) - balIdx := len(b.state.Balances) - 1 + b.balances = append(bals, bal) + balIdx := len(b.balances) - 1 b.markFieldAsDirty(balances) b.addDirtyIndices(balances, []uint64{uint64(balIdx)}) return nil diff --git a/beacon-chain/state/state-native/v1/state_test.go b/beacon-chain/state/state-native/v1/state_test.go index 93227afd57..8d9006e683 100644 --- a/beacon-chain/state/state-native/v1/state_test.go +++ b/beacon-chain/state/state-native/v1/state_test.go @@ -101,12 +101,6 @@ func TestBeaconState_NoDeadlock(t *testing.T) { func TestStateTrie_IsNil(t *testing.T) { var emptyState *BeaconState assert.Equal(t, true, emptyState.IsNil()) - - emptyProto := &BeaconState{state: nil} - assert.Equal(t, true, emptyProto.IsNil()) - - nonNilState := &BeaconState{state: ðpb.BeaconState{}} - assert.Equal(t, false, nonNilState.IsNil()) } func TestBeaconState_AppendBalanceWithTrie(t *testing.T) { @@ -187,7 +181,7 @@ func TestBeaconState_AppendBalanceWithTrie(t *testing.T) { _, err = st.HashTreeRoot(context.Background()) assert.NoError(t, err) newRt := bytesutil.ToBytes32(st.merkleLayers[0][balances]) - wantedRt, err := stateutil.Uint64ListRootWithRegistryLimit(st.state.Balances) + wantedRt, err := stateutil.Uint64ListRootWithRegistryLimit(st.balances) assert.NoError(t, err) assert.Equal(t, wantedRt, newRt, "state roots are unequal") } diff --git a/beacon-chain/state/state-native/v1/state_trie.go b/beacon-chain/state/state-native/v1/state_trie.go index 587554e9eb..440659f733 100644 --- a/beacon-chain/state/state-native/v1/state_trie.go +++ b/beacon-chain/state/state-native/v1/state_trie.go @@ -6,7 +6,9 @@ import ( "sort" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/beacon-chain/state" + customtypes "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/custom-types" "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/fieldtrie" "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/beacon-chain/state/types" @@ -27,16 +29,54 @@ func InitializeFromProto(st *ethpb.BeaconState) (*BeaconState, error) { return InitializeFromProtoUnsafe(proto.Clone(st).(*ethpb.BeaconState)) } -// InitializeFromProtoUnsafe directly uses the beacon state protobuf pointer -// and sets it as the inner state of the BeaconState type. +// InitializeFromProtoUnsafe directly uses the beacon state protobuf fields +// and sets them as fields of the BeaconState type. func InitializeFromProtoUnsafe(st *ethpb.BeaconState) (*BeaconState, error) { if st == nil { return nil, errors.New("received nil state") } + var bRoots customtypes.BlockRoots + for i, r := range st.BlockRoots { + copy(bRoots[i][:], r) + } + var sRoots customtypes.StateRoots + for i, r := range st.StateRoots { + copy(sRoots[i][:], r) + } + hRoots := customtypes.HistoricalRoots(make([][32]byte, len(st.HistoricalRoots))) + for i, r := range st.HistoricalRoots { + copy(hRoots[i][:], r) + } + var mixes customtypes.RandaoMixes + for i, m := range st.RandaoMixes { + copy(mixes[i][:], m) + } + fieldCount := params.BeaconConfig().BeaconStateFieldCount b := &BeaconState{ - state: st, + genesisTime: st.GenesisTime, + genesisValidatorsRoot: bytesutil.ToBytes32(st.GenesisValidatorsRoot), + slot: st.Slot, + fork: st.Fork, + latestBlockHeader: st.LatestBlockHeader, + blockRoots: &bRoots, + stateRoots: &sRoots, + historicalRoots: hRoots, + eth1Data: st.Eth1Data, + eth1DataVotes: st.Eth1DataVotes, + eth1DepositIndex: st.Eth1DepositIndex, + validators: st.Validators, + balances: st.Balances, + randaoMixes: &mixes, + slashings: st.Slashings, + previousEpochAttestations: st.PreviousEpochAttestations, + currentEpochAttestations: st.CurrentEpochAttestations, + justificationBits: st.JustificationBits, + previousJustifiedCheckpoint: st.PreviousJustifiedCheckpoint, + currentJustifiedCheckpoint: st.CurrentJustifiedCheckpoint, + finalizedCheckpoint: st.FinalizedCheckpoint, + dirtyFields: make(map[types.FieldIndex]bool, fieldCount), dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount), stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount), @@ -74,44 +114,41 @@ func InitializeFromProtoUnsafe(st *ethpb.BeaconState) (*BeaconState, error) { // Copy returns a deep copy of the beacon state. func (b *BeaconState) Copy() state.BeaconState { - if !b.hasInnerState() { - return nil - } - b.lock.RLock() defer b.lock.RUnlock() fieldCount := params.BeaconConfig().BeaconStateFieldCount dst := &BeaconState{ - state: ðpb.BeaconState{ - // Primitive types, safe to copy. - GenesisTime: b.state.GenesisTime, - Slot: b.state.Slot, - Eth1DepositIndex: b.state.Eth1DepositIndex, + // Primitive types, safe to copy. + genesisTime: b.genesisTime, + slot: b.slot, + eth1DepositIndex: b.eth1DepositIndex, - // Large arrays, infrequently changed, constant size. - RandaoMixes: b.state.RandaoMixes, - StateRoots: b.state.StateRoots, - BlockRoots: b.state.BlockRoots, - PreviousEpochAttestations: b.state.PreviousEpochAttestations, - CurrentEpochAttestations: b.state.CurrentEpochAttestations, - Slashings: b.state.Slashings, - Eth1DataVotes: b.state.Eth1DataVotes, + // Large arrays, infrequently changed, constant size. + slashings: b.slashings, - // Large arrays, increases over time. - Validators: b.state.Validators, - Balances: b.state.Balances, - HistoricalRoots: b.state.HistoricalRoots, + // Large arrays, infrequently changed, constant size. + blockRoots: b.blockRoots, + stateRoots: b.stateRoots, + randaoMixes: b.randaoMixes, + previousEpochAttestations: b.previousEpochAttestations, + currentEpochAttestations: b.currentEpochAttestations, + eth1DataVotes: b.eth1DataVotes, + + // Large arrays, increases over time. + balances: b.balances, + historicalRoots: b.historicalRoots, + validators: b.validators, + + // Everything else, too small to be concerned about, constant size. + genesisValidatorsRoot: b.genesisValidatorsRoot, + justificationBits: b.justificationBitsVal(), + fork: b.forkVal(), + latestBlockHeader: b.latestBlockHeaderVal(), + eth1Data: b.eth1DataVal(), + previousJustifiedCheckpoint: b.previousJustifiedCheckpointVal(), + currentJustifiedCheckpoint: b.currentJustifiedCheckpointVal(), + finalizedCheckpoint: b.finalizedCheckpointVal(), - // Everything else, too small to be concerned about, constant size. - Fork: b.fork(), - LatestBlockHeader: b.latestBlockHeader(), - Eth1Data: b.eth1Data(), - JustificationBits: b.justificationBits(), - PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint(), - CurrentJustifiedCheckpoint: b.currentJustifiedCheckpoint(), - FinalizedCheckpoint: b.finalizedCheckpoint(), - GenesisValidatorsRoot: b.genesisValidatorRoot(), - }, dirtyFields: make(map[types.FieldIndex]bool, fieldCount), dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount), rebuildTrie: make(map[types.FieldIndex]bool, fieldCount), @@ -210,7 +247,11 @@ func (b *BeaconState) initializeMerkleLayers(ctx context.Context) error { if len(b.merkleLayers) > 0 { return nil } - fieldRoots, err := computeFieldRoots(ctx, b.state) + protoState, ok := b.ToProtoUnsafe().(*ethpb.BeaconState) + if !ok { + return errors.New("state is of the wrong type") + } + fieldRoots, err := computeFieldRoots(ctx, protoState) if err != nil { return err } @@ -258,7 +299,7 @@ func (b *BeaconState) FieldReferencesCount() map[string]uint64 { // IsNil checks if the state and the underlying proto // object are nil. func (b *BeaconState) IsNil() bool { - return b == nil || b.state == nil + return b == nil } func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex) ([32]byte, error) { @@ -269,46 +310,50 @@ func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex) hasher := hash.CustomSHA256Hasher() switch field { case genesisTime: - return ssz.Uint64Root(b.state.GenesisTime), nil + return ssz.Uint64Root(b.genesisTime), nil case genesisValidatorRoot: - return bytesutil.ToBytes32(b.state.GenesisValidatorsRoot), nil + return b.genesisValidatorsRoot, nil case slot: - return ssz.Uint64Root(uint64(b.state.Slot)), nil + return ssz.Uint64Root(uint64(b.slot)), nil case eth1DepositIndex: - return ssz.Uint64Root(b.state.Eth1DepositIndex), nil + return ssz.Uint64Root(b.eth1DepositIndex), nil case fork: - return ssz.ForkRoot(b.state.Fork) + return ssz.ForkRoot(b.fork) case latestBlockHeader: - return stateutil.BlockHeaderRoot(b.state.LatestBlockHeader) + return stateutil.BlockHeaderRoot(b.latestBlockHeader) case blockRoots: if b.rebuildTrie[field] { - err := b.resetFieldTrie(field, b.state.BlockRoots, fieldparams.BlockRootsLength) + err := b.resetFieldTrie(field, b.blockRoots, fieldparams.BlockRootsLength) if err != nil { return [32]byte{}, err } delete(b.rebuildTrie, field) return b.stateFieldLeaves[field].TrieRoot() } - return b.recomputeFieldTrie(blockRoots, b.state.BlockRoots) + return b.recomputeFieldTrie(blockRoots, b.blockRoots) case stateRoots: if b.rebuildTrie[field] { - err := b.resetFieldTrie(field, b.state.StateRoots, fieldparams.StateRootsLength) + err := b.resetFieldTrie(field, b.stateRoots, fieldparams.StateRootsLength) if err != nil { return [32]byte{}, err } delete(b.rebuildTrie, field) return b.stateFieldLeaves[field].TrieRoot() } - return b.recomputeFieldTrie(stateRoots, b.state.StateRoots) + return b.recomputeFieldTrie(stateRoots, b.stateRoots) case historicalRoots: - return ssz.ByteArrayRootWithLimit(b.state.HistoricalRoots, fieldparams.HistoricalRootsLength) + hRoots := make([][]byte, len(b.historicalRoots)) + for i := range hRoots { + hRoots[i] = b.historicalRoots[i][:] + } + return ssz.ByteArrayRootWithLimit(hRoots, fieldparams.HistoricalRootsLength) case eth1Data: - return stateutil.Eth1Root(hasher, b.state.Eth1Data) + return stateutil.Eth1Root(hasher, b.eth1Data) case eth1DataVotes: if b.rebuildTrie[field] { err := b.resetFieldTrie( field, - b.state.Eth1DataVotes, + b.eth1DataVotes, fieldparams.Eth1DataVotesLength, ) if err != nil { @@ -317,50 +362,50 @@ func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex) delete(b.rebuildTrie, field) return b.stateFieldLeaves[field].TrieRoot() } - return b.recomputeFieldTrie(field, b.state.Eth1DataVotes) + return b.recomputeFieldTrie(field, b.eth1DataVotes) case validators: if b.rebuildTrie[field] { - err := b.resetFieldTrie(field, b.state.Validators, fieldparams.ValidatorRegistryLimit) + err := b.resetFieldTrie(field, b.validators, fieldparams.ValidatorRegistryLimit) if err != nil { return [32]byte{}, err } delete(b.rebuildTrie, validators) return b.stateFieldLeaves[field].TrieRoot() } - return b.recomputeFieldTrie(validators, b.state.Validators) + return b.recomputeFieldTrie(validators, b.validators) case balances: if features.Get().EnableBalanceTrieComputation { if b.rebuildTrie[field] { maxBalCap := uint64(fieldparams.ValidatorRegistryLimit) elemSize := uint64(8) balLimit := (maxBalCap*elemSize + 31) / 32 - err := b.resetFieldTrie(field, b.state.Balances, balLimit) + err := b.resetFieldTrie(field, b.balances, balLimit) if err != nil { return [32]byte{}, err } delete(b.rebuildTrie, field) return b.stateFieldLeaves[field].TrieRoot() } - return b.recomputeFieldTrie(balances, b.state.Balances) + return b.recomputeFieldTrie(balances, b.balances) } - return stateutil.Uint64ListRootWithRegistryLimit(b.state.Balances) + return stateutil.Uint64ListRootWithRegistryLimit(b.balances) case randaoMixes: if b.rebuildTrie[field] { - err := b.resetFieldTrie(field, b.state.RandaoMixes, fieldparams.RandaoMixesLength) + err := b.resetFieldTrie(field, b.randaoMixes, fieldparams.RandaoMixesLength) if err != nil { return [32]byte{}, err } delete(b.rebuildTrie, field) return b.stateFieldLeaves[field].TrieRoot() } - return b.recomputeFieldTrie(randaoMixes, b.state.RandaoMixes) + return b.recomputeFieldTrie(randaoMixes, b.randaoMixes) case slashings: - return ssz.SlashingsRoot(b.state.Slashings) + return ssz.SlashingsRoot(b.slashings) case previousEpochAttestations: if b.rebuildTrie[field] { err := b.resetFieldTrie( field, - b.state.PreviousEpochAttestations, + b.previousEpochAttestations, fieldparams.PreviousEpochAttestationsLength, ) if err != nil { @@ -369,12 +414,12 @@ func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex) delete(b.rebuildTrie, field) return b.stateFieldLeaves[field].TrieRoot() } - return b.recomputeFieldTrie(field, b.state.PreviousEpochAttestations) + return b.recomputeFieldTrie(field, b.previousEpochAttestations) case currentEpochAttestations: if b.rebuildTrie[field] { err := b.resetFieldTrie( field, - b.state.CurrentEpochAttestations, + b.currentEpochAttestations, fieldparams.CurrentEpochAttestationsLength, ) if err != nil { @@ -383,15 +428,15 @@ func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex) delete(b.rebuildTrie, field) return b.stateFieldLeaves[field].TrieRoot() } - return b.recomputeFieldTrie(field, b.state.CurrentEpochAttestations) + return b.recomputeFieldTrie(field, b.currentEpochAttestations) case justificationBits: - return bytesutil.ToBytes32(b.state.JustificationBits), nil + return bytesutil.ToBytes32(b.justificationBits), nil case previousJustifiedCheckpoint: - return ssz.CheckpointRoot(hasher, b.state.PreviousJustifiedCheckpoint) + return ssz.CheckpointRoot(hasher, b.previousJustifiedCheckpoint) case currentJustifiedCheckpoint: - return ssz.CheckpointRoot(hasher, b.state.CurrentJustifiedCheckpoint) + return ssz.CheckpointRoot(hasher, b.currentJustifiedCheckpoint) case finalizedCheckpoint: - return ssz.CheckpointRoot(hasher, b.state.FinalizedCheckpoint) + return ssz.CheckpointRoot(hasher, b.finalizedCheckpoint) } return [32]byte{}, errors.New("invalid field index provided") } diff --git a/beacon-chain/state/state-native/v1/types.go b/beacon-chain/state/state-native/v1/types.go index e08e27555f..e395259950 100644 --- a/beacon-chain/state/state-native/v1/types.go +++ b/beacon-chain/state/state-native/v1/types.go @@ -1,15 +1,10 @@ package v1 import ( - "sync" - "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/beacon-chain/state" - "github.com/prysmaticlabs/prysm/beacon-chain/state/state-native/fieldtrie" - "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" "github.com/prysmaticlabs/prysm/beacon-chain/state/types" "github.com/prysmaticlabs/prysm/config/params" - ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" ) // Ensure type BeaconState below implements BeaconState interface. @@ -38,20 +33,6 @@ var fieldMap map[types.FieldIndex]types.DataType // operations can be performed on state. var ErrNilInnerState = errors.New("nil inner state") -// BeaconState defines a struct containing utilities for the Ethereum Beacon Chain state, defining -// getters and setters for its respective values and helpful functions such as HashTreeRoot(). -type BeaconState struct { - state *ethpb.BeaconState - lock sync.RWMutex - dirtyFields map[types.FieldIndex]bool - dirtyIndices map[types.FieldIndex][]uint64 - stateFieldLeaves map[types.FieldIndex]*fieldtrie.FieldTrie - rebuildTrie map[types.FieldIndex]bool - valMapHandler *stateutil.ValidatorMapHandler - merkleLayers [][][]byte - sharedFieldReferences map[types.FieldIndex]*stateutil.Reference -} - // Field Aliases for values from the types package. const ( genesisTime = types.GenesisTime diff --git a/beacon-chain/state/state-native/v1/types_test.go b/beacon-chain/state/state-native/v1/types_test.go index be72103399..80b4cc6c5d 100644 --- a/beacon-chain/state/state-native/v1/types_test.go +++ b/beacon-chain/state/state-native/v1/types_test.go @@ -20,14 +20,18 @@ import ( func TestBeaconState_ProtoBeaconStateCompatibility(t *testing.T) { params.SetupTestConfigCleanup(t) - params.OverrideBeaconConfig(params.MinimalSpecConfig()) + cfg := params.MinimalSpecConfig() + cfg.SlotsPerHistoricalRoot = fieldparams.BlockRootsLength + cfg.EpochsPerHistoricalVector = fieldparams.RandaoMixesLength + params.OverrideBeaconConfig(cfg) + ctx := context.Background() genesis := setupGenesisState(t, 64) customState, err := v1.InitializeFromProto(genesis) require.NoError(t, err) cloned, ok := proto.Clone(genesis).(*ethpb.BeaconState) assert.Equal(t, true, ok, "Object is not of type *ethpb.BeaconState") - custom := customState.CloneInnerState() + custom := customState.ToProto() assert.DeepSSZEqual(t, cloned, custom) r1, err := customState.HashTreeRoot(ctx) @@ -142,7 +146,7 @@ func BenchmarkStateClone_Manual(b *testing.B) { require.NoError(b, err) b.StartTimer() for i := 0; i < b.N; i++ { - _ = st.CloneInnerState() + _ = st.ToProto() } } @@ -226,7 +230,7 @@ func TestForkManualCopy_OK(t *testing.T) { } require.NoError(t, a.SetFork(wantedFork)) - pbState, err := v1.ProtobufBeaconState(a.InnerStateUnsafe()) + pbState, err := v1.ProtobufBeaconState(a.ToProtoUnsafe()) require.NoError(t, err) require.DeepEqual(t, pbState.Fork, wantedFork) } diff --git a/deps.bzl b/deps.bzl index 6ce3c9a323..f8e65ac1ff 100644 --- a/deps.bzl +++ b/deps.bzl @@ -846,8 +846,8 @@ def prysm_deps(): name = "com_github_ferranbt_fastssz", importpath = "github.com/ferranbt/fastssz", replace = "github.com/prysmaticlabs/fastssz", - sum = "h1:BC9nIbhpQMyFlmLUJsVv8/+UewAVIjJegtvgaP9bV/M=", - version = "v0.0.0-20211123050228-97d96f38caae", + sum = "h1:MRQwO/qZtHJFQA7M3uQBadrscFC5org7fWm8CCBRzMM=", + version = "v0.0.0-20220110145812-fafb696cae88", ) go_repository( diff --git a/encoding/bytesutil/bytes.go b/encoding/bytesutil/bytes.go index 65300258a7..efdd78aa75 100644 --- a/encoding/bytesutil/bytes.go +++ b/encoding/bytesutil/bytes.go @@ -228,6 +228,16 @@ func SafeCopy2dBytes(ary [][]byte) [][]byte { return nil } +// SafeCopy2d32Bytes will copy and return a non-nil 2d byte array, otherwise it returns nil. +func SafeCopy2d32Bytes(ary [][32]byte) [][32]byte { + if ary != nil { + copied := make([][32]byte, len(ary)) + copy(copied, ary) + return copied + } + return nil +} + // ReverseBytes32Slice will reverse the provided slice's order. func ReverseBytes32Slice(arr [][32]byte) [][32]byte { for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 { diff --git a/encoding/bytesutil/bytes_test.go b/encoding/bytesutil/bytes_test.go index a2cde829f2..35e8185328 100644 --- a/encoding/bytesutil/bytes_test.go +++ b/encoding/bytesutil/bytes_test.go @@ -507,3 +507,12 @@ func TestReverseByteOrder(t *testing.T) { assert.Equal(t, bytes.Equal(input, []byte{0, 1, 2, 3, 4, 5}), true) assert.Equal(t, bytes.Equal(expectedResult, output), true) } + +func TestSafeCopy2d32Bytes(t *testing.T) { + input := make([][32]byte, 2) + input[0] = bytesutil.ToBytes32([]byte{'a'}) + input[1] = bytesutil.ToBytes32([]byte{'b'}) + output := bytesutil.SafeCopy2d32Bytes(input) + assert.Equal(t, false, &input == &output, "No copy was made") + assert.DeepEqual(t, input, output) +} diff --git a/go.mod b/go.mod index 33fa40a25c..03b4733bbd 100644 --- a/go.mod +++ b/go.mod @@ -117,4 +117,4 @@ replace github.com/json-iterator/go => github.com/prestonvanloon/go v1.1.7-0.201 // See https://github.com/prysmaticlabs/grpc-gateway/issues/2 replace github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1 -replace github.com/ferranbt/fastssz => github.com/prysmaticlabs/fastssz v0.0.0-20211123050228-97d96f38caae +replace github.com/ferranbt/fastssz => github.com/prysmaticlabs/fastssz v0.0.0-20220110145812-fafb696cae88 diff --git a/go.sum b/go.sum index f4846e9006..c269168850 100644 --- a/go.sum +++ b/go.sum @@ -1106,8 +1106,8 @@ github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38i github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d h1:1dN7YAqMN3oAJ0LceWcyv/U4jHLh+5urnSnr4br6zg4= github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d/go.mod h1:kOmQ/zdobQf7HUohDTifDNFEZfNaSCIY5fkONPL+dWU= -github.com/prysmaticlabs/fastssz v0.0.0-20211123050228-97d96f38caae h1:BC9nIbhpQMyFlmLUJsVv8/+UewAVIjJegtvgaP9bV/M= -github.com/prysmaticlabs/fastssz v0.0.0-20211123050228-97d96f38caae/go.mod h1:S8yiDeAXy8f88W4Ul+0dBMPx49S05byYbmZD6Uv94K4= +github.com/prysmaticlabs/fastssz v0.0.0-20220110145812-fafb696cae88 h1:MRQwO/qZtHJFQA7M3uQBadrscFC5org7fWm8CCBRzMM= +github.com/prysmaticlabs/fastssz v0.0.0-20220110145812-fafb696cae88/go.mod h1:ASoCYXOqVPSr7KRfiBbbAOxyOwRBfl9gpwTvEKqbnkc= github.com/prysmaticlabs/go-bitfield v0.0.0-20210108222456-8e92c3709aa0/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= diff --git a/hack/update-go-ssz.sh b/hack/update-go-ssz.sh index dcfa6776d3..a611142bb3 100755 --- a/hack/update-go-ssz.sh +++ b/hack/update-go-ssz.sh @@ -4,7 +4,7 @@ # Script to copy ssz.go files from bazel build folder to appropriate location. # Bazel builds to bazel-bin/... folder, script copies them back to original folder where target is. -bazel query 'kind(ssz_gen_marshal, //proto/...)' | xargs bazel build +bazel query 'kind(ssz_gen_marshal, //proto/...) union kind(ssz_gen_marshal, //beacon-chain/state/...)' | xargs bazel build # Get locations of proto ssz.go files. file_list=() diff --git a/nogo_config.json b/nogo_config.json index 0e8c5a0c3c..475f9b7781 100644 --- a/nogo_config.json +++ b/nogo_config.json @@ -147,6 +147,7 @@ "validator/.*": "" }, "exclude_files": { + "beacon-chain/state/state-native/v1/generated.ssz.go": "Exclude generated SSZ file" } }, "properpermissions": {