From e2e96fcc9fff37a8d8fabb34435494042417da9b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 16 May 2023 19:31:05 +0200 Subject: [PATCH 1/8] detached validator metadata codec --- vms/platformvm/state/validator_metadata.go | 33 ++++++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/vms/platformvm/state/validator_metadata.go b/vms/platformvm/state/validator_metadata.go index a14b9331f0c1..46aa8ea03893 100644 --- a/vms/platformvm/state/validator_metadata.go +++ b/vms/platformvm/state/validator_metadata.go @@ -4,14 +4,16 @@ package state import ( + "math" "time" + "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/avalanchego/vms/platformvm/genesis" "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) @@ -19,9 +21,26 @@ import ( // [preDelegateeRewardMetadata]. // // CodecVersionLen + UpDurationLen + LastUpdatedLen + PotentialRewardLen -const preDelegateeRewardSize = wrappers.ShortLen + 3*wrappers.LongLen +const ( + preDelegateeRewardSize = wrappers.ShortLen + 3*wrappers.LongLen + validatorMetadataCodecV0 = uint16(0) +) + +var ( + _ validatorState = (*metadata)(nil) -var _ validatorState = (*metadata)(nil) + validatorMetadataCodec codec.Manager +) + +func init() { + c := linearcodec.NewDefault() + validatorMetadataCodec = codec.NewManager(math.MaxInt32) + + err := validatorMetadataCodec.RegisterCodec(validatorMetadataCodecV0, c) + if err != nil { + panic(err) + } +} type preDelegateeRewardMetadata struct { UpDuration time.Duration `serialize:"true"` @@ -60,7 +79,8 @@ func parseValidatorMetadata(bytes []byte, metadata *validatorMetadata) error { // potential reward and uptime was stored but potential delegatee reward // was not tmp := preDelegateeRewardMetadata{} - if _, err := txs.Codec.Unmarshal(bytes, &tmp); err != nil { + _, err := validatorMetadataCodec.Unmarshal(bytes, &tmp) + if err != nil { return err } @@ -69,7 +89,8 @@ func parseValidatorMetadata(bytes []byte, metadata *validatorMetadata) error { metadata.PotentialReward = tmp.PotentialReward default: // everything was stored - if _, err := txs.Codec.Unmarshal(bytes, metadata); err != nil { + _, err := validatorMetadataCodec.Unmarshal(bytes, metadata) + if err != nil { return err } } @@ -238,7 +259,7 @@ func (m *metadata) WriteValidatorMetadata( metadata := m.metadata[vdrID][subnetID] metadata.LastUpdated = uint64(metadata.lastUpdated.Unix()) - metadataBytes, err := genesis.Codec.Marshal(txs.Version, metadata) + metadataBytes, err := validatorMetadataCodec.Marshal(txs.Version, metadata) if err != nil { return err } From 7b371af57b33e3f9264c3c99b077ec550c1044ca Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 16 May 2023 20:33:49 +0200 Subject: [PATCH 2/8] nits and fixes --- api/keystore/codec.go | 2 +- codec/linearcodec/codec.go | 4 ++-- codec/linearcodec/codec_test.go | 2 +- vms/platformvm/state/state.go | 2 +- vms/platformvm/state/validator_metadata.go | 23 +++++++++++----------- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/api/keystore/codec.go b/api/keystore/codec.go index df6c18ae9521..ebb196ccbfff 100644 --- a/api/keystore/codec.go +++ b/api/keystore/codec.go @@ -11,7 +11,7 @@ import ( const ( maxPackerSize = 1 * units.GiB // max size, in bytes, of something being marshalled by Marshal() - maxSliceLength = 256 * 1024 + maxSliceLength = linearcodec.DefaultMaxSliceLength codecVersion = 0 ) diff --git a/codec/linearcodec/codec.go b/codec/linearcodec/codec.go index d488b3a1d4c0..677c331b0366 100644 --- a/codec/linearcodec/codec.go +++ b/codec/linearcodec/codec.go @@ -15,7 +15,7 @@ import ( const ( // default max length of a slice being marshalled by Marshal(). Should be <= math.MaxUint32. - defaultMaxSliceLength = 256 * 1024 + DefaultMaxSliceLength = 256 * 1024 ) var ( @@ -56,7 +56,7 @@ func New(tagNames []string, maxSliceLen uint32) Codec { // NewDefault is a convenience constructor; it returns a new codec with reasonable default values func NewDefault() Codec { - return New([]string{reflectcodec.DefaultTagName}, defaultMaxSliceLength) + return New([]string{reflectcodec.DefaultTagName}, DefaultMaxSliceLength) } // NewCustomMaxLength is a convenience constructor; it returns a new codec with custom max length and default tags diff --git a/codec/linearcodec/codec_test.go b/codec/linearcodec/codec_test.go index 1e6b836abd37..f0ebe64f5cc8 100644 --- a/codec/linearcodec/codec_test.go +++ b/codec/linearcodec/codec_test.go @@ -18,7 +18,7 @@ func TestVectors(t *testing.T) { func TestMultipleTags(t *testing.T) { for _, test := range codec.MultipleTagsTests { - c := New([]string{"tag1", "tag2"}, defaultMaxSliceLength) + c := New([]string{"tag1", "tag2"}, DefaultMaxSliceLength) test(c, t) } } diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index ef604688e5ff..0df651df03d0 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1609,7 +1609,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error PotentialDelegateeReward: 0, } - metadataBytes, err := blocks.GenesisCodec.Marshal(blocks.Version, metadata) + metadataBytes, err := validatorMetadataCodec.Marshal(validatorMetadataCodecV0, metadata) if err != nil { return fmt.Errorf("failed to serialize current validator: %w", err) } diff --git a/vms/platformvm/state/validator_metadata.go b/vms/platformvm/state/validator_metadata.go index 46aa8ea03893..995c3dfce4de 100644 --- a/vms/platformvm/state/validator_metadata.go +++ b/vms/platformvm/state/validator_metadata.go @@ -14,7 +14,6 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) // preDelegateeRewardSize is the size of codec marshalling @@ -22,7 +21,9 @@ import ( // // CodecVersionLen + UpDurationLen + LastUpdatedLen + PotentialRewardLen const ( - preDelegateeRewardSize = wrappers.ShortLen + 3*wrappers.LongLen + preDelegateeRewardSize = wrappers.ShortLen + 3*wrappers.LongLen + + v0tag = "v0" validatorMetadataCodecV0 = uint16(0) ) @@ -33,7 +34,7 @@ var ( ) func init() { - c := linearcodec.NewDefault() + c := linearcodec.New([]string{v0tag}, linearcodec.DefaultMaxSliceLength) validatorMetadataCodec = codec.NewManager(math.MaxInt32) err := validatorMetadataCodec.RegisterCodec(validatorMetadataCodecV0, c) @@ -43,16 +44,16 @@ func init() { } type preDelegateeRewardMetadata struct { - UpDuration time.Duration `serialize:"true"` - LastUpdated uint64 `serialize:"true"` // Unix time in seconds - PotentialReward uint64 `serialize:"true"` + UpDuration time.Duration `v0:"true"` + LastUpdated uint64 `v0:"true"` // Unix time in seconds + PotentialReward uint64 `v0:"true"` } type validatorMetadata struct { - UpDuration time.Duration `serialize:"true"` - LastUpdated uint64 `serialize:"true"` // Unix time in seconds - PotentialReward uint64 `serialize:"true"` - PotentialDelegateeReward uint64 `serialize:"true"` + UpDuration time.Duration `v0:"true"` + LastUpdated uint64 `v0:"true"` // Unix time in seconds + PotentialReward uint64 `v0:"true"` + PotentialDelegateeReward uint64 `v0:"true"` txID ids.ID lastUpdated time.Time @@ -259,7 +260,7 @@ func (m *metadata) WriteValidatorMetadata( metadata := m.metadata[vdrID][subnetID] metadata.LastUpdated = uint64(metadata.lastUpdated.Unix()) - metadataBytes, err := validatorMetadataCodec.Marshal(txs.Version, metadata) + metadataBytes, err := validatorMetadataCodec.Marshal(validatorMetadataCodecV0, metadata) if err != nil { return err } From 5a7eeaa68085b851a6a72206e924f9027b32755d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 17 May 2023 12:50:21 +0200 Subject: [PATCH 3/8] nit --- vms/platformvm/state/validator_metadata.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vms/platformvm/state/validator_metadata.go b/vms/platformvm/state/validator_metadata.go index 995c3dfce4de..f812d12b0661 100644 --- a/vms/platformvm/state/validator_metadata.go +++ b/vms/platformvm/state/validator_metadata.go @@ -80,8 +80,7 @@ func parseValidatorMetadata(bytes []byte, metadata *validatorMetadata) error { // potential reward and uptime was stored but potential delegatee reward // was not tmp := preDelegateeRewardMetadata{} - _, err := validatorMetadataCodec.Unmarshal(bytes, &tmp) - if err != nil { + if _, err := validatorMetadataCodec.Unmarshal(bytes, &tmp); err != nil { return err } @@ -90,8 +89,7 @@ func parseValidatorMetadata(bytes []byte, metadata *validatorMetadata) error { metadata.PotentialReward = tmp.PotentialReward default: // everything was stored - _, err := validatorMetadataCodec.Unmarshal(bytes, metadata) - if err != nil { + if _, err := validatorMetadataCodec.Unmarshal(bytes, metadata); err != nil { return err } } From 2cfb6cc0ace23675986b3ba83ad9ff3e0eb12e78 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 16 Aug 2023 15:41:14 +0200 Subject: [PATCH 4/8] nit --- vms/platformvm/state/metadata_codec.go | 32 ++++++++++++++++++++++ vms/platformvm/state/state.go | 2 +- vms/platformvm/state/validator_metadata.go | 32 +++------------------- 3 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 vms/platformvm/state/metadata_codec.go diff --git a/vms/platformvm/state/metadata_codec.go b/vms/platformvm/state/metadata_codec.go new file mode 100644 index 000000000000..9c857ce27394 --- /dev/null +++ b/vms/platformvm/state/metadata_codec.go @@ -0,0 +1,32 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package state + +import ( + "math" + + "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/codec/linearcodec" +) + +const ( + v0tag = "v0" + v0 = uint16(0) +) + +var ( + _ validatorState = (*metadata)(nil) + + metadataCodec codec.Manager +) + +func init() { + c := linearcodec.New([]string{v0tag}, linearcodec.DefaultMaxSliceLength) + metadataCodec = codec.NewManager(math.MaxInt32) + + err := metadataCodec.RegisterCodec(v0, c) + if err != nil { + panic(err) + } +} diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 0fcf6e21702b..1e8ebb9e4477 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1951,7 +1951,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error PotentialDelegateeReward: 0, } - metadataBytes, err := validatorMetadataCodec.Marshal(validatorMetadataCodecV0, metadata) + metadataBytes, err := metadataCodec.Marshal(v0, metadata) if err != nil { return fmt.Errorf("failed to serialize current validator: %w", err) } diff --git a/vms/platformvm/state/validator_metadata.go b/vms/platformvm/state/validator_metadata.go index f812d12b0661..556d65d590b6 100644 --- a/vms/platformvm/state/validator_metadata.go +++ b/vms/platformvm/state/validator_metadata.go @@ -4,11 +4,8 @@ package state import ( - "math" "time" - "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" @@ -20,28 +17,7 @@ import ( // [preDelegateeRewardMetadata]. // // CodecVersionLen + UpDurationLen + LastUpdatedLen + PotentialRewardLen -const ( - preDelegateeRewardSize = wrappers.ShortLen + 3*wrappers.LongLen - - v0tag = "v0" - validatorMetadataCodecV0 = uint16(0) -) - -var ( - _ validatorState = (*metadata)(nil) - - validatorMetadataCodec codec.Manager -) - -func init() { - c := linearcodec.New([]string{v0tag}, linearcodec.DefaultMaxSliceLength) - validatorMetadataCodec = codec.NewManager(math.MaxInt32) - - err := validatorMetadataCodec.RegisterCodec(validatorMetadataCodecV0, c) - if err != nil { - panic(err) - } -} +const preDelegateeRewardSize = wrappers.ShortLen + 3*wrappers.LongLen type preDelegateeRewardMetadata struct { UpDuration time.Duration `v0:"true"` @@ -80,7 +56,7 @@ func parseValidatorMetadata(bytes []byte, metadata *validatorMetadata) error { // potential reward and uptime was stored but potential delegatee reward // was not tmp := preDelegateeRewardMetadata{} - if _, err := validatorMetadataCodec.Unmarshal(bytes, &tmp); err != nil { + if _, err := metadataCodec.Unmarshal(bytes, &tmp); err != nil { return err } @@ -89,7 +65,7 @@ func parseValidatorMetadata(bytes []byte, metadata *validatorMetadata) error { metadata.PotentialReward = tmp.PotentialReward default: // everything was stored - if _, err := validatorMetadataCodec.Unmarshal(bytes, metadata); err != nil { + if _, err := metadataCodec.Unmarshal(bytes, metadata); err != nil { return err } } @@ -258,7 +234,7 @@ func (m *metadata) WriteValidatorMetadata( metadata := m.metadata[vdrID][subnetID] metadata.LastUpdated = uint64(metadata.lastUpdated.Unix()) - metadataBytes, err := validatorMetadataCodec.Marshal(validatorMetadataCodecV0, metadata) + metadataBytes, err := metadataCodec.Marshal(v0, metadata) if err != nil { return err } From e049f4182885fe09bb85c9effa4acefaa7273934 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 16 Aug 2023 15:55:20 +0200 Subject: [PATCH 5/8] nit --- vms/platformvm/state/metadata_codec.go | 6 +----- vms/platformvm/state/validator_metadata.go | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/vms/platformvm/state/metadata_codec.go b/vms/platformvm/state/metadata_codec.go index 9c857ce27394..5e8dd4b333c3 100644 --- a/vms/platformvm/state/metadata_codec.go +++ b/vms/platformvm/state/metadata_codec.go @@ -15,11 +15,7 @@ const ( v0 = uint16(0) ) -var ( - _ validatorState = (*metadata)(nil) - - metadataCodec codec.Manager -) +var metadataCodec codec.Manager func init() { c := linearcodec.New([]string{v0tag}, linearcodec.DefaultMaxSliceLength) diff --git a/vms/platformvm/state/validator_metadata.go b/vms/platformvm/state/validator_metadata.go index 556d65d590b6..6b839ccad801 100644 --- a/vms/platformvm/state/validator_metadata.go +++ b/vms/platformvm/state/validator_metadata.go @@ -19,6 +19,8 @@ import ( // CodecVersionLen + UpDurationLen + LastUpdatedLen + PotentialRewardLen const preDelegateeRewardSize = wrappers.ShortLen + 3*wrappers.LongLen +var _ validatorState = (*metadata)(nil) + type preDelegateeRewardMetadata struct { UpDuration time.Duration `v0:"true"` LastUpdated uint64 `v0:"true"` // Unix time in seconds From ff63392f94ff0a6b665e1a45068c664bab034a4d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 28 Sep 2023 11:26:37 +0200 Subject: [PATCH 6/8] introduced delegator metadata --- vms/platformvm/state/metadata_delegator.go | 16 ++++++++++++++++ ...lidator_metadata.go => metadata_validator.go} | 0 ...tadata_test.go => metadata_validator_test.go} | 0 vms/platformvm/state/state.go | 6 +++--- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 vms/platformvm/state/metadata_delegator.go rename vms/platformvm/state/{validator_metadata.go => metadata_validator.go} (100%) rename vms/platformvm/state/{validator_metadata_test.go => metadata_validator_test.go} (100%) diff --git a/vms/platformvm/state/metadata_delegator.go b/vms/platformvm/state/metadata_delegator.go new file mode 100644 index 000000000000..cd60ddf1d64b --- /dev/null +++ b/vms/platformvm/state/metadata_delegator.go @@ -0,0 +1,16 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package state + +import "github.com/ava-labs/avalanchego/database" + +type delegatorMetadata struct { + PotentialReward uint64 +} + +func parseDelegatorMetadata(bytes []byte, metadata *delegatorMetadata) error { + var err error + metadata.PotentialReward, err = database.ParseUInt64(bytes) + return err +} diff --git a/vms/platformvm/state/validator_metadata.go b/vms/platformvm/state/metadata_validator.go similarity index 100% rename from vms/platformvm/state/validator_metadata.go rename to vms/platformvm/state/metadata_validator.go diff --git a/vms/platformvm/state/validator_metadata_test.go b/vms/platformvm/state/metadata_validator_test.go similarity index 100% rename from vms/platformvm/state/validator_metadata_test.go rename to vms/platformvm/state/metadata_validator_test.go diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 2c86ad8a0118..43d9a78bd4f4 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1510,8 +1510,8 @@ func (s *state) loadCurrentValidators() error { return err } - potentialRewardBytes := delegatorIt.Value() - potentialReward, err := database.ParseUInt64(potentialRewardBytes) + metadata := &delegatorMetadata{} + err = parseDelegatorMetadata(delegatorIt.Value(), metadata) if err != nil { return err } @@ -1521,7 +1521,7 @@ func (s *state) loadCurrentValidators() error { return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } - staker, err := NewCurrentStaker(txID, stakerTx, potentialReward) + staker, err := NewCurrentStaker(txID, stakerTx, metadata.PotentialReward) if err != nil { return err } From e82e82986f376238fd0ea93733c7c3e3d12487fe Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 18 Oct 2023 17:15:36 +0200 Subject: [PATCH 7/8] improved delegator metadata writing --- vms/platformvm/state/metadata_delegator.go | 11 ++++++++++- vms/platformvm/state/state.go | 10 ++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/vms/platformvm/state/metadata_delegator.go b/vms/platformvm/state/metadata_delegator.go index cd60ddf1d64b..04e7ef6a8795 100644 --- a/vms/platformvm/state/metadata_delegator.go +++ b/vms/platformvm/state/metadata_delegator.go @@ -3,10 +3,15 @@ package state -import "github.com/ava-labs/avalanchego/database" +import ( + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/ids" +) type delegatorMetadata struct { PotentialReward uint64 + + txID ids.ID } func parseDelegatorMetadata(bytes []byte, metadata *delegatorMetadata) error { @@ -14,3 +19,7 @@ func parseDelegatorMetadata(bytes []byte, metadata *delegatorMetadata) error { metadata.PotentialReward, err = database.ParseUInt64(bytes) return err } + +func writeDelegatorMetadata(db database.KeyValueWriter, metadata *delegatorMetadata) error { + return database.PutUInt64(db, metadata.txID[:], metadata.PotentialReward) +} diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 6a1b8d02bb0b..41b039d03c89 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1570,7 +1570,9 @@ func (s *state) loadCurrentValidators() error { return err } - metadata := &delegatorMetadata{} + metadata := &delegatorMetadata{ + txID: txID, + } err = parseDelegatorMetadata(delegatorIt.Value(), metadata) if err != nil { return err @@ -2177,7 +2179,11 @@ func writeCurrentDelegatorDiff( return fmt.Errorf("failed to increase node weight diff: %w", err) } - if err := database.PutUInt64(currentDelegatorList, staker.TxID[:], staker.PotentialReward); err != nil { + metadata := &delegatorMetadata{ + txID: staker.TxID, + PotentialReward: staker.PotentialReward, + } + if err := writeDelegatorMetadata(currentDelegatorList, metadata); err != nil { return fmt.Errorf("failed to write current delegator to list: %w", err) } } From a6ae416cb715b48d0c40f49ca3021f9b6c32c2b4 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sat, 21 Oct 2023 00:10:50 +0200 Subject: [PATCH 8/8] nit --- vms/platformvm/state/metadata_codec.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/state/metadata_codec.go b/vms/platformvm/state/metadata_codec.go index 5e8dd4b333c3..6240bbd879ca 100644 --- a/vms/platformvm/state/metadata_codec.go +++ b/vms/platformvm/state/metadata_codec.go @@ -18,7 +18,7 @@ const ( var metadataCodec codec.Manager func init() { - c := linearcodec.New([]string{v0tag}, linearcodec.DefaultMaxSliceLength) + c := linearcodec.New([]string{v0tag}, math.MaxInt32) metadataCodec = codec.NewManager(math.MaxInt32) err := metadataCodec.RegisterCodec(v0, c)