From c174c6230528c9d8a3ace05ee2cc47235f06532d Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 2 Nov 2023 16:20:03 -0400 Subject: [PATCH 001/267] Return log levels from admin.SetLoggerLevel (#2250) --- api/admin/client.go | 16 +++---- api/admin/client_test.go | 74 +++++++++++++++++++------------- api/admin/service.go | 91 ++++++++++++++++++++-------------------- 3 files changed, 101 insertions(+), 80 deletions(-) diff --git a/api/admin/client.go b/api/admin/client.go index 0dcb3e720546..77f3835f060c 100644 --- a/api/admin/client.go +++ b/api/admin/client.go @@ -25,7 +25,7 @@ type Client interface { GetChainAliases(ctx context.Context, chainID string, options ...rpc.Option) ([]string, error) Stacktrace(context.Context, ...rpc.Option) error LoadVMs(context.Context, ...rpc.Option) (map[ids.ID][]string, map[ids.ID]string, error) - SetLoggerLevel(ctx context.Context, loggerName, logLevel, displayLevel string, options ...rpc.Option) error + SetLoggerLevel(ctx context.Context, loggerName, logLevel, displayLevel string, options ...rpc.Option) (map[string]LogAndDisplayLevels, error) GetLoggerLevel(ctx context.Context, loggerName string, options ...rpc.Option) (map[string]LogAndDisplayLevels, error) GetConfig(ctx context.Context, options ...rpc.Option) (interface{}, error) } @@ -96,7 +96,7 @@ func (c *client) SetLoggerLevel( logLevel, displayLevel string, options ...rpc.Option, -) error { +) (map[string]LogAndDisplayLevels, error) { var ( logLevelArg logging.Level displayLevelArg logging.Level @@ -105,20 +105,22 @@ func (c *client) SetLoggerLevel( if len(logLevel) > 0 { logLevelArg, err = logging.ToLevel(logLevel) if err != nil { - return err + return nil, err } } if len(displayLevel) > 0 { displayLevelArg, err = logging.ToLevel(displayLevel) if err != nil { - return err + return nil, err } } - return c.requester.SendRequest(ctx, "admin.setLoggerLevel", &SetLoggerLevelArgs{ + res := &LoggerLevelReply{} + err = c.requester.SendRequest(ctx, "admin.setLoggerLevel", &SetLoggerLevelArgs{ LoggerName: loggerName, LogLevel: &logLevelArg, DisplayLevel: &displayLevelArg, - }, &api.EmptyReply{}, options...) + }, res, options...) + return res.LoggerLevels, err } func (c *client) GetLoggerLevel( @@ -126,7 +128,7 @@ func (c *client) GetLoggerLevel( loggerName string, options ...rpc.Option, ) (map[string]LogAndDisplayLevels, error) { - res := &GetLoggerLevelReply{} + res := &LoggerLevelReply{} err := c.requester.SendRequest(ctx, "admin.getLoggerLevel", &GetLoggerLevelArgs{ LoggerName: loggerName, }, res, options...) diff --git a/api/admin/client_test.go b/api/admin/client_test.go index 4302bd5350fa..d005c49b448a 100644 --- a/api/admin/client_test.go +++ b/api/admin/client_test.go @@ -63,8 +63,8 @@ func (mc *mockClient) SendRequest(_ context.Context, _ string, _ interface{}, re case *LoadVMsReply: response := mc.response.(*LoadVMsReply) *p = *response - case *GetLoggerLevelReply: - response := mc.response.(*GetLoggerLevelReply) + case *LoggerLevelReply: + response := mc.response.(*LoggerLevelReply) *p = *response case *interface{}: response := mc.response.(*interface{}) @@ -212,54 +212,72 @@ func TestReloadInstalledVMs(t *testing.T) { func TestSetLoggerLevel(t *testing.T) { type test struct { - name string - logLevel string - displayLevel string - serviceErr error - clientErr error + name string + logLevel string + displayLevel string + serviceResponse map[string]LogAndDisplayLevels + serviceErr error + clientErr error } tests := []test{ { name: "Happy path", logLevel: "INFO", displayLevel: "INFO", - serviceErr: nil, - clientErr: nil, + serviceResponse: map[string]LogAndDisplayLevels{ + "Happy path": {LogLevel: logging.Info, DisplayLevel: logging.Info}, + }, + serviceErr: nil, + clientErr: nil, }, { - name: "Service errors", - logLevel: "INFO", - displayLevel: "INFO", - serviceErr: errTest, - clientErr: errTest, + name: "Service errors", + logLevel: "INFO", + displayLevel: "INFO", + serviceResponse: nil, + serviceErr: errTest, + clientErr: errTest, }, { - name: "Invalid log level", - logLevel: "invalid", - displayLevel: "INFO", - serviceErr: nil, - clientErr: logging.ErrUnknownLevel, + name: "Invalid log level", + logLevel: "invalid", + displayLevel: "INFO", + serviceResponse: nil, + serviceErr: nil, + clientErr: logging.ErrUnknownLevel, }, { - name: "Invalid display level", - logLevel: "INFO", - displayLevel: "invalid", - serviceErr: nil, - clientErr: logging.ErrUnknownLevel, + name: "Invalid display level", + logLevel: "INFO", + displayLevel: "invalid", + serviceResponse: nil, + serviceErr: nil, + clientErr: logging.ErrUnknownLevel, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + c := client{ - requester: NewMockClient(&api.EmptyReply{}, tt.serviceErr), + requester: NewMockClient( + &LoggerLevelReply{ + LoggerLevels: tt.serviceResponse, + }, + tt.serviceErr, + ), } - err := c.SetLoggerLevel( + res, err := c.SetLoggerLevel( context.Background(), "", tt.logLevel, tt.displayLevel, ) - require.ErrorIs(t, err, tt.clientErr) + require.ErrorIs(err, tt.clientErr) + if tt.clientErr != nil { + return + } + require.Equal(tt.serviceResponse, res) }) } } @@ -296,7 +314,7 @@ func TestGetLoggerLevel(t *testing.T) { c := client{ requester: NewMockClient( - &GetLoggerLevelReply{ + &LoggerLevelReply{ LoggerLevels: tt.serviceResponse, }, tt.serviceErr, diff --git a/api/admin/service.go b/api/admin/service.go index 43e70c37c72c..f94a426b366c 100644 --- a/api/admin/service.go +++ b/api/admin/service.go @@ -224,13 +224,21 @@ func (a *Admin) Stacktrace(_ *http.Request, _ *struct{}, _ *api.EmptyReply) erro return perms.WriteFile(stacktraceFile, stacktrace, perms.ReadWrite) } -// See SetLoggerLevel type SetLoggerLevelArgs struct { LoggerName string `json:"loggerName"` LogLevel *logging.Level `json:"logLevel"` DisplayLevel *logging.Level `json:"displayLevel"` } +type LogAndDisplayLevels struct { + LogLevel logging.Level `json:"logLevel"` + DisplayLevel logging.Level `json:"displayLevel"` +} + +type LoggerLevelReply struct { + LoggerLevels map[string]LogAndDisplayLevels `json:"loggerLevels"` +} + // SetLoggerLevel sets the log level and/or display level for loggers. // If len([args.LoggerName]) == 0, sets the log/display level of all loggers. // Otherwise, sets the log/display level of the loggers named in that argument. @@ -240,7 +248,7 @@ type SetLoggerLevelArgs struct { // Sets the display level of these loggers to args.LogLevel. // If args.DisplayLevel == nil, doesn't set the display level of these loggers. // If args.DisplayLevel != nil, must be a valid string representation of a log level. -func (a *Admin) SetLoggerLevel(_ *http.Request, args *SetLoggerLevelArgs, _ *api.EmptyReply) error { +func (a *Admin) SetLoggerLevel(_ *http.Request, args *SetLoggerLevelArgs, reply *LoggerLevelReply) error { a.Log.Debug("API called", zap.String("service", "admin"), zap.String("method", "setLoggerLevel"), @@ -256,14 +264,7 @@ func (a *Admin) SetLoggerLevel(_ *http.Request, args *SetLoggerLevelArgs, _ *api a.lock.Lock() defer a.lock.Unlock() - var loggerNames []string - if len(args.LoggerName) > 0 { - loggerNames = []string{args.LoggerName} - } else { - // Empty name means all loggers - loggerNames = a.LogFactory.GetLoggerNames() - } - + loggerNames := a.getLoggerNames(args.LoggerName) for _, name := range loggerNames { if args.LogLevel != nil { if err := a.LogFactory.SetLogLevel(name, *args.LogLevel); err != nil { @@ -276,26 +277,18 @@ func (a *Admin) SetLoggerLevel(_ *http.Request, args *SetLoggerLevelArgs, _ *api } } } - return nil -} -type LogAndDisplayLevels struct { - LogLevel logging.Level `json:"logLevel"` - DisplayLevel logging.Level `json:"displayLevel"` + var err error + reply.LoggerLevels, err = a.getLogLevels(loggerNames) + return err } -// See GetLoggerLevel type GetLoggerLevelArgs struct { LoggerName string `json:"loggerName"` } -// See GetLoggerLevel -type GetLoggerLevelReply struct { - LoggerLevels map[string]LogAndDisplayLevels `json:"loggerLevels"` -} - // GetLogLevel returns the log level and display level of all loggers. -func (a *Admin) GetLoggerLevel(_ *http.Request, args *GetLoggerLevelArgs, reply *GetLoggerLevelReply) error { +func (a *Admin) GetLoggerLevel(_ *http.Request, args *GetLoggerLevelArgs, reply *LoggerLevelReply) error { a.Log.Debug("API called", zap.String("service", "admin"), zap.String("method", "getLoggerLevels"), @@ -305,30 +298,11 @@ func (a *Admin) GetLoggerLevel(_ *http.Request, args *GetLoggerLevelArgs, reply a.lock.RLock() defer a.lock.RUnlock() - reply.LoggerLevels = make(map[string]LogAndDisplayLevels) - var loggerNames []string - // Empty name means all loggers - if len(args.LoggerName) > 0 { - loggerNames = []string{args.LoggerName} - } else { - loggerNames = a.LogFactory.GetLoggerNames() - } + loggerNames := a.getLoggerNames(args.LoggerName) - for _, name := range loggerNames { - logLevel, err := a.LogFactory.GetLogLevel(name) - if err != nil { - return err - } - displayLevel, err := a.LogFactory.GetDisplayLevel(name) - if err != nil { - return err - } - reply.LoggerLevels[name] = LogAndDisplayLevels{ - LogLevel: logLevel, - DisplayLevel: displayLevel, - } - } - return nil + var err error + reply.LoggerLevels, err = a.getLogLevels(loggerNames) + return err } // GetConfig returns the config that the node was started with. @@ -375,3 +349,30 @@ func (a *Admin) LoadVMs(r *http.Request, _ *struct{}, reply *LoadVMsReply) error reply.NewVMs, err = ids.GetRelevantAliases(a.VMManager, loadedVMs) return err } + +func (a *Admin) getLoggerNames(loggerName string) []string { + if len(loggerName) == 0 { + // Empty name means all loggers + return a.LogFactory.GetLoggerNames() + } + return []string{loggerName} +} + +func (a *Admin) getLogLevels(loggerNames []string) (map[string]LogAndDisplayLevels, error) { + loggerLevels := make(map[string]LogAndDisplayLevels) + for _, name := range loggerNames { + logLevel, err := a.LogFactory.GetLogLevel(name) + if err != nil { + return nil, err + } + displayLevel, err := a.LogFactory.GetDisplayLevel(name) + if err != nil { + return nil, err + } + loggerLevels[name] = LogAndDisplayLevels{ + LogLevel: logLevel, + DisplayLevel: displayLevel, + } + } + return loggerLevels, nil +} From 11f1b55baf037e6919033d767552d76b37b834b2 Mon Sep 17 00:00:00 2001 From: DoTheBestToGetTheBest <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:41:47 -0700 Subject: [PATCH 002/267] feat(api) : Peers function to return the PrimaryAlias of the chainID (#2251) Signed-off-by: DoTheBestToGetTheBest <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- api/info/service.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/api/info/service.go b/api/info/service.go index 65b5fb2fdf7f..47112e55b630 100644 --- a/api/info/service.go +++ b/api/info/service.go @@ -208,7 +208,7 @@ type PeersArgs struct { type Peer struct { peer.Info - Benched []ids.ID `json:"benched"` + Benched []string `json:"benched"` } // PeersReply are the results from calling Peers @@ -229,9 +229,18 @@ func (i *Info) Peers(_ *http.Request, args *PeersArgs, reply *PeersReply) error peers := i.networking.PeerInfo(args.NodeIDs) peerInfo := make([]Peer, len(peers)) for index, peer := range peers { + benchedIDs := i.benchlist.GetBenched(peer.ID) + benchedAliases := make([]string, len(benchedIDs)) + for idx, id := range benchedIDs { + alias, err := i.chainManager.PrimaryAlias(id) + if err != nil { + return fmt.Errorf("failed to get primary alias for chain ID %s: %w", id, err) + } + benchedAliases[idx] = alias + } peerInfo[index] = Peer{ Info: peer, - Benched: i.benchlist.GetBenched(peer.ID), + Benched: benchedAliases, } } From 437ade80946f525e89697d06ffdd0d19c334bd7a Mon Sep 17 00:00:00 2001 From: marun Date: Fri, 3 Nov 2023 21:45:12 +0100 Subject: [PATCH 003/267] Switch to using require.TestingT interface in SenderTest struct (#2258) --- snow/engine/common/test_sender.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/snow/engine/common/test_sender.go b/snow/engine/common/test_sender.go index 5896f48dfa25..5b76f3b6a2f4 100644 --- a/snow/engine/common/test_sender.go +++ b/snow/engine/common/test_sender.go @@ -6,7 +6,6 @@ package common import ( "context" "errors" - "testing" "github.com/stretchr/testify/require" @@ -27,7 +26,7 @@ var ( // SenderTest is a test sender type SenderTest struct { - T *testing.T + T require.TestingT CantAccept, CantSendGetStateSummaryFrontier, CantSendStateSummaryFrontier, From e4cb2cd484896a6c84c1445da1651aa1e6edf8f0 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 3 Nov 2023 17:33:44 -0400 Subject: [PATCH 004/267] Cleanup `ipcs` `Socket` test (#2257) --- ipcs/socket/socket_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ipcs/socket/socket_test.go b/ipcs/socket/socket_test.go index 4204d032285a..a56329b28c3e 100644 --- a/ipcs/socket/socket_test.go +++ b/ipcs/socket/socket_test.go @@ -8,6 +8,8 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/utils/logging" ) func TestSocketSendAndReceive(t *testing.T) { @@ -21,7 +23,7 @@ func TestSocketSendAndReceive(t *testing.T) { ) // Create socket and client; wait for client to connect - socket := NewSocket(socketName, nil) + socket := NewSocket(socketName, logging.NoLog{}) socket.accept, connCh = newTestAcceptFn(t) require.NoError(socket.Listen()) From cec1cd1d4a3f459671e3fcacdda554e31f4af152 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 3 Nov 2023 19:19:26 -0400 Subject: [PATCH 005/267] Require poll metrics to be registered (#2260) --- snow/consensus/snowman/poll/set.go | 18 ++++++----- snow/consensus/snowman/poll/set_test.go | 42 +++++++++++++++++++------ snow/engine/snowman/transitive.go | 17 ++++++---- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/snow/consensus/snowman/poll/set.go b/snow/consensus/snowman/poll/set.go index e31821476bc8..e58059f20c3d 100644 --- a/snow/consensus/snowman/poll/set.go +++ b/snow/consensus/snowman/poll/set.go @@ -4,6 +4,7 @@ package poll import ( + "errors" "fmt" "strings" "time" @@ -19,6 +20,11 @@ import ( "github.com/ava-labs/avalanchego/utils/metric" ) +var ( + errFailedPollsMetric = errors.New("failed to register polls metric") + errFailedPollDurationMetrics = errors.New("failed to register poll_duration metrics") +) + type pollHolder interface { GetPoll() Poll StartTime() time.Time @@ -52,16 +58,14 @@ func NewSet( log logging.Logger, namespace string, reg prometheus.Registerer, -) Set { +) (Set, error) { numPolls := prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "polls", Help: "Number of pending network polls", }) if err := reg.Register(numPolls); err != nil { - log.Error("failed to register polls statistics", - zap.Error(err), - ) + return nil, fmt.Errorf("%w: %w", errFailedPollsMetric, err) } durPolls, err := metric.NewAverager( @@ -71,9 +75,7 @@ func NewSet( reg, ) if err != nil { - log.Error("failed to register poll_duration statistics", - zap.Error(err), - ) + return nil, fmt.Errorf("%w: %w", errFailedPollDurationMetrics, err) } return &set{ @@ -82,7 +84,7 @@ func NewSet( durPolls: durPolls, factory: factory, polls: linkedhashmap.New[uint32, pollHolder](), - } + }, nil } // Add to the current set of polls diff --git a/snow/consensus/snowman/poll/set_test.go b/snow/consensus/snowman/poll/set_test.go index 8200f25dc5f0..70830e3da36c 100644 --- a/snow/consensus/snowman/poll/set_test.go +++ b/snow/consensus/snowman/poll/set_test.go @@ -28,7 +28,7 @@ var ( vdr5 = ids.NodeID{5} ) -func TestNewSetErrorOnMetrics(t *testing.T) { +func TestNewSetErrorOnPollsMetrics(t *testing.T) { require := require.New(t) factory := NewEarlyTermNoTraversalFactory(1, 1) @@ -37,13 +37,29 @@ func TestNewSetErrorOnMetrics(t *testing.T) { registerer := prometheus.NewRegistry() require.NoError(registerer.Register(prometheus.NewCounter(prometheus.CounterOpts{ - Name: "polls", + Namespace: namespace, + Name: "polls", }))) + + _, err := NewSet(factory, log, namespace, registerer) + require.ErrorIs(err, errFailedPollsMetric) +} + +func TestNewSetErrorOnPollDurationMetrics(t *testing.T) { + require := require.New(t) + + factory := NewEarlyTermNoTraversalFactory(1, 1) + log := logging.NoLog{} + namespace := "" + registerer := prometheus.NewRegistry() + require.NoError(registerer.Register(prometheus.NewCounter(prometheus.CounterOpts{ - Name: "poll_duration", + Namespace: namespace, + Name: "poll_duration_count", }))) - require.NotNil(NewSet(factory, log, namespace, registerer)) + _, err := NewSet(factory, log, namespace, registerer) + require.ErrorIs(err, errFailedPollDurationMetrics) } func TestCreateAndFinishPollOutOfOrder_NewerFinishesFirst(t *testing.T) { @@ -56,7 +72,8 @@ func TestCreateAndFinishPollOutOfOrder_NewerFinishesFirst(t *testing.T) { log := logging.NoLog{} namespace := "" registerer := prometheus.NewRegistry() - s := NewSet(factory, log, namespace, registerer) + s, err := NewSet(factory, log, namespace, registerer) + require.NoError(err) // create two polls for the two blocks vdrBag := bag.Of(vdrs...) @@ -92,7 +109,8 @@ func TestCreateAndFinishPollOutOfOrder_OlderFinishesFirst(t *testing.T) { log := logging.NoLog{} namespace := "" registerer := prometheus.NewRegistry() - s := NewSet(factory, log, namespace, registerer) + s, err := NewSet(factory, log, namespace, registerer) + require.NoError(err) // create two polls for the two blocks vdrBag := bag.Of(vdrs...) @@ -128,7 +146,8 @@ func TestCreateAndFinishPollOutOfOrder_UnfinishedPollsGaps(t *testing.T) { log := logging.NoLog{} namespace := "" registerer := prometheus.NewRegistry() - s := NewSet(factory, log, namespace, registerer) + s, err := NewSet(factory, log, namespace, registerer) + require.NoError(err) // create three polls for the two blocks vdrBag := bag.Of(vdrs...) @@ -172,7 +191,8 @@ func TestCreateAndFinishSuccessfulPoll(t *testing.T) { log := logging.NoLog{} namespace := "" registerer := prometheus.NewRegistry() - s := NewSet(factory, log, namespace, registerer) + s, err := NewSet(factory, log, namespace, registerer) + require.NoError(err) require.Zero(s.Len()) @@ -204,7 +224,8 @@ func TestCreateAndFinishFailedPoll(t *testing.T) { log := logging.NoLog{} namespace := "" registerer := prometheus.NewRegistry() - s := NewSet(factory, log, namespace, registerer) + s, err := NewSet(factory, log, namespace, registerer) + require.NoError(err) require.Zero(s.Len()) @@ -233,7 +254,8 @@ func TestSetString(t *testing.T) { log := logging.NoLog{} namespace := "" registerer := prometheus.NewRegistry() - s := NewSet(factory, log, namespace, registerer) + s, err := NewSet(factory, log, namespace, registerer) + require.NoError(err) expected := `current polls: (Size = 1) RequestID 0: diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 803c03237c96..b4c5e3e54b51 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -116,6 +116,16 @@ func newTransitive(config Config) (*Transitive, error) { config.Params.AlphaPreference, config.Params.AlphaConfidence, ) + polls, err := poll.NewSet( + factory, + config.Ctx.Log, + "", + config.Ctx.Registerer, + ) + if err != nil { + return nil, err + } + t := &Transitive{ Config: config, StateSummaryFrontierHandler: common.NewNoOpStateSummaryFrontierHandler(config.Ctx.Log), @@ -129,12 +139,7 @@ func newTransitive(config Config) (*Transitive, error) { nonVerifieds: ancestor.NewTree(), nonVerifiedCache: nonVerifiedCache, acceptedFrontiers: acceptedFrontiers, - polls: poll.NewSet( - factory, - config.Ctx.Log, - "", - config.Ctx.Registerer, - ), + polls: polls, } return t, t.metrics.Initialize("", config.Ctx.Registerer) From aaed8f34c3b21430a896a2d6d893d215ed62e520 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 4 Nov 2023 17:29:12 -0400 Subject: [PATCH 006/267] Track all subnet validator sets in the validator manager (#2253) --- snow/validators/logger.go | 10 +- vms/platformvm/block/builder/helpers_test.go | 1 - vms/platformvm/block/executor/helpers_test.go | 1 - .../block/executor/proposal_block_test.go | 2 +- .../block/executor/standard_block_test.go | 2 +- vms/platformvm/state/mock_state.go | 14 --- vms/platformvm/state/state.go | 98 ++++++------------- vms/platformvm/state/state_test.go | 2 - .../txs/executor/advance_time_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 1 - vms/platformvm/validators/manager.go | 21 +--- .../validators/manager_benchmark_test.go | 2 - vms/platformvm/vm.go | 9 +- vms/platformvm/vm_regression_test.go | 6 -- 14 files changed, 44 insertions(+), 127 deletions(-) diff --git a/snow/validators/logger.go b/snow/validators/logger.go index 124aef423fc4..2e672a1827ba 100644 --- a/snow/validators/logger.go +++ b/snow/validators/logger.go @@ -7,7 +7,6 @@ import ( "go.uber.org/zap" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" @@ -18,7 +17,6 @@ var _ SetCallbackListener = (*logger)(nil) type logger struct { log logging.Logger - enabled *utils.Atomic[bool] subnetID ids.ID nodeIDs set.Set[ids.NodeID] } @@ -27,14 +25,12 @@ type logger struct { // the specified validators func NewLogger( log logging.Logger, - enabled *utils.Atomic[bool], subnetID ids.ID, nodeIDs ...ids.NodeID, ) SetCallbackListener { nodeIDSet := set.Of(nodeIDs...) return &logger{ log: log, - enabled: enabled, subnetID: subnetID, nodeIDs: nodeIDSet, } @@ -46,7 +42,7 @@ func (l *logger) OnValidatorAdded( txID ids.ID, weight uint64, ) { - if l.enabled.Get() && l.nodeIDs.Contains(nodeID) { + if l.nodeIDs.Contains(nodeID) { var pkBytes []byte if pk != nil { pkBytes = bls.PublicKeyToBytes(pk) @@ -65,7 +61,7 @@ func (l *logger) OnValidatorRemoved( nodeID ids.NodeID, weight uint64, ) { - if l.enabled.Get() && l.nodeIDs.Contains(nodeID) { + if l.nodeIDs.Contains(nodeID) { l.log.Info("node removed from validator set", zap.Stringer("subnetID", l.subnetID), zap.Stringer("nodeID", nodeID), @@ -79,7 +75,7 @@ func (l *logger) OnValidatorWeightChanged( oldWeight uint64, newWeight uint64, ) { - if l.enabled.Get() && l.nodeIDs.Contains(nodeID) { + if l.nodeIDs.Contains(nodeID) { l.log.Info("validator weight changed", zap.Stringer("subnetID", l.subnetID), zap.Stringer("nodeID", nodeID), diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 187c0eb92a70..ed55791147d8 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -236,7 +236,6 @@ func defaultState( ctx, metrics.Noop, rewards, - &utils.Atomic[bool]{}, ) require.NoError(err) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 7d5a67566472..5e79d52c9b10 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -275,7 +275,6 @@ func defaultState( ctx, metrics.Noop, rewards, - &utils.Atomic[bool]{}, ) if err != nil { panic(err) diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 880817414ea8..4300ad9606d9 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -947,7 +947,7 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { require.NoError(propBlk.Accept(context.Background())) require.NoError(commitBlk.Accept(context.Background())) _, ok := env.config.Validators.GetValidator(subnetID, subnetValidatorNodeID) - require.Equal(tracked, ok) + require.True(ok) }) } } diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 76ae7ca55de6..110def5c5987 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -747,7 +747,7 @@ func TestBanffStandardBlockTrackedSubnet(t *testing.T) { require.NoError(block.Verify(context.Background())) require.NoError(block.Accept(context.Background())) _, ok := env.config.Validators.GetValidator(subnetID, subnetValidatorNodeID) - require.Equal(tracked, ok) + require.True(ok) }) } } diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index 1e0265798d33..41ce946a12e0 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -144,20 +144,6 @@ func (mr *MockStateMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockState)(nil).AddUTXO), arg0) } -// ApplyCurrentValidators mocks base method. -func (m *MockState) ApplyCurrentValidators(arg0 ids.ID, arg1 validators.Manager) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ApplyCurrentValidators", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// ApplyCurrentValidators indicates an expected call of ApplyCurrentValidators. -func (mr *MockStateMockRecorder) ApplyCurrentValidators(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyCurrentValidators", reflect.TypeOf((*MockState)(nil).ApplyCurrentValidators), arg0, arg1) -} - // ApplyValidatorPublicKeyDiffs mocks base method. func (m *MockState) ApplyValidatorPublicKeyDiffs(arg0 context.Context, arg1 map[ids.NodeID]*validators.GetValidatorOutput, arg2, arg3 uint64) error { m.ctrl.T.Helper() diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 872d9b669219..e64d24d434b1 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -140,10 +140,6 @@ type State interface { GetBlockIDAtHeight(height uint64) (ids.ID, error) - // ApplyCurrentValidators adds all the current validators and delegators of - // [subnetID] into [vdrs]. - ApplyCurrentValidators(subnetID ids.ID, vdrs validators.Manager) error - // ApplyValidatorWeightDiffs iterates from [startHeight] towards the genesis // block until it has applied all of the diffs up to and including // [endHeight]. Applying the diffs modifies [validators]. @@ -290,11 +286,10 @@ type stateBlk struct { type state struct { validatorState - cfg *config.Config - ctx *snow.Context - metrics metrics.Metrics - rewards reward.Calculator - bootstrapped *utils.Atomic[bool] + cfg *config.Config + ctx *snow.Context + metrics metrics.Metrics + rewards reward.Calculator baseDB *versiondb.Database @@ -461,7 +456,6 @@ func New( ctx *snow.Context, metrics metrics.Metrics, rewards reward.Calculator, - bootstrapped *utils.Atomic[bool], ) (State, error) { s, err := newState( db, @@ -471,7 +465,6 @@ func New( ctx, metricsReg, rewards, - bootstrapped, ) if err != nil { return nil, err @@ -516,7 +509,6 @@ func newState( ctx *snow.Context, metricsReg prometheus.Registerer, rewards reward.Calculator, - bootstrapped *utils.Atomic[bool], ) (*state, error) { blockIDCache, err := metercacher.New[uint64, ids.ID]( "block_id_cache", @@ -635,12 +627,11 @@ func newState( return &state{ validatorState: newValidatorState(), - cfg: cfg, - ctx: ctx, - metrics: metrics, - rewards: rewards, - bootstrapped: bootstrapped, - baseDB: baseDB, + cfg: cfg, + ctx: ctx, + metrics: metrics, + rewards: rewards, + baseDB: baseDB, addedBlockIDs: make(map[uint64]ids.ID), blockIDCache: blockIDCache, @@ -1139,26 +1130,6 @@ func (s *state) SetCurrentSupply(subnetID ids.ID, cs uint64) { } } -func (s *state) ApplyCurrentValidators(subnetID ids.ID, vdrs validators.Manager) error { - for nodeID, validator := range s.currentStakers.validators[subnetID] { - staker := validator.validator - if err := vdrs.AddStaker(subnetID, nodeID, staker.PublicKey, staker.TxID, staker.Weight); err != nil { - return err - } - - delegatorIterator := NewTreeIterator(validator.delegators) - for delegatorIterator.Next() { - staker := delegatorIterator.Value() - if err := vdrs.AddWeight(subnetID, nodeID, staker.Weight); err != nil { - delegatorIterator.Release() - return err - } - } - delegatorIterator.Release() - } - return nil -} - func (s *state) ApplyValidatorWeightDiffs( ctx context.Context, validators map[ids.NodeID]*validators.GetValidatorOutput, @@ -1689,17 +1660,29 @@ func (s *state) loadPendingValidators() error { // Invariant: initValidatorSets requires loadCurrentValidators to have already // been called. func (s *state) initValidatorSets() error { - if s.cfg.Validators.Count(constants.PrimaryNetworkID) != 0 { - // Enforce the invariant that the validator set is empty here. - return errValidatorSetAlreadyPopulated - } - err := s.ApplyCurrentValidators(constants.PrimaryNetworkID, s.cfg.Validators) - if err != nil { - return err - } + for subnetID, validators := range s.currentStakers.validators { + if s.cfg.Validators.Count(subnetID) != 0 { + // Enforce the invariant that the validator set is empty here. + return fmt.Errorf("%w: %s", errValidatorSetAlreadyPopulated, subnetID) + } - vl := validators.NewLogger(s.ctx.Log, s.bootstrapped, constants.PrimaryNetworkID, s.ctx.NodeID) - s.cfg.Validators.RegisterCallbackListener(constants.PrimaryNetworkID, vl) + for nodeID, validator := range validators { + validatorStaker := validator.validator + if err := s.cfg.Validators.AddStaker(subnetID, nodeID, validatorStaker.PublicKey, validatorStaker.TxID, validatorStaker.Weight); err != nil { + return err + } + + delegatorIterator := NewTreeIterator(validator.delegators) + for delegatorIterator.Next() { + delegatorStaker := delegatorIterator.Value() + if err := s.cfg.Validators.AddWeight(subnetID, nodeID, delegatorStaker.Weight); err != nil { + delegatorIterator.Release() + return err + } + } + delegatorIterator.Release() + } + } s.metrics.SetLocalStake(s.cfg.Validators.GetWeight(constants.PrimaryNetworkID, s.ctx.NodeID)) totalWeight, err := s.cfg.Validators.TotalWeight(constants.PrimaryNetworkID) @@ -1707,20 +1690,6 @@ func (s *state) initValidatorSets() error { return fmt.Errorf("failed to get total weight of primary network validators: %w", err) } s.metrics.SetTotalStake(totalWeight) - - for subnetID := range s.cfg.TrackedSubnets { - if s.cfg.Validators.Count(subnetID) != 0 { - // Enforce the invariant that the validator set is empty here. - return errValidatorSetAlreadyPopulated - } - err := s.ApplyCurrentValidators(subnetID, s.cfg.Validators) - if err != nil { - return err - } - - vl := validators.NewLogger(s.ctx.Log, s.bootstrapped, subnetID, s.ctx.NodeID) - s.cfg.Validators.RegisterCallbackListener(subnetID, vl) - } return nil } @@ -2109,11 +2078,6 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error continue } - // We only track the current validator set of tracked subnets. - if subnetID != constants.PrimaryNetworkID && !s.cfg.TrackedSubnets.Contains(subnetID) { - continue - } - if weightDiff.Decrease { err = s.cfg.Validators.RemoveWeight(subnetID, nodeID, weightDiff.Amount) } else { diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index 5a29619c1beb..ae79415f4bbf 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -21,7 +21,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/units" @@ -178,7 +177,6 @@ func newStateFromDB(require *require.Assertions, db database.Database) State { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }), - &utils.Atomic[bool]{}, ) require.NoError(err) require.NotNil(state) diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 9bf5aafed7ac..5f9eabe0553c 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -617,7 +617,7 @@ func TestTrackedSubnet(t *testing.T) { env.state.SetHeight(dummyHeight) require.NoError(env.state.Commit()) _, ok := env.config.Validators.GetValidator(subnetID, ids.NodeID(subnetValidatorNodeID)) - require.Equal(tracked, ok) + require.True(ok) }) } } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index aee0d184d5f8..b1993584cb7a 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -224,7 +224,6 @@ func defaultState( ctx, metrics.Noop, rewards, - &utils.Atomic[bool]{}, ) if err != nil { panic(err) diff --git a/vms/platformvm/validators/manager.go b/vms/platformvm/validators/manager.go index fb7c314c90a7..a4c5c87a3040 100644 --- a/vms/platformvm/validators/manager.go +++ b/vms/platformvm/validators/manager.go @@ -48,10 +48,6 @@ type State interface { GetLastAccepted() ids.ID GetStatelessBlock(blockID ids.ID) (block.Block, error) - // ApplyCurrentValidators adds all the current validators and delegators of - // [subnetID] into [vdrs]. - ApplyCurrentValidators(subnetID ids.ID, vdrs validators.Manager) error - // ApplyValidatorWeightDiffs iterates from [startHeight] towards the genesis // block until it has applied all of the diffs up to and including // [endHeight]. Applying the diffs modifies [validators]. @@ -346,22 +342,7 @@ func (m *manager) getCurrentValidatorSets( ctx context.Context, subnetID ids.ID, ) (map[ids.NodeID]*validators.GetValidatorOutput, map[ids.NodeID]*validators.GetValidatorOutput, uint64, error) { - subnetManager := m.cfg.Validators - if subnetManager.Count(subnetID) == 0 { - // If this subnet isn't tracked, there will not be any registered - // validators. To calculate the current validators we need to first - // fetch them from state. We generate a new manager as we don't want to - // modify that long-lived reference. - // - // TODO: remove this once all subnets are included in the validator - // manager. - subnetManager = validators.NewManager() - if err := m.state.ApplyCurrentValidators(subnetID, subnetManager); err != nil { - return nil, nil, 0, err - } - } - - subnetMap := subnetManager.GetMap(subnetID) + subnetMap := m.cfg.Validators.GetMap(subnetID) primaryMap := m.cfg.Validators.GetMap(constants.PrimaryNetworkID) currentHeight, err := m.getCurrentHeight(ctx) return subnetMap, primaryMap, currentHeight, err diff --git a/vms/platformvm/validators/manager_benchmark_test.go b/vms/platformvm/validators/manager_benchmark_test.go index 54d0e264e63e..d88fca7d7e32 100644 --- a/vms/platformvm/validators/manager_benchmark_test.go +++ b/vms/platformvm/validators/manager_benchmark_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/formatting" @@ -129,7 +128,6 @@ func BenchmarkGetValidatorSet(b *testing.B) { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }), - new(utils.Atomic[bool]), ) require.NoError(err) diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index c1a911f5b919..8522d3ae4715 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -142,7 +142,6 @@ func (vm *VM) Initialize( vm.ctx, vm.metrics, rewards, - &vm.bootstrapped, ) if err != nil { return err @@ -304,17 +303,21 @@ func (vm *VM) onNormalOperationsStarted() error { } primaryVdrIDs := vm.Validators.GetValidatorIDs(constants.PrimaryNetworkID) - if err := vm.uptimeManager.StartTracking(primaryVdrIDs, constants.PrimaryNetworkID); err != nil { return err } + vl := validators.NewLogger(vm.ctx.Log, constants.PrimaryNetworkID, vm.ctx.NodeID) + vm.Validators.RegisterCallbackListener(constants.PrimaryNetworkID, vl) + for subnetID := range vm.TrackedSubnets { vdrIDs := vm.Validators.GetValidatorIDs(subnetID) - if err := vm.uptimeManager.StartTracking(vdrIDs, subnetID); err != nil { return err } + + vl := validators.NewLogger(vm.ctx.Log, subnetID, vm.ctx.NodeID) + vm.Validators.RegisterCallbackListener(subnetID, vl) } if err := vm.state.Commit(); err != nil { diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 8416c4114662..e94a0ea99406 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -25,7 +25,6 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -659,7 +658,6 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { vm.ctx, metrics.Noop, reward.NewCalculator(vm.Config.RewardConfig), - &utils.Atomic[bool]{}, ) require.NoError(err) @@ -968,7 +966,6 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { vm.ctx, metrics.Noop, reward.NewCalculator(vm.Config.RewardConfig), - &utils.Atomic[bool]{}, ) require.NoError(err) @@ -1397,9 +1394,6 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t require.NoError(createSubnetBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - vm.TrackedSubnets.Add(createSubnetTx.ID()) - require.NoError(vm.state.ApplyCurrentValidators(createSubnetTx.ID(), vm.Validators)) - addSubnetValidatorTx, err := vm.txBuilder.NewAddSubnetValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), From a8db08e9be5929b12d84a0e0ac06b028e1e012cd Mon Sep 17 00:00:00 2001 From: marun Date: Mon, 6 Nov 2023 15:26:27 +0100 Subject: [PATCH 007/267] e2e: Make NewWallet and NewEthclient regular functions (#2262) --- tests/e2e/banff/suites.go | 2 +- tests/e2e/c/dynamic_fees.go | 2 +- tests/e2e/c/interchain_workflow.go | 4 +-- tests/e2e/e2e.go | 38 +++++++++++++-------------- tests/e2e/p/interchain_workflow.go | 4 +-- tests/e2e/p/permissionless_subnets.go | 2 +- tests/e2e/p/staking_rewards.go | 4 +-- tests/e2e/p/workflow.go | 2 +- tests/e2e/x/interchain_workflow.go | 4 +-- tests/e2e/x/transfer/virtuous.go | 2 +- 10 files changed, 31 insertions(+), 33 deletions(-) diff --git a/tests/e2e/banff/suites.go b/tests/e2e/banff/suites.go index 6adeb1476cfa..5bc071d6e004 100644 --- a/tests/e2e/banff/suites.go +++ b/tests/e2e/banff/suites.go @@ -25,7 +25,7 @@ var _ = ginkgo.Describe("[Banff]", func() { ginkgo.It("can send custom assets X->P and P->X", func() { keychain := e2e.Env.NewKeychain(1) - wallet := e2e.Env.NewWallet(keychain, e2e.Env.GetRandomNodeURI()) + wallet := e2e.NewWallet(keychain, e2e.Env.GetRandomNodeURI()) // Get the P-chain and the X-chain wallets pWallet := wallet.P() diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index edfbef2671a8..c8e005621983 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -51,7 +51,7 @@ var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { NodeID: node.GetID(), URI: node.GetProcessContext().URI, } - ethClient := e2e.Env.NewEthClient(nodeURI) + ethClient := e2e.NewEthClient(nodeURI) ginkgo.By("initializing a transaction signer") cChainID, err := ethClient.ChainID(e2e.DefaultContext()) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index 8bed85eb1bd9..d4881255ddff 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -34,7 +34,7 @@ var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { // the wallet to avoid having to verify that all nodes are at // the same height before initializing the wallet. nodeURI := e2e.Env.GetRandomNodeURI() - ethClient := e2e.Env.NewEthClient(nodeURI) + ethClient := e2e.NewEthClient(nodeURI) ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") senderKey := e2e.Env.AllocateFundedKey() @@ -79,7 +79,7 @@ var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { // matches on-chain state. ginkgo.By("initializing a keychain and associated wallet") keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) - baseWallet := e2e.Env.NewWallet(keychain, nodeURI) + baseWallet := e2e.NewWallet(keychain, nodeURI) xWallet := baseWallet.X() cWallet := baseWallet.C() pWallet := baseWallet.P() diff --git a/tests/e2e/e2e.go b/tests/e2e/e2e.go index 130f33f1197c..44c5d911e8dd 100644 --- a/tests/e2e/e2e.go +++ b/tests/e2e/e2e.go @@ -127,16 +127,29 @@ func (te *TestEnvironment) NewKeychain(count int) *secp256k1fx.Keychain { return secp256k1fx.NewKeychain(keys...) } +// Create a new private network that is not shared with other tests. +func (te *TestEnvironment) NewPrivateNetwork() testnet.Network { + // Load the shared network to retrieve its path and exec path + sharedNetwork, err := local.ReadNetwork(te.NetworkDir) + te.require.NoError(err) + + // The private networks dir is under the shared network dir to ensure it + // will be included in the artifact uploaded in CI. + privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName) + te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute)) + + return StartLocalNetwork(sharedNetwork.ExecPath, privateNetworksDir) +} + // Create a new wallet for the provided keychain against the specified node URI. -// TODO(marun) Make this a regular function. -func (te *TestEnvironment) NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary.Wallet { +func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary.Wallet { tests.Outf("{{blue}} initializing a new wallet for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, EthKeychain: keychain, }) - te.require.NoError(err) + require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( baseWallet, common.WithPostIssuanceFunc( @@ -148,30 +161,15 @@ func (te *TestEnvironment) NewWallet(keychain *secp256k1fx.Keychain, nodeURI tes } // Create a new eth client targeting the specified node URI. -// TODO(marun) Make this a regular function. -func (te *TestEnvironment) NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { +func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) nodeAddress := strings.Split(nodeURI.URI, "//")[1] uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) client, err := ethclient.Dial(uri) - te.require.NoError(err) + require.NoError(ginkgo.GinkgoT(), err) return client } -// Create a new private network that is not shared with other tests. -func (te *TestEnvironment) NewPrivateNetwork() testnet.Network { - // Load the shared network to retrieve its path and exec path - sharedNetwork, err := local.ReadNetwork(te.NetworkDir) - te.require.NoError(err) - - // The private networks dir is under the shared network dir to ensure it - // will be included in the artifact uploaded in CI. - privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName) - te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute)) - - return StartLocalNetwork(sharedNetwork.ExecPath, privateNetworksDir) -} - // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { ctx, cancel := context.WithTimeout(context.Background(), duration) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 729418adbd97..9bea416294cb 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -53,7 +53,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL keychain := e2e.Env.NewKeychain(1) keychain.Add(recipientKey) nodeURI := e2e.Env.GetRandomNodeURI() - baseWallet := e2e.Env.NewWallet(keychain, nodeURI) + baseWallet := e2e.NewWallet(keychain, nodeURI) xWallet := baseWallet.X() cWallet := baseWallet.C() pWallet := baseWallet.P() @@ -202,7 +202,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL }) ginkgo.By("initializing a new eth client") - ethClient := e2e.Env.NewEthClient(nodeURI) + ethClient := e2e.NewEthClient(nodeURI) ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { _, err := cWallet.IssueImportTx( diff --git a/tests/e2e/p/permissionless_subnets.go b/tests/e2e/p/permissionless_subnets.go index 1369685bf077..ab2909228365 100644 --- a/tests/e2e/p/permissionless_subnets.go +++ b/tests/e2e/p/permissionless_subnets.go @@ -32,7 +32,7 @@ var _ = e2e.DescribePChain("[Permissionless Subnets]", func() { nodeURI := e2e.Env.GetRandomNodeURI() keychain := e2e.Env.NewKeychain(1) - baseWallet := e2e.Env.NewWallet(keychain, nodeURI) + baseWallet := e2e.NewWallet(keychain, nodeURI) pWallet := baseWallet.P() xWallet := baseWallet.X() diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index df64088103ce..09b169dfb8f4 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -90,7 +90,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { fundedKey := e2e.Env.AllocateFundedKey() keychain.Add(fundedKey) nodeURI := e2e.Env.GetRandomNodeURI() - baseWallet := e2e.Env.NewWallet(keychain, nodeURI) + baseWallet := e2e.NewWallet(keychain, nodeURI) pWallet := baseWallet.P() ginkgo.By("retrieving alpha node id and pop") @@ -261,7 +261,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { rewardBalances := make(map[ids.ShortID]uint64, len(rewardKeys)) for _, rewardKey := range rewardKeys { keychain := secp256k1fx.NewKeychain(rewardKey) - baseWallet := e2e.Env.NewWallet(keychain, nodeURI) + baseWallet := e2e.NewWallet(keychain, nodeURI) pWallet := baseWallet.P() balances, err := pWallet.Builder().GetBalance() require.NoError(err) diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 96bf8bafc02c..c0fda23775fd 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -36,7 +36,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { func() { nodeURI := e2e.Env.GetRandomNodeURI() keychain := e2e.Env.NewKeychain(2) - baseWallet := e2e.Env.NewWallet(keychain, nodeURI) + baseWallet := e2e.NewWallet(keychain, nodeURI) pWallet := baseWallet.P() avaxAssetID := baseWallet.P().AVAXAssetID() diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index 6d335199b5b9..373e567a666a 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -36,7 +36,7 @@ var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL require.NoError(err) keychain := e2e.Env.NewKeychain(1) keychain.Add(recipientKey) - baseWallet := e2e.Env.NewWallet(keychain, nodeURI) + baseWallet := e2e.NewWallet(keychain, nodeURI) xWallet := baseWallet.X() cWallet := baseWallet.C() pWallet := baseWallet.P() @@ -103,7 +103,7 @@ var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL }) ginkgo.By("initializing a new eth client") - ethClient := e2e.Env.NewEthClient(nodeURI) + ethClient := e2e.NewEthClient(nodeURI) ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { _, err := cWallet.IssueImportTx( diff --git a/tests/e2e/x/transfer/virtuous.go b/tests/e2e/x/transfer/virtuous.go index d0ee950a53d6..119e28b9d1e9 100644 --- a/tests/e2e/x/transfer/virtuous.go +++ b/tests/e2e/x/transfer/virtuous.go @@ -83,7 +83,7 @@ var _ = e2e.DescribeXChainSerial("[Virtuous Transfer Tx AVAX]", func() { } keychain := secp256k1fx.NewKeychain(testKeys...) - baseWallet := e2e.Env.NewWallet(keychain, e2e.Env.GetRandomNodeURI()) + baseWallet := e2e.NewWallet(keychain, e2e.Env.GetRandomNodeURI()) avaxAssetID := baseWallet.X().AVAXAssetID() wallets := make([]primary.Wallet, len(testKeys)) From 558d8fb602a08468c8bf4fa37bba46261054f43a Mon Sep 17 00:00:00 2001 From: vuittont60 <81072379+vuittont60@users.noreply.github.com> Date: Mon, 6 Nov 2023 22:26:43 +0800 Subject: [PATCH 008/267] Fix typos in docs (#2261) Signed-off-by: vuittont60 <81072379+vuittont60@users.noreply.github.com> --- RELEASES.md | 2 +- x/merkledb/README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 13d983cf2803..0f8d57aea220 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -723,7 +723,7 @@ This version is backwards compatible to [v1.10.0](https://github.com/ava-labs/av - Add workflow to mark stale issues and PRs by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/1443 - Enforce inlining functions with a single error return in `require.NoError` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/1500 - `x/sync` / `x/merkledb` -- add `SyncableDB` interface by @danlaine in https://github.com/ava-labs/avalanchego/pull/1555 -- Rename beacon to boostrapper, define bootstrappers in JSON file for cross-language compatiblity by @gyuho in https://github.com/ava-labs/avalanchego/pull/1439 +- Rename beacon to boostrapper, define bootstrappers in JSON file for cross-language compatibility by @gyuho in https://github.com/ava-labs/avalanchego/pull/1439 - add P-chain height indexing by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/1447 - Add P-chain `GetBlockByHeight` API method by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/1448 - `x/sync` -- use for sending Range Proofs by @danlaine in https://github.com/ava-labs/avalanchego/pull/1537 diff --git a/x/merkledb/README.md b/x/merkledb/README.md index 467a60e19b08..6c7d9d68775c 100644 --- a/x/merkledb/README.md +++ b/x/merkledb/README.md @@ -76,8 +76,8 @@ The node serialization format is as follows: Where: * `Value existence flag` is `1` if this node has a value, otherwise `0`. -* `Value length` is the length of the value, if it exists (i.e. if `Value existince flag` is `1`.) Otherwise not serialized. -* `Value` is the value, if it exists (i.e. if `Value existince flag` is `1`.) Otherwise not serialized. +* `Value length` is the length of the value, if it exists (i.e. if `Value existence flag` is `1`.) Otherwise not serialized. +* `Value` is the value, if it exists (i.e. if `Value existence flag` is `1`.) Otherwise not serialized. * `Number of children` is the number of children this node has. * `Child index` is the index of a child node within the list of the node's children. * `Child compressed key length` is the length of the child node's compressed key. @@ -197,8 +197,8 @@ Where: * `Child index` is the index of a child node within the list of the node's children. * `Child ID` is the child node's ID. * `Value existence flag` is `1` if this node has a value, otherwise `0`. -* `Value length` is the length of the value, if it exists (i.e. if `Value existince flag` is `1`.) Otherwise not serialized. -* `Value` is the value, if it exists (i.e. if `Value existince flag` is `1`.) Otherwise not serialized. +* `Value length` is the length of the value, if it exists (i.e. if `Value existence flag` is `1`.) Otherwise not serialized. +* `Value` is the value, if it exists (i.e. if `Value existence flag` is `1`.) Otherwise not serialized. * `Key length` is the number of nibbles in this node's key. * `Key` is the node's key. From e71089930ee5748ddf1640ad5df5aad8956431b6 Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Mon, 6 Nov 2023 13:36:34 -0500 Subject: [PATCH 009/267] Remove Token constants information from keys (#2197) Signed-off-by: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Signed-off-by: Dan Laine Co-authored-by: Darioush Jalali Co-authored-by: Dan Laine --- x/merkledb/codec.go | 53 +-- x/merkledb/codec_test.go | 98 ++-- x/merkledb/db.go | 52 +-- x/merkledb/db_test.go | 37 +- x/merkledb/helpers_test.go | 4 +- x/merkledb/history.go | 13 +- x/merkledb/history_test.go | 70 ++- x/merkledb/intermediate_node_db.go | 13 +- x/merkledb/intermediate_node_db_test.go | 62 +-- x/merkledb/key.go | 360 +++++++-------- x/merkledb/key_test.go | 569 ++++++++++++------------ x/merkledb/node.go | 36 +- x/merkledb/node_test.go | 33 +- x/merkledb/proof.go | 90 ++-- x/merkledb/proof_test.go | 240 +++++----- x/merkledb/trie_test.go | 62 ++- x/merkledb/trieview.go | 118 ++--- x/merkledb/value_node_db.go | 15 +- x/merkledb/value_node_db_test.go | 10 +- x/merkledb/view_iterator.go | 4 +- x/sync/client.go | 14 +- x/sync/client_test.go | 6 +- x/sync/g_db/db_client.go | 14 +- x/sync/g_db/db_server.go | 14 +- x/sync/manager.go | 46 +- x/sync/network_server_test.go | 2 +- x/sync/sync_test.go | 7 +- 27 files changed, 955 insertions(+), 1087 deletions(-) diff --git a/x/merkledb/codec.go b/x/merkledb/codec.go index e7ef1eddb7f5..a7decc6f6436 100644 --- a/x/merkledb/codec.go +++ b/x/merkledb/codec.go @@ -44,7 +44,6 @@ var ( trueBytes = []byte{trueByte} falseBytes = []byte{falseByte} - errTooManyChildren = errors.New("length of children list is larger than branching factor") errChildIndexTooLarge = errors.New("invalid child index. Must be less than branching factor") errLeadingZeroes = errors.New("varint has leading zeroes") errInvalidBool = errors.New("decoded bool is neither true nor false") @@ -63,13 +62,15 @@ type encoderDecoder interface { type encoder interface { // Assumes [n] is non-nil. encodeDBNode(n *dbNode) []byte - // Assumes [hv] is non-nil. - encodeHashValues(hv *hashValues) []byte + + // Returns the bytes that will be hashed to generate [n]'s ID. + // Assumes [n] is non-nil. + encodeHashValues(n *node) []byte } type decoder interface { // Assumes [n] is non-nil. - decodeDBNode(bytes []byte, n *dbNode, factor BranchFactor) error + decodeDBNode(bytes []byte, n *dbNode) error } func newCodec() encoderDecoder { @@ -114,9 +115,9 @@ func (c *codecImpl) encodeDBNode(n *dbNode) []byte { return buf.Bytes() } -func (c *codecImpl) encodeHashValues(hv *hashValues) []byte { +func (c *codecImpl) encodeHashValues(n *node) []byte { var ( - numChildren = len(hv.Children) + numChildren = len(n.children) // Estimate size [hv] to prevent memory allocations estimatedLen = minVarIntLen + numChildren*hashValuesChildLen + estimatedValueLen + estimatedKeyLen buf = bytes.NewBuffer(make([]byte, 0, estimatedLen)) @@ -125,19 +126,20 @@ func (c *codecImpl) encodeHashValues(hv *hashValues) []byte { c.encodeUint(buf, uint64(numChildren)) // ensure that the order of entries is consistent - for index := 0; BranchFactor(index) < hv.Key.branchFactor; index++ { - if entry, ok := hv.Children[byte(index)]; ok { - c.encodeUint(buf, uint64(index)) - _, _ = buf.Write(entry.id[:]) - } + keys := maps.Keys(n.children) + slices.Sort(keys) + for _, index := range keys { + entry := n.children[index] + c.encodeUint(buf, uint64(index)) + _, _ = buf.Write(entry.id[:]) } - c.encodeMaybeByteSlice(buf, hv.Value) - c.encodeKey(buf, hv.Key) + c.encodeMaybeByteSlice(buf, n.valueDigest) + c.encodeKey(buf, n.key) return buf.Bytes() } -func (c *codecImpl) decodeDBNode(b []byte, n *dbNode, branchFactor BranchFactor) error { +func (c *codecImpl) decodeDBNode(b []byte, n *dbNode) error { if minDBNodeLen > len(b) { return io.ErrUnexpectedEOF } @@ -154,25 +156,23 @@ func (c *codecImpl) decodeDBNode(b []byte, n *dbNode, branchFactor BranchFactor) switch { case err != nil: return err - case numChildren > uint64(branchFactor): - return errTooManyChildren case numChildren > uint64(src.Len()/minChildLen): return io.ErrUnexpectedEOF } - n.children = make(map[byte]child, branchFactor) + n.children = make(map[byte]child, numChildren) var previousChild uint64 for i := uint64(0); i < numChildren; i++ { index, err := c.decodeUint(src) if err != nil { return err } - if index >= uint64(branchFactor) || (i != 0 && index <= previousChild) { + if (i != 0 && index <= previousChild) || index > math.MaxUint8 { return errChildIndexTooLarge } previousChild = index - compressedKey, err := c.decodeKey(src, branchFactor) + compressedKey, err := c.decodeKey(src) if err != nil { return err } @@ -331,11 +331,11 @@ func (*codecImpl) decodeID(src *bytes.Reader) (ids.ID, error) { } func (c *codecImpl) encodeKey(dst *bytes.Buffer, key Key) { - c.encodeUint(dst, uint64(key.tokenLength)) + c.encodeUint(dst, uint64(key.length)) _, _ = dst.Write(key.Bytes()) } -func (c *codecImpl) decodeKey(src *bytes.Reader, branchFactor BranchFactor) (Key, error) { +func (c *codecImpl) decodeKey(src *bytes.Reader) (Key, error) { if minKeyLen > src.Len() { return Key{}, io.ErrUnexpectedEOF } @@ -347,9 +347,10 @@ func (c *codecImpl) decodeKey(src *bytes.Reader, branchFactor BranchFactor) (Key if length > math.MaxInt { return Key{}, errIntOverflow } - result := emptyKey(branchFactor) - result.tokenLength = int(length) - keyBytesLen := result.bytesNeeded(result.tokenLength) + result := Key{ + length: int(length), + } + keyBytesLen := bytesNeeded(result.length) if keyBytesLen > src.Len() { return Key{}, io.ErrUnexpectedEOF } @@ -363,8 +364,8 @@ func (c *codecImpl) decodeKey(src *bytes.Reader, branchFactor BranchFactor) (Key if result.hasPartialByte() { // Confirm that the padding bits in the partial byte are 0. // We want to only look at the bits to the right of the last token, which is at index length-1. - // Generate a mask with (8-bitsToShift) 0s followed by bitsToShift 1s. - paddingMask := byte(0xFF >> (8 - result.bitsToShift(result.tokenLength-1))) + // Generate a mask where the (result.length % 8) left bits are 0. + paddingMask := byte(0xFF >> (result.length % 8)) if buffer[keyBytesLen-1]&paddingMask != 0 { return Key{}, errNonZeroKeyPadding } diff --git a/x/merkledb/codec_test.go b/x/merkledb/codec_test.go index cb83e1ce582c..00e5790b3171 100644 --- a/x/merkledb/codec_test.go +++ b/x/merkledb/codec_test.go @@ -80,24 +80,22 @@ func FuzzCodecKey(f *testing.F) { b []byte, ) { require := require.New(t) - for _, branchFactor := range branchFactors { - codec := codec.(*codecImpl) - reader := bytes.NewReader(b) - startLen := reader.Len() - got, err := codec.decodeKey(reader, branchFactor) - if err != nil { - t.SkipNow() - } - endLen := reader.Len() - numRead := startLen - endLen - - // Encoding [got] should be the same as [b]. - var buf bytes.Buffer - codec.encodeKey(&buf, got) - bufBytes := buf.Bytes() - require.Len(bufBytes, numRead) - require.Equal(b[:numRead], bufBytes) + codec := codec.(*codecImpl) + reader := bytes.NewReader(b) + startLen := reader.Len() + got, err := codec.decodeKey(reader) + if err != nil { + t.SkipNow() } + endLen := reader.Len() + numRead := startLen - endLen + + // Encoding [got] should be the same as [b]. + var buf bytes.Buffer + codec.encodeKey(&buf, got) + bufBytes := buf.Bytes() + require.Len(bufBytes, numRead) + require.Equal(b[:numRead], bufBytes) }, ) } @@ -109,17 +107,15 @@ func FuzzCodecDBNodeCanonical(f *testing.F) { b []byte, ) { require := require.New(t) - for _, branchFactor := range branchFactors { - codec := codec.(*codecImpl) - node := &dbNode{} - if err := codec.decodeDBNode(b, node, branchFactor); err != nil { - t.SkipNow() - } - - // Encoding [node] should be the same as [b]. - buf := codec.encodeDBNode(node) - require.Equal(b, buf) + codec := codec.(*codecImpl) + node := &dbNode{} + if err := codec.decodeDBNode(b, node); err != nil { + t.SkipNow() } + + // Encoding [node] should be the same as [b]. + buf := codec.encodeDBNode(node) + require.Equal(b, buf) }, ) } @@ -133,7 +129,7 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) { valueBytes []byte, ) { require := require.New(t) - for _, branchFactor := range branchFactors { + for _, bf := range validBranchFactors { r := rand.New(rand.NewSource(int64(randSeed))) // #nosec G404 value := maybe.Nothing[[]byte]() @@ -148,7 +144,7 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) { value = maybe.Some(valueBytes) } - numChildren := r.Intn(int(branchFactor)) // #nosec G404 + numChildren := r.Intn(int(bf)) // #nosec G404 children := map[byte]child{} for i := 0; i < numChildren; i++ { @@ -159,7 +155,7 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) { _, _ = r.Read(childKeyBytes) // #nosec G404 children[byte(i)] = child{ - compressedKey: ToKey(childKeyBytes, branchFactor), + compressedKey: ToKey(childKeyBytes), id: childID, } } @@ -171,7 +167,7 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) { nodeBytes := codec.encodeDBNode(&node) var gotNode dbNode - require.NoError(codec.decodeDBNode(nodeBytes, &gotNode, branchFactor)) + require.NoError(codec.decodeDBNode(nodeBytes, &gotNode)) require.Equal(node, gotNode) nodeBytes2 := codec.encodeDBNode(&gotNode) @@ -181,31 +177,15 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) { ) } -func TestCodecDecodeDBNode(t *testing.T) { +func TestCodecDecodeDBNode_TooShort(t *testing.T) { require := require.New(t) var ( parsedDBNode dbNode tooShortBytes = make([]byte, minDBNodeLen-1) ) - err := codec.decodeDBNode(tooShortBytes, &parsedDBNode, BranchFactor16) + err := codec.decodeDBNode(tooShortBytes, &parsedDBNode) require.ErrorIs(err, io.ErrUnexpectedEOF) - - proof := dbNode{ - value: maybe.Some([]byte{1}), - children: map[byte]child{}, - } - - nodeBytes := codec.encodeDBNode(&proof) - // Remove num children (0) from end - nodeBytes = nodeBytes[:len(nodeBytes)-minVarIntLen] - proofBytesBuf := bytes.NewBuffer(nodeBytes) - - // Put num children > branch factor - codec.(*codecImpl).encodeUint(proofBytesBuf, uint64(BranchFactor16+1)) - - err = codec.decodeDBNode(proofBytesBuf.Bytes(), &parsedDBNode, BranchFactor16) - require.ErrorIs(err, errTooManyChildren) } // Ensure that encodeHashValues is deterministic @@ -219,18 +199,18 @@ func FuzzEncodeHashValues(f *testing.F) { randSeed int, ) { require := require.New(t) - for _, branchFactor := range branchFactors { // Create a random *hashValues + for _, bf := range validBranchFactors { // Create a random node r := rand.New(rand.NewSource(int64(randSeed))) // #nosec G404 children := map[byte]child{} - numChildren := r.Intn(int(branchFactor)) // #nosec G404 + numChildren := r.Intn(int(bf)) // #nosec G404 for i := 0; i < numChildren; i++ { compressedKeyLen := r.Intn(32) // #nosec G404 compressedKeyBytes := make([]byte, compressedKeyLen) _, _ = r.Read(compressedKeyBytes) // #nosec G404 children[byte(i)] = child{ - compressedKey: ToKey(compressedKeyBytes, branchFactor), + compressedKey: ToKey(compressedKeyBytes), id: ids.GenerateTestID(), hasValue: r.Intn(2) == 1, // #nosec G404 } @@ -247,13 +227,15 @@ func FuzzEncodeHashValues(f *testing.F) { key := make([]byte, r.Intn(32)) // #nosec G404 _, _ = r.Read(key) // #nosec G404 - hv := &hashValues{ - Children: children, - Value: value, - Key: ToKey(key, branchFactor), + hv := &node{ + key: ToKey(key), + dbNode: dbNode{ + children: children, + value: value, + }, } - // Serialize the *hashValues with both codecs + // Serialize hv with both codecs hvBytes1 := codec1.encodeHashValues(hv) hvBytes2 := codec2.encodeHashValues(hv) @@ -267,6 +249,6 @@ func FuzzEncodeHashValues(f *testing.F) { func TestCodecDecodeKeyLengthOverflowRegression(t *testing.T) { codec := codec.(*codecImpl) bytes := bytes.NewReader(binary.AppendUvarint(nil, math.MaxInt)) - _, err := codec.decodeKey(bytes, BranchFactor16) + _, err := codec.decodeKey(bytes) require.ErrorIs(t, err, io.ErrUnexpectedEOF) } diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 87439010b1f0..88dd667ae22a 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -204,8 +204,7 @@ type merkleDB struct { // [calculateNodeIDsHelper] at any given time. calculateNodeIDsSema *semaphore.Weighted - toKey func(p []byte) Key - rootKey Key + tokenSize int } // New returns a new merkle database. @@ -223,17 +222,13 @@ func newDatabase( config Config, metrics merkleMetrics, ) (*merkleDB, error) { - rootGenConcurrency := uint(runtime.NumCPU()) - if config.RootGenConcurrency != 0 { - rootGenConcurrency = config.RootGenConcurrency - } - if err := config.BranchFactor.Valid(); err != nil { return nil, err } - toKey := func(b []byte) Key { - return ToKey(b, config.BranchFactor) + rootGenConcurrency := uint(runtime.NumCPU()) + if config.RootGenConcurrency != 0 { + rootGenConcurrency = config.RootGenConcurrency } // Share a sync.Pool of []byte between the intermediateNodeDB and valueNodeDB @@ -246,15 +241,14 @@ func newDatabase( trieDB := &merkleDB{ metrics: metrics, baseDB: db, - valueNodeDB: newValueNodeDB(db, bufferPool, metrics, int(config.ValueNodeCacheSize), config.BranchFactor), - intermediateNodeDB: newIntermediateNodeDB(db, bufferPool, metrics, int(config.IntermediateNodeCacheSize), int(config.EvictionBatchSize)), - history: newTrieHistory(int(config.HistoryLength), toKey), + valueNodeDB: newValueNodeDB(db, bufferPool, metrics, int(config.ValueNodeCacheSize)), + intermediateNodeDB: newIntermediateNodeDB(db, bufferPool, metrics, int(config.IntermediateNodeCacheSize), int(config.EvictionBatchSize), BranchFactorToTokenSize[config.BranchFactor]), + history: newTrieHistory(int(config.HistoryLength)), debugTracer: getTracerIfEnabled(config.TraceLevel, DebugTrace, config.Tracer), infoTracer: getTracerIfEnabled(config.TraceLevel, InfoTrace, config.Tracer), childViews: make([]*trieView, 0, defaultPreallocationSize), calculateNodeIDsSema: semaphore.NewWeighted(int64(rootGenConcurrency)), - toKey: toKey, - rootKey: toKey(rootKey), + tokenSize: BranchFactorToTokenSize[config.BranchFactor], } root, err := trieDB.initializeRootIfNeeded() @@ -292,7 +286,7 @@ func newDatabase( // Deletes every intermediate node and rebuilds them by re-adding every key/value. // TODO: make this more efficient by only clearing out the stale portions of the trie. func (db *merkleDB) rebuild(ctx context.Context, cacheSize int) error { - db.root = newNode(nil, db.rootKey) + db.root = newNode(Key{}) // Delete intermediate nodes. if err := database.ClearPrefix(db.baseDB, intermediateNodePrefix, rebuildIntermediateDeletionWriteSize); err != nil { @@ -474,7 +468,7 @@ func (db *merkleDB) PrefetchPath(key []byte) error { } func (db *merkleDB) prefetchPath(view *trieView, keyBytes []byte) error { - return view.visitPathToKey(db.toKey(keyBytes), func(n *node) error { + return view.visitPathToKey(ToKey(keyBytes), func(n *node) error { if !n.hasValue() { return db.intermediateNodeDB.nodeCache.Put(n.key, n) } @@ -503,7 +497,7 @@ func (db *merkleDB) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []e values := make([][]byte, len(keys)) errors := make([]error, len(keys)) for i, key := range keys { - values[i], errors[i] = db.getValueCopy(db.toKey(key)) + values[i], errors[i] = db.getValueCopy(ToKey(key)) } return values, errors } @@ -517,7 +511,7 @@ func (db *merkleDB) GetValue(ctx context.Context, key []byte) ([]byte, error) { db.lock.RLock() defer db.lock.RUnlock() - return db.getValueCopy(db.toKey(key)) + return db.getValueCopy(ToKey(key)) } // getValueCopy returns a copy of the value for the given [key]. @@ -783,7 +777,7 @@ func (db *merkleDB) Has(k []byte) (bool, error) { return false, database.ErrClosed } - _, err := db.getValueWithoutLock(db.toKey(k)) + _, err := db.getValueWithoutLock(ToKey(k)) if err == database.ErrNotFound { return false, nil } @@ -921,7 +915,7 @@ func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *trieView) e return nil } - rootChange, ok := changes.nodes[db.rootKey] + rootChange, ok := changes.nodes[Key{}] if !ok { return errNoNewRoot } @@ -1020,7 +1014,7 @@ func (db *merkleDB) VerifyChangeProof( return err } - smallestKey := maybe.Bind(start, db.toKey) + smallestKey := maybe.Bind(start, ToKey) // Make sure the start proof, if given, is well-formed. if err := verifyProofPath(proof.StartProof, smallestKey); err != nil { @@ -1030,12 +1024,12 @@ func (db *merkleDB) VerifyChangeProof( // Find the greatest key in [proof.KeyChanges] // Note that [proof.EndProof] is a proof for this key. // [largestKey] is also used when we add children of proof nodes to [trie] below. - largestKey := maybe.Bind(end, db.toKey) + largestKey := maybe.Bind(end, ToKey) if len(proof.KeyChanges) > 0 { // If [proof] has key-value pairs, we should insert children // greater than [end] to ancestors of the node containing [end] // so that we get the expected root ID. - largestKey = maybe.Some(db.toKey(proof.KeyChanges[len(proof.KeyChanges)-1].Key)) + largestKey = maybe.Some(ToKey(proof.KeyChanges[len(proof.KeyChanges)-1].Key)) } // Make sure the end proof, if given, is well-formed. @@ -1045,7 +1039,7 @@ func (db *merkleDB) VerifyChangeProof( keyValues := make(map[Key]maybe.Maybe[[]byte], len(proof.KeyChanges)) for _, keyValue := range proof.KeyChanges { - keyValues[db.toKey(keyValue.Key)] = keyValue.Value + keyValues[ToKey(keyValue.Key)] = keyValue.Value } // want to prevent commit writes to DB, but not prevent DB reads @@ -1149,9 +1143,9 @@ func (db *merkleDB) initializeRootIfNeeded() (ids.ID, error) { // not sure if the root exists or had a value or not // check under both prefixes var err error - db.root, err = db.intermediateNodeDB.Get(db.rootKey) + db.root, err = db.intermediateNodeDB.Get(Key{}) if err == database.ErrNotFound { - db.root, err = db.valueNodeDB.Get(db.rootKey) + db.root, err = db.valueNodeDB.Get(Key{}) } if err == nil { // Root already exists, so calculate its id @@ -1163,12 +1157,12 @@ func (db *merkleDB) initializeRootIfNeeded() (ids.ID, error) { } // Root doesn't exist; make a new one. - db.root = newNode(nil, db.rootKey) + db.root = newNode(Key{}) // update its ID db.root.calculateID(db.metrics) - if err := db.intermediateNodeDB.Put(db.rootKey, db.root); err != nil { + if err := db.intermediateNodeDB.Put(Key{}, db.root); err != nil { return ids.Empty, err } @@ -1248,7 +1242,7 @@ func (db *merkleDB) getNode(key Key, hasValue bool) (*node, error) { switch { case db.closed: return nil, database.ErrClosed - case key == db.rootKey: + case key == Key{}: return db.root, nil case hasValue: return db.valueNodeDB.Get(key) diff --git a/x/merkledb/db_test.go b/x/merkledb/db_test.go index d4f09803cdaf..2d6439fd294b 100644 --- a/x/merkledb/db_test.go +++ b/x/merkledb/db_test.go @@ -63,7 +63,7 @@ func Test_MerkleDB_Get_Safety(t *testing.T) { val, err := db.Get(keyBytes) require.NoError(err) - n, err := db.getNode(ToKey(keyBytes, BranchFactor16), true) + n, err := db.getNode(ToKey(keyBytes), true) require.NoError(err) // node's value shouldn't be affected by the edit @@ -96,7 +96,7 @@ func Test_MerkleDB_GetValues_Safety(t *testing.T) { } func Test_MerkleDB_DB_Interface(t *testing.T) { - for _, bf := range branchFactors { + for _, bf := range validBranchFactors { for _, test := range database.Tests { db, err := getBasicDBWithBranchFactor(bf) require.NoError(t, err) @@ -108,7 +108,7 @@ func Test_MerkleDB_DB_Interface(t *testing.T) { func Benchmark_MerkleDB_DBInterface(b *testing.B) { for _, size := range database.BenchmarkSizes { keys, values := database.SetupBenchmark(b, size[0], size[1], size[2]) - for _, bf := range branchFactors { + for _, bf := range validBranchFactors { for _, bench := range database.Benchmarks { db, err := getBasicDBWithBranchFactor(bf) require.NoError(b, err) @@ -785,7 +785,7 @@ func FuzzMerkleDBEmptyRandomizedActions(f *testing.F) { } require := require.New(t) r := rand.New(rand.NewSource(randSeed)) // #nosec G404 - for _, bf := range branchFactors { + for _, ts := range validTokenSizes { runRandDBTest( require, r, @@ -795,7 +795,7 @@ func FuzzMerkleDBEmptyRandomizedActions(f *testing.F) { size, 0.01, /*checkHashProbability*/ ), - bf, + ts, ) } }) @@ -813,7 +813,7 @@ func FuzzMerkleDBInitialValuesRandomizedActions(f *testing.F) { } require := require.New(t) r := rand.New(rand.NewSource(randSeed)) // #nosec G404 - for _, bf := range branchFactors { + for _, ts := range validTokenSizes { runRandDBTest( require, r, @@ -824,7 +824,7 @@ func FuzzMerkleDBInitialValuesRandomizedActions(f *testing.F) { numSteps, 0.001, /*checkHashProbability*/ ), - bf, + ts, ) } }) @@ -851,8 +851,8 @@ const ( opMax // boundary value, not an actual op ) -func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, bf BranchFactor) { - db, err := getBasicDBWithBranchFactor(bf) +func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, tokenSize int) { + db, err := getBasicDBWithBranchFactor(tokenSizeToBranchFactor[tokenSize]) require.NoError(err) const ( @@ -877,13 +877,13 @@ func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, bf Br case opUpdate: require.NoError(currentBatch.Put(step.key, step.value)) - uncommittedKeyValues[ToKey(step.key, bf)] = step.value - uncommittedDeletes.Remove(ToKey(step.key, bf)) + uncommittedKeyValues[ToKey(step.key)] = step.value + uncommittedDeletes.Remove(ToKey(step.key)) case opDelete: require.NoError(currentBatch.Delete(step.key)) - uncommittedDeletes.Add(ToKey(step.key, bf)) - delete(uncommittedKeyValues, ToKey(step.key, bf)) + uncommittedDeletes.Add(ToKey(step.key)) + delete(uncommittedKeyValues, ToKey(step.key)) case opGenerateRangeProof: root, err := db.GetMerkleRoot(context.Background()) require.NoError(err) @@ -910,6 +910,7 @@ func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, bf Br start, end, root, + tokenSize, )) case opGenerateChangeProof: root, err := db.GetMerkleRoot(context.Background()) @@ -937,7 +938,7 @@ func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, bf Br require.NoError(err) require.LessOrEqual(len(changeProof.KeyChanges), maxProofLen) - changeProofDB, err := getBasicDBWithBranchFactor(bf) + changeProofDB, err := getBasicDBWithBranchFactor(tokenSizeToBranchFactor[tokenSize]) require.NoError(err) require.NoError(changeProofDB.VerifyChangeProof( @@ -984,10 +985,10 @@ func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, bf Br require.ErrorIs(err, database.ErrNotFound) } - want := values[ToKey(step.key, bf)] + want := values[ToKey(step.key)] require.True(bytes.Equal(want, v)) // Use bytes.Equal so nil treated equal to []byte{} - trieValue, err := getNodeValueWithBranchFactor(db, string(step.key), bf) + trieValue, err := getNodeValue(db, string(step.key)) if err != nil { require.ErrorIs(err, database.ErrNotFound) } @@ -995,7 +996,7 @@ func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, bf Br require.True(bytes.Equal(want, trieValue)) // Use bytes.Equal so nil treated equal to []byte{} case opCheckhash: // Create a view with the same key-values as [db] - newDB, err := getBasicDBWithBranchFactor(bf) + newDB, err := getBasicDBWithBranchFactor(tokenSizeToBranchFactor[tokenSize]) require.NoError(err) ops := make([]database.BatchOp, 0, len(values)) @@ -1093,7 +1094,7 @@ func generateRandTestWithKeys( step.value = genEnd(step.key) case opCheckhash: // this gets really expensive so control how often it happens - if r.Float64() < checkHashProbability { + if r.Float64() > checkHashProbability { continue } } diff --git a/x/merkledb/helpers_test.go b/x/merkledb/helpers_test.go index 3cd84ce11e7c..b7a2908ff377 100644 --- a/x/merkledb/helpers_test.go +++ b/x/merkledb/helpers_test.go @@ -52,13 +52,13 @@ func writeBasicBatch(t *testing.T, db *merkleDB) { func newRandomProofNode(r *rand.Rand) ProofNode { key := make([]byte, r.Intn(32)) // #nosec G404 _, _ = r.Read(key) // #nosec G404 - serializedKey := ToKey(key, BranchFactor16) + serializedKey := ToKey(key) val := make([]byte, r.Intn(64)) // #nosec G404 _, _ = r.Read(val) // #nosec G404 children := map[byte]ids.ID{} - for j := 0; j < int(BranchFactor16); j++ { + for j := 0; j < 16; j++ { if r.Float64() < 0.5 { var childID ids.ID _, _ = r.Read(childID[:]) // #nosec G404 diff --git a/x/merkledb/history.go b/x/merkledb/history.go index c82fbb1e5f78..103c4c9357e8 100644 --- a/x/merkledb/history.go +++ b/x/merkledb/history.go @@ -32,8 +32,6 @@ type trieHistory struct { // Each change is tagged with this monotonic increasing number. nextInsertNumber uint64 - - toKey func([]byte) Key } // Tracks the beginning and ending state of a value. @@ -65,12 +63,11 @@ func newChangeSummary(estimatedSize int) *changeSummary { } } -func newTrieHistory(maxHistoryLookback int, toKey func([]byte) Key) *trieHistory { +func newTrieHistory(maxHistoryLookback int) *trieHistory { return &trieHistory{ maxHistoryLen: maxHistoryLookback, history: buffer.NewUnboundedDeque[*changeSummaryAndInsertNumber](maxHistoryLookback), lastChanges: make(map[ids.ID]*changeSummaryAndInsertNumber), - toKey: toKey, } } @@ -158,8 +155,8 @@ func (th *trieHistory) getValueChanges( // in order to stay within the [maxLength] limit if necessary. changedKeys = set.Set[Key]{} - startKey = maybe.Bind(start, th.toKey) - endKey = maybe.Bind(end, th.toKey) + startKey = maybe.Bind(start, ToKey) + endKey = maybe.Bind(end, ToKey) // For each element in the history in the range between [startRoot]'s // last appearance (exclusive) and [endRoot]'s last appearance (inclusive), @@ -237,8 +234,8 @@ func (th *trieHistory) getChangesToGetToRoot(rootID ids.ID, start maybe.Maybe[[] } var ( - startKey = maybe.Bind(start, th.toKey) - endKey = maybe.Bind(end, th.toKey) + startKey = maybe.Bind(start, ToKey) + endKey = maybe.Bind(end, ToKey) combinedChanges = newChangeSummary(defaultPreallocationSize) mostRecentChangeInsertNumber = th.nextInsertNumber - 1 mostRecentChangeIndex = th.history.Len() - 1 diff --git a/x/merkledb/history_test.go b/x/merkledb/history_test.go index 1261c92b22df..f27c1293cde0 100644 --- a/x/merkledb/history_test.go +++ b/x/merkledb/history_test.go @@ -37,7 +37,7 @@ func Test_History_Simple(t *testing.T) { require.NoError(err) require.NotNil(origProof) origRootID := db.root.id - require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Put([]byte("key"), []byte("value0"))) @@ -45,7 +45,7 @@ func Test_History_Simple(t *testing.T) { newProof, err := db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Put([]byte("key1"), []byte("value1"))) @@ -54,7 +54,7 @@ func Test_History_Simple(t *testing.T) { newProof, err = db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Put([]byte("k"), []byte("v"))) @@ -62,7 +62,7 @@ func Test_History_Simple(t *testing.T) { newProof, err = db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Delete([]byte("k"))) @@ -78,7 +78,7 @@ func Test_History_Simple(t *testing.T) { newProof, err = db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) } func Test_History_Large(t *testing.T) { @@ -141,7 +141,7 @@ func Test_History_Large(t *testing.T) { require.NoError(err) require.NotNil(proof) - require.NoError(proof.Verify(context.Background(), maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), roots[i])) + require.NoError(proof.Verify(context.Background(), maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), roots[i], BranchFactorToTokenSize[config.BranchFactor])) } } } @@ -240,6 +240,7 @@ func Test_History_Trigger_History_Queue_Looping(t *testing.T) { maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, + db.tokenSize, )) // write a new value into the db, now there should be 2 roots in the history @@ -256,6 +257,7 @@ func Test_History_Trigger_History_Queue_Looping(t *testing.T) { maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, + db.tokenSize, )) // trigger a new root to be added to the history, which should cause rollover since there can only be 2 @@ -312,10 +314,10 @@ func Test_History_Values_Lookup_Over_Queue_Break(t *testing.T) { // changes should still be collectable even though the history has had to loop due to hitting max size changes, err := db.history.getValueChanges(startRoot, endRoot, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 10) require.NoError(err) - require.Contains(changes.values, ToKey([]byte("key1"), BranchFactor16)) - require.Equal([]byte("value1"), changes.values[ToKey([]byte("key1"), BranchFactor16)].after.Value()) - require.Contains(changes.values, ToKey([]byte("key2"), BranchFactor16)) - require.Equal([]byte("value3"), changes.values[ToKey([]byte("key2"), BranchFactor16)].after.Value()) + require.Contains(changes.values, ToKey([]byte("key1"))) + require.Equal([]byte("value1"), changes.values[ToKey([]byte("key1"))].after.Value()) + require.Contains(changes.values, ToKey([]byte("key2"))) + require.Equal([]byte("value3"), changes.values[ToKey([]byte("key2"))].after.Value()) } func Test_History_RepeatedRoot(t *testing.T) { @@ -337,7 +339,7 @@ func Test_History_RepeatedRoot(t *testing.T) { require.NoError(err) require.NotNil(origProof) origRootID := db.root.id - require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Put([]byte("key1"), []byte("other"))) @@ -347,7 +349,7 @@ func Test_History_RepeatedRoot(t *testing.T) { newProof, err := db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) // revert state to be the same as in orig proof batch = db.NewBatch() @@ -359,7 +361,7 @@ func Test_History_RepeatedRoot(t *testing.T) { newProof, err = db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) } func Test_History_ExcessDeletes(t *testing.T) { @@ -379,7 +381,7 @@ func Test_History_ExcessDeletes(t *testing.T) { require.NoError(err) require.NotNil(origProof) origRootID := db.root.id - require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Delete([]byte("key1"))) @@ -391,7 +393,7 @@ func Test_History_ExcessDeletes(t *testing.T) { newProof, err := db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) } func Test_History_DontIncludeAllNodes(t *testing.T) { @@ -411,7 +413,7 @@ func Test_History_DontIncludeAllNodes(t *testing.T) { require.NoError(err) require.NotNil(origProof) origRootID := db.root.id - require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Put([]byte("z"), []byte("z"))) @@ -419,7 +421,7 @@ func Test_History_DontIncludeAllNodes(t *testing.T) { newProof, err := db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) } func Test_History_Branching2Nodes(t *testing.T) { @@ -439,7 +441,7 @@ func Test_History_Branching2Nodes(t *testing.T) { require.NoError(err) require.NotNil(origProof) origRootID := db.root.id - require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Put([]byte("k"), []byte("v"))) @@ -447,7 +449,7 @@ func Test_History_Branching2Nodes(t *testing.T) { newProof, err := db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) } func Test_History_Branching3Nodes(t *testing.T) { @@ -467,7 +469,7 @@ func Test_History_Branching3Nodes(t *testing.T) { require.NoError(err) require.NotNil(origProof) origRootID := db.root.id - require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() require.NoError(batch.Put([]byte("key321"), []byte("value321"))) @@ -475,7 +477,7 @@ func Test_History_Branching3Nodes(t *testing.T) { newProof, err := db.GetRangeProofAtRoot(context.Background(), origRootID, maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(newProof) - require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID)) + require.NoError(newProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) } func Test_History_MaxLength(t *testing.T) { @@ -572,9 +574,7 @@ func TestHistoryRecord(t *testing.T) { require := require.New(t) maxHistoryLen := 3 - th := newTrieHistory(maxHistoryLen, func(bytes []byte) Key { - return ToKey(bytes, BranchFactor16) - }) + th := newTrieHistory(maxHistoryLen) changes := []*changeSummary{} for i := 0; i < maxHistoryLen; i++ { // Fill the history @@ -647,22 +647,20 @@ func TestHistoryRecord(t *testing.T) { func TestHistoryGetChangesToRoot(t *testing.T) { maxHistoryLen := 3 - history := newTrieHistory(maxHistoryLen, func(bytes []byte) Key { - return ToKey(bytes, BranchFactor16) - }) + history := newTrieHistory(maxHistoryLen) changes := []*changeSummary{} for i := 0; i < maxHistoryLen; i++ { // Fill the history changes = append(changes, &changeSummary{ rootID: ids.GenerateTestID(), nodes: map[Key]*change[*node]{ - history.toKey([]byte{byte(i)}): { + ToKey([]byte{byte(i)}): { before: &node{id: ids.GenerateTestID()}, after: &node{id: ids.GenerateTestID()}, }, }, values: map[Key]*change[maybe.Maybe[[]byte]]{ - history.toKey([]byte{byte(i)}): { + ToKey([]byte{byte(i)}): { before: maybe.Some([]byte{byte(i)}), after: maybe.Some([]byte{byte(i + 1)}), }, @@ -701,7 +699,7 @@ func TestHistoryGetChangesToRoot(t *testing.T) { require.Len(got.nodes, 1) require.Len(got.values, 1) reversedChanges := changes[maxHistoryLen-1] - removedKey := history.toKey([]byte{byte(maxHistoryLen - 1)}) + removedKey := ToKey([]byte{byte(maxHistoryLen - 1)}) require.Equal(reversedChanges.nodes[removedKey].before, got.nodes[removedKey].after) require.Equal(reversedChanges.values[removedKey].before, got.values[removedKey].after) require.Equal(reversedChanges.values[removedKey].after, got.values[removedKey].before) @@ -714,12 +712,12 @@ func TestHistoryGetChangesToRoot(t *testing.T) { require.Len(got.nodes, 2) require.Len(got.values, 2) reversedChanges1 := changes[maxHistoryLen-1] - removedKey1 := history.toKey([]byte{byte(maxHistoryLen - 1)}) + removedKey1 := ToKey([]byte{byte(maxHistoryLen - 1)}) require.Equal(reversedChanges1.nodes[removedKey1].before, got.nodes[removedKey1].after) require.Equal(reversedChanges1.values[removedKey1].before, got.values[removedKey1].after) require.Equal(reversedChanges1.values[removedKey1].after, got.values[removedKey1].before) reversedChanges2 := changes[maxHistoryLen-2] - removedKey2 := history.toKey([]byte{byte(maxHistoryLen - 2)}) + removedKey2 := ToKey([]byte{byte(maxHistoryLen - 2)}) require.Equal(reversedChanges2.nodes[removedKey2].before, got.nodes[removedKey2].after) require.Equal(reversedChanges2.values[removedKey2].before, got.values[removedKey2].after) require.Equal(reversedChanges2.values[removedKey2].after, got.values[removedKey2].before) @@ -733,12 +731,12 @@ func TestHistoryGetChangesToRoot(t *testing.T) { require.Len(got.nodes, 2) require.Len(got.values, 1) reversedChanges1 := changes[maxHistoryLen-1] - removedKey1 := history.toKey([]byte{byte(maxHistoryLen - 1)}) + removedKey1 := ToKey([]byte{byte(maxHistoryLen - 1)}) require.Equal(reversedChanges1.nodes[removedKey1].before, got.nodes[removedKey1].after) require.Equal(reversedChanges1.values[removedKey1].before, got.values[removedKey1].after) require.Equal(reversedChanges1.values[removedKey1].after, got.values[removedKey1].before) reversedChanges2 := changes[maxHistoryLen-2] - removedKey2 := history.toKey([]byte{byte(maxHistoryLen - 2)}) + removedKey2 := ToKey([]byte{byte(maxHistoryLen - 2)}) require.Equal(reversedChanges2.nodes[removedKey2].before, got.nodes[removedKey2].after) }, }, @@ -750,10 +748,10 @@ func TestHistoryGetChangesToRoot(t *testing.T) { require.Len(got.nodes, 2) require.Len(got.values, 1) reversedChanges1 := changes[maxHistoryLen-1] - removedKey1 := history.toKey([]byte{byte(maxHistoryLen - 1)}) + removedKey1 := ToKey([]byte{byte(maxHistoryLen - 1)}) require.Equal(reversedChanges1.nodes[removedKey1].before, got.nodes[removedKey1].after) reversedChanges2 := changes[maxHistoryLen-2] - removedKey2 := history.toKey([]byte{byte(maxHistoryLen - 2)}) + removedKey2 := ToKey([]byte{byte(maxHistoryLen - 2)}) require.Equal(reversedChanges2.nodes[removedKey2].before, got.nodes[removedKey2].after) require.Equal(reversedChanges2.values[removedKey2].before, got.values[removedKey2].after) require.Equal(reversedChanges2.values[removedKey2].after, got.values[removedKey2].before) diff --git a/x/merkledb/intermediate_node_db.go b/x/merkledb/intermediate_node_db.go index e146b943d6c2..1602aa05bbaa 100644 --- a/x/merkledb/intermediate_node_db.go +++ b/x/merkledb/intermediate_node_db.go @@ -13,7 +13,7 @@ const defaultBufferLength = 256 // Holds intermediate nodes. That is, those without values. // Changes to this database aren't written to [baseDB] until -// they're evicted from the [nodeCache] or Flush is called.. +// they're evicted from the [nodeCache] or Flush is called. type intermediateNodeDB struct { // Holds unused []byte bufferPool *sync.Pool @@ -31,6 +31,7 @@ type intermediateNodeDB struct { // the number of bytes to evict during an eviction batch evictionBatchSize int metrics merkleMetrics + tokenSize int } func newIntermediateNodeDB( @@ -39,12 +40,14 @@ func newIntermediateNodeDB( metrics merkleMetrics, size int, evictionBatchSize int, + tokenSize int, ) *intermediateNodeDB { result := &intermediateNodeDB{ metrics: metrics, baseDB: db, bufferPool: bufferPool, evictionBatchSize: evictionBatchSize, + tokenSize: tokenSize, } result.nodeCache = newOnEvictCache( size, @@ -121,15 +124,15 @@ func (db *intermediateNodeDB) Get(key Key) (*node, error) { // constructDBKey returns a key that can be used in [db.baseDB]. // We need to be able to differentiate between two keys of equal -// byte length but different token length, so we add padding to differentiate. +// byte length but different bit length, so we add padding to differentiate. // Additionally, we add a prefix indicating it is part of the intermediateNodeDB. func (db *intermediateNodeDB) constructDBKey(key Key) []byte { - if key.branchFactor == BranchFactor256 { - // For BranchFactor256, no padding is needed since byte length == token length + if db.tokenSize == 8 { + // For tokens of size byte, no padding is needed since byte length == token length return addPrefixToKey(db.bufferPool, intermediateNodePrefix, key.Bytes()) } - return addPrefixToKey(db.bufferPool, intermediateNodePrefix, key.Append(1).Bytes()) + return addPrefixToKey(db.bufferPool, intermediateNodePrefix, key.Extend(ToToken(1, db.tokenSize)).Bytes()) } func (db *intermediateNodeDB) Put(key Key, n *node) error { diff --git a/x/merkledb/intermediate_node_db_test.go b/x/merkledb/intermediate_node_db_test.go index 3d40aa7f8a05..027798017e95 100644 --- a/x/merkledb/intermediate_node_db_test.go +++ b/x/merkledb/intermediate_node_db_test.go @@ -23,7 +23,7 @@ import ( func Test_IntermediateNodeDB(t *testing.T) { require := require.New(t) - n := newNode(nil, ToKey([]byte{0x00}, BranchFactor16)) + n := newNode(ToKey([]byte{0x00})) n.setValue(maybe.Some([]byte{byte(0x02)})) nodeSize := cacheEntrySize(n.key, n) @@ -39,11 +39,12 @@ func Test_IntermediateNodeDB(t *testing.T) { &mockMetrics{}, cacheSize, evictionBatchSize, + 4, ) // Put a key-node pair - node1Key := ToKey([]byte{0x01}, BranchFactor16) - node1 := newNode(nil, node1Key) + node1Key := ToKey([]byte{0x01}) + node1 := newNode(node1Key) node1.setValue(maybe.Some([]byte{byte(0x01)})) require.NoError(db.Put(node1Key, node1)) @@ -53,7 +54,7 @@ func Test_IntermediateNodeDB(t *testing.T) { require.Equal(node1, node1Read) // Overwrite the key-node pair - node1Updated := newNode(nil, node1Key) + node1Updated := newNode(node1Key) node1Updated.setValue(maybe.Some([]byte{byte(0x02)})) require.NoError(db.Put(node1Key, node1Updated)) @@ -73,8 +74,8 @@ func Test_IntermediateNodeDB(t *testing.T) { expectedSize := 0 added := 0 for { - key := ToKey([]byte{byte(added)}, BranchFactor16) - node := newNode(nil, emptyKey(BranchFactor16)) + key := ToKey([]byte{byte(added)}) + node := newNode(Key{}) node.setValue(maybe.Some([]byte{byte(added)})) newExpectedSize := expectedSize + cacheEntrySize(key, node) if newExpectedSize > cacheSize { @@ -93,8 +94,8 @@ func Test_IntermediateNodeDB(t *testing.T) { // Put one more element in the cache, which should trigger an eviction // of all but 2 elements. 2 elements remain rather than 1 element because of // the added key prefix increasing the size tracked by the batch. - key := ToKey([]byte{byte(added)}, BranchFactor16) - node := newNode(nil, emptyKey(BranchFactor16)) + key := ToKey([]byte{byte(added)}) + node := newNode(Key{}) node.setValue(maybe.Some([]byte{byte(added)})) require.NoError(db.Put(key, node)) @@ -102,7 +103,7 @@ func Test_IntermediateNodeDB(t *testing.T) { require.Equal(1, db.nodeCache.fifo.Len()) gotKey, _, ok := db.nodeCache.fifo.Oldest() require.True(ok) - require.Equal(ToKey([]byte{byte(added)}, BranchFactor16), gotKey) + require.Equal(ToKey([]byte{byte(added)}), gotKey) // Get a node from the base database // Use an early key that has been evicted from the cache @@ -134,41 +135,45 @@ func FuzzIntermediateNodeDBConstructDBKey(f *testing.F) { cacheSize := 200 evictionBatchSize := cacheSize baseDB := memdb.New() - db := newIntermediateNodeDB( - baseDB, - &sync.Pool{ - New: func() interface{} { return make([]byte, 0) }, - }, - &mockMetrics{}, - cacheSize, - evictionBatchSize, - ) + f.Fuzz(func( t *testing.T, key []byte, tokenLength uint, ) { require := require.New(t) - for _, branchFactor := range branchFactors { - p := ToKey(key, branchFactor) - if p.tokenLength <= int(tokenLength) { + for _, tokenSize := range validTokenSizes { + db := newIntermediateNodeDB( + baseDB, + &sync.Pool{ + New: func() interface{} { return make([]byte, 0) }, + }, + &mockMetrics{}, + cacheSize, + evictionBatchSize, + tokenSize, + ) + + p := ToKey(key) + uBitLength := tokenLength * uint(tokenSize) + if uBitLength >= uint(p.length) { t.SkipNow() } - p = p.Take(int(tokenLength)) + p = p.Take(int(uBitLength)) constructedKey := db.constructDBKey(p) baseLength := len(p.value) + len(intermediateNodePrefix) require.Equal(intermediateNodePrefix, constructedKey[:len(intermediateNodePrefix)]) switch { - case branchFactor == BranchFactor256: + case tokenSize == 8: // for keys with tokens of size byte, no padding is added require.Equal(p.Bytes(), constructedKey[len(intermediateNodePrefix):]) case p.hasPartialByte(): require.Len(constructedKey, baseLength) - require.Equal(p.Append(1).Bytes(), constructedKey[len(intermediateNodePrefix):]) + require.Equal(p.Extend(ToToken(1, tokenSize)).Bytes(), constructedKey[len(intermediateNodePrefix):]) default: // when a whole number of bytes, there is an extra padding byte require.Len(constructedKey, baseLength+1) - require.Equal(p.Append(1).Bytes(), constructedKey[len(intermediateNodePrefix):]) + require.Equal(p.Extend(ToToken(1, tokenSize)).Bytes(), constructedKey[len(intermediateNodePrefix):]) } } }) @@ -187,10 +192,11 @@ func Test_IntermediateNodeDB_ConstructDBKey_DirtyBuffer(t *testing.T) { &mockMetrics{}, cacheSize, evictionBatchSize, + 4, ) db.bufferPool.Put([]byte{0xFF, 0xFF, 0xFF}) - constructedKey := db.constructDBKey(ToKey([]byte{}, BranchFactor16)) + constructedKey := db.constructDBKey(ToKey([]byte{})) require.Len(constructedKey, 2) require.Equal(intermediateNodePrefix, constructedKey[:len(intermediateNodePrefix)]) require.Equal(byte(16), constructedKey[len(constructedKey)-1]) @@ -201,9 +207,9 @@ func Test_IntermediateNodeDB_ConstructDBKey_DirtyBuffer(t *testing.T) { }, } db.bufferPool.Put([]byte{0xFF, 0xFF, 0xFF}) - p := ToKey([]byte{0xF0}, BranchFactor16).Take(1) + p := ToKey([]byte{0xF0}).Take(4) constructedKey = db.constructDBKey(p) require.Len(constructedKey, 2) require.Equal(intermediateNodePrefix, constructedKey[:len(intermediateNodePrefix)]) - require.Equal(p.Append(1).Bytes(), constructedKey[len(intermediateNodePrefix):]) + require.Equal(p.Extend(ToToken(1, 4)).Bytes(), constructedKey[len(intermediateNodePrefix):]) } diff --git a/x/merkledb/key.go b/x/merkledb/key.go index 461372a2baa8..b92ac2d7ceec 100644 --- a/x/merkledb/key.go +++ b/x/merkledb/key.go @@ -8,112 +8,135 @@ import ( "fmt" "strings" "unsafe" + + "golang.org/x/exp/maps" + "golang.org/x/exp/slices" ) var ( - errInvalidBranchFactor = errors.New("invalid branch factor") - - branchFactorToTokenConfig = map[BranchFactor]tokenConfig{ - BranchFactor2: { - branchFactor: BranchFactor2, - tokenBitSize: 1, - tokensPerByte: 8, - singleTokenMask: 0b0000_0001, - }, - BranchFactor4: { - branchFactor: BranchFactor4, - tokenBitSize: 2, - tokensPerByte: 4, - singleTokenMask: 0b0000_0011, - }, - BranchFactor16: { - branchFactor: BranchFactor16, - tokenBitSize: 4, - tokensPerByte: 2, - singleTokenMask: 0b0000_1111, - }, - BranchFactor256: { - branchFactor: BranchFactor256, - tokenBitSize: 8, - tokensPerByte: 1, - singleTokenMask: 0b1111_1111, - }, + ErrInvalidBranchFactor = errors.New("branch factor must match one of the predefined branch factors") + + BranchFactorToTokenSize = map[BranchFactor]int{ + BranchFactor2: 1, + BranchFactor4: 2, + BranchFactor16: 4, + BranchFactor256: 8, + } + + tokenSizeToBranchFactor = map[int]BranchFactor{ + 1: BranchFactor2, + 2: BranchFactor4, + 4: BranchFactor16, + 8: BranchFactor256, + } + + validTokenSizes = maps.Keys(tokenSizeToBranchFactor) + + validBranchFactors = []BranchFactor{ + BranchFactor2, + BranchFactor4, + BranchFactor16, + BranchFactor256, } ) type BranchFactor int const ( - BranchFactor2 BranchFactor = 2 - BranchFactor4 BranchFactor = 4 - BranchFactor16 BranchFactor = 16 - BranchFactor256 BranchFactor = 256 + BranchFactor2 = BranchFactor(2) + BranchFactor4 = BranchFactor(4) + BranchFactor16 = BranchFactor(16) + BranchFactor256 = BranchFactor(256) ) -func (f BranchFactor) Valid() error { - if _, ok := branchFactorToTokenConfig[f]; ok { - return nil +// Valid checks if BranchFactor [b] is one of the predefined valid options for BranchFactor +func (b BranchFactor) Valid() error { + for _, validBF := range validBranchFactors { + if validBF == b { + return nil + } } - return fmt.Errorf("%w: %d", errInvalidBranchFactor, f) + return fmt.Errorf("%w: %d", ErrInvalidBranchFactor, b) } -type tokenConfig struct { - branchFactor BranchFactor - tokensPerByte int - tokenBitSize byte - singleTokenMask byte +// ToToken creates a key version of the passed byte with bit length equal to tokenSize +func ToToken(val byte, tokenSize int) Key { + return Key{ + value: string([]byte{val << dualBitIndex(tokenSize)}), + length: tokenSize, + } } -type Key struct { - tokenLength int - value string - tokenConfig +// Token returns the token at the specified index, +// Assumes that bitindex + tokenSize doesn't cross a byte boundary +func (k Key) Token(bitIndex int, tokenSize int) byte { + storageByte := k.value[bitIndex/8] + // Shift the byte right to get the last bit to the rightmost position. + storageByte >>= dualBitIndex((bitIndex + tokenSize) % 8) + // Apply a mask to remove any other bits in the byte. + return storageByte & (0xFF >> dualBitIndex(tokenSize)) } -func emptyKey(bf BranchFactor) Key { - return Key{ - tokenConfig: branchFactorToTokenConfig[bf], +// iteratedHasPrefix checks if the provided prefix key is a prefix of the current key starting after the [bitsOffset]th bit +// this has better performance than constructing the actual key via Skip() then calling HasPrefix because it avoids an allocation +func (k Key) iteratedHasPrefix(prefix Key, bitsOffset int, tokenSize int) bool { + if k.length-bitsOffset < prefix.length { + return false } + for i := 0; i < prefix.length; i += tokenSize { + if k.Token(bitsOffset+i, tokenSize) != prefix.Token(i, tokenSize) { + return false + } + } + return true } -// ToKey returns [keyBytes] as a new key with the given [branchFactor]. -// Assumes [branchFactor] is valid. -func ToKey(keyBytes []byte, branchFactor BranchFactor) Key { - tc := branchFactorToTokenConfig[branchFactor] - return Key{ - value: byteSliceToString(keyBytes), - tokenConfig: tc, - tokenLength: len(keyBytes) * tc.tokensPerByte, - } +type Key struct { + // The number of bits in the key. + length int + // The string representation of the key + value string } -// TokensLength returns the number of tokens in [k]. -func (k Key) TokensLength() int { - return k.tokenLength +// ToKey returns [keyBytes] as a new key +// Assumes all bits of the keyBytes are part of the Key, call Key.Take if that is not the case +// Creates a copy of [keyBytes], so keyBytes are safe to edit after the call +func ToKey(keyBytes []byte) Key { + return toKey(slices.Clone(keyBytes)) +} + +// toKey returns [keyBytes] as a new key +// Assumes all bits of the keyBytes are part of the Key, call Key.Take if that is not the case +// Caller must not modify [keyBytes] after this call. +func toKey(keyBytes []byte) Key { + return Key{ + value: byteSliceToString(keyBytes), + length: len(keyBytes) * 8, + } } // hasPartialByte returns true iff the key fits into a non-whole number of bytes func (k Key) hasPartialByte() bool { - return k.tokenLength%k.tokensPerByte > 0 + return k.length%8 > 0 } // HasPrefix returns true iff [prefix] is a prefix of [k] or equal to it. func (k Key) HasPrefix(prefix Key) bool { // [prefix] must be shorter than [k] to be a prefix. - if k.tokenLength < prefix.tokenLength { + if k.length < prefix.length { return false } // The number of tokens in the last byte of [prefix], or zero // if [prefix] fits into a whole number of bytes. - remainderTokensCount := prefix.tokenLength % k.tokensPerByte - if remainderTokensCount == 0 { + remainderBitCount := prefix.length % 8 + if remainderBitCount == 0 { return strings.HasPrefix(k.value, prefix.value) } // check that the tokens in the partially filled final byte of [prefix] are // equal to the tokens in the final byte of [k]. - remainderBitsMask := byte(0xFF >> (remainderTokensCount * int(k.tokenBitSize))) + remainderBitsMask := byte(0xFF >> remainderBitCount) prefixRemainderTokens := prefix.value[len(prefix.value)-1] | remainderBitsMask remainderTokens := k.value[len(prefix.value)-1] | remainderBitsMask @@ -134,130 +157,64 @@ func (k Key) HasStrictPrefix(prefix Key) bool { return k != prefix && k.HasPrefix(prefix) } -// Token returns the token at the specified index, -func (k Key) Token(index int) byte { - // Find the index in [k.value] of the byte containing the token at [index]. - storageByteIndex := index / k.tokensPerByte - storageByte := k.value[storageByteIndex] - // Shift the byte right to get the token to the rightmost position. - storageByte >>= k.bitsToShift(index) - // Apply a mask to remove any other tokens in the byte. - return storageByte & k.singleTokenMask -} - -// Append returns a new Path that equals the current -// Path with [token] appended to the end. -func (k Key) Append(token byte) Key { - buffer := make([]byte, k.bytesNeeded(k.tokenLength+1)) - k.appendIntoBuffer(buffer, token) - return Key{ - value: byteSliceToString(buffer), - tokenLength: k.tokenLength + 1, - tokenConfig: k.tokenConfig, - } +// Length returns the number of bits in the Key +func (k Key) Length() int { + return k.length } // Greater returns true if current Key is greater than other Key func (k Key) Greater(other Key) bool { - return k.value > other.value || (k.value == other.value && k.tokenLength > other.tokenLength) + return k.value > other.value || (k.value == other.value && k.length > other.length) } // Less returns true if current Key is less than other Key func (k Key) Less(other Key) bool { - return k.value < other.value || (k.value == other.value && k.tokenLength < other.tokenLength) + return k.value < other.value || (k.value == other.value && k.length < other.length) } -// bitsToShift returns the number of bits to right shift a token -// within its storage byte to get it to the rightmost -// position in the byte. Equivalently, this is the number of bits -// to left shift a raw token value to get it to the correct position -// within its storage byte. -// Example with branch factor 16: -// Suppose the token array is -// [0x01, 0x02, 0x03, 0x04] -// The byte representation of this array is -// [0b0001_0010, 0b0011_0100] -// To get the token at index 0 (0b0001) to the rightmost position -// in its storage byte (i.e. to make 0b0001_0010 into 0b0000_0001), -// we need to shift 0b0001_0010 to the right by 4 bits. -// Similarly: -// * Token at index 1 (0b0010) needs to be shifted by 0 bits -// * Token at index 2 (0b0011) needs to be shifted by 4 bits -// * Token at index 3 (0b0100) needs to be shifted by 0 bits -func (k Key) bitsToShift(index int) byte { - // [tokenIndex] is the index of the token in the byte. - // For example, if the branch factor is 16, then each byte contains 2 tokens. - // The first is at index 0, and the second is at index 1, by this definition. - tokenIndex := index % k.tokensPerByte - // The bit within the byte that the token starts at. - startBitIndex := k.tokenBitSize * byte(tokenIndex) - // The bit within the byte that the token ends at. - endBitIndex := startBitIndex + k.tokenBitSize - 1 - // We want to right shift until [endBitIndex] is at the last index, so return - // the distance from the end of the byte to the end of the token. - // Note that 7 is the index of the last bit in a byte. - return 7 - endBitIndex -} - -// bytesNeeded returns the number of bytes needed to store the passed number of -// tokens. -// -// Invariant: [tokens] is a non-negative, but otherwise untrusted, input and -// this method must never overflow. -func (k Key) bytesNeeded(tokens int) int { - size := tokens / k.tokensPerByte - if tokens%k.tokensPerByte != 0 { - size++ +// Extend returns a new Key that is the in-order aggregation of Key [k] with [keys] +func (k Key) Extend(keys ...Key) Key { + totalBitLength := k.length + for _, key := range keys { + totalBitLength += key.length } - return size -} - -func (k Key) AppendExtend(token byte, extensionKey Key) Key { - appendBytes := k.bytesNeeded(k.tokenLength + 1) - totalLength := k.tokenLength + 1 + extensionKey.tokenLength - buffer := make([]byte, k.bytesNeeded(totalLength)) - k.appendIntoBuffer(buffer[:appendBytes], token) - - // the extension path will be shifted based on the number of tokens in the partial byte - tokenRemainder := (k.tokenLength + 1) % k.tokensPerByte - result := Key{ - value: byteSliceToString(buffer), - tokenLength: totalLength, - tokenConfig: k.tokenConfig, + buffer := make([]byte, bytesNeeded(totalBitLength)) + copy(buffer, k.value) + currentTotal := k.length + for _, key := range keys { + extendIntoBuffer(buffer, key, currentTotal) + currentTotal += key.length } - extensionBuffer := buffer[appendBytes-1:] - if extensionKey.tokenLength == 0 { - return result + return Key{ + value: byteSliceToString(buffer), + length: totalBitLength, } +} - // If the existing value fits into a whole number of bytes, - // the extension path can be copied directly into the buffer. - if tokenRemainder == 0 { - copy(extensionBuffer[1:], extensionKey.value) - return result +func extendIntoBuffer(buffer []byte, val Key, bitsOffset int) { + if val.length == 0 { + return + } + bytesOffset := bytesNeeded(bitsOffset) + bitsRemainder := bitsOffset % 8 + if bitsRemainder == 0 { + copy(buffer[bytesOffset:], val.value) + return } - // The existing path doesn't fit into a whole number of bytes. - // Figure out how many bits to shift. - shift := extensionKey.bitsToShift(tokenRemainder - 1) // Fill the partial byte with the first [shift] bits of the extension path - extensionBuffer[0] |= extensionKey.value[0] >> (8 - shift) + buffer[bytesOffset-1] |= val.value[0] >> bitsRemainder // copy the rest of the extension path bytes into the buffer, // shifted byte shift bits - shiftCopy(extensionBuffer[1:], extensionKey.value, shift) - - return result + shiftCopy(buffer[bytesOffset:], val.value, dualBitIndex(bitsRemainder)) } -func (k Key) appendIntoBuffer(buffer []byte, token byte) { - copy(buffer, k.value) - - // Shift [token] to the left such that it's at the correct - // index within its storage byte, then OR it with its storage - // byte to write the token into the byte. - buffer[len(buffer)-1] |= token << k.bitsToShift(k.tokenLength) +// dualBitIndex gets the dual of the bit index +// ex: in a byte, the bit 5 from the right is the same as the bit 3 from the left +func dualBitIndex(shift int) int { + return (8 - shift) % 8 } // Treats [src] as a bit array and copies it into [dst] shifted by [shift] bits. @@ -266,10 +223,11 @@ func (k Key) appendIntoBuffer(buffer []byte, token byte) { // Assumes len(dst) >= len(src)-1. // If len(dst) == len(src)-1 the last byte of [src] is only partially copied // (i.e. the rightmost bits are not copied). -func shiftCopy(dst []byte, src string, shift byte) { +func shiftCopy(dst []byte, src string, shift int) { i := 0 + dualShift := dualBitIndex(shift) for ; i < len(src)-1; i++ { - dst[i] = src[i]<>(8-shift) + dst[i] = src[i]<>dualShift } if i < len(dst) { @@ -279,59 +237,56 @@ func shiftCopy(dst []byte, src string, shift byte) { } // Skip returns a new Key that contains the last -// k.length-tokensToSkip tokens of [k]. -func (k Key) Skip(tokensToSkip int) Key { - if k.tokenLength == tokensToSkip { - return emptyKey(k.branchFactor) +// k.length-bitsToSkip bits of [k]. +func (k Key) Skip(bitsToSkip int) Key { + if k.length <= bitsToSkip { + return Key{} } result := Key{ - value: k.value[tokensToSkip/k.tokensPerByte:], - tokenLength: k.tokenLength - tokensToSkip, - tokenConfig: k.tokenConfig, + value: k.value[bitsToSkip/8:], + length: k.length - bitsToSkip, } // if the tokens to skip is a whole number of bytes, // the remaining bytes exactly equals the new key. - if tokensToSkip%k.tokensPerByte == 0 { + if bitsToSkip%8 == 0 { return result } - // tokensToSkip does not remove a whole number of bytes. + // bitsToSkip does not remove a whole number of bytes. // copy the remaining shifted bytes into a new buffer. - buffer := make([]byte, k.bytesNeeded(result.tokenLength)) - bitsSkipped := tokensToSkip * int(k.tokenBitSize) - bitsRemovedFromFirstRemainingByte := byte(bitsSkipped % 8) + buffer := make([]byte, bytesNeeded(result.length)) + bitsRemovedFromFirstRemainingByte := bitsToSkip % 8 shiftCopy(buffer, result.value, bitsRemovedFromFirstRemainingByte) result.value = byteSliceToString(buffer) return result } -// Take returns a new Key that contains the first tokensToTake tokens of the current Key -func (k Key) Take(tokensToTake int) Key { - if k.tokenLength <= tokensToTake { +// Take returns a new Key that contains the first bitsToTake bits of the current Key +func (k Key) Take(bitsToTake int) Key { + if k.length <= bitsToTake { return k } result := Key{ - tokenLength: tokensToTake, - tokenConfig: k.tokenConfig, + length: bitsToTake, } - if !result.hasPartialByte() { - result.value = k.value[:tokensToTake/k.tokensPerByte] + remainderBits := result.length % 8 + if remainderBits == 0 { + result.value = k.value[:bitsToTake/8] return result } // We need to zero out some bits of the last byte so a simple slice will not work // Create a new []byte to store the altered value - buffer := make([]byte, k.bytesNeeded(tokensToTake)) + buffer := make([]byte, bytesNeeded(bitsToTake)) copy(buffer, k.value) - // We want to zero out everything to the right of the last token, which is at index [tokensToTake] - 1 - // Mask will be (8-bitsToShift) number of 1's followed by (bitsToShift) number of 0's - mask := byte(0xFF << k.bitsToShift(tokensToTake-1)) - buffer[len(buffer)-1] &= mask + // We want to zero out everything to the right of the last token, which is at index bitsToTake-1 + // Mask will be (8-remainderBits) number of 1's followed by (remainderBits) number of 0's + buffer[len(buffer)-1] &= byte(0xFF << dualBitIndex(remainderBits)) result.value = byteSliceToString(buffer) return result @@ -345,20 +300,6 @@ func (k Key) Bytes() []byte { return stringToByteSlice(k.value) } -// iteratedHasPrefix checks if the provided prefix path is a prefix of the current path after having skipped [skipTokens] tokens first -// this has better performance than constructing the actual path via Skip() then calling HasPrefix because it avoids the []byte allocation -func (k Key) iteratedHasPrefix(skipTokens int, prefix Key) bool { - if k.tokenLength-skipTokens < prefix.tokenLength { - return false - } - for i := 0; i < prefix.tokenLength; i++ { - if k.Token(skipTokens+i) != prefix.Token(i) { - return false - } - } - return true -} - // byteSliceToString converts the []byte to a string // Invariant: The input []byte must not be modified. func byteSliceToString(bs []byte) string { @@ -374,3 +315,12 @@ func stringToByteSlice(value string) []byte { // "safe" because we never edit the []byte return unsafe.Slice(unsafe.StringData(value), len(value)) } + +// Returns the number of bytes needed to store [bits] bits. +func bytesNeeded(bits int) int { + size := bits / 8 + if bits%8 != 0 { + size++ + } + return size +} diff --git a/x/merkledb/key_test.go b/x/merkledb/key_test.go index e56ee1a98050..f0819483b1a8 100644 --- a/x/merkledb/key_test.go +++ b/x/merkledb/key_test.go @@ -5,48 +5,52 @@ package merkledb import ( "fmt" + "strconv" "testing" "github.com/stretchr/testify/require" ) -var branchFactors = []BranchFactor{ - BranchFactor2, - BranchFactor4, - BranchFactor16, - BranchFactor256, +func TestBranchFactor_Valid(t *testing.T) { + require := require.New(t) + for _, bf := range validBranchFactors { + require.NoError(bf.Valid()) + } + var empty BranchFactor + err := empty.Valid() + require.ErrorIs(err, ErrInvalidBranchFactor) } func TestHasPartialByte(t *testing.T) { - for _, branchFactor := range branchFactors { - t.Run(fmt.Sprint(branchFactor), func(t *testing.T) { + for _, ts := range validTokenSizes { + t.Run(strconv.Itoa(ts), func(t *testing.T) { require := require.New(t) - key := emptyKey(branchFactor) + key := Key{} require.False(key.hasPartialByte()) - if branchFactor == BranchFactor256 { + if ts == 8 { // Tokens are an entire byte so // there is never a partial byte. - key = key.Append(0) + key = key.Extend(ToToken(1, ts)) require.False(key.hasPartialByte()) - key = key.Append(0) + key = key.Extend(ToToken(0, ts)) require.False(key.hasPartialByte()) return } // Fill all but the last token of the first byte. - for i := 0; i < key.tokensPerByte-1; i++ { - key = key.Append(0) + for i := 0; i < 8-ts; i += ts { + key = key.Extend(ToToken(1, ts)) require.True(key.hasPartialByte()) } // Fill the last token of the first byte. - key = key.Append(0) + key = key.Extend(ToToken(0, ts)) require.False(key.hasPartialByte()) // Fill the first token of the second byte. - key = key.Append(0) + key = key.Extend(ToToken(0, ts)) require.True(key.hasPartialByte()) }) } @@ -55,66 +59,71 @@ func TestHasPartialByte(t *testing.T) { func Test_Key_Has_Prefix(t *testing.T) { type test struct { name string - keyA func(bf BranchFactor) Key - keyB func(bf BranchFactor) Key + keyA func(ts int) Key + keyB func(ts int) Key isStrictPrefix bool isPrefix bool } key := "Key" - keyLength := map[BranchFactor]int{} - for _, branchFactor := range branchFactors { - config := branchFactorToTokenConfig[branchFactor] - keyLength[branchFactor] = len(key) * config.tokensPerByte - } tests := []test{ { name: "equal keys", - keyA: func(bf BranchFactor) Key { return ToKey([]byte(key), bf) }, - keyB: func(bf BranchFactor) Key { return ToKey([]byte(key), bf) }, + keyA: func(ts int) Key { return ToKey([]byte(key)) }, + keyB: func(ts int) Key { return ToKey([]byte(key)) }, isPrefix: true, isStrictPrefix: false, }, { - name: "one key has one fewer token", - keyA: func(bf BranchFactor) Key { return ToKey([]byte(key), bf) }, - keyB: func(bf BranchFactor) Key { return ToKey([]byte(key), bf).Take(keyLength[bf] - 1) }, + name: "one key has one fewer token", + keyA: func(ts int) Key { return ToKey([]byte(key)) }, + keyB: func(ts int) Key { + return ToKey([]byte(key)).Take(len(key)*8 - ts) + }, isPrefix: true, isStrictPrefix: true, }, { - name: "equal keys, both have one fewer token", - keyA: func(bf BranchFactor) Key { return ToKey([]byte(key), bf).Take(keyLength[bf] - 1) }, - keyB: func(bf BranchFactor) Key { return ToKey([]byte(key), bf).Take(keyLength[bf] - 1) }, + name: "equal keys, both have one fewer token", + keyA: func(ts int) Key { + return ToKey([]byte(key)).Take(len(key)*8 - ts) + }, + keyB: func(ts int) Key { + return ToKey([]byte(key)).Take(len(key)*8 - ts) + }, isPrefix: true, isStrictPrefix: false, }, { name: "different keys", - keyA: func(bf BranchFactor) Key { return ToKey([]byte{0xF7}, bf) }, - keyB: func(bf BranchFactor) Key { return ToKey([]byte{0xF0}, bf) }, + keyA: func(ts int) Key { return ToKey([]byte{0xF7}) }, + keyB: func(ts int) Key { return ToKey([]byte{0xF0}) }, isPrefix: false, isStrictPrefix: false, }, { - name: "same bytes, different lengths", - keyA: func(bf BranchFactor) Key { return ToKey([]byte{0x10, 0x00}, bf).Take(1) }, - keyB: func(bf BranchFactor) Key { return ToKey([]byte{0x10, 0x00}, bf).Take(2) }, + name: "same bytes, different lengths", + keyA: func(ts int) Key { + return ToKey([]byte{0x10, 0x00}).Take(ts) + }, + keyB: func(ts int) Key { + return ToKey([]byte{0x10, 0x00}).Take(ts * 2) + }, isPrefix: false, isStrictPrefix: false, }, } for _, tt := range tests { - for _, bf := range branchFactors { - t.Run(tt.name+" bf "+fmt.Sprint(bf), func(t *testing.T) { + for _, ts := range validTokenSizes { + t.Run(tt.name+" ts "+strconv.Itoa(ts), func(t *testing.T) { require := require.New(t) - keyA := tt.keyA(bf) - keyB := tt.keyB(bf) + keyA := tt.keyA(ts) + keyB := tt.keyB(ts) require.Equal(tt.isPrefix, keyA.HasPrefix(keyB)) - require.Equal(tt.isPrefix, keyA.iteratedHasPrefix(0, keyB)) + require.Equal(tt.isPrefix, keyA.iteratedHasPrefix(keyB, 0, ts)) require.Equal(tt.isStrictPrefix, keyA.HasStrictPrefix(keyB)) }) } @@ -124,30 +133,29 @@ func Test_Key_Has_Prefix(t *testing.T) { func Test_Key_Skip(t *testing.T) { require := require.New(t) - for _, bf := range branchFactors { - empty := emptyKey(bf) - require.Equal(ToKey([]byte{0}, bf).Skip(empty.tokensPerByte), empty) - if bf == BranchFactor256 { + empty := Key{} + require.Equal(ToKey([]byte{0}).Skip(8), empty) + for _, ts := range validTokenSizes { + if ts == 8 { continue } - shortKey := ToKey([]byte{0b0101_0101}, bf) - longKey := ToKey([]byte{0b0101_0101, 0b0101_0101}, bf) - for i := 0; i < shortKey.tokensPerByte; i++ { - shift := byte(i) * shortKey.tokenBitSize - skipKey := shortKey.Skip(i) + shortKey := ToKey([]byte{0b0101_0101}) + longKey := ToKey([]byte{0b0101_0101, 0b0101_0101}) + for shift := 0; shift < 8; shift += ts { + skipKey := shortKey.Skip(shift) require.Equal(byte(0b0101_0101<>(8-shift)), skipKey.value[0]) require.Equal(byte(0b0101_0101<>shift)< ts { + key1 = key1.Take(key1.length - ts) + } + key2 := ToKey(second) + if forceSecondOdd && key2.length > ts { + key2 = key2.Take(key2.length - ts) + } + token := byte(int(tokenByte) % int(tokenSizeToBranchFactor[ts])) + extendedP := key1.Extend(ToToken(token, ts), key2) + require.Equal(key1.length+key2.length+ts, extendedP.length) + firstIndex := 0 + for ; firstIndex < key1.length; firstIndex += ts { + require.Equal(key1.Token(firstIndex, ts), extendedP.Token(firstIndex, ts)) + } + require.Equal(token, extendedP.Token(firstIndex, ts)) + firstIndex += ts + for secondIndex := 0; secondIndex < key2.length; secondIndex += ts { + require.Equal(key2.Token(secondIndex, ts), extendedP.Token(firstIndex+secondIndex, ts)) + } + } + }) +} + +func FuzzKeyDoubleExtend_Any(f *testing.F) { + f.Fuzz(func( + t *testing.T, + baseKeyBytes []byte, + firstKeyBytes []byte, + secondKeyBytes []byte, + forceBaseOdd bool, forceFirstOdd bool, forceSecondOdd bool, ) { require := require.New(t) - for _, branchFactor := range branchFactors { - key1 := ToKey(first, branchFactor) - if forceFirstOdd && key1.tokenLength > 0 { - key1 = key1.Take(key1.tokenLength - 1) + for _, ts := range validTokenSizes { + baseKey := ToKey(baseKeyBytes) + if forceBaseOdd && baseKey.length > ts { + baseKey = baseKey.Take(baseKey.length - ts) + } + firstKey := ToKey(firstKeyBytes) + if forceFirstOdd && firstKey.length > ts { + firstKey = firstKey.Take(firstKey.length - ts) } - key2 := ToKey(second, branchFactor) - if forceSecondOdd && key2.tokenLength > 0 { - key2 = key2.Take(key2.tokenLength - 1) + + secondKey := ToKey(secondKeyBytes) + if forceSecondOdd && secondKey.length > ts { + secondKey = secondKey.Take(secondKey.length - ts) } - token = byte(int(token) % int(branchFactor)) - extendedP := key1.AppendExtend(token, key2) - require.Equal(key1.tokenLength+key2.tokenLength+1, extendedP.tokenLength) - for i := 0; i < key1.tokenLength; i++ { - require.Equal(key1.Token(i), extendedP.Token(i)) + + extendedP := baseKey.Extend(firstKey, secondKey) + require.Equal(baseKey.length+firstKey.length+secondKey.length, extendedP.length) + totalIndex := 0 + for baseIndex := 0; baseIndex < baseKey.length; baseIndex += ts { + require.Equal(baseKey.Token(baseIndex, ts), extendedP.Token(baseIndex, ts)) } - require.Equal(token, extendedP.Token(key1.tokenLength)) - for i := 0; i < key2.tokenLength; i++ { - require.Equal(key2.Token(i), extendedP.Token(i+1+key1.tokenLength)) + totalIndex += baseKey.length + for firstIndex := 0; firstIndex < firstKey.length; firstIndex += ts { + require.Equal(firstKey.Token(firstIndex, ts), extendedP.Token(totalIndex+firstIndex, ts)) + } + totalIndex += firstKey.length + for secondIndex := 0; secondIndex < secondKey.length; secondIndex += ts { + require.Equal(secondKey.Token(secondIndex, ts), extendedP.Token(totalIndex+secondIndex, ts)) } } }) @@ -509,15 +478,18 @@ func FuzzKeySkip(f *testing.F) { tokensToSkip uint, ) { require := require.New(t) - for _, branchFactor := range branchFactors { - key1 := ToKey(first, branchFactor) - if int(tokensToSkip) >= key1.tokenLength { + key1 := ToKey(first) + for _, ts := range validTokenSizes { + // need bits to be a multiple of token size + ubitsToSkip := tokensToSkip * uint(ts) + if ubitsToSkip >= uint(key1.length) { t.SkipNow() } - key2 := key1.Skip(int(tokensToSkip)) - require.Equal(key1.tokenLength-int(tokensToSkip), key2.tokenLength) - for i := 0; i < key2.tokenLength; i++ { - require.Equal(key1.Token(int(tokensToSkip)+i), key2.Token(i)) + bitsToSkip := int(ubitsToSkip) + key2 := key1.Skip(bitsToSkip) + require.Equal(key1.length-bitsToSkip, key2.length) + for i := 0; i < key2.length; i += ts { + require.Equal(key1.Token(bitsToSkip+i, ts), key2.Token(i, ts)) } } }) @@ -527,19 +499,24 @@ func FuzzKeyTake(f *testing.F) { f.Fuzz(func( t *testing.T, first []byte, - tokensToTake uint, + uTokensToTake uint, ) { require := require.New(t) - for _, branchFactor := range branchFactors { - key1 := ToKey(first, branchFactor) - if int(tokensToTake) >= key1.tokenLength { + for _, ts := range validTokenSizes { + key1 := ToKey(first) + uBitsToTake := uTokensToTake * uint(ts) + if uBitsToTake >= uint(key1.length) { t.SkipNow() } - key2 := key1.Take(int(tokensToTake)) - require.Equal(int(tokensToTake), key2.tokenLength) - - for i := 0; i < key2.tokenLength; i++ { - require.Equal(key1.Token(i), key2.Token(i)) + bitsToTake := int(uBitsToTake) + key2 := key1.Take(bitsToTake) + require.Equal(bitsToTake, key2.length) + if key2.hasPartialByte() { + paddingMask := byte(0xFF >> (key2.length % 8)) + require.Zero(key2.value[len(key2.value)-1] & paddingMask) + } + for i := 0; i < bitsToTake; i += ts { + require.Equal(key1.Token(i, ts), key2.Token(i, ts)) } } }) @@ -550,7 +527,7 @@ func TestShiftCopy(t *testing.T) { dst []byte src []byte expected []byte - shift byte + shift int } tests := []test{ diff --git a/x/merkledb/node.go b/x/merkledb/node.go index 259e048c1793..3fd38021a0c8 100644 --- a/x/merkledb/node.go +++ b/x/merkledb/node.go @@ -14,13 +14,6 @@ import ( const HashLength = 32 -// the values that go into the node's id -type hashValues struct { - Children map[byte]child - Value maybe.Maybe[[]byte] - Key Key -} - // Representation of a node stored in the database. type dbNode struct { value maybe.Maybe[[]byte] @@ -43,24 +36,19 @@ type node struct { } // Returns a new node with the given [key] and no value. -// If [parent] isn't nil, the new node is added as a child of [parent]. -func newNode(parent *node, key Key) *node { - newNode := &node{ +func newNode(key Key) *node { + return &node{ dbNode: dbNode{ - children: make(map[byte]child, key.branchFactor), + children: make(map[byte]child, 2), }, key: key, } - if parent != nil { - parent.addChild(newNode) - } - return newNode } // Parse [nodeBytes] to a node and set its key to [key]. func parseNode(key Key, nodeBytes []byte) (*node, error) { n := dbNode{} - if err := codec.decodeDBNode(nodeBytes, &n, key.branchFactor); err != nil { + if err := codec.decodeDBNode(nodeBytes, &n); err != nil { return nil, err } result := &node{ @@ -101,11 +89,7 @@ func (n *node) calculateID(metrics merkleMetrics) { } metrics.HashCalculated() - bytes := codec.encodeHashValues(&hashValues{ - Children: n.children, - Value: n.valueDigest, - Key: n.key, - }) + bytes := codec.encodeHashValues(n) n.id = hashing.ComputeHash256Array(bytes) } @@ -127,11 +111,11 @@ func (n *node) setValueDigest() { // Adds [child] as a child of [n]. // Assumes [child]'s key is valid as a child of [n]. // That is, [n.key] is a prefix of [child.key]. -func (n *node) addChild(childNode *node) { +func (n *node) addChild(childNode *node, tokenSize int) { n.setChildEntry( - childNode.key.Token(n.key.tokenLength), + childNode.key.Token(n.key.length, tokenSize), child{ - compressedKey: childNode.key.Skip(n.key.tokenLength + 1), + compressedKey: childNode.key.Skip(n.key.length + tokenSize), id: childNode.id, hasValue: childNode.hasValue(), }, @@ -145,9 +129,9 @@ func (n *node) setChildEntry(index byte, childEntry child) { } // Removes [child] from [n]'s children. -func (n *node) removeChild(child *node) { +func (n *node) removeChild(child *node, tokenSize int) { n.onNodeChanged() - delete(n.children, child.key.Token(n.key.tokenLength)) + delete(n.children, child.key.Token(n.key.length, tokenSize)) } // clone Returns a copy of [n]. diff --git a/x/merkledb/node_test.go b/x/merkledb/node_test.go index 9632b7c7dacb..e0cb4dd04b06 100644 --- a/x/merkledb/node_test.go +++ b/x/merkledb/node_test.go @@ -13,54 +13,57 @@ import ( ) func Test_Node_Marshal(t *testing.T) { - root := newNode(nil, emptyKey(BranchFactor16)) + root := newNode(Key{}) require.NotNil(t, root) - fullKey := ToKey([]byte("key"), BranchFactor16) - childNode := newNode(root, fullKey) + fullKey := ToKey([]byte("key")) + childNode := newNode(fullKey) + root.addChild(childNode, 4) childNode.setValue(maybe.Some([]byte("value"))) require.NotNil(t, childNode) childNode.calculateID(&mockMetrics{}) - root.addChild(childNode) + root.addChild(childNode, 4) data := root.bytes() - rootParsed, err := parseNode(ToKey([]byte(""), BranchFactor16), data) + rootParsed, err := parseNode(ToKey([]byte("")), data) require.NoError(t, err) require.Len(t, rootParsed.children, 1) - rootIndex := getSingleChildKey(root).Token(root.key.tokenLength) - parsedIndex := getSingleChildKey(rootParsed).Token(rootParsed.key.tokenLength) + rootIndex := getSingleChildKey(root, 4).Token(0, 4) + parsedIndex := getSingleChildKey(rootParsed, 4).Token(0, 4) rootChildEntry := root.children[rootIndex] parseChildEntry := rootParsed.children[parsedIndex] require.Equal(t, rootChildEntry.id, parseChildEntry.id) } func Test_Node_Marshal_Errors(t *testing.T) { - root := newNode(nil, emptyKey(BranchFactor16)) + root := newNode(Key{}) require.NotNil(t, root) - fullKey := ToKey([]byte{255}, BranchFactor16) - childNode1 := newNode(root, fullKey) + fullKey := ToKey([]byte{255}) + childNode1 := newNode(fullKey) + root.addChild(childNode1, 4) childNode1.setValue(maybe.Some([]byte("value1"))) require.NotNil(t, childNode1) childNode1.calculateID(&mockMetrics{}) - root.addChild(childNode1) + root.addChild(childNode1, 4) - fullKey = ToKey([]byte{237}, BranchFactor16) - childNode2 := newNode(root, fullKey) + fullKey = ToKey([]byte{237}) + childNode2 := newNode(fullKey) + root.addChild(childNode2, 4) childNode2.setValue(maybe.Some([]byte("value2"))) require.NotNil(t, childNode2) childNode2.calculateID(&mockMetrics{}) - root.addChild(childNode2) + root.addChild(childNode2, 4) data := root.bytes() for i := 1; i < len(data); i++ { broken := data[:i] - _, err := parseNode(ToKey([]byte(""), BranchFactor16), broken) + _, err := parseNode(ToKey([]byte("")), broken) require.ErrorIs(t, err, io.ErrUnexpectedEOF) } } diff --git a/x/merkledb/proof.go b/x/merkledb/proof.go index 63ea34542c9b..f750158d4c11 100644 --- a/x/merkledb/proof.go +++ b/x/merkledb/proof.go @@ -31,8 +31,6 @@ var ( ErrNonIncreasingValues = errors.New("keys sent are not in increasing order") ErrStateFromOutsideOfRange = errors.New("state key falls outside of the start->end range") ErrNonIncreasingProofNodes = errors.New("each proof node key must be a strict prefix of the next") - ErrExtraProofNodes = errors.New("extra proof nodes in path") - ErrDataInMissingRootProof = errors.New("there should be no state or deleted keys in a change proof that had a missing root") ErrNoMerkleProof = errors.New("empty key response must include merkle proof") ErrShouldJustBeRoot = errors.New("end proof should only contain root") ErrNoStartProof = errors.New("no start proof") @@ -42,7 +40,6 @@ var ( ErrProofValueDoesntMatch = errors.New("the provided value does not match the proof node for the provided key's value") ErrProofNodeHasUnincludedValue = errors.New("the provided proof has a value for a key within the range that is not present in the provided key/values") ErrInvalidMaybe = errors.New("maybe is nothing but has value") - ErrInvalidChildIndex = errors.New("child index must be less than branch factor") ErrNilProofNode = errors.New("proof node is nil") ErrNilValueOrHash = errors.New("proof node's valueOrHash field is nil") ErrNilKey = errors.New("key is nil") @@ -69,7 +66,7 @@ type ProofNode struct { func (node *ProofNode) ToProto() *pb.ProofNode { pbNode := &pb.ProofNode{ Key: &pb.Key{ - Length: uint64(node.Key.tokenLength), + Length: uint64(node.Key.length), Value: node.Key.Bytes(), }, ValueOrHash: &pb.MaybeBytes{ @@ -87,7 +84,7 @@ func (node *ProofNode) ToProto() *pb.ProofNode { return pbNode } -func (node *ProofNode) UnmarshalProto(pbNode *pb.ProofNode, bf BranchFactor) error { +func (node *ProofNode) UnmarshalProto(pbNode *pb.ProofNode) error { switch { case pbNode == nil: return ErrNilProofNode @@ -97,17 +94,14 @@ func (node *ProofNode) UnmarshalProto(pbNode *pb.ProofNode, bf BranchFactor) err return ErrInvalidMaybe case pbNode.Key == nil: return ErrNilKey - } - node.Key = ToKey(pbNode.Key.Value, bf).Take(int(pbNode.Key.Length)) - - if len(pbNode.Key.Value) != node.Key.bytesNeeded(node.Key.tokenLength) { + case len(pbNode.Key.Value) != bytesNeeded(int(pbNode.Key.Length)): return ErrInvalidKeyLength } - + node.Key = ToKey(pbNode.Key.Value).Take(int(pbNode.Key.Length)) node.Children = make(map[byte]ids.ID, len(pbNode.Children)) for childIndex, childIDBytes := range pbNode.Children { - if childIndex >= uint32(bf) { - return ErrInvalidChildIndex + if childIndex > math.MaxUint8 { + return errChildIndexTooLarge } childID, err := ids.ToID(childIDBytes) if err != nil { @@ -123,7 +117,7 @@ func (node *ProofNode) UnmarshalProto(pbNode *pb.ProofNode, bf BranchFactor) err return nil } -// An inclusion/exclustion proof of a key. +// Proof represents an inclusion/exclusion proof of a key. type Proof struct { // Nodes in the proof path from root --> target key // (or node that would be where key is if it doesn't exist). @@ -140,7 +134,7 @@ type Proof struct { // Returns nil if the trie given in [proof] has root [expectedRootID]. // That is, this is a valid proof that [proof.Key] exists/doesn't exist // in the trie with root [expectedRootID]. -func (proof *Proof) Verify(ctx context.Context, expectedRootID ids.ID) error { +func (proof *Proof) Verify(ctx context.Context, expectedRootID ids.ID, tokenSize int) error { // Make sure the proof is well-formed. if len(proof.Path) == 0 { return ErrNoProof @@ -172,7 +166,7 @@ func (proof *Proof) Verify(ctx context.Context, expectedRootID ids.ID) error { } // Don't bother locking [view] -- nobody else has a reference to it. - view, err := getStandaloneTrieView(ctx, nil, proof.Key.branchFactor) + view, err := getStandaloneTrieView(ctx, nil, tokenSize) if err != nil { return err } @@ -215,7 +209,7 @@ func (proof *Proof) ToProto() *pb.Proof { return pbProof } -func (proof *Proof) UnmarshalProto(pbProof *pb.Proof, bf BranchFactor) error { +func (proof *Proof) UnmarshalProto(pbProof *pb.Proof) error { switch { case pbProof == nil: return ErrNilProof @@ -225,7 +219,7 @@ func (proof *Proof) UnmarshalProto(pbProof *pb.Proof, bf BranchFactor) error { return ErrInvalidMaybe } - proof.Key = ToKey(pbProof.Key, bf) + proof.Key = ToKey(pbProof.Key) if !pbProof.Value.IsNothing { proof.Value = maybe.Some(pbProof.Value.Value) @@ -233,7 +227,7 @@ func (proof *Proof) UnmarshalProto(pbProof *pb.Proof, bf BranchFactor) error { proof.Path = make([]ProofNode, len(pbProof.Proof)) for i, pbNode := range pbProof.Proof { - if err := proof.Path[i].UnmarshalProto(pbNode, bf); err != nil { + if err := proof.Path[i].UnmarshalProto(pbNode); err != nil { return err } } @@ -287,6 +281,7 @@ func (proof *RangeProof) Verify( start maybe.Maybe[[]byte], end maybe.Maybe[[]byte], expectedRootID ids.ID, + tokenSize int, ) error { switch { case start.HasValue() && end.HasValue() && bytes.Compare(start.Value(), end.Value()) > 0: @@ -301,15 +296,6 @@ func (proof *RangeProof) Verify( return ErrNoEndProof } - // determine branch factor based on proof paths - var branchFactor BranchFactor - if len(proof.StartProof) > 0 { - branchFactor = proof.StartProof[0].Key.branchFactor - } else { - // safe because invariants prevent both start proof and end proof from being empty at the same time - branchFactor = proof.EndProof[0].Key.branchFactor - } - // Make sure the key-value pairs are sorted and in [start, end]. if err := verifyKeyValues(proof.KeyValues, start, end); err != nil { return err @@ -322,24 +308,21 @@ func (proof *RangeProof) Verify( // If [largestProvenPath] is Nothing, [proof] should // provide and prove all keys > [smallestProvenPath]. // If both are Nothing, [proof] should prove the entire trie. - smallestProvenPath := maybe.Bind(start, func(b []byte) Key { - return ToKey(b, branchFactor) - }) + smallestProvenPath := maybe.Bind(start, ToKey) + + largestProvenPath := maybe.Bind(end, ToKey) - largestProvenPath := maybe.Bind(end, func(b []byte) Key { - return ToKey(b, branchFactor) - }) if len(proof.KeyValues) > 0 { // If [proof] has key-value pairs, we should insert children // greater than [largestProvenPath] to ancestors of the node containing // [largestProvenPath] so that we get the expected root ID. - largestProvenPath = maybe.Some(ToKey(proof.KeyValues[len(proof.KeyValues)-1].Key, branchFactor)) + largestProvenPath = maybe.Some(ToKey(proof.KeyValues[len(proof.KeyValues)-1].Key)) } // The key-value pairs (allegedly) proven by [proof]. keyValues := make(map[Key][]byte, len(proof.KeyValues)) for _, keyValue := range proof.KeyValues { - keyValues[ToKey(keyValue.Key, branchFactor)] = keyValue.Value + keyValues[ToKey(keyValue.Key)] = keyValue.Value } // Ensure that the start proof is valid and contains values that @@ -380,7 +363,7 @@ func (proof *RangeProof) Verify( } // Don't need to lock [view] because nobody else has a reference to it. - view, err := getStandaloneTrieView(ctx, ops, branchFactor) + view, err := getStandaloneTrieView(ctx, ops, tokenSize) if err != nil { return err } @@ -444,21 +427,21 @@ func (proof *RangeProof) ToProto() *pb.RangeProof { } } -func (proof *RangeProof) UnmarshalProto(pbProof *pb.RangeProof, bf BranchFactor) error { +func (proof *RangeProof) UnmarshalProto(pbProof *pb.RangeProof) error { if pbProof == nil { return ErrNilRangeProof } proof.StartProof = make([]ProofNode, len(pbProof.StartProof)) for i, protoNode := range pbProof.StartProof { - if err := proof.StartProof[i].UnmarshalProto(protoNode, bf); err != nil { + if err := proof.StartProof[i].UnmarshalProto(protoNode); err != nil { return err } } proof.EndProof = make([]ProofNode, len(pbProof.EndProof)) for i, protoNode := range pbProof.EndProof { - if err := proof.EndProof[i].UnmarshalProto(protoNode, bf); err != nil { + if err := proof.EndProof[i].UnmarshalProto(protoNode); err != nil { return err } } @@ -596,21 +579,21 @@ func (proof *ChangeProof) ToProto() *pb.ChangeProof { } } -func (proof *ChangeProof) UnmarshalProto(pbProof *pb.ChangeProof, bf BranchFactor) error { +func (proof *ChangeProof) UnmarshalProto(pbProof *pb.ChangeProof) error { if pbProof == nil { return ErrNilChangeProof } proof.StartProof = make([]ProofNode, len(pbProof.StartProof)) for i, protoNode := range pbProof.StartProof { - if err := proof.StartProof[i].UnmarshalProto(protoNode, bf); err != nil { + if err := proof.StartProof[i].UnmarshalProto(protoNode); err != nil { return err } } proof.EndProof = make([]ProofNode, len(pbProof.EndProof)) for i, protoNode := range pbProof.EndProof { - if err := proof.EndProof[i].UnmarshalProto(protoNode, bf); err != nil { + if err := proof.EndProof[i].UnmarshalProto(protoNode); err != nil { return err } } @@ -754,10 +737,8 @@ func verifyProofPath(proof []ProofNode, key maybe.Maybe[Key]) error { // loop over all but the last node since it will not have the prefix in exclusion proofs for i := 0; i < len(proof)-1; i++ { - nodeKey := proof[i].Key - if key.HasValue() && nodeKey.branchFactor != key.Value().branchFactor { - return ErrInconsistentBranchFactor - } + currentProofNode := proof[i] + nodeKey := currentProofNode.Key // Because the interface only support []byte keys, // a key with a partial byte should store a value @@ -770,11 +751,8 @@ func verifyProofPath(proof []ProofNode, key maybe.Maybe[Key]) error { return ErrProofNodeNotForKey } - // each node should have a key that has a matching BranchFactor and is a prefix of the next node's key + // each node should have a key that has a matching TokenConfig and is a prefix of the next node's key nextKey := proof[i+1].Key - if nextKey.branchFactor != nodeKey.branchFactor { - return ErrInconsistentBranchFactor - } if !nextKey.HasStrictPrefix(nodeKey) { return ErrNonIncreasingProofNodes } @@ -857,12 +835,12 @@ func addPathInfo( // Add [proofNode]'s children which are outside the range // [insertChildrenLessThan, insertChildrenGreaterThan]. - compressedPath := emptyKey(key.branchFactor) + compressedKey := Key{} for index, childID := range proofNode.Children { if existingChild, ok := n.children[index]; ok { - compressedPath = existingChild.compressedKey + compressedKey = existingChild.compressedKey } - childPath := key.AppendExtend(index, compressedPath) + childPath := key.Extend(ToToken(index, t.tokenSize), compressedKey) if (shouldInsertLeftChildren && childPath.Less(insertChildrenLessThan.Value())) || (shouldInsertRightChildren && childPath.Greater(insertChildrenGreaterThan.Value())) { // We didn't set the other values on the child entry, but it doesn't matter. @@ -871,7 +849,7 @@ func addPathInfo( index, child{ id: childID, - compressedKey: compressedPath, + compressedKey: compressedKey, }) } } @@ -881,7 +859,7 @@ func addPathInfo( } // getStandaloneTrieView returns a new view that has nothing in it besides the changes due to [ops] -func getStandaloneTrieView(ctx context.Context, ops []database.BatchOp, factor BranchFactor) (*trieView, error) { +func getStandaloneTrieView(ctx context.Context, ops []database.BatchOp, size int) (*trieView, error) { db, err := newDatabase( ctx, memdb.New(), @@ -890,7 +868,7 @@ func getStandaloneTrieView(ctx context.Context, ops []database.BatchOp, factor B Tracer: trace.Noop, ValueNodeCacheSize: verificationCacheSize, IntermediateNodeCacheSize: verificationCacheSize, - BranchFactor: factor, + BranchFactor: tokenSizeToBranchFactor[size], }, &mockMetrics{}, ) diff --git a/x/merkledb/proof_test.go b/x/merkledb/proof_test.go index bf9d9da18996..508e3d545d76 100644 --- a/x/merkledb/proof_test.go +++ b/x/merkledb/proof_test.go @@ -23,7 +23,7 @@ import ( func Test_Proof_Empty(t *testing.T) { proof := &Proof{} - err := proof.Verify(context.Background(), ids.Empty) + err := proof.Verify(context.Background(), ids.Empty, 4) require.ErrorIs(t, err, ErrNoProof) } @@ -43,7 +43,7 @@ func Test_Proof_Simple(t *testing.T) { proof, err := db.GetProof(ctx, []byte{}) require.NoError(err) - require.NoError(proof.Verify(ctx, expectedRoot)) + require.NoError(proof.Verify(ctx, expectedRoot, 4)) } func Test_Proof_Verify_Bad_Data(t *testing.T) { @@ -112,7 +112,7 @@ func Test_Proof_Verify_Bad_Data(t *testing.T) { tt.malform(proof) - err = proof.Verify(context.Background(), db.getMerkleRoot()) + err = proof.Verify(context.Background(), db.getMerkleRoot(), 4) require.ErrorIs(err, tt.expectedErr) }) } @@ -151,6 +151,7 @@ func Test_RangeProof_Extra_Value(t *testing.T) { maybe.Some([]byte{1}), maybe.Some([]byte{5, 5}), db.root.id, + db.tokenSize, )) proof.KeyValues = append(proof.KeyValues, KeyValue{Key: []byte{5}, Value: []byte{5}}) @@ -160,6 +161,7 @@ func Test_RangeProof_Extra_Value(t *testing.T) { maybe.Some([]byte{1}), maybe.Some([]byte{5, 5}), db.root.id, + db.tokenSize, ) require.ErrorIs(err, ErrInvalidProof) } @@ -221,7 +223,7 @@ func Test_RangeProof_Verify_Bad_Data(t *testing.T) { tt.malform(proof) - err = proof.Verify(context.Background(), maybe.Some([]byte{2}), maybe.Some([]byte{3, 0}), db.getMerkleRoot()) + err = proof.Verify(context.Background(), maybe.Some([]byte{2}), maybe.Some([]byte{3, 0}), db.getMerkleRoot(), db.tokenSize) require.ErrorIs(err, tt.expectedErr) }) } @@ -271,19 +273,19 @@ func Test_Proof(t *testing.T) { require.Len(proof.Path, 3) - require.Equal(ToKey([]byte("key1"), BranchFactor16), proof.Path[2].Key) + require.Equal(ToKey([]byte("key1")), proof.Path[2].Key) require.Equal(maybe.Some([]byte("value1")), proof.Path[2].ValueOrHash) - require.Equal(ToKey([]byte{}, BranchFactor16), proof.Path[0].Key) + require.Equal(ToKey([]byte{}), proof.Path[0].Key) require.True(proof.Path[0].ValueOrHash.IsNothing()) expectedRootID, err := trie.GetMerkleRoot(context.Background()) require.NoError(err) - require.NoError(proof.Verify(context.Background(), expectedRootID)) + require.NoError(proof.Verify(context.Background(), expectedRootID, dbTrie.tokenSize)) proof.Path[0].ValueOrHash = maybe.Some([]byte("value2")) - err = proof.Verify(context.Background(), expectedRootID) + err = proof.Verify(context.Background(), expectedRootID, dbTrie.tokenSize) require.ErrorIs(err, ErrInvalidProof) } @@ -357,7 +359,7 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { {Key: []byte{1}, Value: []byte{1}}, {Key: []byte{0}, Value: []byte{0}}, }, - EndProof: []ProofNode{{Key: emptyKey(BranchFactor16)}}, + EndProof: []ProofNode{{Key: Key{}}}, }, expectedErr: ErrNonIncreasingValues, }, @@ -369,7 +371,7 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { KeyValues: []KeyValue{ {Key: []byte{0}, Value: []byte{0}}, }, - EndProof: []ProofNode{{Key: emptyKey(BranchFactor16)}}, + EndProof: []ProofNode{{Key: Key{}}}, }, expectedErr: ErrStateFromOutsideOfRange, }, @@ -381,7 +383,7 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { KeyValues: []KeyValue{ {Key: []byte{2}, Value: []byte{0}}, }, - EndProof: []ProofNode{{Key: emptyKey(BranchFactor16)}}, + EndProof: []ProofNode{{Key: Key{}}}, }, expectedErr: ErrStateFromOutsideOfRange, }, @@ -395,13 +397,13 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { }, StartProof: []ProofNode{ { - Key: ToKey([]byte{2}, BranchFactor16), + Key: ToKey([]byte{2}), }, { - Key: ToKey([]byte{1}, BranchFactor16), + Key: ToKey([]byte{1}), }, }, - EndProof: []ProofNode{{Key: emptyKey(BranchFactor16)}}, + EndProof: []ProofNode{{Key: Key{}}}, }, expectedErr: ErrProofNodeNotForKey, }, @@ -415,16 +417,16 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { }, StartProof: []ProofNode{ { - Key: ToKey([]byte{1}, BranchFactor16), + Key: ToKey([]byte{1}), }, { - Key: ToKey([]byte{1, 2, 3}, BranchFactor16), // Not a prefix of [1, 2] + Key: ToKey([]byte{1, 2, 3}), // Not a prefix of [1, 2] }, { - Key: ToKey([]byte{1, 2, 3, 4}, BranchFactor16), + Key: ToKey([]byte{1, 2, 3, 4}), }, }, - EndProof: []ProofNode{{Key: emptyKey(BranchFactor16)}}, + EndProof: []ProofNode{{Key: Key{}}}, }, expectedErr: ErrProofNodeNotForKey, }, @@ -438,39 +440,15 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { }, EndProof: []ProofNode{ { - Key: ToKey([]byte{2}, BranchFactor16), + Key: ToKey([]byte{2}), }, { - Key: ToKey([]byte{1}, BranchFactor16), + Key: ToKey([]byte{1}), }, }, }, expectedErr: ErrProofNodeNotForKey, }, - { - name: "inconsistent branching factor", - start: maybe.Some([]byte{1, 2}), - end: maybe.Some([]byte{1, 2}), - proof: &RangeProof{ - StartProof: []ProofNode{ - { - Key: ToKey([]byte{1}, BranchFactor16), - }, - { - Key: ToKey([]byte{1, 2}, BranchFactor16), - }, - }, - EndProof: []ProofNode{ - { - Key: ToKey([]byte{1}, BranchFactor4), - }, - { - Key: ToKey([]byte{1, 2}, BranchFactor4), - }, - }, - }, - expectedErr: ErrInconsistentBranchFactor, - }, { name: "end proof has node for wrong key", start: maybe.Nothing[[]byte](), @@ -481,13 +459,13 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { }, EndProof: []ProofNode{ { - Key: ToKey([]byte{1}, BranchFactor16), + Key: ToKey([]byte{1}), }, { - Key: ToKey([]byte{1, 2, 3}, BranchFactor16), // Not a prefix of [1, 2] + Key: ToKey([]byte{1, 2, 3}), // Not a prefix of [1, 2] }, { - Key: ToKey([]byte{1, 2, 3, 4}, BranchFactor16), + Key: ToKey([]byte{1, 2, 3, 4}), }, }, }, @@ -497,7 +475,7 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.proof.Verify(context.Background(), tt.start, tt.end, ids.Empty) + err := tt.proof.Verify(context.Background(), tt.start, tt.end, ids.Empty, 4) require.ErrorIs(t, err, tt.expectedErr) }) } @@ -535,6 +513,7 @@ func Test_RangeProof(t *testing.T) { maybe.Some([]byte{1}), maybe.Some([]byte{3, 5}), db.root.id, + db.tokenSize, )) } @@ -578,15 +557,16 @@ func Test_RangeProof_NilStart(t *testing.T) { require.Equal([]byte("value1"), proof.KeyValues[0].Value) require.Equal([]byte("value2"), proof.KeyValues[1].Value) - require.Equal(ToKey([]byte("key2"), BranchFactor16), proof.EndProof[2].Key, BranchFactor16) - require.Equal(ToKey([]byte("key2"), BranchFactor16).Take(7), proof.EndProof[1].Key) - require.Equal(ToKey([]byte(""), BranchFactor16), proof.EndProof[0].Key, BranchFactor16) + require.Equal(ToKey([]byte("key2")), proof.EndProof[2].Key) + require.Equal(ToKey([]byte("key2")).Take(28), proof.EndProof[1].Key) + require.Equal(ToKey([]byte("")), proof.EndProof[0].Key) require.NoError(proof.Verify( context.Background(), maybe.Nothing[[]byte](), maybe.Some([]byte("key35")), db.root.id, + db.tokenSize, )) } @@ -621,6 +601,7 @@ func Test_RangeProof_NilEnd(t *testing.T) { maybe.Some([]byte{1}), maybe.Nothing[[]byte](), db.root.id, + db.tokenSize, )) } @@ -652,17 +633,18 @@ func Test_RangeProof_EmptyValues(t *testing.T) { require.Empty(proof.KeyValues[2].Value) require.Len(proof.StartProof, 1) - require.Equal(ToKey([]byte("key1"), BranchFactor16), proof.StartProof[0].Key, BranchFactor16) + require.Equal(ToKey([]byte("key1")), proof.StartProof[0].Key) require.Len(proof.EndProof, 3) - require.Equal(ToKey([]byte("key2"), BranchFactor16), proof.EndProof[2].Key, BranchFactor16) - require.Equal(ToKey([]byte{}, BranchFactor16), proof.EndProof[0].Key, BranchFactor16) + require.Equal(ToKey([]byte("key2")), proof.EndProof[2].Key) + require.Equal(ToKey([]byte{}), proof.EndProof[0].Key) require.NoError(proof.Verify( context.Background(), maybe.Some([]byte("key1")), maybe.Some([]byte("key2")), db.root.id, + db.tokenSize, )) } @@ -942,8 +924,8 @@ func Test_ChangeProof_Syntactic_Verify(t *testing.T) { name: "start proof node has wrong prefix", proof: &ChangeProof{ StartProof: []ProofNode{ - {Key: ToKey([]byte{2}, BranchFactor16)}, - {Key: ToKey([]byte{2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{2})}, + {Key: ToKey([]byte{2, 3})}, }, }, start: maybe.Some([]byte{1, 2, 3}), @@ -954,8 +936,8 @@ func Test_ChangeProof_Syntactic_Verify(t *testing.T) { name: "start proof non-increasing", proof: &ChangeProof{ StartProof: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{2, 3})}, }, }, start: maybe.Some([]byte{1, 2, 3}), @@ -969,8 +951,8 @@ func Test_ChangeProof_Syntactic_Verify(t *testing.T) { {Key: []byte{1, 2}, Value: maybe.Some([]byte{0})}, }, EndProof: []ProofNode{ - {Key: ToKey([]byte{2}, BranchFactor16)}, - {Key: ToKey([]byte{2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{2})}, + {Key: ToKey([]byte{2, 3})}, }, }, start: maybe.Nothing[[]byte](), @@ -984,8 +966,8 @@ func Test_ChangeProof_Syntactic_Verify(t *testing.T) { {Key: []byte{1, 2, 3}}, }, EndProof: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{2, 3})}, }, }, start: maybe.Nothing[[]byte](), @@ -1100,119 +1082,118 @@ func TestVerifyProofPath(t *testing.T) { }, { name: "1 element", - path: []ProofNode{{Key: ToKey([]byte{1}, BranchFactor16)}}, + path: []ProofNode{{Key: ToKey([]byte{1})}}, proofKey: maybe.Nothing[Key](), expectedErr: nil, }, { name: "non-increasing keys", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 3})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2, 3}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2, 3})), expectedErr: ErrNonIncreasingProofNodes, }, { name: "invalid key", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 4}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 2, 4})}, + {Key: ToKey([]byte{1, 2, 3})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2, 3}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2, 3})), expectedErr: ErrProofNodeNotForKey, }, { name: "extra node inclusion proof", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 2, 3})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2})), expectedErr: ErrProofNodeNotForKey, }, { name: "extra node exclusion proof", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 3}, BranchFactor16)}, - {Key: ToKey([]byte{1, 3, 4}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 3})}, + {Key: ToKey([]byte{1, 3, 4})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2})), expectedErr: ErrProofNodeNotForKey, }, { name: "happy path exclusion proof", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 4}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 2, 4})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2, 3}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2, 3})), expectedErr: nil, }, { name: "happy path inclusion proof", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 2, 3})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2, 3}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2, 3})), expectedErr: nil, }, { name: "repeat nodes", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 2, 3})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2, 3}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2, 3})), expectedErr: ErrNonIncreasingProofNodes, }, { name: "repeat nodes 2", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 2, 3})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2, 3}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2, 3})), expectedErr: ErrNonIncreasingProofNodes, }, { name: "repeat nodes 3", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 3}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2, 3}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, + {Key: ToKey([]byte{1, 2, 3})}, + {Key: ToKey([]byte{1, 2, 3})}, }, - proofKey: maybe.Some(ToKey([]byte{1, 2, 3}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2, 3})), expectedErr: ErrProofNodeNotForKey, }, { name: "oddLength key with value", path: []ProofNode{ - {Key: ToKey([]byte{1}, BranchFactor16)}, - {Key: ToKey([]byte{1, 2}, BranchFactor16)}, + {Key: ToKey([]byte{1})}, + {Key: ToKey([]byte{1, 2})}, { Key: Key{ - value: string([]byte{1, 2, 240}), - tokenLength: 5, - tokenConfig: branchFactorToTokenConfig[BranchFactor16], + value: string([]byte{1, 2, 240}), + length: 20, }, ValueOrHash: maybe.Some([]byte{1}), }, }, - proofKey: maybe.Some(ToKey([]byte{1, 2, 3}, BranchFactor16)), + proofKey: maybe.Some(ToKey([]byte{1, 2, 3})), expectedErr: ErrPartialByteLengthWithValue, }, } @@ -1240,7 +1221,7 @@ func TestProofNodeUnmarshalProtoInvalidMaybe(t *testing.T) { } var unmarshaledNode ProofNode - err := unmarshaledNode.UnmarshalProto(protoNode, BranchFactor16) + err := unmarshaledNode.UnmarshalProto(protoNode) require.ErrorIs(t, err, ErrInvalidMaybe) } @@ -1257,7 +1238,7 @@ func TestProofNodeUnmarshalProtoInvalidChildBytes(t *testing.T) { } var unmarshaledNode ProofNode - err := unmarshaledNode.UnmarshalProto(protoNode, BranchFactor16) + err := unmarshaledNode.UnmarshalProto(protoNode) require.ErrorIs(t, err, hashing.ErrInvalidHashLen) } @@ -1270,11 +1251,11 @@ func TestProofNodeUnmarshalProtoInvalidChildIndex(t *testing.T) { protoNode := node.ToProto() childID := ids.GenerateTestID() - protoNode.Children[uint32(BranchFactor16)] = childID[:] + protoNode.Children[256] = childID[:] var unmarshaledNode ProofNode - err := unmarshaledNode.UnmarshalProto(protoNode, BranchFactor16) - require.ErrorIs(t, err, ErrInvalidChildIndex) + err := unmarshaledNode.UnmarshalProto(protoNode) + require.ErrorIs(t, err, errChildIndexTooLarge) } func TestProofNodeUnmarshalProtoMissingFields(t *testing.T) { @@ -1321,7 +1302,7 @@ func TestProofNodeUnmarshalProtoMissingFields(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var node ProofNode - err := node.UnmarshalProto(tt.nodeFunc(), BranchFactor16) + err := node.UnmarshalProto(tt.nodeFunc()) require.ErrorIs(t, err, tt.expectedErr) }) } @@ -1340,7 +1321,7 @@ func FuzzProofNodeProtoMarshalUnmarshal(f *testing.F) { // Assert the unmarshaled one is the same as the original. protoNode := node.ToProto() var unmarshaledNode ProofNode - require.NoError(unmarshaledNode.UnmarshalProto(protoNode, BranchFactor16)) + require.NoError(unmarshaledNode.UnmarshalProto(protoNode)) require.Equal(node, unmarshaledNode) // Marshaling again should yield same result. @@ -1397,7 +1378,7 @@ func FuzzRangeProofProtoMarshalUnmarshal(f *testing.F) { // Assert the unmarshaled one is the same as the original. var unmarshaledProof RangeProof protoProof := proof.ToProto() - require.NoError(unmarshaledProof.UnmarshalProto(protoProof, BranchFactor16)) + require.NoError(unmarshaledProof.UnmarshalProto(protoProof)) require.Equal(proof, unmarshaledProof) // Marshaling again should yield same result. @@ -1459,7 +1440,7 @@ func FuzzChangeProofProtoMarshalUnmarshal(f *testing.F) { // Assert the unmarshaled one is the same as the original. var unmarshaledProof ChangeProof protoProof := proof.ToProto() - require.NoError(unmarshaledProof.UnmarshalProto(protoProof, BranchFactor16)) + require.NoError(unmarshaledProof.UnmarshalProto(protoProof)) require.Equal(proof, unmarshaledProof) // Marshaling again should yield same result. @@ -1470,7 +1451,7 @@ func FuzzChangeProofProtoMarshalUnmarshal(f *testing.F) { func TestChangeProofUnmarshalProtoNil(t *testing.T) { var proof ChangeProof - err := proof.UnmarshalProto(nil, BranchFactor16) + err := proof.UnmarshalProto(nil) require.ErrorIs(t, err, ErrNilChangeProof) } @@ -1524,7 +1505,7 @@ func TestChangeProofUnmarshalProtoNilValue(t *testing.T) { protoProof.KeyChanges[0].Value = nil var unmarshaledProof ChangeProof - err := unmarshaledProof.UnmarshalProto(protoProof, BranchFactor16) + err := unmarshaledProof.UnmarshalProto(protoProof) require.ErrorIs(t, err, ErrNilMaybeBytes) } @@ -1542,7 +1523,7 @@ func TestChangeProofUnmarshalProtoInvalidMaybe(t *testing.T) { } var proof ChangeProof - err := proof.UnmarshalProto(protoProof, BranchFactor16) + err := proof.UnmarshalProto(protoProof) require.ErrorIs(t, err, ErrInvalidMaybe) } @@ -1575,7 +1556,7 @@ func FuzzProofProtoMarshalUnmarshal(f *testing.F) { } proof := Proof{ - Key: ToKey(key, BranchFactor16), + Key: ToKey(key), Value: value, Path: proofPath, } @@ -1584,7 +1565,7 @@ func FuzzProofProtoMarshalUnmarshal(f *testing.F) { // Assert the unmarshaled one is the same as the original. var unmarshaledProof Proof protoProof := proof.ToProto() - require.NoError(unmarshaledProof.UnmarshalProto(protoProof, BranchFactor16)) + require.NoError(unmarshaledProof.UnmarshalProto(protoProof)) require.Equal(proof, unmarshaledProof) // Marshaling again should yield same result. @@ -1626,7 +1607,7 @@ func TestProofProtoUnmarshal(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var proof Proof - err := proof.UnmarshalProto(tt.proof, BranchFactor16) + err := proof.UnmarshalProto(tt.proof) require.ErrorIs(t, err, tt.expectedErr) }) } @@ -1694,6 +1675,7 @@ func FuzzRangeProofInvariants(f *testing.F) { start, end, rootID, + db.tokenSize, )) // Make sure the start proof doesn't contain any nodes @@ -1732,14 +1714,14 @@ func FuzzRangeProofInvariants(f *testing.F) { proof := Proof{ Path: rangeProof.EndProof, - Key: ToKey(endBytes, BranchFactor16), + Key: ToKey(endBytes), Value: value, } rootID, err := db.GetMerkleRoot(context.Background()) require.NoError(err) - require.NoError(proof.Verify(context.Background(), rootID)) + require.NoError(proof.Verify(context.Background(), rootID, db.tokenSize)) default: require.NotEmpty(rangeProof.EndProof) @@ -1747,14 +1729,14 @@ func FuzzRangeProofInvariants(f *testing.F) { // EndProof should be a proof for largest key-value. proof := Proof{ Path: rangeProof.EndProof, - Key: ToKey(greatestKV.Key, BranchFactor16), + Key: ToKey(greatestKV.Key), Value: maybe.Some(greatestKV.Value), } rootID, err := db.GetMerkleRoot(context.Background()) require.NoError(err) - require.NoError(proof.Verify(context.Background(), rootID)) + require.NoError(proof.Verify(context.Background(), rootID, db.tokenSize)) } }) } @@ -1790,7 +1772,7 @@ func FuzzProofVerification(f *testing.F) { rootID, err := db.GetMerkleRoot(context.Background()) require.NoError(err) - require.NoError(proof.Verify(context.Background(), rootID)) + require.NoError(proof.Verify(context.Background(), rootID, db.tokenSize)) // Insert a new key-value pair newKey := make([]byte, 32) diff --git a/x/merkledb/trie_test.go b/x/merkledb/trie_test.go index 7908c1266af7..e278456649b1 100644 --- a/x/merkledb/trie_test.go +++ b/x/merkledb/trie_test.go @@ -19,10 +19,6 @@ import ( ) func getNodeValue(t ReadOnlyTrie, key string) ([]byte, error) { - return getNodeValueWithBranchFactor(t, key, BranchFactor16) -} - -func getNodeValueWithBranchFactor(t ReadOnlyTrie, key string, bf BranchFactor) ([]byte, error) { var view *trieView if asTrieView, ok := t.(*trieView); ok { if err := asTrieView.calculateNodeIDs(context.Background()); err != nil { @@ -38,7 +34,7 @@ func getNodeValueWithBranchFactor(t ReadOnlyTrie, key string, bf BranchFactor) ( view = dbView.(*trieView) } - path := ToKey([]byte(key), bf) + path := ToKey([]byte(key)) var result *node err := view.visitPathToKey(path, func(n *node) error { result = n @@ -123,7 +119,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { trie := trieIntf.(*trieView) var nodePath []*node - require.NoError(trie.visitPathToKey(ToKey(nil, BranchFactor16), func(n *node) error { + require.NoError(trie.visitPathToKey(ToKey(nil), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -148,7 +144,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { require.NoError(trie.calculateNodeIDs(context.Background())) nodePath = make([]*node, 0, 2) - require.NoError(trie.visitPathToKey(ToKey(key1, BranchFactor16), func(n *node) error { + require.NoError(trie.visitPathToKey(ToKey(key1), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -156,7 +152,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { // Root and 1 value require.Len(nodePath, 2) require.Equal(trie.root, nodePath[0]) - require.Equal(ToKey(key1, BranchFactor16), nodePath[1].key) + require.Equal(ToKey(key1), nodePath[1].key) // Insert another key which is a child of the first key2 := []byte{0, 1} @@ -174,14 +170,14 @@ func TestTrieViewVisitPathToKey(t *testing.T) { require.NoError(trie.calculateNodeIDs(context.Background())) nodePath = make([]*node, 0, 3) - require.NoError(trie.visitPathToKey(ToKey(key2, BranchFactor16), func(n *node) error { + require.NoError(trie.visitPathToKey(ToKey(key2), func(n *node) error { nodePath = append(nodePath, n) return nil })) require.Len(nodePath, 3) require.Equal(trie.root, nodePath[0]) - require.Equal(ToKey(key1, BranchFactor16), nodePath[1].key) - require.Equal(ToKey(key2, BranchFactor16), nodePath[2].key) + require.Equal(ToKey(key1), nodePath[1].key) + require.Equal(ToKey(key2), nodePath[2].key) // Insert a key which shares no prefix with the others key3 := []byte{255} @@ -199,41 +195,43 @@ func TestTrieViewVisitPathToKey(t *testing.T) { require.NoError(trie.calculateNodeIDs(context.Background())) nodePath = make([]*node, 0, 2) - require.NoError(trie.visitPathToKey(ToKey(key3, BranchFactor16), func(n *node) error { + require.NoError(trie.visitPathToKey(ToKey(key3), func(n *node) error { nodePath = append(nodePath, n) return nil })) + require.Len(nodePath, 2) require.Equal(trie.root, nodePath[0]) - require.Equal(ToKey(key3, BranchFactor16), nodePath[1].key) + require.Equal(ToKey(key3), nodePath[1].key) // Other key path not affected nodePath = make([]*node, 0, 3) - require.NoError(trie.visitPathToKey(ToKey(key2, BranchFactor16), func(n *node) error { + require.NoError(trie.visitPathToKey(ToKey(key2), func(n *node) error { nodePath = append(nodePath, n) return nil })) require.Len(nodePath, 3) require.Equal(trie.root, nodePath[0]) - require.Equal(ToKey(key1, BranchFactor16), nodePath[1].key) - require.Equal(ToKey(key2, BranchFactor16), nodePath[2].key) + require.Equal(ToKey(key1), nodePath[1].key) + require.Equal(ToKey(key2), nodePath[2].key) // Gets closest node when key doesn't exist key4 := []byte{0, 1, 2} nodePath = make([]*node, 0, 3) - require.NoError(trie.visitPathToKey(ToKey(key4, BranchFactor16), func(n *node) error { + require.NoError(trie.visitPathToKey(ToKey(key4), func(n *node) error { nodePath = append(nodePath, n) return nil })) + require.Len(nodePath, 3) require.Equal(trie.root, nodePath[0]) - require.Equal(ToKey(key1, BranchFactor16), nodePath[1].key) - require.Equal(ToKey(key2, BranchFactor16), nodePath[2].key) + require.Equal(ToKey(key1), nodePath[1].key) + require.Equal(ToKey(key2), nodePath[2].key) // Gets just root when key doesn't exist and no key shares a prefix key5 := []byte{128} nodePath = make([]*node, 0, 1) - require.NoError(trie.visitPathToKey(ToKey(key5, BranchFactor16), func(n *node) error { + require.NoError(trie.visitPathToKey(ToKey(key5), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -320,7 +318,7 @@ func Test_Trie_WriteToDB(t *testing.T) { rawBytes, err := dbTrie.baseDB.Get(prefixedKey) require.NoError(err) - node, err := parseNode(ToKey(key, BranchFactor16), rawBytes) + node, err := parseNode(ToKey(key), rawBytes) require.NoError(err) require.Equal([]byte("value"), node.value.Value()) } @@ -488,7 +486,7 @@ func Test_Trie_ExpandOnKeyPath(t *testing.T) { require.Equal([]byte("value12"), value) } -func Test_Trie_CompressedPaths(t *testing.T) { +func Test_Trie_compressedKeys(t *testing.T) { require := require.New(t) dbTrie, err := getBasicDB() @@ -619,7 +617,7 @@ func Test_Trie_HashCountOnBranch(t *testing.T) { // Make sure the branch node with the common prefix was created. // Note it's only created on call to GetMerkleRoot, not in NewView. - _, err = view2.getEditableNode(ToKey(keyPrefix, BranchFactor16), false) + _, err = view2.getEditableNode(ToKey(keyPrefix), false) require.NoError(err) // only hashes the new branch node, the new child node, and root @@ -760,7 +758,7 @@ func Test_Trie_ChainDeletion(t *testing.T) { require.NoError(err) require.NoError(newTrie.(*trieView).calculateNodeIDs(context.Background())) - root, err := newTrie.getEditableNode(emptyKey(BranchFactor16), false) + root, err := newTrie.getEditableNode(Key{}, false) require.NoError(err) require.Len(root.children, 1) @@ -777,7 +775,7 @@ func Test_Trie_ChainDeletion(t *testing.T) { ) require.NoError(err) require.NoError(newTrie.(*trieView).calculateNodeIDs(context.Background())) - root, err = newTrie.getEditableNode(emptyKey(BranchFactor16), false) + root, err = newTrie.getEditableNode(Key{}, false) require.NoError(err) // since all values have been deleted, the nodes should have been cleaned up require.Empty(root.children) @@ -842,15 +840,15 @@ func Test_Trie_NodeCollapse(t *testing.T) { require.NoError(err) require.NoError(trie.(*trieView).calculateNodeIDs(context.Background())) - root, err := trie.getEditableNode(emptyKey(BranchFactor16), false) + root, err := trie.getEditableNode(Key{}, false) require.NoError(err) require.Len(root.children, 1) - root, err = trie.getEditableNode(emptyKey(BranchFactor16), false) + root, err = trie.getEditableNode(Key{}, false) require.NoError(err) require.Len(root.children, 1) - firstNode, err := trie.getEditableNode(getSingleChildKey(root), true) + firstNode, err := trie.getEditableNode(getSingleChildKey(root, dbTrie.tokenSize), true) require.NoError(err) require.Len(firstNode.children, 1) @@ -868,11 +866,11 @@ func Test_Trie_NodeCollapse(t *testing.T) { require.NoError(err) require.NoError(trie.(*trieView).calculateNodeIDs(context.Background())) - root, err = trie.getEditableNode(emptyKey(BranchFactor16), false) + root, err = trie.getEditableNode(Key{}, false) require.NoError(err) require.Len(root.children, 1) - firstNode, err = trie.getEditableNode(getSingleChildKey(root), true) + firstNode, err = trie.getEditableNode(getSingleChildKey(root, dbTrie.tokenSize), true) require.NoError(err) require.Len(firstNode.children, 2) } @@ -1215,9 +1213,9 @@ func Test_Trie_ConcurrentNewViewAndCommit(t *testing.T) { // Returns the path of the only child of this node. // Assumes this node has exactly one child. -func getSingleChildKey(n *node) Key { +func getSingleChildKey(n *node, tokenSize int) Key { for index, entry := range n.children { - return n.key.AppendExtend(index, entry.compressedKey) + return n.key.Extend(ToToken(index, tokenSize), entry.compressedKey) } return Key{} } diff --git a/x/merkledb/trieview.go b/x/merkledb/trieview.go index 3422379a20cc..c905cb82c218 100644 --- a/x/merkledb/trieview.go +++ b/x/merkledb/trieview.go @@ -35,7 +35,7 @@ var ( ErrPartialByteLengthWithValue = errors.New( "the underlying db only supports whole number of byte keys, so cannot record changes with partial byte lengths", ) - ErrGetPathToFailure = errors.New("GetPathTo failed to return the closest node") + ErrVisitPathToKey = errors.New("failed to visit expected node during insertion") ErrStartAfterEnd = errors.New("start key > end key") ErrNoValidRoot = errors.New("a valid root was not provided to the trieView constructor") ErrParentNotDatabase = errors.New("parent trie is not database") @@ -98,6 +98,8 @@ type trieView struct { // The root of the trie represented by this view. root *node + + tokenSize int } // NewView returns a new view on top of this Trie where the passed changes @@ -145,7 +147,7 @@ func newTrieView( parentTrie TrieView, changes ViewChanges, ) (*trieView, error) { - root, err := parentTrie.getEditableNode(db.rootKey, false /* hasValue */) + root, err := parentTrie.getEditableNode(Key{}, false /* hasValue */) if err != nil { if err == database.ErrNotFound { return nil, ErrNoValidRoot @@ -158,6 +160,7 @@ func newTrieView( db: db, parentTrie: parentTrie, changes: newChangeSummary(len(changes.BatchOps) + len(changes.MapOps)), + tokenSize: db.tokenSize, } for _, op := range changes.BatchOps { @@ -173,7 +176,7 @@ func newTrieView( newVal = maybe.Some(slices.Clone(op.Value)) } } - if err := newView.recordValueChange(db.toKey(key), newVal); err != nil { + if err := newView.recordValueChange(toKey(key), newVal); err != nil { return nil, err } } @@ -181,7 +184,7 @@ func newTrieView( if !changes.ConsumeBytes { val = maybe.Bind(val, slices.Clone[[]byte]) } - if err := newView.recordValueChange(db.toKey(stringToByteSlice(key)), val); err != nil { + if err := newView.recordValueChange(toKey(stringToByteSlice(key)), val); err != nil { return nil, err } } @@ -197,7 +200,7 @@ func newHistoricalTrieView( return nil, ErrNoValidRoot } - passedRootChange, ok := changes.nodes[db.rootKey] + passedRootChange, ok := changes.nodes[Key{}] if !ok { return nil, ErrNoValidRoot } @@ -207,6 +210,7 @@ func newHistoricalTrieView( db: db, parentTrie: db, changes: changes, + tokenSize: db.tokenSize, } // since this is a set of historical changes, all nodes have already been calculated // since no new changes have occurred, no new calculations need to be done @@ -269,7 +273,7 @@ func (t *trieView) calculateNodeIDsHelper(n *node) { ) for childIndex, child := range n.children { - childPath := n.key.AppendExtend(childIndex, child.compressedKey) + childPath := n.key.Extend(ToToken(childIndex, t.tokenSize), child.compressedKey) childNodeChange, ok := t.changes.nodes[childPath] if !ok { // This child wasn't changed. @@ -302,9 +306,8 @@ func (t *trieView) calculateNodeIDsHelper(n *node) { wg.Wait() close(updatedChildren) - keyLength := n.key.tokenLength for updatedChild := range updatedChildren { - index := updatedChild.key.Token(keyLength) + index := updatedChild.key.Token(n.key.length, t.tokenSize) n.setChildEntry(index, child{ compressedKey: n.children[index].compressedKey, id: updatedChild.id, @@ -334,7 +337,7 @@ func (t *trieView) getProof(ctx context.Context, key []byte) (*Proof, error) { defer span.End() proof := &Proof{ - Key: t.db.toKey(key), + Key: ToKey(key), } var closestNode *node @@ -355,7 +358,7 @@ func (t *trieView) getProof(ctx context.Context, key []byte) (*Proof, error) { // There is no node with the given [key]. // If there is a child at the index where the node would be // if it existed, include that child in the proof. - nextIndex := proof.Key.Token(closestNode.key.tokenLength) + nextIndex := proof.Key.Token(closestNode.key.length, t.tokenSize) child, ok := closestNode.children[nextIndex] if !ok { return proof, nil @@ -363,7 +366,7 @@ func (t *trieView) getProof(ctx context.Context, key []byte) (*Proof, error) { childNode, err := t.getNodeWithID( child.id, - closestNode.key.AppendExtend(nextIndex, child.compressedKey), + closestNode.key.Extend(ToToken(nextIndex, t.tokenSize), child.compressedKey), child.hasValue, ) if err != nil { @@ -557,7 +560,7 @@ func (t *trieView) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []er valueErrors := make([]error, len(keys)) for i, key := range keys { - results[i], valueErrors[i] = t.getValueCopy(t.db.toKey(key)) + results[i], valueErrors[i] = t.getValueCopy(ToKey(key)) } return results, valueErrors } @@ -568,7 +571,7 @@ func (t *trieView) GetValue(ctx context.Context, key []byte) ([]byte, error) { _, span := t.db.debugTracer.Start(ctx, "MerkleDB.trieview.GetValue") defer span.End() - return t.getValueCopy(t.db.toKey(key)) + return t.getValueCopy(ToKey(key)) } // getValueCopy returns a copy of the value for the given [key]. @@ -654,7 +657,7 @@ func (t *trieView) remove(key Key) error { return err } if parent != nil { - parent.removeChild(nodeToDelete) + parent.removeChild(nodeToDelete, t.tokenSize) // merge the parent node and its child into a single node if possible return t.compressNodePath(grandParent, parent) @@ -692,15 +695,15 @@ func (t *trieView) compressNodePath(parent, node *node) error { // "Cycle" over the key/values to find the only child. // Note this iteration once because len(node.children) == 1. for index, entry := range node.children { - childKey = node.key.AppendExtend(index, entry.compressedKey) + childKey = node.key.Extend(ToToken(index, t.tokenSize), entry.compressedKey) childEntry = entry } // [node] is the first node with multiple children. // combine it with the [node] passed in. - parent.setChildEntry(childKey.Token(parent.key.tokenLength), + parent.setChildEntry(childKey.Token(parent.key.length, t.tokenSize), child{ - compressedKey: childKey.Skip(parent.key.tokenLength + 1), + compressedKey: childKey.Skip(parent.key.length + t.tokenSize), id: childEntry.id, hasValue: childEntry.hasValue, }) @@ -722,17 +725,16 @@ func (t *trieView) visitPathToKey(key Key, visitNode func(*node) error) error { return err } // while the entire path hasn't been matched - for currentNode.key.tokenLength < key.tokenLength { + for currentNode.key.length < key.length { // confirm that a child exists and grab its ID before attempting to load it - nextChildEntry, hasChild := currentNode.children[key.Token(currentNode.key.tokenLength)] + nextChildEntry, hasChild := currentNode.children[key.Token(currentNode.key.length, t.tokenSize)] - if !hasChild || !key.iteratedHasPrefix(currentNode.key.tokenLength+1, nextChildEntry.compressedKey) { + if !hasChild || !key.iteratedHasPrefix(nextChildEntry.compressedKey, currentNode.key.length+t.tokenSize, t.tokenSize) { // there was no child along the path or the child that was there doesn't match the remaining path return nil } - // grab the next node along the path - currentNode, err = t.getNodeWithID(nextChildEntry.id, key.Take(currentNode.key.tokenLength+1+nextChildEntry.compressedKey.tokenLength), nextChildEntry.hasValue) + currentNode, err = t.getNodeWithID(nextChildEntry.id, key.Take(currentNode.key.length+t.tokenSize+nextChildEntry.compressedKey.length), nextChildEntry.hasValue) if err != nil { return err } @@ -743,14 +745,6 @@ func (t *trieView) visitPathToKey(key Key, visitNode func(*node) error) error { return nil } -func getLengthOfCommonPrefix(first, second Key, secondOffset int) int { - commonIndex := 0 - for first.tokenLength > commonIndex && second.tokenLength > (commonIndex+secondOffset) && first.Token(commonIndex) == second.Token(commonIndex+secondOffset) { - commonIndex++ - } - return commonIndex -} - // Get a copy of the node matching the passed key from the trie. // Used by views to get nodes from their ancestors. func (t *trieView) getEditableNode(key Key, hadValue bool) (*node, error) { @@ -791,31 +785,27 @@ func (t *trieView) insert( return nil, err } - // a node with that exact path already exists so update its value + // a node with that exact key already exists so update its value if closestNode.key == key { closestNode.setValue(value) // closestNode was already marked as changed in the ancestry loop above return closestNode, nil } - closestNodeKeyLength := closestNode.key.tokenLength - // A node with the exact key doesn't exist so determine the portion of the // key that hasn't been matched yet - // Note that [key] has prefix [closestNodeFullPath] but exactMatch was false, - // so [key] must be longer than [closestNodeFullPath] and the following index and slice won't OOB. - existingChildEntry, hasChild := closestNode.children[key.Token(closestNodeKeyLength)] + // Note that [key] has prefix [closestNode.key], so [key] must be longer + // and the following index won't OOB. + existingChildEntry, hasChild := closestNode.children[key.Token(closestNode.key.length, t.tokenSize)] if !hasChild { - // there are no existing nodes along the path [fullPath], so create a new node to insert [value] - newNode := newNode( - closestNode, - key, - ) + // there are no existing nodes along the key [key], so create a new node to insert [value] + newNode := newNode(key) newNode.setValue(value) + closestNode.addChild(newNode, t.tokenSize) return newNode, t.recordNewNode(newNode) } - // if we have reached this point, then the [fullpath] we are trying to insert and + // if we have reached this point, then the [key] we are trying to insert and // the existing path node have some common prefix. // a new branching node will be created that will represent this common prefix and // have the existing path node and the value being inserted as children. @@ -824,31 +814,32 @@ func (t *trieView) insert( // find how many tokens are common between the existing child's compressed path and // the current key(offset by the closest node's key), // then move all the common tokens into the branch node - commonPrefixLength := getLengthOfCommonPrefix(existingChildEntry.compressedKey, key, closestNodeKeyLength+1) + commonPrefixLength := getLengthOfCommonPrefix( + existingChildEntry.compressedKey, + key, + closestNode.key.length+t.tokenSize, + t.tokenSize, + ) - // If the length of the existing child's compressed path is less than or equal to the branch node's key that implies that the existing child's key matched the key to be inserted. - // Since it matched the key to be inserted, it should have been the last node returned by GetPathTo - if existingChildEntry.compressedKey.tokenLength <= commonPrefixLength { - return nil, ErrGetPathToFailure + if existingChildEntry.compressedKey.length <= commonPrefixLength { + // Since the compressed key is shorter than the common prefix, + // we should have visited [existingChildEntry] in [visitPathToKey]. + return nil, ErrVisitPathToKey } - branchNode := newNode( - closestNode, - key.Take(closestNodeKeyLength+1+commonPrefixLength), - ) + branchNode := newNode(key.Take(closestNode.key.length + t.tokenSize + commonPrefixLength)) + closestNode.addChild(branchNode, t.tokenSize) nodeWithValue := branchNode - if key.tokenLength == branchNode.key.tokenLength { + if key.length == branchNode.key.length { // the branch node has exactly the key to be inserted as its key, so set the value on the branch node branchNode.setValue(value) } else { // the key to be inserted is a child of the branch node // create a new node and add the value to it - newNode := newNode( - branchNode, - key, - ) + newNode := newNode(key) newNode.setValue(value) + branchNode.addChild(newNode, t.tokenSize) if err := t.recordNewNode(newNode); err != nil { return nil, err } @@ -857,9 +848,9 @@ func (t *trieView) insert( // add the existing child onto the branch node branchNode.setChildEntry( - existingChildEntry.compressedKey.Token(commonPrefixLength), + existingChildEntry.compressedKey.Token(commonPrefixLength, t.tokenSize), child{ - compressedKey: existingChildEntry.compressedKey.Skip(commonPrefixLength + 1), + compressedKey: existingChildEntry.compressedKey.Skip(commonPrefixLength + t.tokenSize), id: existingChildEntry.id, hasValue: existingChildEntry.hasValue, }) @@ -867,6 +858,15 @@ func (t *trieView) insert( return nodeWithValue, t.recordNewNode(branchNode) } +func getLengthOfCommonPrefix(first, second Key, secondOffset int, tokenSize int) int { + commonIndex := 0 + for first.length > commonIndex && second.length > commonIndex+secondOffset && + first.Token(commonIndex, tokenSize) == second.Token(commonIndex+secondOffset, tokenSize) { + commonIndex += tokenSize + } + return commonIndex +} + // Records that a node has been created. // Must not be called after [calculateNodeIDs] has returned. func (t *trieView) recordNewNode(after *node) error { @@ -883,7 +883,7 @@ func (t *trieView) recordNodeChange(after *node) error { // Must not be called after [calculateNodeIDs] has returned. func (t *trieView) recordNodeDeleted(after *node) error { // don't delete the root. - if after.key.tokenLength == 0 { + if after.key.length == 0 { return t.recordKeyChange(after.key, after, after.hasValue(), false /* newNode */) } return t.recordKeyChange(after.key, nil, after.hasValue(), false /* newNode */) diff --git a/x/merkledb/value_node_db.go b/x/merkledb/value_node_db.go index 8f168560d7fa..339fa25f78f0 100644 --- a/x/merkledb/value_node_db.go +++ b/x/merkledb/value_node_db.go @@ -27,8 +27,7 @@ type valueNodeDB struct { nodeCache cache.Cacher[Key, *node] metrics merkleMetrics - closed utils.Atomic[bool] - branchFactor BranchFactor + closed utils.Atomic[bool] } func newValueNodeDB( @@ -36,14 +35,12 @@ func newValueNodeDB( bufferPool *sync.Pool, metrics merkleMetrics, cacheSize int, - branchFactor BranchFactor, ) *valueNodeDB { return &valueNodeDB{ - metrics: metrics, - baseDB: db, - bufferPool: bufferPool, - nodeCache: cache.NewSizedLRU(cacheSize, cacheEntrySize), - branchFactor: branchFactor, + metrics: metrics, + baseDB: db, + bufferPool: bufferPool, + nodeCache: cache.NewSizedLRU(cacheSize, cacheEntrySize), } } @@ -170,7 +167,7 @@ func (i *iterator) Next() bool { i.db.metrics.DatabaseNodeRead() key := i.nodeIter.Key() key = key[valueNodePrefixLen:] - n, err := parseNode(ToKey(key, i.db.branchFactor), i.nodeIter.Value()) + n, err := parseNode(ToKey(key), i.nodeIter.Value()) if err != nil { i.err = err return false diff --git a/x/merkledb/value_node_db_test.go b/x/merkledb/value_node_db_test.go index 910c6e1e9d6b..96c5b4b038cc 100644 --- a/x/merkledb/value_node_db_test.go +++ b/x/merkledb/value_node_db_test.go @@ -28,11 +28,10 @@ func TestValueNodeDB(t *testing.T) { }, &mockMetrics{}, size, - BranchFactor16, ) // Getting a key that doesn't exist should return an error. - key := ToKey([]byte{0x01}, BranchFactor16) + key := ToKey([]byte{0x01}) _, err := db.Get(key) require.ErrorIs(err, database.ErrNotFound) @@ -124,12 +123,11 @@ func TestValueNodeDBIterator(t *testing.T) { }, &mockMetrics{}, cacheSize, - BranchFactor16, ) // Put key-node pairs. for i := 0; i < cacheSize; i++ { - key := ToKey([]byte{byte(i)}, BranchFactor16) + key := ToKey([]byte{byte(i)}) node := &node{ dbNode: dbNode{ value: maybe.Some([]byte{byte(i)}), @@ -167,7 +165,7 @@ func TestValueNodeDBIterator(t *testing.T) { it.Release() // Put key-node pairs with a common prefix. - key := ToKey([]byte{0xFF, 0x00}, BranchFactor16) + key := ToKey([]byte{0xFF, 0x00}) n := &node{ dbNode: dbNode{ value: maybe.Some([]byte{0xFF, 0x00}), @@ -178,7 +176,7 @@ func TestValueNodeDBIterator(t *testing.T) { batch.Put(key, n) require.NoError(batch.Write()) - key = ToKey([]byte{0xFF, 0x01}, BranchFactor16) + key = ToKey([]byte{0xFF, 0x01}) n = &node{ dbNode: dbNode{ value: maybe.Some([]byte{0xFF, 0x01}), diff --git a/x/merkledb/view_iterator.go b/x/merkledb/view_iterator.go index 263aa409e882..fac213bf350b 100644 --- a/x/merkledb/view_iterator.go +++ b/x/merkledb/view_iterator.go @@ -26,8 +26,8 @@ func (t *trieView) NewIteratorWithPrefix(prefix []byte) database.Iterator { func (t *trieView) NewIteratorWithStartAndPrefix(start, prefix []byte) database.Iterator { var ( changes = make([]KeyChange, 0, len(t.changes.values)) - startKey = t.db.toKey(start) - prefixKey = t.db.toKey(prefix) + startKey = ToKey(start) + prefixKey = ToKey(prefix) ) for key, change := range t.changes.values { diff --git a/x/sync/client.go b/x/sync/client.go index 095f515d41fb..e86c37485c7f 100644 --- a/x/sync/client.go +++ b/x/sync/client.go @@ -73,7 +73,7 @@ type client struct { stateSyncMinVersion *version.Application log logging.Logger metrics SyncMetrics - branchFactor merkledb.BranchFactor + tokenSize int } type ClientConfig struct { @@ -95,7 +95,7 @@ func NewClient(config *ClientConfig) (Client, error) { stateSyncMinVersion: config.StateSyncMinVersion, log: config.Log, metrics: config.Metrics, - branchFactor: config.BranchFactor, + tokenSize: merkledb.BranchFactorToTokenSize[config.BranchFactor], }, nil } @@ -124,7 +124,7 @@ func (c *client) GetChangeProof( case *pb.SyncGetChangeProofResponse_ChangeProof: // The server had enough history to send us a change proof var changeProof merkledb.ChangeProof - if err := changeProof.UnmarshalProto(changeProofResp.ChangeProof, c.branchFactor); err != nil { + if err := changeProof.UnmarshalProto(changeProofResp.ChangeProof); err != nil { return nil, err } @@ -158,7 +158,7 @@ func (c *client) GetChangeProof( case *pb.SyncGetChangeProofResponse_RangeProof: var rangeProof merkledb.RangeProof - if err := rangeProof.UnmarshalProto(changeProofResp.RangeProof, c.branchFactor); err != nil { + if err := rangeProof.UnmarshalProto(changeProofResp.RangeProof); err != nil { return nil, err } @@ -171,6 +171,7 @@ func (c *client) GetChangeProof( startKey, endKey, req.EndRootHash, + c.tokenSize, ) if err != nil { return nil, err @@ -208,6 +209,7 @@ func verifyRangeProof( start maybe.Maybe[[]byte], end maybe.Maybe[[]byte], rootBytes []byte, + tokenSize int, ) error { root, err := ids.ToID(rootBytes) if err != nil { @@ -227,6 +229,7 @@ func verifyRangeProof( start, end, root, + tokenSize, ); err != nil { return fmt.Errorf("%w due to %w", errInvalidRangeProof, err) } @@ -257,7 +260,7 @@ func (c *client) GetRangeProof( endKey := maybeBytesToMaybe(req.EndKey) var rangeProof merkledb.RangeProof - if err := rangeProof.UnmarshalProto(&rangeProofProto, c.branchFactor); err != nil { + if err := rangeProof.UnmarshalProto(&rangeProofProto); err != nil { return nil, err } @@ -268,6 +271,7 @@ func (c *client) GetRangeProof( startKey, endKey, req.RootHash, + c.tokenSize, ); err != nil { return nil, err } diff --git a/x/sync/client_test.go b/x/sync/client_test.go index 08c1a787b474..c9f473bea53e 100644 --- a/x/sync/client_test.go +++ b/x/sync/client_test.go @@ -138,7 +138,7 @@ func sendRangeProofRequest( require.NoError(proto.Unmarshal(responseBytes, &responseProto)) var response merkledb.RangeProof - require.NoError(response.UnmarshalProto(&responseProto, merkledb.BranchFactor16)) + require.NoError(response.UnmarshalProto(&responseProto)) // modify if needed if modifyResponse != nil { @@ -456,7 +456,7 @@ func sendChangeProofRequest( if responseProto.GetChangeProof() != nil { // Server responded with a change proof var changeProof merkledb.ChangeProof - require.NoError(changeProof.UnmarshalProto(responseProto.GetChangeProof(), merkledb.BranchFactor16)) + require.NoError(changeProof.UnmarshalProto(responseProto.GetChangeProof())) // modify if needed if modifyChangeProof != nil { @@ -478,7 +478,7 @@ func sendChangeProofRequest( // Server responded with a range proof var rangeProof merkledb.RangeProof - require.NoError(rangeProof.UnmarshalProto(responseProto.GetRangeProof(), merkledb.BranchFactor16)) + require.NoError(rangeProof.UnmarshalProto(responseProto.GetRangeProof())) // modify if needed if modifyRangeProof != nil { diff --git a/x/sync/g_db/db_client.go b/x/sync/g_db/db_client.go index 8bd936a53975..9ce402f5e6ca 100644 --- a/x/sync/g_db/db_client.go +++ b/x/sync/g_db/db_client.go @@ -19,16 +19,14 @@ import ( var _ sync.DB = (*DBClient)(nil) -func NewDBClient(client pb.DBClient, branchFactor merkledb.BranchFactor) *DBClient { +func NewDBClient(client pb.DBClient) *DBClient { return &DBClient{ - client: client, - branchFactor: branchFactor, + client: client, } } type DBClient struct { - client pb.DBClient - branchFactor merkledb.BranchFactor + client pb.DBClient } func (c *DBClient) GetMerkleRoot(ctx context.Context) (ids.ID, error) { @@ -70,7 +68,7 @@ func (c *DBClient) GetChangeProof( } var proof merkledb.ChangeProof - if err := proof.UnmarshalProto(resp.GetChangeProof(), c.branchFactor); err != nil { + if err := proof.UnmarshalProto(resp.GetChangeProof()); err != nil { return nil, err } return &proof, nil @@ -122,7 +120,7 @@ func (c *DBClient) GetProof(ctx context.Context, key []byte) (*merkledb.Proof, e } var proof merkledb.Proof - if err := proof.UnmarshalProto(resp.Proof, c.branchFactor); err != nil { + if err := proof.UnmarshalProto(resp.Proof); err != nil { return nil, err } return &proof, nil @@ -152,7 +150,7 @@ func (c *DBClient) GetRangeProofAtRoot( } var proof merkledb.RangeProof - if err := proof.UnmarshalProto(resp.Proof, c.branchFactor); err != nil { + if err := proof.UnmarshalProto(resp.Proof); err != nil { return nil, err } return &proof, nil diff --git a/x/sync/g_db/db_server.go b/x/sync/g_db/db_server.go index b6471542dcca..da454e2d77cd 100644 --- a/x/sync/g_db/db_server.go +++ b/x/sync/g_db/db_server.go @@ -19,18 +19,16 @@ import ( var _ pb.DBServer = (*DBServer)(nil) -func NewDBServer(db sync.DB, branchFactor merkledb.BranchFactor) *DBServer { +func NewDBServer(db sync.DB) *DBServer { return &DBServer{ - db: db, - branchFactor: branchFactor, + db: db, } } type DBServer struct { pb.UnsafeDBServer - db sync.DB - branchFactor merkledb.BranchFactor + db sync.DB } func (s *DBServer) GetMerkleRoot( @@ -98,7 +96,7 @@ func (s *DBServer) VerifyChangeProof( req *pb.VerifyChangeProofRequest, ) (*pb.VerifyChangeProofResponse, error) { var proof merkledb.ChangeProof - if err := proof.UnmarshalProto(req.Proof, s.branchFactor); err != nil { + if err := proof.UnmarshalProto(req.Proof); err != nil { return nil, err } @@ -130,7 +128,7 @@ func (s *DBServer) CommitChangeProof( req *pb.CommitChangeProofRequest, ) (*emptypb.Empty, error) { var proof merkledb.ChangeProof - if err := proof.UnmarshalProto(req.Proof, s.branchFactor); err != nil { + if err := proof.UnmarshalProto(req.Proof); err != nil { return nil, err } @@ -201,7 +199,7 @@ func (s *DBServer) CommitRangeProof( req *pb.CommitRangeProofRequest, ) (*emptypb.Empty, error) { var proof merkledb.RangeProof - if err := proof.UnmarshalProto(req.RangeProof, s.branchFactor); err != nil { + if err := proof.UnmarshalProto(req.RangeProof); err != nil { return nil, err } diff --git a/x/sync/manager.go b/x/sync/manager.go index 0a13a89eb32b..6bd81e847aee 100644 --- a/x/sync/manager.go +++ b/x/sync/manager.go @@ -10,12 +10,15 @@ import ( "fmt" "sync" + "golang.org/x/exp/maps" + "go.uber.org/zap" "golang.org/x/exp/slices" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/maybe" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/x/merkledb" pb "github.com/ava-labs/avalanchego/proto/pb/sync" @@ -102,9 +105,9 @@ type Manager struct { cancelCtx context.CancelFunc // Set to true when StartSyncing is called. - syncing bool - closeOnce sync.Once - branchFactor merkledb.BranchFactor + syncing bool + closeOnce sync.Once + tokenSize int } type ManagerConfig struct { @@ -136,7 +139,7 @@ func NewManager(config ManagerConfig) (*Manager, error) { doneChan: make(chan struct{}), unprocessedWork: newWorkHeap(), processedWork: newWorkHeap(), - branchFactor: config.BranchFactor, + tokenSize: merkledb.BranchFactorToTokenSize[config.BranchFactor], } m.unprocessedWorkCond.L = &m.workLock @@ -404,7 +407,7 @@ func (m *Manager) findNextKey( // and traversing them from the longest key to the shortest key. // For each node in these proofs, compare if the children of that node exist // or have the same ID in the other proof. - proofKeyPath := merkledb.ToKey(lastReceivedKey, m.branchFactor) + proofKeyPath := merkledb.ToKey(lastReceivedKey) // If the received proof is an exclusion proof, the last node may be for a // key that is after the [lastReceivedKey]. @@ -447,7 +450,7 @@ func (m *Manager) findNextKey( // select the deepest proof node from the two proofs switch { - case receivedProofNode.Key.TokensLength() > localProofNode.Key.TokensLength(): + case receivedProofNode.Key.Length() > localProofNode.Key.Length(): // there was a branch node in the received proof that isn't in the local proof // see if the received proof node has children not present in the local proof deepestNode = &receivedProofNode @@ -455,7 +458,7 @@ func (m *Manager) findNextKey( // we have dealt with this received node, so move on to the next received node receivedProofNodeIndex-- - case localProofNode.Key.TokensLength() > receivedProofNode.Key.TokensLength(): + case localProofNode.Key.Length() > receivedProofNode.Key.Length(): // there was a branch node in the local proof that isn't in the received proof // see if the local proof node has children not present in the received proof deepestNode = &localProofNode @@ -482,20 +485,20 @@ func (m *Manager) findNextKey( // If the deepest node has the same key as [proofKeyPath], // then all of its children have keys greater than the proof key, // so we can start at the 0 token. - startingChildToken := byte(0) + startingChildToken := 0 // If the deepest node has a key shorter than the key being proven, // we can look at the next token index of the proof key to determine which of that // node's children have keys larger than [proofKeyPath]. // Any child with a token greater than the [proofKeyPath]'s token at that // index will have a larger key. - if deepestNode.Key.TokensLength() < proofKeyPath.TokensLength() { - startingChildToken = proofKeyPath.Token(deepestNode.Key.TokensLength()) + 1 + if deepestNode.Key.Length() < proofKeyPath.Length() { + startingChildToken = int(proofKeyPath.Token(deepestNode.Key.Length(), m.tokenSize)) + 1 } // determine if there are any differences in the children for the deepest unhandled node of the two proofs - if childIndex, hasDifference := findChildDifference(deepestNode, deepestNodeFromOtherProof, startingChildToken, m.branchFactor); hasDifference { - nextKey = maybe.Some(deepestNode.Key.Append(childIndex).Bytes()) + if childIndex, hasDifference := findChildDifference(deepestNode, deepestNodeFromOtherProof, startingChildToken); hasDifference { + nextKey = maybe.Some(deepestNode.Key.Extend(merkledb.ToToken(childIndex, m.tokenSize)).Bytes()) break } } @@ -794,12 +797,27 @@ func midPoint(startMaybe, endMaybe maybe.Maybe[[]byte]) maybe.Maybe[[]byte] { // findChildDifference returns the first child index that is different between node 1 and node 2 if one exists and // a bool indicating if any difference was found -func findChildDifference(node1, node2 *merkledb.ProofNode, startIndex byte, branchFactor merkledb.BranchFactor) (byte, bool) { +func findChildDifference(node1, node2 *merkledb.ProofNode, startIndex int) (byte, bool) { + // Children indices >= [startIndex] present in at least one of the nodes. + childIndices := set.Set[byte]{} + for _, node := range []*merkledb.ProofNode{node1, node2} { + if node == nil { + continue + } + for key := range node.Children { + if int(key) >= startIndex { + childIndices.Add(key) + } + } + } + + sortedChildIndices := maps.Keys(childIndices) + slices.Sort(sortedChildIndices) var ( child1, child2 ids.ID ok1, ok2 bool ) - for childIndex := startIndex; merkledb.BranchFactor(childIndex) < branchFactor; childIndex++ { + for _, childIndex := range sortedChildIndices { if node1 != nil { child1, ok1 = node1.Children[childIndex] } diff --git a/x/sync/network_server_test.go b/x/sync/network_server_test.go index 60555498457f..d79b27a14c44 100644 --- a/x/sync/network_server_test.go +++ b/x/sync/network_server_test.go @@ -114,7 +114,7 @@ func Test_Server_GetRangeProof(t *testing.T) { require.NoError(proto.Unmarshal(responseBytes, &proofProto)) var p merkledb.RangeProof - require.NoError(p.UnmarshalProto(&proofProto, merkledb.BranchFactor16)) + require.NoError(p.UnmarshalProto(&proofProto)) proof = &p } return nil diff --git a/x/sync/sync_test.go b/x/sync/sync_test.go index 9a6a5de2dba9..af908c9d941c 100644 --- a/x/sync/sync_test.go +++ b/x/sync/sync_test.go @@ -586,10 +586,11 @@ func TestFindNextKeyRandom(t *testing.T) { ) require.NoError(err) + config := newDefaultDBConfig() localDB, err := merkledb.New( context.Background(), memdb.New(), - newDefaultDBConfig(), + config, ) require.NoError(err) @@ -677,7 +678,7 @@ func TestFindNextKeyRandom(t *testing.T) { for _, node := range remoteProof.EndProof { for childIdx, childID := range node.Children { remoteKeyIDs = append(remoteKeyIDs, keyAndID{ - key: node.Key.Append(childIdx), + key: node.Key.Extend(merkledb.ToToken(childIdx, merkledb.BranchFactorToTokenSize[config.BranchFactor])), id: childID, }) } @@ -688,7 +689,7 @@ func TestFindNextKeyRandom(t *testing.T) { for _, node := range localProof.Path { for childIdx, childID := range node.Children { localKeyIDs = append(localKeyIDs, keyAndID{ - key: node.Key.Append(childIdx), + key: node.Key.Extend(merkledb.ToToken(childIdx, merkledb.BranchFactorToTokenSize[config.BranchFactor])), id: childID, }) } From 10bd4286d2572044dda9193dc8ceabf7c60c4f42 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 6 Nov 2023 14:49:45 -0500 Subject: [PATCH 010/267] Remove unused `UnsortedEquals` function (#2264) --- utils/compare/compare.go | 27 --------------------------- utils/compare/compare_test.go | 26 -------------------------- 2 files changed, 53 deletions(-) delete mode 100644 utils/compare/compare.go delete mode 100644 utils/compare/compare_test.go diff --git a/utils/compare/compare.go b/utils/compare/compare.go deleted file mode 100644 index 13ec52f386cb..000000000000 --- a/utils/compare/compare.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package compare - -// Returns true iff the slices have the same elements, regardless of order. -func UnsortedEquals[T comparable](a, b []T) bool { - if len(a) != len(b) { - return false - } - m := make(map[T]int, len(a)) - for _, v := range a { - m[v]++ - } - for _, v := range b { - switch count := m[v]; count { - case 0: - // There were more instances of [v] in [b] than [a]. - return false - case 1: - delete(m, v) - default: - m[v] = count - 1 - } - } - return len(m) == 0 -} diff --git a/utils/compare/compare_test.go b/utils/compare/compare_test.go deleted file mode 100644 index e46bc838f72b..000000000000 --- a/utils/compare/compare_test.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package compare - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestUnsortedEquals(t *testing.T) { - require := require.New(t) - - require.True(UnsortedEquals([]int{}, []int{})) - require.True(UnsortedEquals(nil, []int{})) - require.True(UnsortedEquals([]int{}, nil)) - require.False(UnsortedEquals([]int{1}, nil)) - require.False(UnsortedEquals(nil, []int{1})) - require.True(UnsortedEquals([]int{1}, []int{1})) - require.False(UnsortedEquals([]int{1, 2}, []int{})) - require.False(UnsortedEquals([]int{1, 2}, []int{1})) - require.False(UnsortedEquals([]int{1}, []int{1, 2})) - require.True(UnsortedEquals([]int{2, 1}, []int{1, 2})) - require.True(UnsortedEquals([]int{1, 2}, []int{2, 1})) -} From 7490a925f72f0435878320373e79ca8217a60ceb Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Mon, 6 Nov 2023 15:39:23 -0500 Subject: [PATCH 011/267] Document p2p package (#2254) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- network/p2p/handler.go | 4 ++++ network/p2p/router.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/network/p2p/handler.go b/network/p2p/handler.go index 790893142087..3e08c356eea8 100644 --- a/network/p2p/handler.go +++ b/network/p2p/handler.go @@ -50,6 +50,7 @@ type Handler interface { ) ([]byte, error) } +// NoOpHandler drops all messages type NoOpHandler struct{} func (NoOpHandler) AppGossip(context.Context, ids.NodeID, []byte) error { @@ -94,6 +95,7 @@ type responder struct { sender common.AppSender } +// AppRequest calls the underlying handler and sends back the response to nodeID func (r *responder) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { appResponse, err := r.handler.AppRequest(ctx, nodeID, deadline, request) if err != nil { @@ -122,6 +124,8 @@ func (r *responder) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte } } +// CrossChainAppRequest calls the underlying handler and sends back the response +// to chainID func (r *responder) CrossChainAppRequest(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, request []byte) error { appResponse, err := r.handler.CrossChainAppRequest(ctx, chainID, deadline, request) if err != nil { diff --git a/network/p2p/router.go b/network/p2p/router.go index 1da66a7d2d4e..e872152195db 100644 --- a/network/p2p/router.go +++ b/network/p2p/router.go @@ -49,6 +49,7 @@ type pendingCrossChainAppRequest struct { CrossChainAppResponseCallback } +// meteredHandler emits metrics for a Handler type meteredHandler struct { *responder *metrics @@ -198,6 +199,11 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp }, nil } +// AppRequest routes an AppRequest to a Handler based on the handler prefix. The +// message is dropped if no matching handler can be found. +// +// Any error condition propagated outside Handler application logic is +// considered fatal func (r *Router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { start := time.Now() parsedMsg, handler, ok := r.parse(request) @@ -212,6 +218,7 @@ func (r *Router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID ui return nil } + // call the corresponding handler and send back a response to nodeID if err := handler.AppRequest(ctx, nodeID, requestID, deadline, parsedMsg); err != nil { return err } @@ -220,10 +227,16 @@ func (r *Router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID ui return nil } +// AppRequestFailed routes an AppRequestFailed message to the callback +// corresponding to requestID. +// +// Any error condition propagated outside Handler application logic is +// considered fatal func (r *Router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { start := time.Now() pending, ok := r.clearAppRequest(requestID) if !ok { + // we should never receive a timeout without a corresponding requestID return ErrUnrequestedResponse } @@ -232,10 +245,16 @@ func (r *Router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, reques return nil } +// AppResponse routes an AppResponse message to the callback corresponding to +// requestID. +// +// Any error condition propagated outside Handler application logic is +// considered fatal func (r *Router) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { start := time.Now() pending, ok := r.clearAppRequest(requestID) if !ok { + // we should never receive a timeout without a corresponding requestID return ErrUnrequestedResponse } @@ -244,6 +263,11 @@ func (r *Router) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID u return nil } +// AppGossip routes an AppGossip message to a Handler based on the handler +// prefix. The message is dropped if no matching handler can be found. +// +// Any error condition propagated outside Handler application logic is +// considered fatal func (r *Router) AppGossip(ctx context.Context, nodeID ids.NodeID, gossip []byte) error { start := time.Now() parsedMsg, handler, ok := r.parse(gossip) @@ -262,6 +286,12 @@ func (r *Router) AppGossip(ctx context.Context, nodeID ids.NodeID, gossip []byte return nil } +// CrossChainAppRequest routes a CrossChainAppRequest message to a Handler +// based on the handler prefix. The message is dropped if no matching handler +// can be found. +// +// Any error condition propagated outside Handler application logic is +// considered fatal func (r *Router) CrossChainAppRequest( ctx context.Context, chainID ids.ID, @@ -290,10 +320,16 @@ func (r *Router) CrossChainAppRequest( return nil } +// CrossChainAppRequestFailed routes a CrossChainAppRequestFailed message to +// the callback corresponding to requestID. +// +// Any error condition propagated outside Handler application logic is +// considered fatal func (r *Router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { start := time.Now() pending, ok := r.clearCrossChainAppRequest(requestID) if !ok { + // we should never receive a timeout without a corresponding requestID return ErrUnrequestedResponse } @@ -302,10 +338,16 @@ func (r *Router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, return nil } +// CrossChainAppResponse routes a CrossChainAppResponse message to the callback +// corresponding to requestID. +// +// Any error condition propagated outside Handler application logic is +// considered fatal func (r *Router) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error { start := time.Now() pending, ok := r.clearCrossChainAppRequest(requestID) if !ok { + // we should never receive a timeout without a corresponding requestID return ErrUnrequestedResponse } From cdcfb5be8668a889be185513628f2b75aa34f19a Mon Sep 17 00:00:00 2001 From: felipemadero Date: Tue, 7 Nov 2023 17:06:59 -0300 Subject: [PATCH 012/267] Use extended public key to derive ledger addresses (#2246) Signed-off-by: felipemadero Co-authored-by: Dan Laine Co-authored-by: Stephen Buttolph --- go.mod | 11 +++++++---- go.sum | 29 ++++++++++++++++++++--------- utils/crypto/ledger/ledger.go | 31 +++++++++++++++++++++++++------ 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 3117c0edf3e1..0c161de4a463 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 github.com/ava-labs/coreth v0.12.8-rc.1 - github.com/ava-labs/ledger-avalanche/go v0.0.0-20230105152938-00a24d05a8c7 + github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 @@ -44,10 +44,11 @@ require ( github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.12.0 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.4 github.com/supranational/blst v0.3.11 github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a github.com/thepudds/fzgen v0.4.2 + github.com/tyler-smith/go-bip32 v1.0.0 go.opentelemetry.io/otel v1.11.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.0 @@ -72,6 +73,8 @@ require ( require ( github.com/BurntSushi/toml v1.2.1 // indirect + github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect + github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -138,8 +141,8 @@ require ( github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect - github.com/zondax/hid v0.9.1 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect diff --git a/go.sum b/go.sum index 0ad1313cd1b7..164a7e96d6c0 100644 --- a/go.sum +++ b/go.sum @@ -45,6 +45,10 @@ github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3 github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= @@ -64,8 +68,8 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/ava-labs/coreth v0.12.8-rc.1 h1:tvJcxQTQzxIQqx8TnrxdyMhZYbdsMaiy6AEiOyjvaa4= github.com/ava-labs/coreth v0.12.8-rc.1/go.mod h1:GBH5SxHZdScSp95IijDs9+Gxw/QDIWvfoLKiJMNYLsE= -github.com/ava-labs/ledger-avalanche/go v0.0.0-20230105152938-00a24d05a8c7 h1:EdxD90j5sClfL5Ngpz2TlnbnkNYdFPDXa0jDOjam65c= -github.com/ava-labs/ledger-avalanche/go v0.0.0-20230105152938-00a24d05a8c7/go.mod h1:XhiXSrh90sHUbkERzaxEftCmUz53eCijshDLZ4fByVM= +github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= +github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -113,6 +117,8 @@ github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86c github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -573,8 +579,8 @@ github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -583,8 +589,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -599,6 +605,8 @@ github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITn github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= +github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -632,10 +640,10 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -674,6 +682,7 @@ go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95a go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1107,6 +1116,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/utils/crypto/ledger/ledger.go b/utils/crypto/ledger/ledger.go index 37de44fec4ea..5f8c34fe5715 100644 --- a/utils/crypto/ledger/ledger.go +++ b/utils/crypto/ledger/ledger.go @@ -8,6 +8,8 @@ import ( ledger "github.com/ava-labs/ledger-avalanche/go" + bip32 "github.com/tyler-smith/go-bip32" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/hashing" @@ -15,7 +17,7 @@ import ( ) const ( - rootPath = "m/44'/9000'/0'" + rootPath = "m/44'/9000'/0'" // BIP44: m / purpose' / coin_type' / account' ledgerBufferLimit = 8192 ledgerPathSize = 9 ) @@ -26,6 +28,7 @@ var _ keychain.Ledger = (*Ledger)(nil) // provides Avalanche-specific access. type Ledger struct { device *ledger.LedgerAvalanche + epk *bip32.Key } func New() (keychain.Ledger, error) { @@ -40,21 +43,37 @@ func addressPath(index uint32) string { } func (l *Ledger) Address(hrp string, addressIndex uint32) (ids.ShortID, error) { - _, hash, err := l.device.GetPubKey(addressPath(addressIndex), true, hrp, "") + resp, err := l.device.GetPubKey(addressPath(addressIndex), true, hrp, "") if err != nil { return ids.ShortEmpty, err } - return ids.ToShortID(hash) + return ids.ToShortID(resp.Hash) } func (l *Ledger) Addresses(addressIndices []uint32) ([]ids.ShortID, error) { + if l.epk == nil { + pk, chainCode, err := l.device.GetExtPubKey(rootPath, false, "", "") + if err != nil { + return nil, err + } + l.epk = &bip32.Key{ + Key: pk, + ChainCode: chainCode, + } + } + // derivation path rootPath/0 (BIP44 change level, when set to 0, known as external chain) + externalChain, err := l.epk.NewChildKey(0) + if err != nil { + return nil, err + } addresses := make([]ids.ShortID, len(addressIndices)) - for i, v := range addressIndices { - _, hash, err := l.device.GetPubKey(addressPath(v), false, "", "") + for i, addressIndex := range addressIndices { + // derivation path rootPath/0/v (BIP44 address index level) + address, err := externalChain.NewChildKey(addressIndex) if err != nil { return nil, err } - copy(addresses[i][:], hash) + copy(addresses[i][:], hashing.PubkeyBytesToAddress(address.Key)) } return addresses, nil } From 1faec387fe4c950beb770f47ae4725919dcd6c65 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Nov 2023 17:34:09 -0500 Subject: [PATCH 013/267] `merkledb` -- rename nit (#2267) --- x/merkledb/proof.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/merkledb/proof.go b/x/merkledb/proof.go index f750158d4c11..c94a68f7db5b 100644 --- a/x/merkledb/proof.go +++ b/x/merkledb/proof.go @@ -840,9 +840,9 @@ func addPathInfo( if existingChild, ok := n.children[index]; ok { compressedKey = existingChild.compressedKey } - childPath := key.Extend(ToToken(index, t.tokenSize), compressedKey) - if (shouldInsertLeftChildren && childPath.Less(insertChildrenLessThan.Value())) || - (shouldInsertRightChildren && childPath.Greater(insertChildrenGreaterThan.Value())) { + childKey := key.Extend(ToToken(index, t.tokenSize), compressedKey) + if (shouldInsertLeftChildren && childKey.Less(insertChildrenLessThan.Value())) || + (shouldInsertRightChildren && childKey.Greater(insertChildrenGreaterThan.Value())) { // We didn't set the other values on the child entry, but it doesn't matter. // We only need the IDs to be correct so that the calculated hash is correct. n.setChildEntry( From 52f93c8ef3d35aa83e64ed19ccf1c80137535572 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Nov 2023 17:34:19 -0500 Subject: [PATCH 014/267] `merkledb` -- fix nil check in test (#2268) --- x/merkledb/trie_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/merkledb/trie_test.go b/x/merkledb/trie_test.go index e278456649b1..9bce417a7b1a 100644 --- a/x/merkledb/trie_test.go +++ b/x/merkledb/trie_test.go @@ -43,7 +43,7 @@ func getNodeValue(t ReadOnlyTrie, key string) ([]byte, error) { if err != nil { return nil, err } - if result.key != path || result == nil { + if result == nil || result.key != path { return nil, database.ErrNotFound } From 683fcfaa84edb9203a5474caab6d191be4c93af2 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Nov 2023 17:36:20 -0500 Subject: [PATCH 015/267] Add read-only database flag (`--db-read-only`) (#2266) --- config/config.go | 3 ++- config/flags.go | 1 + config/keys.go | 1 + node/config.go | 3 +++ node/node.go | 5 +++++ 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index 1ecbe33f33f8..1b0eff0f96a4 100644 --- a/config/config.go +++ b/config/config.go @@ -928,7 +928,8 @@ func getDatabaseConfig(v *viper.Viper, networkID uint32) (node.DatabaseConfig, e } return node.DatabaseConfig{ - Name: v.GetString(DBTypeKey), + Name: v.GetString(DBTypeKey), + ReadOnly: v.GetBool(DBReadOnlyKey), Path: filepath.Join( GetExpandedArg(v, DBPathKey), constants.NetworkName(networkID), diff --git a/config/flags.go b/config/flags.go index 9fce19ae501f..edece3ada4a3 100644 --- a/config/flags.go +++ b/config/flags.go @@ -105,6 +105,7 @@ func addNodeFlags(fs *pflag.FlagSet) { // Database fs.String(DBTypeKey, leveldb.Name, fmt.Sprintf("Database type to use. Must be one of {%s, %s, %s}", leveldb.Name, memdb.Name, pebble.Name)) + fs.Bool(DBReadOnlyKey, false, "If true, database writes are to memory and never persisted. May still initialize database directory/files on disk if they don't exist") fs.String(DBPathKey, defaultDBDir, "Path to database directory") fs.String(DBConfigFileKey, "", fmt.Sprintf("Path to database config file. Ignored if %s is specified", DBConfigContentKey)) fs.String(DBConfigContentKey, "", "Specifies base64 encoded database config content") diff --git a/config/keys.go b/config/keys.go index a62e960f16bb..7263cf0a6bdd 100644 --- a/config/keys.go +++ b/config/keys.go @@ -34,6 +34,7 @@ const ( StakeMintingPeriodKey = "stake-minting-period" StakeSupplyCapKey = "stake-supply-cap" DBTypeKey = "db-type" + DBReadOnlyKey = "db-read-only" DBPathKey = "db-dir" DBConfigFileKey = "db-config-file" DBConfigContentKey = "db-config-file-content" diff --git a/node/config.go b/node/config.go index f78987822c33..736bf08b74dc 100644 --- a/node/config.go +++ b/node/config.go @@ -131,6 +131,9 @@ type BootstrapConfig struct { } type DatabaseConfig struct { + // If true, all writes are to memory and are discarded at node shutdown. + ReadOnly bool `json:"readOnly"` + // Path to database Path string `json:"path"` diff --git a/node/node.go b/node/node.go index cad0073899b8..d4763db746ec 100644 --- a/node/node.go +++ b/node/node.go @@ -42,6 +42,7 @@ import ( "github.com/ava-labs/avalanchego/database/meterdb" "github.com/ava-labs/avalanchego/database/pebble" "github.com/ava-labs/avalanchego/database/prefixdb" + "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/indexer" @@ -531,6 +532,10 @@ func (n *Node) initDatabase() error { ) } + if n.Config.ReadOnly && n.Config.DatabaseConfig.Name != memdb.Name { + n.DB = versiondb.New(n.DB) + } + var err error n.DB, err = meterdb.New("db", n.MetricsRegisterer, n.DB) if err != nil { From 22f3c894d712c55dbe84a23fe1cca0242dba77c7 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 7 Nov 2023 19:12:17 -0500 Subject: [PATCH 016/267] `merkledb` -- remove unneeded var declarations (#2269) --- x/sync/client.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x/sync/client.go b/x/sync/client.go index e86c37485c7f..6605a5089935 100644 --- a/x/sync/client.go +++ b/x/sync/client.go @@ -256,9 +256,6 @@ func (c *client) GetRangeProof( return nil, err } - startKey := maybeBytesToMaybe(req.StartKey) - endKey := maybeBytesToMaybe(req.EndKey) - var rangeProof merkledb.RangeProof if err := rangeProof.UnmarshalProto(&rangeProofProto); err != nil { return nil, err @@ -268,8 +265,8 @@ func (c *client) GetRangeProof( ctx, &rangeProof, int(req.KeyLimit), - startKey, - endKey, + maybeBytesToMaybe(req.StartKey), + maybeBytesToMaybe(req.EndKey), req.RootHash, c.tokenSize, ); err != nil { From 1329a591e9d8ca0511037caac9bf947c08ac464e Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 8 Nov 2023 12:56:27 -0500 Subject: [PATCH 017/267] Add fuzz test for `NewIteratorWithStartAndPrefix` (#1992) Co-authored-by: Alberto Benegiamo --- database/corruptabledb/db_test.go | 25 +++++------ database/encdb/db_test.go | 24 ++++++----- database/leveldb/db_test.go | 27 +++++++----- database/memdb/db_test.go | 4 ++ database/meterdb/db_test.go | 24 ++++++----- database/pebble/db_test.go | 6 +++ database/prefixdb/db_test.go | 4 ++ database/rpcdb/db_test.go | 7 ++++ database/test_database.go | 69 ++++++++++++++++++++++++++++++- database/versiondb/db_test.go | 4 ++ 10 files changed, 148 insertions(+), 46 deletions(-) diff --git a/database/corruptabledb/db_test.go b/database/corruptabledb/db_test.go index d4c14f782986..b58c65b4b162 100644 --- a/database/corruptabledb/db_test.go +++ b/database/corruptabledb/db_test.go @@ -26,16 +26,21 @@ func TestInterface(t *testing.T) { } } -func FuzzKeyValue(f *testing.F) { +func newDB() *Database { baseDB := memdb.New() - db := New(baseDB) - database.FuzzKeyValue(f, db) + return New(baseDB) +} + +func FuzzKeyValue(f *testing.F) { + database.FuzzKeyValue(f, newDB()) } func FuzzNewIteratorWithPrefix(f *testing.F) { - baseDB := memdb.New() - db := New(baseDB) - database.FuzzNewIteratorWithPrefix(f, db) + database.FuzzNewIteratorWithPrefix(f, newDB()) +} + +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + database.FuzzNewIteratorWithStartAndPrefix(f, newDB()) } // TestCorruption tests to make sure corruptabledb wrapper works as expected. @@ -70,9 +75,7 @@ func TestCorruption(t *testing.T) { return err }, } - baseDB := memdb.New() - // wrap this db - corruptableDB := New(baseDB) + corruptableDB := newDB() _ = corruptableDB.handleError(errTest) for name, testFn := range tests { t.Run(name, func(tt *testing.T) { @@ -176,9 +179,7 @@ func TestIterator(t *testing.T) { ctrl := gomock.NewController(t) // Make a database - baseDB := memdb.New() - corruptableDB := New(baseDB) - + corruptableDB := newDB() // Put a key-value pair in the database. require.NoError(corruptableDB.Put([]byte{0}, []byte{1})) diff --git a/database/encdb/db_test.go b/database/encdb/db_test.go index 177259f5c7f2..f49dd7ebb28d 100644 --- a/database/encdb/db_test.go +++ b/database/encdb/db_test.go @@ -24,28 +24,30 @@ func TestInterface(t *testing.T) { } } -func FuzzKeyValue(f *testing.F) { +func newDB(t testing.TB) database.Database { unencryptedDB := memdb.New() db, err := New([]byte(testPassword), unencryptedDB) - require.NoError(f, err) - database.FuzzKeyValue(f, db) + require.NoError(t, err) + return db +} + +func FuzzKeyValue(f *testing.F) { + database.FuzzKeyValue(f, newDB(f)) } func FuzzNewIteratorWithPrefix(f *testing.F) { - unencryptedDB := memdb.New() - db, err := New([]byte(testPassword), unencryptedDB) - require.NoError(f, err) - database.FuzzNewIteratorWithPrefix(f, db) + database.FuzzNewIteratorWithPrefix(f, newDB(f)) +} + +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + database.FuzzNewIteratorWithStartAndPrefix(f, newDB(f)) } func BenchmarkInterface(b *testing.B) { for _, size := range database.BenchmarkSizes { keys, values := database.SetupBenchmark(b, size[0], size[1], size[2]) for _, bench := range database.Benchmarks { - unencryptedDB := memdb.New() - db, err := New([]byte(testPassword), unencryptedDB) - require.NoError(b, err) - bench(b, db, "encdb", keys, values) + bench(b, newDB(b), "encdb", keys, values) } } } diff --git a/database/leveldb/db_test.go b/database/leveldb/db_test.go index bf6bdeac7f27..23733dacaff4 100644 --- a/database/leveldb/db_test.go +++ b/database/leveldb/db_test.go @@ -26,34 +26,39 @@ func TestInterface(t *testing.T) { } } -func FuzzKeyValue(f *testing.F) { - folder := f.TempDir() +func newDB(t testing.TB) database.Database { + folder := t.TempDir() db, err := New(folder, nil, logging.NoLog{}, "", prometheus.NewRegistry()) - require.NoError(f, err) + require.NoError(t, err) + return db +} +func FuzzKeyValue(f *testing.F) { + db := newDB(f) defer db.Close() database.FuzzKeyValue(f, db) } func FuzzNewIteratorWithPrefix(f *testing.F) { - folder := f.TempDir() - db, err := New(folder, nil, logging.NoLog{}, "", prometheus.NewRegistry()) - require.NoError(f, err) - + db := newDB(f) defer db.Close() database.FuzzNewIteratorWithPrefix(f, db) } +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + db := newDB(f) + defer db.Close() + + database.FuzzNewIteratorWithStartAndPrefix(f, db) +} + func BenchmarkInterface(b *testing.B) { for _, size := range database.BenchmarkSizes { keys, values := database.SetupBenchmark(b, size[0], size[1], size[2]) for _, bench := range database.Benchmarks { - folder := b.TempDir() - - db, err := New(folder, nil, logging.NoLog{}, "", prometheus.NewRegistry()) - require.NoError(b, err) + db := newDB(b) bench(b, db, "leveldb", keys, values) diff --git a/database/memdb/db_test.go b/database/memdb/db_test.go index b0497758f5c2..10d8ebe2be25 100644 --- a/database/memdb/db_test.go +++ b/database/memdb/db_test.go @@ -23,6 +23,10 @@ func FuzzNewIteratorWithPrefix(f *testing.F) { database.FuzzNewIteratorWithPrefix(f, New()) } +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + database.FuzzNewIteratorWithStartAndPrefix(f, New()) +} + func BenchmarkInterface(b *testing.B) { for _, size := range database.BenchmarkSizes { keys, values := database.SetupBenchmark(b, size[0], size[1], size[2]) diff --git a/database/meterdb/db_test.go b/database/meterdb/db_test.go index ddd613353946..a54d25c21542 100644 --- a/database/meterdb/db_test.go +++ b/database/meterdb/db_test.go @@ -24,28 +24,30 @@ func TestInterface(t *testing.T) { } } -func FuzzKeyValue(f *testing.F) { +func newDB(t testing.TB) database.Database { baseDB := memdb.New() db, err := New("", prometheus.NewRegistry(), baseDB) - require.NoError(f, err) - database.FuzzKeyValue(f, db) + require.NoError(t, err) + return db +} + +func FuzzKeyValue(f *testing.F) { + database.FuzzKeyValue(f, newDB(f)) } func FuzzNewIteratorWithPrefix(f *testing.F) { - baseDB := memdb.New() - db, err := New("", prometheus.NewRegistry(), baseDB) - require.NoError(f, err) - database.FuzzNewIteratorWithPrefix(f, db) + database.FuzzNewIteratorWithPrefix(f, newDB(f)) +} + +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + database.FuzzNewIteratorWithStartAndPrefix(f, newDB(f)) } func BenchmarkInterface(b *testing.B) { for _, size := range database.BenchmarkSizes { keys, values := database.SetupBenchmark(b, size[0], size[1], size[2]) for _, bench := range database.Benchmarks { - baseDB := memdb.New() - db, err := New("", prometheus.NewRegistry(), baseDB) - require.NoError(b, err) - bench(b, db, "meterdb", keys, values) + bench(b, newDB(b), "meterdb", keys, values) } } } diff --git a/database/pebble/db_test.go b/database/pebble/db_test.go index cba67a79a88f..043caa23c813 100644 --- a/database/pebble/db_test.go +++ b/database/pebble/db_test.go @@ -41,6 +41,12 @@ func FuzzNewIteratorWithPrefix(f *testing.F) { _ = db.Close() } +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + db := newDB(f) + database.FuzzNewIteratorWithStartAndPrefix(f, db) + _ = db.Close() +} + func BenchmarkInterface(b *testing.B) { for _, size := range database.BenchmarkSizes { keys, values := database.SetupBenchmark(b, size[0], size[1], size[2]) diff --git a/database/prefixdb/db_test.go b/database/prefixdb/db_test.go index 065e1d7a00c8..a0539b8e0105 100644 --- a/database/prefixdb/db_test.go +++ b/database/prefixdb/db_test.go @@ -30,6 +30,10 @@ func FuzzNewIteratorWithPrefix(f *testing.F) { database.FuzzNewIteratorWithPrefix(f, New([]byte(""), memdb.New())) } +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + database.FuzzNewIteratorWithStartAndPrefix(f, New([]byte(""), memdb.New())) +} + func BenchmarkInterface(b *testing.B) { for _, size := range database.BenchmarkSizes { keys, values := database.SetupBenchmark(b, size[0], size[1], size[2]) diff --git a/database/rpcdb/db_test.go b/database/rpcdb/db_test.go index 763b95b83f75..baabc9a69fbf 100644 --- a/database/rpcdb/db_test.go +++ b/database/rpcdb/db_test.go @@ -75,6 +75,13 @@ func FuzzNewIteratorWithPrefix(f *testing.F) { db.closeFn() } +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + db := setupDB(f) + database.FuzzNewIteratorWithStartAndPrefix(f, db.client) + + db.closeFn() +} + func BenchmarkInterface(b *testing.B) { for _, size := range database.BenchmarkSizes { keys, values := database.SetupBenchmark(b, size[0], size[1], size[2]) diff --git a/database/test_database.go b/database/test_database.go index 2e68f53341b8..fc7e644ae5fd 100644 --- a/database/test_database.go +++ b/database/test_database.go @@ -1266,7 +1266,74 @@ func FuzzNewIteratorWithPrefix(f *testing.F, db Database) { require.Equal(expected[string(iter.Key())], val) numIterElts++ } - require.Equal(len(expectedList), numIterElts) + require.Len(expectedList, numIterElts) + + // Clear the database for the next fuzz iteration. + require.NoError(AtomicClear(db, db)) + }) +} + +func FuzzNewIteratorWithStartAndPrefix(f *testing.F, db Database) { + const ( + maxKeyLen = 32 + maxValueLen = 32 + ) + + f.Fuzz(func( + t *testing.T, + randSeed int64, + start []byte, + prefix []byte, + numKeyValues uint, + ) { + require := require.New(t) + r := rand.New(rand.NewSource(randSeed)) // #nosec G404 + + expected := map[string][]byte{} + + // Put a bunch of key-values + for i := 0; i < int(numKeyValues); i++ { + key := make([]byte, r.Intn(maxKeyLen)) + _, _ = r.Read(key) // #nosec G404 + + value := make([]byte, r.Intn(maxValueLen)) + _, _ = r.Read(value) // #nosec G404 + + if len(value) == 0 { + // Consistently treat zero length values as nil + // so that we can compare [expected] and [got] with + // require.Equal, which treats nil and empty byte + // as being unequal, whereas the database treats + // them as being equal. + value = nil + } + + if bytes.HasPrefix(key, prefix) && bytes.Compare(key, start) >= 0 { + expected[string(key)] = value + } + + require.NoError(db.Put(key, value)) + } + + expectedList := maps.Keys(expected) + slices.Sort(expectedList) + + iter := db.NewIteratorWithStartAndPrefix(start, prefix) + defer iter.Release() + + // Assert the iterator returns the expected key-values. + numIterElts := 0 + for iter.Next() { + val := iter.Value() + if len(val) == 0 { + val = nil + } + keyStr := string(iter.Key()) + require.Equal(expectedList[numIterElts], keyStr) + require.Equal(expected[keyStr], val) + numIterElts++ + } + require.Len(expectedList, numIterElts) // Clear the database for the next fuzz iteration. require.NoError(AtomicClear(db, db)) diff --git a/database/versiondb/db_test.go b/database/versiondb/db_test.go index fdea2934b8d2..c2f57caacf61 100644 --- a/database/versiondb/db_test.go +++ b/database/versiondb/db_test.go @@ -27,6 +27,10 @@ func FuzzNewIteratorWithPrefix(f *testing.F) { database.FuzzNewIteratorWithPrefix(f, New(memdb.New())) } +func FuzzNewIteratorWithStartAndPrefix(f *testing.F) { + database.FuzzNewIteratorWithStartAndPrefix(f, New(memdb.New())) +} + func TestIterate(t *testing.T) { require := require.New(t) From 93d88c04437a3053f1de8a761d2504a80b00a512 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 8 Nov 2023 15:02:10 -0500 Subject: [PATCH 018/267] Return if element was deleted from `Hashmap` (#2271) Co-authored-by: Dan Laine --- utils/linkedhashmap/linkedhashmap.go | 12 +++++++----- utils/linkedhashmap/linkedhashmap_test.go | 8 ++++---- vms/avm/txs/mempool/mempool.go | 14 +++++--------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/utils/linkedhashmap/linkedhashmap.go b/utils/linkedhashmap/linkedhashmap.go index 12e9569c3391..fa5a123a0942 100644 --- a/utils/linkedhashmap/linkedhashmap.go +++ b/utils/linkedhashmap/linkedhashmap.go @@ -17,7 +17,7 @@ var _ LinkedHashmap[int, struct{}] = (*linkedHashmap[int, struct{}])(nil) type Hashmap[K, V any] interface { Put(key K, val V) Get(key K) (val V, exists bool) - Delete(key K) + Delete(key K) (deleted bool) Len() int } @@ -63,11 +63,11 @@ func (lh *linkedHashmap[K, V]) Get(key K) (V, bool) { return lh.get(key) } -func (lh *linkedHashmap[K, V]) Delete(key K) { +func (lh *linkedHashmap[K, V]) Delete(key K) bool { lh.lock.Lock() defer lh.lock.Unlock() - lh.delete(key) + return lh.delete(key) } func (lh *linkedHashmap[K, V]) Len() int { @@ -114,11 +114,13 @@ func (lh *linkedHashmap[K, V]) get(key K) (V, bool) { return utils.Zero[V](), false } -func (lh *linkedHashmap[K, V]) delete(key K) { - if e, ok := lh.entryMap[key]; ok { +func (lh *linkedHashmap[K, V]) delete(key K) bool { + e, ok := lh.entryMap[key] + if ok { lh.entryList.Remove(e) delete(lh.entryMap, key) } + return ok } func (lh *linkedHashmap[K, V]) len() int { diff --git a/utils/linkedhashmap/linkedhashmap_test.go b/utils/linkedhashmap/linkedhashmap_test.go index 8bd7239ed5d9..0c95c30b24a8 100644 --- a/utils/linkedhashmap/linkedhashmap_test.go +++ b/utils/linkedhashmap/linkedhashmap_test.go @@ -62,7 +62,7 @@ func TestLinkedHashmap(t *testing.T) { require.Equal(key1, rkey1, "wrong key") require.Equal(1, val1, "wrong value") - lh.Delete(key0) + require.True(lh.Delete(key0)) require.Equal(1, lh.Len(), "wrong hashmap length") _, exists = lh.Get(key0) @@ -132,7 +132,7 @@ func TestIterator(t *testing.T) { // Should be empty require.False(iter.Next()) // Delete id1 - lh.Delete(id1) + require.True(lh.Delete(id1)) iter = lh.NewIterator() require.NotNil(iter) // Should immediately be exhausted @@ -169,8 +169,8 @@ func TestIterator(t *testing.T) { iter := lh.NewIterator() require.True(iter.Next()) require.True(iter.Next()) - lh.Delete(id1) - lh.Delete(id2) + require.True(lh.Delete(id1)) + require.True(lh.Delete(id2)) require.True(iter.Next()) require.Equal(id3, iter.Key()) require.Equal(3, iter.Value()) diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index b64002e8f39d..84a3583781ef 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -48,8 +48,7 @@ type Mempool interface { Get(txID ids.ID) *txs.Tx Remove(txs []*txs.Tx) - // Peek returns the next first tx that was added to the mempool whose size - // is less than or equal to maxTxSize. + // Peek returns the first tx in the mempool whose size is <= [maxTxSize]. Peek(maxTxSize int) *txs.Tx // RequestBuildBlock notifies the consensus engine that a block should be @@ -162,23 +161,20 @@ func (m *mempool) Has(txID ids.ID) bool { } func (m *mempool) Get(txID ids.ID) *txs.Tx { - unissuedTxs, _ := m.unissuedTxs.Get(txID) - return unissuedTxs + tx, _ := m.unissuedTxs.Get(txID) + return tx } func (m *mempool) Remove(txsToRemove []*txs.Tx) { for _, tx := range txsToRemove { txID := tx.ID() - if _, ok := m.unissuedTxs.Get(txID); !ok { - // If tx isn't in the mempool, there is nothing to do. + if !m.unissuedTxs.Delete(txID) { continue } - txBytes := tx.Bytes() - m.bytesAvailable += len(txBytes) + m.bytesAvailable += len(tx.Bytes()) m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) - m.unissuedTxs.Delete(txID) m.numTxs.Dec() inputs := tx.Unsigned.InputIDs() From fc95834bb2ef89faffc4f8de43eaec71aa80cad3 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 8 Nov 2023 16:41:39 -0500 Subject: [PATCH 019/267] `mempool.NewMempool` -> `mempool.New` (#2276) --- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/txs/mempool/mempool.go | 2 +- vms/platformvm/txs/mempool/mempool_test.go | 6 +++--- vms/platformvm/vm.go | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index ed55791147d8..a773fc964ef6 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -157,7 +157,7 @@ func newEnvironment(t *testing.T) *environment { metrics, err := metrics.New("", registerer) require.NoError(err) - res.mempool, err = mempool.NewMempool("mempool", registerer, res) + res.mempool, err = mempool.New("mempool", registerer, res) require.NoError(err) res.blkManager = blockexecutor.NewManager( diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 5e79d52c9b10..9448cdde44eb 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -189,7 +189,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller) *environment { metrics := metrics.Noop var err error - res.mempool, err = mempool.NewMempool("mempool", registerer, res) + res.mempool, err = mempool.New("mempool", registerer, res) if err != nil { panic(fmt.Errorf("failed to create mempool: %w", err)) } diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 7d1ba9b609bd..086e29b7047c 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -97,7 +97,7 @@ type mempool struct { blkTimer BlockTimer } -func NewMempool( +func New( namespace string, registerer prometheus.Registerer, blkTimer BlockTimer, diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index bdcd3101233f..dbfe895f9d9b 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -34,7 +34,7 @@ func TestBlockBuilderMaxMempoolSizeHandling(t *testing.T) { require := require.New(t) registerer := prometheus.NewRegistry() - mpool, err := NewMempool("mempool", registerer, &noopBlkTimer{}) + mpool, err := New("mempool", registerer, &noopBlkTimer{}) require.NoError(err) decisionTxs, err := createTestDecisionTxs(1) @@ -58,7 +58,7 @@ func TestDecisionTxsInMempool(t *testing.T) { require := require.New(t) registerer := prometheus.NewRegistry() - mpool, err := NewMempool("mempool", registerer, &noopBlkTimer{}) + mpool, err := New("mempool", registerer, &noopBlkTimer{}) require.NoError(err) decisionTxs, err := createTestDecisionTxs(2) @@ -110,7 +110,7 @@ func TestProposalTxsInMempool(t *testing.T) { require := require.New(t) registerer := prometheus.NewRegistry() - mpool, err := NewMempool("mempool", registerer, &noopBlkTimer{}) + mpool, err := New("mempool", registerer, &noopBlkTimer{}) require.NoError(err) // The proposal txs are ordered by decreasing start time. This means after diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 8522d3ae4715..72201c16e42f 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -177,7 +177,7 @@ func (vm *VM) Initialize( // Note: There is a circular dependency between the mempool and block // builder which is broken by passing in the vm. - mempool, err := mempool.NewMempool("mempool", registerer, vm) + mempool, err := mempool.New("mempool", registerer, vm) if err != nil { return fmt.Errorf("failed to create mempool: %w", err) } From aba404e8e40a080391f5acef5192ea216269406e Mon Sep 17 00:00:00 2001 From: marun Date: Wed, 8 Nov 2023 22:54:42 +0100 Subject: [PATCH 020/267] e2e: Refactor suite setup and helpers to tests/fixture/e2e for reuse by coreth (#2265) --- tests/e2e/banff/suites.go | 2 +- tests/e2e/c/dynamic_fees.go | 2 +- tests/e2e/c/interchain_workflow.go | 2 +- tests/e2e/e2e_test.go | 76 +--------- tests/e2e/faultinjection/duplicate_node_id.go | 2 +- tests/e2e/p/interchain_workflow.go | 2 +- tests/e2e/p/permissionless_subnets.go | 2 +- tests/e2e/p/staking_rewards.go | 2 +- tests/e2e/p/workflow.go | 2 +- tests/e2e/static-handlers/suites.go | 2 +- tests/e2e/x/interchain_workflow.go | 2 +- tests/e2e/x/transfer/virtuous.go | 2 +- tests/{ => fixture}/e2e/describe.go | 0 tests/fixture/e2e/env.go | 138 ++++++++++++++++++ tests/fixture/e2e/flags.go | 57 ++++++++ tests/{e2e/e2e.go => fixture/e2e/helpers.go} | 80 ---------- tests/upgrade/upgrade_test.go | 2 +- 17 files changed, 212 insertions(+), 163 deletions(-) rename tests/{ => fixture}/e2e/describe.go (100%) create mode 100644 tests/fixture/e2e/env.go create mode 100644 tests/fixture/e2e/flags.go rename tests/{e2e/e2e.go => fixture/e2e/helpers.go} (73%) diff --git a/tests/e2e/banff/suites.go b/tests/e2e/banff/suites.go index 5bc071d6e004..37d0aa90156a 100644 --- a/tests/e2e/banff/suites.go +++ b/tests/e2e/banff/suites.go @@ -11,7 +11,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index c8e005621983..8f15b6d43caf 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -19,7 +19,7 @@ import ( "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/tests/fixture/testnet" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" ) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index d4881255ddff..2c9bd198ec39 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -14,7 +14,7 @@ import ( "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/set" diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 2e9a86684df0..3245516262d2 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -4,22 +4,13 @@ package e2e_test import ( - "encoding/json" - "flag" - "fmt" - "os" "testing" ginkgo "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/e2e" - "github.com/ava-labs/avalanchego/tests/fixture" - "github.com/ava-labs/avalanchego/tests/fixture/testnet/local" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" // ensure test packages are scanned by ginkgo _ "github.com/ava-labs/avalanchego/tests/e2e/banff" @@ -36,75 +27,18 @@ func TestE2E(t *testing.T) { ginkgo.RunSpecs(t, "e2e test suites") } -var ( - avalancheGoExecPath string - persistentNetworkDir string - usePersistentNetwork bool -) +var flagVars *e2e.FlagVars func init() { - flag.StringVar( - &avalancheGoExecPath, - "avalanchego-path", - os.Getenv(local.AvalancheGoPathEnvName), - fmt.Sprintf("avalanchego executable path (required if not using a persistent network). Also possible to configure via the %s env variable.", local.AvalancheGoPathEnvName), - ) - flag.StringVar( - &persistentNetworkDir, - "network-dir", - "", - fmt.Sprintf("[optional] the dir containing the configuration of a persistent network to target for testing. Useful for speeding up test development. Also possible to configure via the %s env variable.", local.NetworkDirEnvName), - ) - flag.BoolVar( - &usePersistentNetwork, - "use-persistent-network", - false, - "[optional] whether to target the persistent network identified by --network-dir.", - ) + flagVars = e2e.RegisterFlags() } var _ = ginkgo.SynchronizedBeforeSuite(func() []byte { // Run only once in the first ginkgo process - - require := require.New(ginkgo.GinkgoT()) - - if usePersistentNetwork && len(persistentNetworkDir) == 0 { - persistentNetworkDir = os.Getenv(local.NetworkDirEnvName) - } - - // Load or create a test network - var network *local.LocalNetwork - if len(persistentNetworkDir) > 0 { - tests.Outf("{{yellow}}Using a persistent network configured at %s{{/}}\n", persistentNetworkDir) - - var err error - network, err = local.ReadNetwork(persistentNetworkDir) - require.NoError(err) - } else { - network = e2e.StartLocalNetwork(avalancheGoExecPath, e2e.DefaultNetworkDir) - } - - uris := network.GetURIs() - require.NotEmpty(uris, "network contains no nodes") - tests.Outf("{{green}}network URIs: {{/}} %+v\n", uris) - - testDataServerURI, err := fixture.ServeTestData(fixture.TestData{ - FundedKeys: network.FundedKeys, - }) - tests.Outf("{{green}}test data server URI: {{/}} %+v\n", testDataServerURI) - require.NoError(err) - - env := &e2e.TestEnvironment{ - NetworkDir: network.Dir, - URIs: uris, - TestDataServerURI: testDataServerURI, - } - bytes, err := json.Marshal(env) - require.NoError(err) - return bytes + return e2e.NewTestEnvironment(flagVars).Marshal() }, func(envBytes []byte) { // Run in every ginkgo process // Initialize the local test environment from the global state - e2e.InitTestEnvironment(envBytes) + e2e.InitSharedTestEnvironment(envBytes) }) diff --git a/tests/e2e/faultinjection/duplicate_node_id.go b/tests/e2e/faultinjection/duplicate_node_id.go index bcdd05cb35b0..1d865d840f51 100644 --- a/tests/e2e/faultinjection/duplicate_node_id.go +++ b/tests/e2e/faultinjection/duplicate_node_id.go @@ -14,7 +14,7 @@ import ( "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/tests/fixture/testnet" "github.com/ava-labs/avalanchego/utils/set" ) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 9bea416294cb..44a6912715ef 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -18,7 +18,7 @@ import ( "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/tests/fixture/testnet" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" diff --git a/tests/e2e/p/permissionless_subnets.go b/tests/e2e/p/permissionless_subnets.go index ab2909228365..0521306b9b40 100644 --- a/tests/e2e/p/permissionless_subnets.go +++ b/tests/e2e/p/permissionless_subnets.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index 09b169dfb8f4..41a77985729b 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -19,7 +19,7 @@ import ( "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/tests/fixture/testnet" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index c0fda23775fd..3f0440ac49b6 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/units" diff --git a/tests/e2e/static-handlers/suites.go b/tests/e2e/static-handlers/suites.go index 596a79f3afda..52c0f50a9436 100644 --- a/tests/e2e/static-handlers/suites.go +++ b/tests/e2e/static-handlers/suites.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils/cb58" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index 373e567a666a..f0c2951feb84 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/set" diff --git a/tests/e2e/x/transfer/virtuous.go b/tests/e2e/x/transfer/virtuous.go index 119e28b9d1e9..7a1eb1bb6b91 100644 --- a/tests/e2e/x/transfer/virtuous.go +++ b/tests/e2e/x/transfer/virtuous.go @@ -16,7 +16,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/avm" "github.com/ava-labs/avalanchego/vms/components/avax" diff --git a/tests/e2e/describe.go b/tests/fixture/e2e/describe.go similarity index 100% rename from tests/e2e/describe.go rename to tests/fixture/e2e/describe.go diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go new file mode 100644 index 000000000000..54a4676482e1 --- /dev/null +++ b/tests/fixture/e2e/env.go @@ -0,0 +1,138 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package e2e + +import ( + "encoding/json" + "math/rand" + "os" + "path/filepath" + "time" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/tests" + "github.com/ava-labs/avalanchego/tests/fixture" + "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/tests/fixture/testnet/local" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/perms" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +// Env is used to access shared test fixture. Intended to be +// initialized from SynchronizedBeforeSuite. +var Env *TestEnvironment + +func InitSharedTestEnvironment(envBytes []byte) { + require := require.New(ginkgo.GinkgoT()) + require.Nil(Env, "env already initialized") + Env = &TestEnvironment{ + require: require, + } + require.NoError(json.Unmarshal(envBytes, Env)) +} + +type TestEnvironment struct { + // The directory where the test network configuration is stored + NetworkDir string + // URIs used to access the API endpoints of nodes of the network + URIs []testnet.NodeURI + // The URI used to access the http server that allocates test data + TestDataServerURI string + + require *require.Assertions +} + +func (te *TestEnvironment) Marshal() []byte { + bytes, err := json.Marshal(te) + require.NoError(ginkgo.GinkgoT(), err) + return bytes +} + +// Initialize a new test environment with a shared network (either pre-existing or newly created). +func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { + require := require.New(ginkgo.GinkgoT()) + + persistentNetworkDir := flagVars.PersistentNetworkDir() + + // Load or create a test network + var network *local.LocalNetwork + if len(persistentNetworkDir) > 0 { + tests.Outf("{{yellow}}Using a persistent network configured at %s{{/}}\n", persistentNetworkDir) + + var err error + network, err = local.ReadNetwork(persistentNetworkDir) + require.NoError(err) + } else { + network = StartLocalNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir) + } + + uris := network.GetURIs() + require.NotEmpty(uris, "network contains no nodes") + tests.Outf("{{green}}network URIs: {{/}} %+v\n", uris) + + testDataServerURI, err := fixture.ServeTestData(fixture.TestData{ + FundedKeys: network.FundedKeys, + }) + tests.Outf("{{green}}test data server URI: {{/}} %+v\n", testDataServerURI) + require.NoError(err) + + return &TestEnvironment{ + NetworkDir: network.Dir, + URIs: uris, + TestDataServerURI: testDataServerURI, + } +} + +// Retrieve a random URI to naively attempt to spread API load across +// nodes. +func (te *TestEnvironment) GetRandomNodeURI() testnet.NodeURI { + r := rand.New(rand.NewSource(time.Now().Unix())) //#nosec G404 + nodeURI := te.URIs[r.Intn(len(te.URIs))] + tests.Outf("{{blue}} targeting node %s with URI: %s{{/}}\n", nodeURI.NodeID, nodeURI.URI) + return nodeURI +} + +// Retrieve the network to target for testing. +func (te *TestEnvironment) GetNetwork() testnet.Network { + network, err := local.ReadNetwork(te.NetworkDir) + te.require.NoError(err) + return network +} + +// Retrieve the specified number of funded keys allocated for the caller's exclusive use. +func (te *TestEnvironment) AllocateFundedKeys(count int) []*secp256k1.PrivateKey { + keys, err := fixture.AllocateFundedKeys(te.TestDataServerURI, count) + te.require.NoError(err) + tests.Outf("{{blue}} allocated funded key(s): %+v{{/}}\n", keys) + return keys +} + +// Retrieve a funded key allocated for the caller's exclusive use. +func (te *TestEnvironment) AllocateFundedKey() *secp256k1.PrivateKey { + return te.AllocateFundedKeys(1)[0] +} + +// Create a new keychain with the specified number of test keys. +func (te *TestEnvironment) NewKeychain(count int) *secp256k1fx.Keychain { + keys := te.AllocateFundedKeys(count) + return secp256k1fx.NewKeychain(keys...) +} + +// Create a new private network that is not shared with other tests. +func (te *TestEnvironment) NewPrivateNetwork() testnet.Network { + // Load the shared network to retrieve its path and exec path + sharedNetwork, err := local.ReadNetwork(te.NetworkDir) + te.require.NoError(err) + + // The private networks dir is under the shared network dir to ensure it + // will be included in the artifact uploaded in CI. + privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName) + te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute)) + + return StartLocalNetwork(sharedNetwork.ExecPath, privateNetworksDir) +} diff --git a/tests/fixture/e2e/flags.go b/tests/fixture/e2e/flags.go new file mode 100644 index 000000000000..c7838cb7c761 --- /dev/null +++ b/tests/fixture/e2e/flags.go @@ -0,0 +1,57 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package e2e + +import ( + "flag" + "fmt" + "os" + + "github.com/ava-labs/avalanchego/tests/fixture/testnet/local" +) + +type FlagVars struct { + avalancheGoExecPath string + persistentNetworkDir string + usePersistentNetwork bool +} + +func (v *FlagVars) PersistentNetworkDir() string { + if v.usePersistentNetwork && len(v.persistentNetworkDir) == 0 { + return os.Getenv(local.NetworkDirEnvName) + } + return v.persistentNetworkDir +} + +func (v *FlagVars) AvalancheGoExecPath() string { + return v.avalancheGoExecPath +} + +func (v *FlagVars) UsePersistentNetwork() bool { + return v.usePersistentNetwork +} + +func RegisterFlags() *FlagVars { + vars := FlagVars{} + flag.StringVar( + &vars.avalancheGoExecPath, + "avalanchego-path", + os.Getenv(local.AvalancheGoPathEnvName), + fmt.Sprintf("avalanchego executable path (required if not using a persistent network). Also possible to configure via the %s env variable.", local.AvalancheGoPathEnvName), + ) + flag.StringVar( + &vars.persistentNetworkDir, + "network-dir", + "", + fmt.Sprintf("[optional] the dir containing the configuration of a persistent network to target for testing. Useful for speeding up test development. Also possible to configure via the %s env variable.", local.NetworkDirEnvName), + ) + flag.BoolVar( + &vars.usePersistentNetwork, + "use-persistent-network", + false, + "[optional] whether to target the persistent network identified by --network-dir.", + ) + + return &vars +} diff --git a/tests/e2e/e2e.go b/tests/fixture/e2e/helpers.go similarity index 73% rename from tests/e2e/e2e.go rename to tests/fixture/e2e/helpers.go index 44c5d911e8dd..cc1e22ae3aa9 100644 --- a/tests/e2e/e2e.go +++ b/tests/fixture/e2e/helpers.go @@ -1,18 +1,14 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -// e2e implements the e2e tests. package e2e import ( "context" - "encoding/json" "errors" "fmt" "math/big" - "math/rand" "os" - "path/filepath" "strings" "time" @@ -26,11 +22,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/fixture" "github.com/ava-labs/avalanchego/tests/fixture/testnet" "github.com/ava-labs/avalanchego/tests/fixture/testnet/local" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary" @@ -68,79 +61,6 @@ const ( PrivateNetworksDirName = "private_networks" ) -// Env is used to access shared test fixture. Intended to be -// initialized by SynchronizedBeforeSuite. -var Env *TestEnvironment - -type TestEnvironment struct { - // The directory where the test network configuration is stored - NetworkDir string - // URIs used to access the API endpoints of nodes of the network - URIs []testnet.NodeURI - // The URI used to access the http server that allocates test data - TestDataServerURI string - - require *require.Assertions -} - -func InitTestEnvironment(envBytes []byte) { - require := require.New(ginkgo.GinkgoT()) - require.Nil(Env, "env already initialized") - Env = &TestEnvironment{ - require: require, - } - require.NoError(json.Unmarshal(envBytes, Env)) -} - -// Retrieve a random URI to naively attempt to spread API load across -// nodes. -func (te *TestEnvironment) GetRandomNodeURI() testnet.NodeURI { - r := rand.New(rand.NewSource(time.Now().Unix())) //#nosec G404 - nodeURI := te.URIs[r.Intn(len(te.URIs))] - tests.Outf("{{blue}} targeting node %s with URI: %s{{/}}\n", nodeURI.NodeID, nodeURI.URI) - return nodeURI -} - -// Retrieve the network to target for testing. -func (te *TestEnvironment) GetNetwork() testnet.Network { - network, err := local.ReadNetwork(te.NetworkDir) - te.require.NoError(err) - return network -} - -// Retrieve the specified number of funded keys allocated for the caller's exclusive use. -func (te *TestEnvironment) AllocateFundedKeys(count int) []*secp256k1.PrivateKey { - keys, err := fixture.AllocateFundedKeys(te.TestDataServerURI, count) - te.require.NoError(err) - tests.Outf("{{blue}} allocated funded key(s): %+v{{/}}\n", keys) - return keys -} - -// Retrieve a funded key allocated for the caller's exclusive use. -func (te *TestEnvironment) AllocateFundedKey() *secp256k1.PrivateKey { - return te.AllocateFundedKeys(1)[0] -} - -// Create a new keychain with the specified number of test keys. -func (te *TestEnvironment) NewKeychain(count int) *secp256k1fx.Keychain { - keys := te.AllocateFundedKeys(count) - return secp256k1fx.NewKeychain(keys...) -} - -// Create a new private network that is not shared with other tests. -func (te *TestEnvironment) NewPrivateNetwork() testnet.Network { - // Load the shared network to retrieve its path and exec path - sharedNetwork, err := local.ReadNetwork(te.NetworkDir) - te.require.NoError(err) - - // The private networks dir is under the shared network dir to ensure it - // will be included in the artifact uploaded in CI. - privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName) - te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute)) - - return StartLocalNetwork(sharedNetwork.ExecPath, privateNetworksDir) -} - // Create a new wallet for the provided keychain against the specified node URI. func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary.Wallet { tests.Outf("{{blue}} initializing a new wallet for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) diff --git a/tests/upgrade/upgrade_test.go b/tests/upgrade/upgrade_test.go index 8a633fd6244a..b8f8147c831a 100644 --- a/tests/upgrade/upgrade_test.go +++ b/tests/upgrade/upgrade_test.go @@ -16,7 +16,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/tests/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" ) func TestUpgrade(t *testing.T) { From bcd4a9482c7ce9909faec3fdb2aafc396e17ae37 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 8 Nov 2023 17:28:33 -0500 Subject: [PATCH 021/267] Cleanup platformvm mempool errs (#2278) --- vms/platformvm/txs/mempool/mempool.go | 30 +++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 086e29b7047c..36c9f9d7d748 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -18,9 +18,9 @@ import ( ) const ( - // targetTxSize is the maximum number of bytes a transaction can use to be + // MaxTxSize is the maximum number of bytes a transaction can use to be // allowed into the mempool. - targetTxSize = 64 * units.KiB + MaxTxSize = 64 * units.KiB // droppedTxIDsCacheSize is the maximum number of dropped txIDs to cache droppedTxIDsCacheSize = 64 @@ -34,7 +34,10 @@ const ( var ( _ Mempool = (*mempool)(nil) - errMempoolFull = errors.New("mempool is full") + errDuplicateTx = errors.New("duplicate tx") + errTxTooLarge = errors.New("tx too large") + errMempoolFull = errors.New("mempool is full") + errConflictsWithOtherTx = errors.New("tx conflicts with other tx") ) type BlockTimer interface { @@ -158,25 +161,30 @@ func (m *mempool) Add(tx *txs.Tx) error { // Note: a previously dropped tx can be re-added txID := tx.ID() if m.Has(txID) { - return fmt.Errorf("duplicate tx %s", txID) + return fmt.Errorf("%w: %s", errDuplicateTx, txID) } - txBytes := tx.Bytes() - if len(txBytes) > targetTxSize { - return fmt.Errorf("tx %s size (%d) > target size (%d)", txID, len(txBytes), targetTxSize) + txSize := len(tx.Bytes()) + if txSize > MaxTxSize { + return fmt.Errorf("%w: %s size (%d) > max size (%d)", + errTxTooLarge, + txID, + txSize, + MaxTxSize, + ) } - if len(txBytes) > m.bytesAvailable { - return fmt.Errorf("%w, tx %s size (%d) exceeds available space (%d)", + if txSize > m.bytesAvailable { + return fmt.Errorf("%w: %s size (%d) > available space (%d)", errMempoolFull, txID, - len(txBytes), + txSize, m.bytesAvailable, ) } inputs := tx.Unsigned.InputIDs() if m.consumedUTXOs.Overlaps(inputs) { - return fmt.Errorf("tx %s conflicts with a transaction in the mempool", txID) + return fmt.Errorf("%w: %s", errConflictsWithOtherTx, txID) } if err := tx.Unsigned.Visit(&issuer{ From c94ff4e3a4d881ce6277d3422be8220bb7751746 Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Wed, 8 Nov 2023 17:55:02 -0500 Subject: [PATCH 022/267] MerkleDB:Naming and comments cleanup (#2274) Co-authored-by: Dan Laine --- x/merkledb/cache.go | 2 +- x/merkledb/codec.go | 6 +-- x/merkledb/db.go | 18 ++++---- x/merkledb/history.go | 2 +- x/merkledb/key.go | 6 +-- x/merkledb/proof.go | 90 ++++++++++++++++++++-------------------- x/merkledb/trieview.go | 10 ++--- x/sync/network_server.go | 1 - 8 files changed, 67 insertions(+), 68 deletions(-) diff --git a/x/merkledb/cache.go b/x/merkledb/cache.go index 57d674ed63ef..7b280c1208d4 100644 --- a/x/merkledb/cache.go +++ b/x/merkledb/cache.go @@ -48,7 +48,7 @@ func (c *onEvictCache[K, V]) Get(key K) (V, bool) { // Put an element into this cache. If this causes an element // to be evicted, calls [c.onEviction] on the evicted element -// and returns the error from [c.onEviction]. Otherwise returns nil. +// and returns the error from [c.onEviction]. Otherwise, returns nil. func (c *onEvictCache[K, V]) Put(key K, value V) error { c.lock.Lock() defer c.lock.Unlock() diff --git a/x/merkledb/codec.go b/x/merkledb/codec.go index a7decc6f6436..c9837abb509f 100644 --- a/x/merkledb/codec.go +++ b/x/merkledb/codec.go @@ -83,7 +83,7 @@ func newCodec() encoderDecoder { } } -// Note that bytes.Buffer.Write always returns nil so we +// Note that bytes.Buffer.Write always returns nil, so we // can ignore its return values in [codecImpl] methods. type codecImpl struct { // Invariant: Every byte slice returned by [varIntPool] has @@ -277,12 +277,12 @@ func (c *codecImpl) decodeMaybeByteSlice(src *bytes.Reader) (maybe.Maybe[[]byte] return maybe.Nothing[[]byte](), err } - bytes, err := c.decodeByteSlice(src) + rawBytes, err := c.decodeByteSlice(src) if err != nil { return maybe.Nothing[[]byte](), err } - return maybe.Some(bytes), nil + return maybe.Some(rawBytes), nil } func (c *codecImpl) decodeByteSlice(src *bytes.Reader) ([]byte, error) { diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 88dd667ae22a..7e52e1fa9ecf 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -73,7 +73,7 @@ type ChangeProofer interface { maxLength int, ) (*ChangeProof, error) - // Returns nil iff all of the following hold: + // Returns nil iff all the following hold: // - [start] <= [end]. // - [proof] is non-empty. // - All keys in [proof.KeyValues] and [proof.DeletedKeys] are in [start, end]. @@ -175,7 +175,7 @@ type merkleDB struct { // Should be held before taking [db.lock] commitLock sync.RWMutex - // Contains all of the key-value pairs stored by this database, + // Contains all the key-value pairs stored by this database, // including metadata, intermediate nodes and value nodes. baseDB database.Database @@ -495,11 +495,11 @@ func (db *merkleDB) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []e defer db.lock.RUnlock() values := make([][]byte, len(keys)) - errors := make([]error, len(keys)) + getErrors := make([]error, len(keys)) for i, key := range keys { - values[i], errors[i] = db.getValueCopy(ToKey(key)) + values[i], getErrors[i] = db.getValueCopy(ToKey(key)) } - return values, errors + return values, getErrors } // GetValue returns the value associated with [key]. @@ -778,7 +778,7 @@ func (db *merkleDB) Has(k []byte) (bool, error) { } _, err := db.getValueWithoutLock(ToKey(k)) - if err == database.ErrNotFound { + if errors.Is(err, database.ErrNotFound) { return false, nil } return err == nil, err @@ -862,7 +862,7 @@ func (db *merkleDB) DeleteContext(ctx context.Context, key []byte) error { return view.commitToDB(ctx) } -// Assumes values inside of [ops] are safe to reference after the function +// Assumes values inside [ops] are safe to reference after the function // returns. Assumes [db.lock] isn't held. func (db *merkleDB) commitBatch(ops []database.BatchOp) error { db.commitLock.Lock() @@ -1144,7 +1144,7 @@ func (db *merkleDB) initializeRootIfNeeded() (ids.ID, error) { // check under both prefixes var err error db.root, err = db.intermediateNodeDB.Get(Key{}) - if err == database.ErrNotFound { + if errors.Is(err, database.ErrNotFound) { db.root, err = db.valueNodeDB.Get(Key{}) } if err == nil { @@ -1152,7 +1152,7 @@ func (db *merkleDB) initializeRootIfNeeded() (ids.ID, error) { db.root.calculateID(db.metrics) return db.root.id, nil } - if err != database.ErrNotFound { + if !errors.Is(err, database.ErrNotFound) { return ids.Empty, err } diff --git a/x/merkledb/history.go b/x/merkledb/history.go index 103c4c9357e8..c52385445cd2 100644 --- a/x/merkledb/history.go +++ b/x/merkledb/history.go @@ -49,7 +49,7 @@ type changeSummaryAndInsertNumber struct { insertNumber uint64 } -// Tracks all of the node and value changes that resulted in the rootID. +// Tracks all the node and value changes that resulted in the rootID. type changeSummary struct { rootID ids.ID nodes map[Key]*change[*node] diff --git a/x/merkledb/key.go b/x/merkledb/key.go index b92ac2d7ceec..d65d9b74a0a6 100644 --- a/x/merkledb/key.go +++ b/x/merkledb/key.go @@ -68,7 +68,7 @@ func ToToken(val byte, tokenSize int) Key { } // Token returns the token at the specified index, -// Assumes that bitindex + tokenSize doesn't cross a byte boundary +// Assumes that bitIndex + tokenSize doesn't cross a byte boundary func (k Key) Token(bitIndex int, tokenSize int) byte { storageByte := k.value[bitIndex/8] // Shift the byte right to get the last bit to the rightmost position. @@ -145,7 +145,7 @@ func (k Key) HasPrefix(prefix Key) bool { } // Note that this will never be an index OOB because len(prefix.value) > 0. - // If len(prefix.value) == 0 were true, [remainderTokens] would be 0 so we + // If len(prefix.value) == 0 were true, [remainderTokens] would be 0, so we // would have returned above. prefixWithoutPartialByte := prefix.value[:len(prefix.value)-1] return strings.HasPrefix(k.value, prefixWithoutPartialByte) @@ -167,7 +167,7 @@ func (k Key) Greater(other Key) bool { return k.value > other.value || (k.value == other.value && k.length > other.length) } -// Less returns true if current Key is less than other Key +// Less will return true if current Key is less than other Key func (k Key) Less(other Key) bool { return k.value < other.value || (k.value == other.value && k.length < other.length) } diff --git a/x/merkledb/proof.go b/x/merkledb/proof.go index c94a68f7db5b..e348a83f0f13 100644 --- a/x/merkledb/proof.go +++ b/x/merkledb/proof.go @@ -50,7 +50,6 @@ var ( ErrNilProof = errors.New("proof is nil") ErrNilValue = errors.New("value is nil") ErrUnexpectedEndProof = errors.New("end proof should be empty") - ErrInconsistentBranchFactor = errors.New("all keys in proof nodes should have the same branch factor") ) type ProofNode struct { @@ -62,6 +61,7 @@ type ProofNode struct { Children map[byte]ids.ID } +// ToProto converts the ProofNode into the protobuf version of a proof node // Assumes [node.Key.Key.length] <= math.MaxUint64. func (node *ProofNode) ToProto() *pb.ProofNode { pbNode := &pb.ProofNode{ @@ -127,11 +127,11 @@ type Proof struct { Key Key // Nothing if [Key] isn't in the trie. - // Otherwise the value corresponding to [Key]. + // Otherwise, the value corresponding to [Key]. Value maybe.Maybe[[]byte] } -// Returns nil if the trie given in [proof] has root [expectedRootID]. +// Verify returns nil if the trie given in [proof] has root [expectedRootID]. // That is, this is a valid proof that [proof.Key] exists/doesn't exist // in the trie with root [expectedRootID]. func (proof *Proof) Verify(ctx context.Context, expectedRootID ids.ID, tokenSize int) error { @@ -172,11 +172,11 @@ func (proof *Proof) Verify(ctx context.Context, expectedRootID ids.ID, tokenSize } // Insert all proof nodes. - // [provenPath] is the path that we are proving exists, or the path - // that is where the path we are proving doesn't exist should be. - provenPath := maybe.Some(proof.Path[len(proof.Path)-1].Key) + // [provenKey] is the key that we are proving exists, or the key + // that is the next key along the node path, proving that [proof.Key] doesn't exist in the trie. + provenKey := maybe.Some(proof.Path[len(proof.Path)-1].Key) - if err = addPathInfo(view, proof.Path, provenPath, provenPath); err != nil { + if err = addPathInfo(view, proof.Path, provenKey, provenKey); err != nil { return err } @@ -240,7 +240,7 @@ type KeyValue struct { Value []byte } -// A proof that a given set of key-value pairs are in a trie. +// RangeProof is a proof that a given set of key-value pairs are in a trie. type RangeProof struct { // Invariant: At least one of [StartProof], [EndProof], [KeyValues] is non-empty. @@ -302,21 +302,21 @@ func (proof *RangeProof) Verify( } // [proof] allegedly provides and proves all key-value - // pairs in [smallestProvenPath, largestProvenPath]. - // If [smallestProvenPath] is Nothing, [proof] should - // provide and prove all keys < [largestProvenPath]. - // If [largestProvenPath] is Nothing, [proof] should - // provide and prove all keys > [smallestProvenPath]. + // pairs in [smallestProvenKey, largestProvenKey]. + // If [smallestProvenKey] is Nothing, [proof] should + // provide and prove all keys < [largestProvenKey]. + // If [largestProvenKey] is Nothing, [proof] should + // provide and prove all keys > [smallestProvenKey]. // If both are Nothing, [proof] should prove the entire trie. - smallestProvenPath := maybe.Bind(start, ToKey) + smallestProvenKey := maybe.Bind(start, ToKey) - largestProvenPath := maybe.Bind(end, ToKey) + largestProvenKey := maybe.Bind(end, ToKey) if len(proof.KeyValues) > 0 { // If [proof] has key-value pairs, we should insert children - // greater than [largestProvenPath] to ancestors of the node containing - // [largestProvenPath] so that we get the expected root ID. - largestProvenPath = maybe.Some(ToKey(proof.KeyValues[len(proof.KeyValues)-1].Key)) + // greater than [largestProvenKey] to ancestors of the node containing + // [largestProvenKey] so that we get the expected root ID. + largestProvenKey = maybe.Some(ToKey(proof.KeyValues[len(proof.KeyValues)-1].Key)) } // The key-value pairs (allegedly) proven by [proof]. @@ -327,13 +327,13 @@ func (proof *RangeProof) Verify( // Ensure that the start proof is valid and contains values that // match the key/values that were sent. - if err := verifyProofPath(proof.StartProof, smallestProvenPath); err != nil { + if err := verifyProofPath(proof.StartProof, smallestProvenKey); err != nil { return err } if err := verifyAllRangeProofKeyValuesPresent( proof.StartProof, - smallestProvenPath, - largestProvenPath, + smallestProvenKey, + largestProvenKey, keyValues, ); err != nil { return err @@ -341,13 +341,13 @@ func (proof *RangeProof) Verify( // Ensure that the end proof is valid and contains values that // match the key/values that were sent. - if err := verifyProofPath(proof.EndProof, largestProvenPath); err != nil { + if err := verifyProofPath(proof.EndProof, largestProvenKey); err != nil { return err } if err := verifyAllRangeProofKeyValuesPresent( proof.EndProof, - smallestProvenPath, - largestProvenPath, + smallestProvenKey, + largestProvenKey, keyValues, ); err != nil { return err @@ -369,24 +369,24 @@ func (proof *RangeProof) Verify( } // For all the nodes along the edges of the proof, insert children - // < [smallestProvenPath] and > [largestProvenPath] + // < [smallestProvenKey] and > [largestProvenKey] // into the trie so that we get the expected root ID (if this proof is valid). - // By inserting all children < [smallestProvenPath], we prove that there are no keys - // > [smallestProvenPath] but less than the first key given. + // By inserting all children < [smallestProvenKey], we prove that there are no keys + // > [smallestProvenKey] but less than the first key given. // That is, the peer who gave us this proof is not omitting nodes. if err := addPathInfo( view, proof.StartProof, - smallestProvenPath, - largestProvenPath, + smallestProvenKey, + largestProvenKey, ); err != nil { return err } if err := addPathInfo( view, proof.EndProof, - smallestProvenPath, - largestProvenPath, + smallestProvenKey, + largestProvenKey, ); err != nil { return err } @@ -462,13 +462,13 @@ func (proof *RangeProof) UnmarshalProto(pbProof *pb.RangeProof) error { func verifyAllRangeProofKeyValuesPresent(proof []ProofNode, start maybe.Maybe[Key], end maybe.Maybe[Key], keysValues map[Key][]byte) error { for i := 0; i < len(proof); i++ { var ( - node = proof[i] - nodePath = node.Key + node = proof[i] + nodeKey = node.Key ) // Skip keys that cannot have a value (enforced by [verifyProofPath]). - if !nodePath.hasPartialByte() && (start.IsNothing() || !nodePath.Less(start.Value())) && (end.IsNothing() || !nodePath.Greater(end.Value())) { - value, ok := keysValues[nodePath] + if !nodeKey.hasPartialByte() && (start.IsNothing() || !nodeKey.Less(start.Value())) && (end.IsNothing() || !nodeKey.Greater(end.Value())) { + value, ok := keysValues[nodeKey] if !ok && node.ValueOrHash.HasValue() { // We didn't get a key-value pair for this key, but the proof node has a value. return ErrProofNodeHasUnincludedValue @@ -488,7 +488,7 @@ type KeyChange struct { Value maybe.Maybe[[]byte] } -// A change proof proves that a set of key-value changes occurred +// ChangeProof proves that a set of key-value changes occurred // between two trie roots, where each key-value pair's key is // between some lower and upper bound (inclusive). type ChangeProof struct { @@ -622,8 +622,8 @@ func (proof *ChangeProof) UnmarshalProto(pbProof *pb.ChangeProof) error { } // Verifies that all values present in the [proof]: -// - Are nothing when deleted, not in the db, or the node has path partial byte length -// - if the node's path is within the key range, that has a value that matches the value passed in the change list or in the db +// - Are nothing when deleted, not in the db, or the node has key partial byte length +// - if the node's key is within the key range, that has a value that matches the value passed in the change list or in the db func verifyAllChangeProofKeyValuesPresent( ctx context.Context, db MerkleDB, @@ -634,19 +634,19 @@ func verifyAllChangeProofKeyValuesPresent( ) error { for i := 0; i < len(proof); i++ { var ( - node = proof[i] - nodePath = node.Key + node = proof[i] + nodeKey = node.Key ) // Check the value of any node with a key that is within the range. // Skip keys that cannot have a value (enforced by [verifyProofPath]). - if !nodePath.hasPartialByte() && (start.IsNothing() || !nodePath.Less(start.Value())) && (end.IsNothing() || !nodePath.Greater(end.Value())) { - value, ok := keysValues[nodePath] + if !nodeKey.hasPartialByte() && (start.IsNothing() || !nodeKey.Less(start.Value())) && (end.IsNothing() || !nodeKey.Greater(end.Value())) { + value, ok := keysValues[nodeKey] if !ok { // This value isn't in the list of key-value pairs we got. - dbValue, err := db.GetValue(ctx, nodePath.Bytes()) + dbValue, err := db.GetValue(ctx, nodeKey.Bytes()) if err != nil { - if err != database.ErrNotFound { + if !errors.Is(err, database.ErrNotFound) { return err } // This key isn't in the database so proof node should have Nothing. @@ -669,7 +669,7 @@ func (proof *ChangeProof) Empty() bool { len(proof.StartProof) == 0 && len(proof.EndProof) == 0 } -// Exactly one of [ChangeProof] or [RangeProof] is non-nil. +// ChangeOrRangeProof has exactly one of [ChangeProof] or [RangeProof] is non-nil. type ChangeOrRangeProof struct { ChangeProof *ChangeProof RangeProof *RangeProof diff --git a/x/merkledb/trieview.go b/x/merkledb/trieview.go index c905cb82c218..d8d9cfbdeb28 100644 --- a/x/merkledb/trieview.go +++ b/x/merkledb/trieview.go @@ -149,7 +149,7 @@ func newTrieView( ) (*trieView, error) { root, err := parentTrie.getEditableNode(Key{}, false /* hasValue */) if err != nil { - if err == database.ErrNotFound { + if errors.Is(err, database.ErrNotFound) { return nil, ErrNoValidRoot } return nil, err @@ -273,8 +273,8 @@ func (t *trieView) calculateNodeIDsHelper(n *node) { ) for childIndex, child := range n.children { - childPath := n.key.Extend(ToToken(childIndex, t.tokenSize), child.compressedKey) - childNodeChange, ok := t.changes.nodes[childPath] + childKey := n.key.Extend(ToToken(childIndex, t.tokenSize), child.compressedKey) + childNodeChange, ok := t.changes.nodes[childKey] if !ok { // This child wasn't changed. continue @@ -811,7 +811,7 @@ func (t *trieView) insert( // have the existing path node and the value being inserted as children. // generate the new branch node - // find how many tokens are common between the existing child's compressed path and + // find how many tokens are common between the existing child's compressed key and // the current key(offset by the closest node's key), // then move all the common tokens into the branch node commonPrefixLength := getLengthOfCommonPrefix( @@ -910,7 +910,7 @@ func (t *trieView) recordKeyChange(key Key, after *node, hadValue bool, newNode } before, err := t.getParentTrie().getEditableNode(key, hadValue) - if err != nil && err != database.ErrNotFound { + if err != nil && !errors.Is(err, database.ErrNotFound) { return err } t.changes.nodes[key] = &change[*node]{ diff --git a/x/sync/network_server.go b/x/sync/network_server.go index 6f21702ce397..c213bee6a739 100644 --- a/x/sync/network_server.go +++ b/x/sync/network_server.go @@ -39,7 +39,6 @@ const ( // TODO: refine this estimate. This is almost certainly a large overestimate. estimatedMessageOverhead = 4 * units.KiB maxByteSizeLimit = constants.DefaultMaxMessageSize - estimatedMessageOverhead - endProofSizeBufferAmount = 2 * units.KiB ) var ( From ebaf9d4bb1e6ba5a0e2f24e05b57945d9d68b1dd Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 8 Nov 2023 18:08:23 -0500 Subject: [PATCH 023/267] Move `DropExpiredStakerTxs` to platformvm mempool (#2279) --- vms/platformvm/block/builder/builder.go | 38 +++++-------------------- vms/platformvm/txs/mempool/mempool.go | 32 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 66a90f99e7f5..734762215395 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -244,36 +244,6 @@ func (b *builder) ResetBlockTimer() { b.timer.SetTimeoutIn(0) } -// dropExpiredStakerTxs drops add validator/delegator transactions in the -// mempool whose start time is not sufficiently far in the future -// (i.e. within local time plus [MaxFutureStartFrom]). -func (b *builder) dropExpiredStakerTxs(timestamp time.Time) { - minStartTime := timestamp.Add(txexecutor.SyncBound) - for b.Mempool.HasStakerTx() { - tx := b.Mempool.PeekStakerTx() - startTime := tx.Unsigned.(txs.Staker).StartTime() - if !startTime.Before(minStartTime) { - // The next proposal tx in the mempool starts sufficiently far in - // the future. - return - } - - txID := tx.ID() - err := fmt.Errorf( - "synchrony bound (%s) is later than staker start time (%s)", - minStartTime, - startTime, - ) - - b.Mempool.Remove([]*txs.Tx{tx}) - b.Mempool.MarkDropped(txID, err) // cache tx as dropped - b.txExecutorBackend.Ctx.Log.Debug("dropping tx", - zap.Stringer("txID", txID), - zap.Error(err), - ) - } -} - func (b *builder) setNextBuildBlockTime() { ctx := b.txExecutorBackend.Ctx @@ -368,7 +338,13 @@ func buildBlock( } // Clean out the mempool's transactions with invalid timestamps. - builder.dropExpiredStakerTxs(timestamp) + droppedStakerTxIDs := mempool.DropExpiredStakerTxs(builder.Mempool, timestamp.Add(txexecutor.SyncBound)) + for _, txID := range droppedStakerTxIDs { + builder.txExecutorBackend.Ctx.Log.Debug("dropping tx", + zap.Stringer("txID", txID), + zap.Error(err), + ) + } // If there is no reason to build a block, don't. if !builder.Mempool.HasTxs() && !forceAdvanceTime { diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 36c9f9d7d748..91b547cf5414 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -6,6 +6,7 @@ package mempool import ( "errors" "fmt" + "time" "github.com/prometheus/client_golang/prometheus" @@ -305,3 +306,34 @@ func (m *mempool) deregister(tx *txs.Tx) { inputs := tx.Unsigned.InputIDs() m.consumedUTXOs.Difference(inputs) } + +// Drops all [txs.Staker] transactions whose [StartTime] is before +// [minStartTime] from [mempool]. The dropped tx ids are returned. +// +// TODO: Remove once [StartTime] field is ignored in staker txs +func DropExpiredStakerTxs(mempool Mempool, minStartTime time.Time) []ids.ID { + var droppedTxIDs []ids.ID + + for mempool.HasStakerTx() { + tx := mempool.PeekStakerTx() + startTime := tx.Unsigned.(txs.Staker).StartTime() + if !startTime.Before(minStartTime) { + // The next proposal tx in the mempool starts sufficiently far in + // the future. + break + } + + txID := tx.ID() + err := fmt.Errorf( + "synchrony bound (%s) is later than staker start time (%s)", + minStartTime, + startTime, + ) + + mempool.Remove([]*txs.Tx{tx}) + mempool.MarkDropped(txID, err) // cache tx as dropped + droppedTxIDs = append(droppedTxIDs, txID) + } + + return droppedTxIDs +} From 151621ff66f28266d140eb28f423071578d87643 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 9 Nov 2023 09:33:42 -0700 Subject: [PATCH 024/267] Cleanup `ids.NodeID` usage (#2280) --- ids/test_generator.go | 9 +++ network/peer/set_test.go | 16 ++-- network/peer/upgrader.go | 8 +- node/insecure_validator_manager.go | 2 +- node/node.go | 2 +- snow/consensus/snowman/poll/set_test.go | 10 +-- .../common/appsender/appsender_client.go | 8 +- snow/engine/common/requests_test.go | 4 +- .../snowman/bootstrap/bootstrapper_test.go | 2 +- snow/networking/sender/sender_test.go | 4 +- snow/networking/timeout/manager_test.go | 2 +- .../tracker/resource_tracker_test.go | 4 +- snow/networking/tracker/targeter_test.go | 4 +- .../gvalidators/validator_state_server.go | 2 +- snow/validators/manager_test.go | 12 +-- snow/validators/set_test.go | 16 ++-- utils/beacon/set_test.go | 6 +- vms/platformvm/api/static_service_test.go | 8 +- .../state/disk_staker_diff_iterator.go | 2 +- .../state/disk_staker_diff_iterator_test.go | 4 +- vms/platformvm/state/state.go | 4 +- .../add_permissionless_delegator_tx_test.go | 8 +- .../add_permissionless_validator_tx_test.go | 8 +- .../txs/remove_subnet_validator_tx_test.go | 4 +- vms/platformvm/txs/txheap/by_end_time_test.go | 6 +- .../txs/txheap/by_start_time_test.go | 6 +- vms/platformvm/vm_test.go | 2 +- vms/proposervm/batched_vm_test.go | 22 ++++-- vms/proposervm/proposer/validators_test.go | 2 +- vms/proposervm/proposer/windower_test.go | 4 +- vms/proposervm/vm_test.go | 76 ++++++++++++------- vms/rpcchainvm/vm_client.go | 12 +-- x/sync/client_test.go | 2 +- 33 files changed, 157 insertions(+), 124 deletions(-) diff --git a/ids/test_generator.go b/ids/test_generator.go index 2f8edf3567d8..29ecfa8d409c 100644 --- a/ids/test_generator.go +++ b/ids/test_generator.go @@ -23,3 +23,12 @@ func GenerateTestShortID() ShortID { func GenerateTestNodeID() NodeID { return NodeID(GenerateTestShortID()) } + +// BuildTestNodeID is an utility to build NodeID from bytes in UTs +// It must not be used in production code. In production code we should +// use ToNodeID, which performs proper length checking. +func BuildTestNodeID(src []byte) NodeID { + res := NodeID{} + copy(res[:], src) + return res +} diff --git a/network/peer/set_test.go b/network/peer/set_test.go index f26b1d19f8ec..fb67d25ef05f 100644 --- a/network/peer/set_test.go +++ b/network/peer/set_test.go @@ -18,24 +18,24 @@ func TestSet(t *testing.T) { set := NewSet() peer1 := &peer{ - id: ids.NodeID{0x01}, + id: ids.BuildTestNodeID([]byte{0x01}), observedUptimes: map[ids.ID]uint32{constants.PrimaryNetworkID: 0}, } updatedPeer1 := &peer{ - id: ids.NodeID{0x01}, + id: ids.BuildTestNodeID([]byte{0x01}), observedUptimes: map[ids.ID]uint32{constants.PrimaryNetworkID: 1}, } peer2 := &peer{ - id: ids.NodeID{0x02}, + id: ids.BuildTestNodeID([]byte{0x02}), } unknownPeer := &peer{ - id: ids.NodeID{0xff}, + id: ids.BuildTestNodeID([]byte{0xff}), } peer3 := &peer{ - id: ids.NodeID{0x03}, + id: ids.BuildTestNodeID([]byte{0x03}), } peer4 := &peer{ - id: ids.NodeID{0x04}, + id: ids.BuildTestNodeID([]byte{0x04}), } // add of first peer is handled @@ -105,10 +105,10 @@ func TestSetSample(t *testing.T) { set := NewSet() peer1 := &peer{ - id: ids.NodeID{0x01}, + id: ids.BuildTestNodeID([]byte{0x01}), } peer2 := &peer{ - id: ids.NodeID{0x02}, + id: ids.BuildTestNodeID([]byte{0x02}), } // Case: Empty diff --git a/network/peer/upgrader.go b/network/peer/upgrader.go index 47a6d0bc7c68..b601ee370947 100644 --- a/network/peer/upgrader.go +++ b/network/peer/upgrader.go @@ -60,12 +60,12 @@ func (t *tlsClientUpgrader) Upgrade(conn net.Conn) (ids.NodeID, net.Conn, *staki func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter) (ids.NodeID, net.Conn, *staking.Certificate, error) { if err := conn.Handshake(); err != nil { - return ids.NodeID{}, nil, nil, err + return ids.EmptyNodeID, nil, nil, err } state := conn.ConnectionState() if len(state.PeerCertificates) == 0 { - return ids.NodeID{}, nil, nil, errNoCert + return ids.EmptyNodeID, nil, nil, errNoCert } tlsCert := state.PeerCertificates[0] @@ -75,7 +75,7 @@ func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter) (ids.NodeI peerCert, err := staking.ParseCertificate(tlsCert.Raw) if err != nil { invalidCerts.Inc() - return ids.NodeID{}, nil, nil, err + return ids.EmptyNodeID, nil, nil, err } // We validate the certificate here to attempt to make the validity of the @@ -84,7 +84,7 @@ func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter) (ids.NodeI // healthy. if err := staking.ValidateCertificate(peerCert); err != nil { invalidCerts.Inc() - return ids.NodeID{}, nil, nil, err + return ids.EmptyNodeID, nil, nil, err } nodeID := ids.NodeIDFromCert(peerCert) diff --git a/node/insecure_validator_manager.go b/node/insecure_validator_manager.go index bd69529619dc..d2cdab94cc89 100644 --- a/node/insecure_validator_manager.go +++ b/node/insecure_validator_manager.go @@ -27,7 +27,7 @@ func (i *insecureValidatorManager) Connected(vdrID ids.NodeID, nodeVersion *vers // peer as a validator. Because each validator needs a txID associated // with it, we hack one together by padding the nodeID with zeroes. dummyTxID := ids.Empty - copy(dummyTxID[:], vdrID[:]) + copy(dummyTxID[:], vdrID.Bytes()) err := i.vdrs.AddStaker(constants.PrimaryNetworkID, vdrID, nil, dummyTxID, i.weight) if err != nil { diff --git a/node/node.go b/node/node.go index d4763db746ec..49548e2fc164 100644 --- a/node/node.go +++ b/node/node.go @@ -304,7 +304,7 @@ func (n *Node) initNetworking() error { // a validator. Because each validator needs a txID associated with it, // we hack one together by just padding our nodeID with zeroes. dummyTxID := ids.Empty - copy(dummyTxID[:], n.ID[:]) + copy(dummyTxID[:], n.ID.Bytes()) err := n.vdrs.AddStaker( constants.PrimaryNetworkID, diff --git a/snow/consensus/snowman/poll/set_test.go b/snow/consensus/snowman/poll/set_test.go index 70830e3da36c..84ed8f7a5c8c 100644 --- a/snow/consensus/snowman/poll/set_test.go +++ b/snow/consensus/snowman/poll/set_test.go @@ -21,11 +21,11 @@ var ( blkID3 = ids.ID{3} blkID4 = ids.ID{4} - vdr1 = ids.NodeID{1} - vdr2 = ids.NodeID{2} - vdr3 = ids.NodeID{3} - vdr4 = ids.NodeID{4} - vdr5 = ids.NodeID{5} + vdr1 = ids.BuildTestNodeID([]byte{0x01}) + vdr2 = ids.BuildTestNodeID([]byte{0x02}) + vdr3 = ids.BuildTestNodeID([]byte{0x03}) + vdr4 = ids.BuildTestNodeID([]byte{0x04}) + vdr5 = ids.BuildTestNodeID([]byte{0x05}) // k = 5 ) func TestNewSetErrorOnPollsMetrics(t *testing.T) { diff --git a/snow/engine/common/appsender/appsender_client.go b/snow/engine/common/appsender/appsender_client.go index a816dd68241e..c74616d71006 100644 --- a/snow/engine/common/appsender/appsender_client.go +++ b/snow/engine/common/appsender/appsender_client.go @@ -52,8 +52,7 @@ func (c *Client) SendAppRequest(ctx context.Context, nodeIDs set.Set[ids.NodeID] nodeIDsBytes := make([][]byte, nodeIDs.Len()) i := 0 for nodeID := range nodeIDs { - nodeID := nodeID // Prevent overwrite in next iteration - nodeIDsBytes[i] = nodeID[:] + nodeIDsBytes[i] = nodeID.Bytes() i++ } _, err := c.client.SendAppRequest( @@ -71,7 +70,7 @@ func (c *Client) SendAppResponse(ctx context.Context, nodeID ids.NodeID, request _, err := c.client.SendAppResponse( ctx, &appsenderpb.SendAppResponseMsg{ - NodeId: nodeID[:], + NodeId: nodeID.Bytes(), RequestId: requestID, Response: response, }, @@ -93,8 +92,7 @@ func (c *Client) SendAppGossipSpecific(ctx context.Context, nodeIDs set.Set[ids. nodeIDsBytes := make([][]byte, nodeIDs.Len()) i := 0 for nodeID := range nodeIDs { - nodeID := nodeID // Prevent overwrite in next iteration - nodeIDsBytes[i] = nodeID[:] + nodeIDsBytes[i] = nodeID.Bytes() i++ } _, err := c.client.SendAppGossipSpecific( diff --git a/snow/engine/common/requests_test.go b/snow/engine/common/requests_test.go index 00e648dfa90a..73a98e4ccb94 100644 --- a/snow/engine/common/requests_test.go +++ b/snow/engine/common/requests_test.go @@ -30,7 +30,7 @@ func TestRequests(t *testing.T) { _, removed = req.Remove(ids.EmptyNodeID, 1) require.False(removed) - _, removed = req.Remove(ids.NodeID{1}, 0) + _, removed = req.Remove(ids.BuildTestNodeID([]byte{0x01}), 0) require.False(removed) require.True(req.Contains(ids.Empty)) @@ -42,7 +42,7 @@ func TestRequests(t *testing.T) { _, removed = req.Remove(ids.EmptyNodeID, 1) require.False(removed) - _, removed = req.Remove(ids.NodeID{1}, 0) + _, removed = req.Remove(ids.BuildTestNodeID([]byte{0x01}), 0) require.False(removed) require.True(req.Contains(ids.Empty)) diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index 620d85b0ba80..81f04d44ba01 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -405,7 +405,7 @@ func TestBootstrapperUnknownByzantineResponse(t *testing.T) { require.NoError(bs.Ancestors(context.Background(), peerID, *requestID+1, [][]byte{blkBytes1})) // respond with wrong request ID require.Equal(oldReqID, *requestID) - require.NoError(bs.Ancestors(context.Background(), ids.NodeID{1, 2, 3}, *requestID, [][]byte{blkBytes1})) // respond from wrong peer + require.NoError(bs.Ancestors(context.Background(), ids.BuildTestNodeID([]byte{1, 2, 3}), *requestID, [][]byte{blkBytes1})) // respond from wrong peer require.Equal(oldReqID, *requestID) require.NoError(bs.Ancestors(context.Background(), peerID, *requestID, [][]byte{blkBytes0})) // respond with wrong block diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index 6355834dcf78..88c02b9a7f3f 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -312,7 +312,7 @@ func TestReliableMessages(t *testing.T) { ctx := snow.DefaultConsensusContextTest() vdrs := validators.NewManager() - require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.NodeID{1}, nil, ids.Empty, 1)) + require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.BuildTestNodeID([]byte{1}), nil, ids.Empty, 1)) benchlist := benchlist.NewNoBenchlist() tm, err := timeout.NewManager( &timer.AdaptiveTimeoutConfig{ @@ -443,7 +443,7 @@ func TestReliableMessages(t *testing.T) { go func() { for i := 0; i < queriesToSend; i++ { - vdrIDs := set.Of(ids.NodeID{1}) + vdrIDs := set.Of(ids.BuildTestNodeID([]byte{1})) sender.SendPullQuery(context.Background(), vdrIDs, uint32(i), ids.Empty, 0) time.Sleep(time.Duration(rand.Float64() * float64(time.Microsecond))) // #nosec G404 diff --git a/snow/networking/timeout/manager_test.go b/snow/networking/timeout/manager_test.go index ce412150b1b6..582da3a9ea1b 100644 --- a/snow/networking/timeout/manager_test.go +++ b/snow/networking/timeout/manager_test.go @@ -39,7 +39,7 @@ func TestManagerFire(t *testing.T) { wg.Add(1) manager.RegisterRequest( - ids.NodeID{}, + ids.EmptyNodeID, ids.ID{}, true, ids.RequestID{}, diff --git a/snow/networking/tracker/resource_tracker_test.go b/snow/networking/tracker/resource_tracker_test.go index 4bc78eb4827a..64a897589f90 100644 --- a/snow/networking/tracker/resource_tracker_test.go +++ b/snow/networking/tracker/resource_tracker_test.go @@ -48,8 +48,8 @@ func TestCPUTracker(t *testing.T) { tracker, err := NewResourceTracker(prometheus.NewRegistry(), mockUser, meter.ContinuousFactory{}, time.Second) require.NoError(err) - node1 := ids.NodeID{1} - node2 := ids.NodeID{2} + node1 := ids.BuildTestNodeID([]byte{1}) + node2 := ids.BuildTestNodeID([]byte{2}) // Note that all the durations between start and end are [halflife]. startTime1 := time.Now() diff --git a/snow/networking/tracker/targeter_test.go b/snow/networking/tracker/targeter_test.go index 23096adbed28..55974dbf4ac6 100644 --- a/snow/networking/tracker/targeter_test.go +++ b/snow/networking/tracker/targeter_test.go @@ -46,10 +46,10 @@ func TestNewTargeter(t *testing.T) { func TestTarget(t *testing.T) { ctrl := gomock.NewController(t) - vdr := ids.NodeID{1} + vdr := ids.BuildTestNodeID([]byte{1}) vdrWeight := uint64(1) totalVdrWeight := uint64(10) - nonVdr := ids.NodeID{2} + nonVdr := ids.BuildTestNodeID([]byte{2}) vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker(constants.PrimaryNetworkID, vdr, nil, ids.Empty, 1)) require.NoError(t, vdrs.AddStaker(constants.PrimaryNetworkID, ids.GenerateTestNodeID(), nil, ids.Empty, totalVdrWeight-vdrWeight)) diff --git a/snow/validators/gvalidators/validator_state_server.go b/snow/validators/gvalidators/validator_state_server.go index 5f0dbc7f46c4..ad9b75197947 100644 --- a/snow/validators/gvalidators/validator_state_server.go +++ b/snow/validators/gvalidators/validator_state_server.go @@ -66,7 +66,7 @@ func (s *Server) GetValidatorSet(ctx context.Context, req *pb.GetValidatorSetReq i := 0 for _, vdr := range vdrs { vdrPB := &pb.Validator{ - NodeId: vdr.NodeID[:], + NodeId: vdr.NodeID.Bytes(), Weight: vdr.Weight, } if vdr.PublicKey != nil { diff --git a/snow/validators/manager_test.go b/snow/validators/manager_test.go index 01a84201f91d..f93ab719e18a 100644 --- a/snow/validators/manager_test.go +++ b/snow/validators/manager_test.go @@ -324,9 +324,9 @@ func TestGetMap(t *testing.T) { func TestWeight(t *testing.T) { require := require.New(t) - vdr0 := ids.NodeID{1} + vdr0 := ids.BuildTestNodeID([]byte{1}) weight0 := uint64(93) - vdr1 := ids.NodeID{2} + vdr1 := ids.BuildTestNodeID([]byte{2}) weight1 := uint64(123) m := NewManager() @@ -411,7 +411,7 @@ func TestString(t *testing.T) { func TestAddCallback(t *testing.T) { require := require.New(t) - nodeID0 := ids.NodeID{1} + nodeID0 := ids.BuildTestNodeID([]byte{1}) sk0, err := bls.NewSecretKey() require.NoError(err) pk0 := bls.PublicFromSecretKey(sk0) @@ -442,7 +442,7 @@ func TestAddCallback(t *testing.T) { func TestAddWeightCallback(t *testing.T) { require := require.New(t) - nodeID0 := ids.NodeID{1} + nodeID0 := ids.BuildTestNodeID([]byte{1}) txID0 := ids.GenerateTestID() weight0 := uint64(1) weight1 := uint64(93) @@ -480,7 +480,7 @@ func TestAddWeightCallback(t *testing.T) { func TestRemoveWeightCallback(t *testing.T) { require := require.New(t) - nodeID0 := ids.NodeID{1} + nodeID0 := ids.BuildTestNodeID([]byte{1}) txID0 := ids.GenerateTestID() weight0 := uint64(93) weight1 := uint64(92) @@ -518,7 +518,7 @@ func TestRemoveWeightCallback(t *testing.T) { func TestValidatorRemovedCallback(t *testing.T) { require := require.New(t) - nodeID0 := ids.NodeID{1} + nodeID0 := ids.BuildTestNodeID([]byte{1}) txID0 := ids.GenerateTestID() weight0 := uint64(93) diff --git a/snow/validators/set_test.go b/snow/validators/set_test.go index 99651e7930e0..0067a520b5a9 100644 --- a/snow/validators/set_test.go +++ b/snow/validators/set_test.go @@ -273,9 +273,9 @@ func TestSetMap(t *testing.T) { func TestSetWeight(t *testing.T) { require := require.New(t) - vdr0 := ids.NodeID{1} + vdr0 := ids.BuildTestNodeID([]byte{1}) weight0 := uint64(93) - vdr1 := ids.NodeID{2} + vdr1 := ids.BuildTestNodeID([]byte{2}) weight1 := uint64(123) s := newSet() @@ -332,10 +332,10 @@ func TestSetString(t *testing.T) { require := require.New(t) nodeID0 := ids.EmptyNodeID - nodeID1 := ids.NodeID{ + nodeID1 := ids.BuildTestNodeID([]byte{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - } + }) s := newSet() require.NoError(s.Add(nodeID0, nil, ids.Empty, 1)) @@ -385,7 +385,7 @@ func (c *callbackListener) OnValidatorWeightChanged(nodeID ids.NodeID, oldWeight func TestSetAddCallback(t *testing.T) { require := require.New(t) - nodeID0 := ids.NodeID{1} + nodeID0 := ids.BuildTestNodeID([]byte{1}) sk0, err := bls.NewSecretKey() require.NoError(err) pk0 := bls.PublicFromSecretKey(sk0) @@ -413,7 +413,7 @@ func TestSetAddCallback(t *testing.T) { func TestSetAddWeightCallback(t *testing.T) { require := require.New(t) - nodeID0 := ids.NodeID{1} + nodeID0 := ids.BuildTestNodeID([]byte{1}) txID0 := ids.GenerateTestID() weight0 := uint64(1) weight1 := uint64(93) @@ -447,7 +447,7 @@ func TestSetAddWeightCallback(t *testing.T) { func TestSetRemoveWeightCallback(t *testing.T) { require := require.New(t) - nodeID0 := ids.NodeID{1} + nodeID0 := ids.BuildTestNodeID([]byte{1}) txID0 := ids.GenerateTestID() weight0 := uint64(93) weight1 := uint64(92) @@ -481,7 +481,7 @@ func TestSetRemoveWeightCallback(t *testing.T) { func TestSetValidatorRemovedCallback(t *testing.T) { require := require.New(t) - nodeID0 := ids.NodeID{1} + nodeID0 := ids.BuildTestNodeID([]byte{1}) txID0 := ids.GenerateTestID() weight0 := uint64(93) diff --git a/utils/beacon/set_test.go b/utils/beacon/set_test.go index 2dc240404988..3f4d6cbc4053 100644 --- a/utils/beacon/set_test.go +++ b/utils/beacon/set_test.go @@ -16,9 +16,9 @@ import ( func TestSet(t *testing.T) { require := require.New(t) - id0 := ids.NodeID{0} - id1 := ids.NodeID{1} - id2 := ids.NodeID{2} + id0 := ids.BuildTestNodeID([]byte{0}) + id1 := ids.BuildTestNodeID([]byte{1}) + id2 := ids.BuildTestNodeID([]byte{2}) ip0 := ips.IPPort{ IP: net.IPv4zero, diff --git a/vms/platformvm/api/static_service_test.go b/vms/platformvm/api/static_service_test.go index 49822d9679d4..12bdb91bfa60 100644 --- a/vms/platformvm/api/static_service_test.go +++ b/vms/platformvm/api/static_service_test.go @@ -18,7 +18,7 @@ import ( func TestBuildGenesisInvalidUTXOBalance(t *testing.T) { require := require.New(t) - nodeID := ids.NodeID{1, 2, 3} + nodeID := ids.BuildTestNodeID([]byte{1, 2, 3}) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) @@ -62,7 +62,7 @@ func TestBuildGenesisInvalidUTXOBalance(t *testing.T) { func TestBuildGenesisInvalidStakeWeight(t *testing.T) { require := require.New(t) - nodeID := ids.NodeID{1, 2, 3} + nodeID := ids.BuildTestNodeID([]byte{1, 2, 3}) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) @@ -106,7 +106,7 @@ func TestBuildGenesisInvalidStakeWeight(t *testing.T) { func TestBuildGenesisInvalidEndtime(t *testing.T) { require := require.New(t) - nodeID := ids.NodeID{1, 2, 3} + nodeID := ids.BuildTestNodeID([]byte{1, 2, 3}) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) @@ -151,7 +151,7 @@ func TestBuildGenesisInvalidEndtime(t *testing.T) { func TestBuildGenesisReturnsSortedValidators(t *testing.T) { require := require.New(t) - nodeID := ids.NodeID{1} + nodeID := ids.BuildTestNodeID([]byte{1}) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) diff --git a/vms/platformvm/state/disk_staker_diff_iterator.go b/vms/platformvm/state/disk_staker_diff_iterator.go index 44ee1ed87180..efac5ec7b6d7 100644 --- a/vms/platformvm/state/disk_staker_diff_iterator.go +++ b/vms/platformvm/state/disk_staker_diff_iterator.go @@ -43,7 +43,7 @@ func marshalDiffKey(subnetID ids.ID, height uint64, nodeID ids.NodeID) []byte { key := make([]byte, diffKeyLength) copy(key, subnetID[:]) packIterableHeight(key[ids.IDLen:], height) - copy(key[diffKeyNodeIDOffset:], nodeID[:]) + copy(key[diffKeyNodeIDOffset:], nodeID.Bytes()) return key } diff --git a/vms/platformvm/state/disk_staker_diff_iterator_test.go b/vms/platformvm/state/disk_staker_diff_iterator_test.go index 9439428937b5..543f42a4b9c3 100644 --- a/vms/platformvm/state/disk_staker_diff_iterator_test.go +++ b/vms/platformvm/state/disk_staker_diff_iterator_test.go @@ -58,8 +58,8 @@ func TestDiffIteration(t *testing.T) { subnetID0 := ids.GenerateTestID() subnetID1 := ids.GenerateTestID() - nodeID0 := ids.NodeID{0x00} - nodeID1 := ids.NodeID{0x01} + nodeID0 := ids.BuildTestNodeID([]byte{0x00}) + nodeID1 := ids.BuildTestNodeID([]byte{0x01}) subnetID0Height0NodeID0 := marshalDiffKey(subnetID0, 0, nodeID0) subnetID0Height1NodeID0 := marshalDiffKey(subnetID0, 1, nodeID0) diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index e64d24d434b1..fd842f684eae 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -2030,7 +2030,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error // // Note: We store the compressed public key here. pkBytes := bls.PublicKeyToBytes(staker.PublicKey) - if err := nestedPKDiffDB.Put(nodeID[:], pkBytes); err != nil { + if err := nestedPKDiffDB.Put(nodeID.Bytes(), pkBytes); err != nil { return err } } @@ -2069,7 +2069,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error if err != nil { return fmt.Errorf("failed to serialize validator weight diff: %w", err) } - if err := nestedWeightDiffDB.Put(nodeID[:], weightDiffBytes); err != nil { + if err := nestedWeightDiffDB.Put(nodeID.Bytes(), weightDiffBytes); err != nil { return err } diff --git a/vms/platformvm/txs/add_permissionless_delegator_tx_test.go b/vms/platformvm/txs/add_permissionless_delegator_tx_test.go index 821a3b7da849..c70bf720bfe3 100644 --- a/vms/platformvm/txs/add_permissionless_delegator_tx_test.go +++ b/vms/platformvm/txs/add_permissionless_delegator_tx_test.go @@ -54,11 +54,11 @@ func TestAddPermissionlessPrimaryDelegatorSerialization(t *testing.T) { 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, } - nodeID := ids.NodeID{ + nodeID := ids.BuildTestNodeID([]byte{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, - } + }) simpleAddPrimaryTx := &AddPermissionlessDelegatorTx{ BaseTx: BaseTx{ @@ -768,11 +768,11 @@ func TestAddPermissionlessSubnetDelegatorSerialization(t *testing.T) { 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, } - nodeID := ids.NodeID{ + nodeID := ids.BuildTestNodeID([]byte{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, - } + }) subnetID := ids.ID{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, diff --git a/vms/platformvm/txs/add_permissionless_validator_tx_test.go b/vms/platformvm/txs/add_permissionless_validator_tx_test.go index 79b1a64abd00..80e4d3b6ae93 100644 --- a/vms/platformvm/txs/add_permissionless_validator_tx_test.go +++ b/vms/platformvm/txs/add_permissionless_validator_tx_test.go @@ -60,11 +60,11 @@ func TestAddPermissionlessPrimaryValidator(t *testing.T) { 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, } - nodeID := ids.NodeID{ + nodeID := ids.BuildTestNodeID([]byte{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, - } + }) simpleAddPrimaryTx := &AddPermissionlessValidatorTx{ BaseTx: BaseTx{ @@ -725,11 +725,11 @@ func TestAddPermissionlessSubnetValidator(t *testing.T) { 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, } - nodeID := ids.NodeID{ + nodeID := ids.BuildTestNodeID([]byte{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, - } + }) subnetID := ids.ID{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, diff --git a/vms/platformvm/txs/remove_subnet_validator_tx_test.go b/vms/platformvm/txs/remove_subnet_validator_tx_test.go index 73f2df3cdcf2..4b1f381c039b 100644 --- a/vms/platformvm/txs/remove_subnet_validator_tx_test.go +++ b/vms/platformvm/txs/remove_subnet_validator_tx_test.go @@ -51,11 +51,11 @@ func TestRemoveSubnetValidatorTxSerialization(t *testing.T) { 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, } - nodeID := ids.NodeID{ + nodeID := ids.BuildTestNodeID([]byte{ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, - } + }) subnetID := ids.ID{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, diff --git a/vms/platformvm/txs/txheap/by_end_time_test.go b/vms/platformvm/txs/txheap/by_end_time_test.go index 8ea152d27e02..5d95a2c66ad7 100644 --- a/vms/platformvm/txs/txheap/by_end_time_test.go +++ b/vms/platformvm/txs/txheap/by_end_time_test.go @@ -23,7 +23,7 @@ func TestByEndTime(t *testing.T) { utx0 := &txs.AddValidatorTx{ Validator: txs.Validator{ - NodeID: ids.NodeID{0}, + NodeID: ids.BuildTestNodeID([]byte{0}), Start: uint64(baseTime.Unix()), End: uint64(baseTime.Unix()) + 1, }, @@ -34,7 +34,7 @@ func TestByEndTime(t *testing.T) { utx1 := &txs.AddValidatorTx{ Validator: txs.Validator{ - NodeID: ids.NodeID{1}, + NodeID: ids.BuildTestNodeID([]byte{1}), Start: uint64(baseTime.Unix()), End: uint64(baseTime.Unix()) + 2, }, @@ -45,7 +45,7 @@ func TestByEndTime(t *testing.T) { utx2 := &txs.AddValidatorTx{ Validator: txs.Validator{ - NodeID: ids.NodeID{1}, + NodeID: ids.BuildTestNodeID([]byte{1}), Start: uint64(baseTime.Unix()), End: uint64(baseTime.Unix()) + 3, }, diff --git a/vms/platformvm/txs/txheap/by_start_time_test.go b/vms/platformvm/txs/txheap/by_start_time_test.go index 164e2ec35e59..e00d42076015 100644 --- a/vms/platformvm/txs/txheap/by_start_time_test.go +++ b/vms/platformvm/txs/txheap/by_start_time_test.go @@ -23,7 +23,7 @@ func TestByStartTime(t *testing.T) { utx0 := &txs.AddValidatorTx{ Validator: txs.Validator{ - NodeID: ids.NodeID{0}, + NodeID: ids.BuildTestNodeID([]byte{0}), Start: uint64(baseTime.Unix()) + 1, End: uint64(baseTime.Unix()) + 1, }, @@ -34,7 +34,7 @@ func TestByStartTime(t *testing.T) { utx1 := &txs.AddValidatorTx{ Validator: txs.Validator{ - NodeID: ids.NodeID{1}, + NodeID: ids.BuildTestNodeID([]byte{1}), Start: uint64(baseTime.Unix()) + 2, End: uint64(baseTime.Unix()) + 2, }, @@ -45,7 +45,7 @@ func TestByStartTime(t *testing.T) { utx2 := &txs.AddValidatorTx{ Validator: txs.Validator{ - NodeID: ids.NodeID{1}, + NodeID: ids.BuildTestNodeID([]byte{1}), Start: uint64(baseTime.Unix()) + 3, End: uint64(baseTime.Unix()) + 3, }, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index ea8d43891dd6..31dfcfbda183 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1388,7 +1388,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { advanceTimeBlkID := advanceTimeBlk.ID() advanceTimeBlkBytes := advanceTimeBlk.Bytes() - peerID := ids.NodeID{1, 2, 3, 4, 5, 4, 3, 2, 1} + peerID := ids.BuildTestNodeID([]byte{1, 2, 3, 4, 5, 4, 3, 2, 1}) beacons := validators.NewManager() require.NoError(beacons.AddStaker(ctx.SubnetID, peerID, nil, ids.Empty, 1)) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 499025c6b2f4..326272275dac 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -1038,21 +1038,27 @@ func initTestRemoteProposerVM( return defaultPChainHeight, nil } valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + var ( + thisNode = proVM.ctx.NodeID + nodeID1 = ids.BuildTestNodeID([]byte{1}) + nodeID2 = ids.BuildTestNodeID([]byte{2}) + nodeID3 = ids.BuildTestNodeID([]byte{3}) + ) return map[ids.NodeID]*validators.GetValidatorOutput{ - proVM.ctx.NodeID: { - NodeID: proVM.ctx.NodeID, + thisNode: { + NodeID: thisNode, Weight: 10, }, - {1}: { - NodeID: ids.NodeID{1}, + nodeID1: { + NodeID: nodeID1, Weight: 5, }, - {2}: { - NodeID: ids.NodeID{2}, + nodeID2: { + NodeID: nodeID2, Weight: 6, }, - {3}: { - NodeID: ids.NodeID{3}, + nodeID3: { + NodeID: nodeID3, Weight: 7, }, }, nil diff --git a/vms/proposervm/proposer/validators_test.go b/vms/proposervm/proposer/validators_test.go index a0703d498ec8..2f7913d01e2e 100644 --- a/vms/proposervm/proposer/validators_test.go +++ b/vms/proposervm/proposer/validators_test.go @@ -19,7 +19,7 @@ func TestValidatorDataLess(t *testing.T) { require.False(v2.Less(v1)) v1 = validatorData{ - id: ids.NodeID{1}, + id: ids.BuildTestNodeID([]byte{1}), } require.False(v1.Less(v2)) require.True(v2.Less(v1)) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index ec2225003230..961398c78867 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -72,7 +72,7 @@ func TestWindowerChangeByHeight(t *testing.T) { chainID := ids.ID{0, 2} validatorIDs := make([]ids.NodeID, MaxWindows) for i := range validatorIDs { - validatorIDs[i] = ids.NodeID{byte(i + 1)} + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) } vdrState := &validators.TestState{ T: t, @@ -134,7 +134,7 @@ func TestWindowerChangeByChain(t *testing.T) { validatorIDs := make([]ids.NodeID, MaxWindows) for i := range validatorIDs { - validatorIDs[i] = ids.NodeID{byte(i + 1)} + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) } vdrState := &validators.TestState{ T: t, diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index b3c22862f9bf..b75493f26ac6 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -152,21 +152,27 @@ func initTestProposerVM( return defaultPChainHeight, nil } valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + var ( + thisNode = proVM.ctx.NodeID + nodeID1 = ids.BuildTestNodeID([]byte{1}) + nodeID2 = ids.BuildTestNodeID([]byte{2}) + nodeID3 = ids.BuildTestNodeID([]byte{3}) + ) return map[ids.NodeID]*validators.GetValidatorOutput{ - proVM.ctx.NodeID: { - NodeID: proVM.ctx.NodeID, + thisNode: { + NodeID: thisNode, Weight: 10, }, - {1}: { - NodeID: ids.NodeID{1}, + nodeID1: { + NodeID: nodeID1, Weight: 5, }, - {2}: { - NodeID: ids.NodeID{2}, + nodeID2: { + NodeID: nodeID2, Weight: 6, }, - {3}: { - NodeID: ids.NodeID{3}, + nodeID3: { + NodeID: nodeID3, Weight: 7, }, }, nil @@ -892,9 +898,10 @@ func TestExpiredBuildBlock(t *testing.T) { return defaultPChainHeight, nil } valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + nodeID := ids.BuildTestNodeID([]byte{1}) return map[ids.NodeID]*validators.GetValidatorOutput{ - {1}: { - NodeID: ids.NodeID{1}, + nodeID: { + NodeID: nodeID, Weight: 100, }, }, nil @@ -1160,9 +1167,10 @@ func TestInnerVMRollback(t *testing.T) { return defaultPChainHeight, nil } valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + nodeID := ids.BuildTestNodeID([]byte{1}) return map[ids.NodeID]*validators.GetValidatorOutput{ - {1}: { - NodeID: ids.NodeID{1}, + nodeID: { + NodeID: nodeID, Weight: 100, }, }, nil @@ -1813,21 +1821,27 @@ func TestRejectedHeightNotIndexed(t *testing.T) { return defaultPChainHeight, nil } valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + var ( + thisNode = proVM.ctx.NodeID + nodeID1 = ids.BuildTestNodeID([]byte{1}) + nodeID2 = ids.BuildTestNodeID([]byte{2}) + nodeID3 = ids.BuildTestNodeID([]byte{3}) + ) return map[ids.NodeID]*validators.GetValidatorOutput{ - proVM.ctx.NodeID: { - NodeID: proVM.ctx.NodeID, + thisNode: { + NodeID: thisNode, Weight: 10, }, - {1}: { - NodeID: ids.NodeID{1}, + nodeID1: { + NodeID: nodeID1, Weight: 5, }, - {2}: { - NodeID: ids.NodeID{2}, + nodeID2: { + NodeID: nodeID2, Weight: 6, }, - {3}: { - NodeID: ids.NodeID{3}, + nodeID3: { + NodeID: nodeID3, Weight: 7, }, }, nil @@ -2014,21 +2028,27 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { return defaultPChainHeight, nil } valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + var ( + thisNode = proVM.ctx.NodeID + nodeID1 = ids.BuildTestNodeID([]byte{1}) + nodeID2 = ids.BuildTestNodeID([]byte{2}) + nodeID3 = ids.BuildTestNodeID([]byte{3}) + ) return map[ids.NodeID]*validators.GetValidatorOutput{ - proVM.ctx.NodeID: { - NodeID: proVM.ctx.NodeID, + thisNode: { + NodeID: thisNode, Weight: 10, }, - {1}: { - NodeID: ids.NodeID{1}, + nodeID1: { + NodeID: nodeID1, Weight: 5, }, - {2}: { - NodeID: ids.NodeID{2}, + nodeID2: { + NodeID: nodeID2, Weight: 6, }, - {3}: { - NodeID: ids.NodeID{3}, + nodeID3: { + NodeID: nodeID3, Weight: 7, }, }, nil diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go index 9a7823979348..d9915bfbfcd6 100644 --- a/vms/rpcchainvm/vm_client.go +++ b/vms/rpcchainvm/vm_client.go @@ -396,7 +396,7 @@ func (vm *VMClient) CreateStaticHandlers(ctx context.Context) (map[string]http.H func (vm *VMClient) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { _, err := vm.client.Connected(ctx, &vmpb.ConnectedRequest{ - NodeId: nodeID[:], + NodeId: nodeID.Bytes(), Version: nodeVersion.String(), }) return err @@ -404,7 +404,7 @@ func (vm *VMClient) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersio func (vm *VMClient) Disconnected(ctx context.Context, nodeID ids.NodeID) error { _, err := vm.client.Disconnected(ctx, &vmpb.DisconnectedRequest{ - NodeId: nodeID[:], + NodeId: nodeID.Bytes(), }) return err } @@ -568,7 +568,7 @@ func (vm *VMClient) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID _, err := vm.client.AppRequest( ctx, &vmpb.AppRequestMsg{ - NodeId: nodeID[:], + NodeId: nodeID.Bytes(), RequestId: requestID, Request: request, Deadline: grpcutils.TimestampFromTime(deadline), @@ -581,7 +581,7 @@ func (vm *VMClient) AppResponse(ctx context.Context, nodeID ids.NodeID, requestI _, err := vm.client.AppResponse( ctx, &vmpb.AppResponseMsg{ - NodeId: nodeID[:], + NodeId: nodeID.Bytes(), RequestId: requestID, Response: response, }, @@ -593,7 +593,7 @@ func (vm *VMClient) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, req _, err := vm.client.AppRequestFailed( ctx, &vmpb.AppRequestFailedMsg{ - NodeId: nodeID[:], + NodeId: nodeID.Bytes(), RequestId: requestID, }, ) @@ -604,7 +604,7 @@ func (vm *VMClient) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte _, err := vm.client.AppGossip( ctx, &vmpb.AppGossipMsg{ - NodeId: nodeID[:], + NodeId: nodeID.Bytes(), Msg: msg, }, ) diff --git a/x/sync/client_test.go b/x/sync/client_test.go index c9f473bea53e..f6c67debe5ee 100644 --- a/x/sync/client_test.go +++ b/x/sync/client_test.go @@ -812,7 +812,7 @@ func TestAppRequestSendFailed(t *testing.T) { gomock.Any(), gomock.Any(), gomock.Any(), - ).Return(ids.NodeID{}, nil, errAppSendFailed).Times(2) + ).Return(ids.EmptyNodeID, nil, errAppSendFailed).Times(2) _, err = client.GetChangeProof( context.Background(), From e3f121299b8c2366f6085c52e4fe6bcdb0397303 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 9 Nov 2023 10:08:59 -0700 Subject: [PATCH 025/267] Genesis validators cleanup (#2282) --- genesis/genesis.go | 4 +-- tests/e2e/static-handlers/suites.go | 6 ++-- vms/platformvm/api/static_service.go | 30 +++++++++++------ vms/platformvm/api/static_service_test.go | 32 +++++++++---------- vms/platformvm/block/builder/helpers_test.go | 6 ++-- vms/platformvm/block/executor/helpers_test.go | 6 ++-- vms/platformvm/txs/executor/helpers_test.go | 6 ++-- vms/platformvm/validator_set_property_test.go | 6 ++-- .../validators/manager_benchmark_test.go | 4 +-- vms/platformvm/vm_test.go | 12 +++---- 10 files changed, 62 insertions(+), 50 deletions(-) diff --git a/genesis/genesis.go b/genesis/genesis.go index 821f72502488..e59b8c6fbbbc 100644 --- a/genesis/genesis.go +++ b/genesis/genesis.go @@ -418,8 +418,8 @@ func FromConfig(config *Config) ([]byte, ids.ID, error) { delegationFee := json.Uint32(staker.DelegationFee) platformvmArgs.Validators = append(platformvmArgs.Validators, - api.PermissionlessValidator{ - Staker: api.Staker{ + api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(genesisTime.Unix()), EndTime: json.Uint64(endStakingTime.Unix()), NodeID: staker.NodeID, diff --git a/tests/e2e/static-handlers/suites.go b/tests/e2e/static-handlers/suites.go index 52c0f50a9436..2351b32e09ed 100644 --- a/tests/e2e/static-handlers/suites.go +++ b/tests/e2e/static-handlers/suites.go @@ -141,13 +141,13 @@ var _ = ginkgo.Describe("[StaticHandlers]", func() { } } - genesisValidators := make([]api.PermissionlessValidator, len(keys)) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(keys)) for i, key := range keys { id := key.PublicKey().Address() addr, err := address.FormatBech32(hrp, id.Bytes()) require.NoError(err) - genesisValidators[i] = api.PermissionlessValidator{ - Staker: api.Staker{ + genesisValidators[i] = api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(time.Date(1997, 1, 1, 0, 0, 0, 0, time.UTC).Unix()), EndTime: json.Uint64(time.Date(1997, 1, 30, 0, 0, 0, 0, time.UTC).Unix()), NodeID: ids.NodeID(id), diff --git a/vms/platformvm/api/static_service.go b/vms/platformvm/api/static_service.go index d06c2e757962..1cf2fbe29096 100644 --- a/vms/platformvm/api/static_service.go +++ b/vms/platformvm/api/static_service.go @@ -98,6 +98,9 @@ type Staker struct { StakeAmount *json.Uint64 `json:"stakeAmount,omitempty"` } +// GenesisValidator should to be used for genesis validators only. +type GenesisValidator Staker + // Owner is the repr. of a reward owner sent over APIs. type Owner struct { Locktime json.Uint64 `json:"locktime"` @@ -132,6 +135,15 @@ type PermissionlessValidator struct { Delegators *[]PrimaryDelegator `json:"delegators,omitempty"` } +// GenesisPermissionlessValidator should to be used for genesis validators only. +type GenesisPermissionlessValidator struct { + GenesisValidator + RewardOwner *Owner `json:"rewardOwner,omitempty"` + DelegationFee json.Float32 `json:"delegationFee"` + ExactDelegationFee *json.Uint32 `json:"exactDelegationFee,omitempty"` + Staked []UTXO `json:"staked,omitempty"` +} + // PermissionedValidator is the repr. of a permissioned validator sent over APIs. type PermissionedValidator struct { Staker @@ -170,15 +182,15 @@ type Chain struct { // [Chains] are the chains that exist at genesis. // [Time] is the Platform Chain's time at network genesis. type BuildGenesisArgs struct { - AvaxAssetID ids.ID `json:"avaxAssetID"` - NetworkID json.Uint32 `json:"networkID"` - UTXOs []UTXO `json:"utxos"` - Validators []PermissionlessValidator `json:"validators"` - Chains []Chain `json:"chains"` - Time json.Uint64 `json:"time"` - InitialSupply json.Uint64 `json:"initialSupply"` - Message string `json:"message"` - Encoding formatting.Encoding `json:"encoding"` + AvaxAssetID ids.ID `json:"avaxAssetID"` + NetworkID json.Uint32 `json:"networkID"` + UTXOs []UTXO `json:"utxos"` + Validators []GenesisPermissionlessValidator `json:"validators"` + Chains []Chain `json:"chains"` + Time json.Uint64 `json:"time"` + InitialSupply json.Uint64 `json:"initialSupply"` + Message string `json:"message"` + Encoding formatting.Encoding `json:"encoding"` } // BuildGenesisReply is the reply from BuildGenesis diff --git a/vms/platformvm/api/static_service_test.go b/vms/platformvm/api/static_service_test.go index 12bdb91bfa60..8bcbf4e766db 100644 --- a/vms/platformvm/api/static_service_test.go +++ b/vms/platformvm/api/static_service_test.go @@ -27,8 +27,8 @@ func TestBuildGenesisInvalidUTXOBalance(t *testing.T) { Amount: 0, } weight := json.Uint64(987654321) - validator := PermissionlessValidator{ - Staker: Staker{ + validator := GenesisPermissionlessValidator{ + GenesisValidator: GenesisValidator{ EndTime: 15, Weight: weight, NodeID: nodeID, @@ -47,7 +47,7 @@ func TestBuildGenesisInvalidUTXOBalance(t *testing.T) { UTXOs: []UTXO{ utxo, }, - Validators: []PermissionlessValidator{ + Validators: []GenesisPermissionlessValidator{ validator, }, Time: 5, @@ -71,8 +71,8 @@ func TestBuildGenesisInvalidStakeWeight(t *testing.T) { Amount: 123456789, } weight := json.Uint64(0) - validator := PermissionlessValidator{ - Staker: Staker{ + validator := GenesisPermissionlessValidator{ + GenesisValidator: GenesisValidator{ StartTime: 0, EndTime: 15, NodeID: nodeID, @@ -91,7 +91,7 @@ func TestBuildGenesisInvalidStakeWeight(t *testing.T) { UTXOs: []UTXO{ utxo, }, - Validators: []PermissionlessValidator{ + Validators: []GenesisPermissionlessValidator{ validator, }, Time: 5, @@ -116,8 +116,8 @@ func TestBuildGenesisInvalidEndtime(t *testing.T) { } weight := json.Uint64(987654321) - validator := PermissionlessValidator{ - Staker: Staker{ + validator := GenesisPermissionlessValidator{ + GenesisValidator: GenesisValidator{ StartTime: 0, EndTime: 5, NodeID: nodeID, @@ -136,7 +136,7 @@ func TestBuildGenesisInvalidEndtime(t *testing.T) { UTXOs: []UTXO{ utxo, }, - Validators: []PermissionlessValidator{ + Validators: []GenesisPermissionlessValidator{ validator, }, Time: 5, @@ -161,8 +161,8 @@ func TestBuildGenesisReturnsSortedValidators(t *testing.T) { } weight := json.Uint64(987654321) - validator1 := PermissionlessValidator{ - Staker: Staker{ + validator1 := GenesisPermissionlessValidator{ + GenesisValidator: GenesisValidator{ StartTime: 0, EndTime: 20, NodeID: nodeID, @@ -177,8 +177,8 @@ func TestBuildGenesisReturnsSortedValidators(t *testing.T) { }}, } - validator2 := PermissionlessValidator{ - Staker: Staker{ + validator2 := GenesisPermissionlessValidator{ + GenesisValidator: GenesisValidator{ StartTime: 3, EndTime: 15, NodeID: nodeID, @@ -193,8 +193,8 @@ func TestBuildGenesisReturnsSortedValidators(t *testing.T) { }}, } - validator3 := PermissionlessValidator{ - Staker: Staker{ + validator3 := GenesisPermissionlessValidator{ + GenesisValidator: GenesisValidator{ StartTime: 1, EndTime: 10, NodeID: nodeID, @@ -214,7 +214,7 @@ func TestBuildGenesisReturnsSortedValidators(t *testing.T) { UTXOs: []UTXO{ utxo, }, - Validators: []PermissionlessValidator{ + Validators: []GenesisPermissionlessValidator{ validator1, validator2, validator3, diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index a773fc964ef6..8da4c45b4639 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -357,13 +357,13 @@ func buildGenesisTest(t *testing.T, ctx *snow.Context) []byte { } } - genesisValidators := make([]api.PermissionlessValidator, len(preFundedKeys)) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(preFundedKeys)) for i, key := range preFundedKeys { nodeID := ids.NodeID(key.PublicKey().Address()) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) - genesisValidators[i] = api.PermissionlessValidator{ - Staker: api.Staker{ + genesisValidators[i] = api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(defaultValidateStartTime.Unix()), EndTime: json.Uint64(defaultValidateEndTime.Unix()), NodeID: nodeID, diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 9448cdde44eb..4f452f1144c0 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -399,15 +399,15 @@ func buildGenesisTest(ctx *snow.Context) []byte { } } - genesisValidators := make([]api.PermissionlessValidator, len(preFundedKeys)) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(preFundedKeys)) for i, key := range preFundedKeys { nodeID := ids.NodeID(key.PublicKey().Address()) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) if err != nil { panic(err) } - genesisValidators[i] = api.PermissionlessValidator{ - Staker: api.Staker{ + genesisValidators[i] = api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(defaultValidateStartTime.Unix()), EndTime: json.Uint64(defaultValidateEndTime.Unix()), NodeID: nodeID, diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index b1993584cb7a..409fe79c7002 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -366,15 +366,15 @@ func buildGenesisTest(ctx *snow.Context) []byte { } } - genesisValidators := make([]api.PermissionlessValidator, len(preFundedKeys)) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(preFundedKeys)) for i, key := range preFundedKeys { nodeID := ids.NodeID(key.PublicKey().Address()) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) if err != nil { panic(err) } - genesisValidators[i] = api.PermissionlessValidator{ - Staker: api.Staker{ + genesisValidators[i] = api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(defaultValidateStartTime.Unix()), EndTime: json.Uint64(defaultValidateEndTime.Unix()), NodeID: nodeID, diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index fab84cc6d50b..be3962f36701 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -849,8 +849,8 @@ func buildCustomGenesis() ([]byte, error) { starTime := mockable.MaxTime.Add(-1 * defaultMinStakingDuration) endTime := mockable.MaxTime - genesisValidator := api.PermissionlessValidator{ - Staker: api.Staker{ + genesisValidator := api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(starTime.Unix()), EndTime: json.Uint64(endTime.Unix()), NodeID: nodeID, @@ -871,7 +871,7 @@ func buildCustomGenesis() ([]byte, error) { NetworkID: json.Uint32(constants.UnitTestID), AvaxAssetID: avaxAssetID, UTXOs: genesisUTXOs, - Validators: []api.PermissionlessValidator{genesisValidator}, + Validators: []api.GenesisPermissionlessValidator{genesisValidator}, Chains: nil, Time: json.Uint64(defaultGenesisTime.Unix()), InitialSupply: json.Uint64(360 * units.MegaAvax), diff --git a/vms/platformvm/validators/manager_benchmark_test.go b/vms/platformvm/validators/manager_benchmark_test.go index d88fca7d7e32..0664c085c942 100644 --- a/vms/platformvm/validators/manager_benchmark_test.go +++ b/vms/platformvm/validators/manager_benchmark_test.go @@ -65,8 +65,8 @@ func BenchmarkGetValidatorSet(b *testing.B) { addr, err := address.FormatBech32(constants.UnitTestHRP, ids.GenerateTestShortID().Bytes()) require.NoError(err) - genesisValidators := []api.PermissionlessValidator{{ - Staker: api.Staker{ + genesisValidators := []api.GenesisPermissionlessValidator{{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(genesisTime.Unix()), EndTime: json.Uint64(genesisEndTime.Unix()), NodeID: ids.GenerateTestNodeID(), diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 31dfcfbda183..d4dcb20b4264 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -175,13 +175,13 @@ func defaultGenesis(t *testing.T) (*api.BuildGenesisArgs, []byte) { } } - genesisValidators := make([]api.PermissionlessValidator, len(keys)) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(keys)) for i, key := range keys { nodeID := ids.NodeID(key.PublicKey().Address()) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) - genesisValidators[i] = api.PermissionlessValidator{ - Staker: api.Staker{ + genesisValidators[i] = api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(defaultValidateStartTime.Unix()), EndTime: json.Uint64(defaultValidateEndTime.Unix()), NodeID: nodeID, @@ -243,14 +243,14 @@ func BuildGenesisTestWithArgs(t *testing.T, args *api.BuildGenesisArgs) (*api.Bu } } - genesisValidators := make([]api.PermissionlessValidator, len(keys)) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(keys)) for i, key := range keys { nodeID := ids.NodeID(key.PublicKey().Address()) addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) - genesisValidators[i] = api.PermissionlessValidator{ - Staker: api.Staker{ + genesisValidators[i] = api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(defaultValidateStartTime.Unix()), EndTime: json.Uint64(defaultValidateEndTime.Unix()), NodeID: nodeID, From 094ce50a65e7baaa5186b19fec997c07d1e4b559 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Thu, 9 Nov 2023 13:58:28 -0500 Subject: [PATCH 026/267] Remove Lazy Initialize on Node (#1384) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Dan Laine --- app/app.go | 114 ++++++++++---------- main/main.go | 7 +- node/node.go | 299 ++++++++++++++++++++++++++------------------------- 3 files changed, 214 insertions(+), 206 deletions(-) diff --git a/app/app.go b/app/app.go index 76cf137034b3..af651235ba77 100644 --- a/app/app.go +++ b/app/app.go @@ -54,11 +54,45 @@ type App interface { ExitCode() (int, error) } -func New(config node.Config) App { - return &app{ - config: config, - node: &node.Node{}, +func New(config node.Config) (App, error) { + // Set the data directory permissions to be read write. + if err := perms.ChmodR(config.DatabaseConfig.Path, true, perms.ReadWriteExecute); err != nil { + return nil, fmt.Errorf("failed to restrict the permissions of the database directory with: %w", err) + } + if err := perms.ChmodR(config.LoggingConfig.Directory, true, perms.ReadWriteExecute); err != nil { + return nil, fmt.Errorf("failed to restrict the permissions of the log directory with: %w", err) + } + + logFactory := logging.NewFactory(config.LoggingConfig) + log, err := logFactory.Make("main") + if err != nil { + logFactory.Close() + return nil, fmt.Errorf("failed to initialize log: %w", err) } + + // update fd limit + fdLimit := config.FdLimit + if err := ulimit.Set(fdLimit, log); err != nil { + log.Fatal("failed to set fd-limit", + zap.Error(err), + ) + logFactory.Close() + return nil, err + } + + n, err := node.New(&config, logFactory, log) + if err != nil { + log.Stop() + logFactory.Close() + return nil, fmt.Errorf("failed to initialize node: %w", err) + } + + return &app{ + config: config, + node: n, + log: log, + logFactory: logFactory, + }, nil } func Run(app App) int { @@ -99,56 +133,33 @@ func Run(app App) int { // app is a wrapper around a node that runs in this process type app struct { - config node.Config - node *node.Node - exitWG sync.WaitGroup + config node.Config + node *node.Node + log logging.Logger + logFactory logging.Factory + exitWG sync.WaitGroup } // Start the business logic of the node (as opposed to config reading, etc). // Does not block until the node is done. Errors returned from this method // are not logged. func (a *app) Start() error { - // Set the data directory permissions to be read write. - if err := perms.ChmodR(a.config.DatabaseConfig.Path, true, perms.ReadWriteExecute); err != nil { - return fmt.Errorf("failed to restrict the permissions of the database directory with: %w", err) - } - if err := perms.ChmodR(a.config.LoggingConfig.Directory, true, perms.ReadWriteExecute); err != nil { - return fmt.Errorf("failed to restrict the permissions of the log directory with: %w", err) - } - - // we want to create the logger after the plugin has started the app - logFactory := logging.NewFactory(a.config.LoggingConfig) - log, err := logFactory.Make("main") - if err != nil { - logFactory.Close() - return err - } - - // update fd limit - fdLimit := a.config.FdLimit - if err := ulimit.Set(fdLimit, log); err != nil { - log.Fatal("failed to set fd-limit", - zap.Error(err), - ) - logFactory.Close() - return err - } - // Track if sybil control is enforced if !a.config.SybilProtectionEnabled { - log.Warn("sybil control is not enforced") + a.log.Warn("sybil control is not enforced") } // TODO move this to config // SupportsNAT() for NoRouter is false. // Which means we tried to perform a NAT activity but we were not successful. if a.config.AttemptedNATTraversal && !a.config.Nat.SupportsNAT() { - log.Warn("UPnP and NAT-PMP router attach failed, you may not be listening publicly. " + + a.log.Warn("UPnP and NAT-PMP router attach failed, " + + "you may not be listening publicly. " + "Please confirm the settings in your router") } if ip := a.config.IPPort.IPPort().IP; ip.IsLoopback() || ip.IsPrivate() { - log.Warn("P2P IP is private, you will not be publicly discoverable", + a.log.Warn("P2P IP is private, you will not be publicly discoverable", zap.Stringer("ip", ip), ) } @@ -159,23 +170,23 @@ func (a *app) Start() error { if !hostIsPublic { ip, err := ips.Lookup(a.config.HTTPHost) if err != nil { - log.Fatal("failed to lookup HTTP host", + a.log.Fatal("failed to lookup HTTP host", zap.String("host", a.config.HTTPHost), zap.Error(err), ) - logFactory.Close() + a.logFactory.Close() return err } hostIsPublic = !ip.IsLoopback() && !ip.IsPrivate() - log.Debug("finished HTTP host lookup", + a.log.Debug("finished HTTP host lookup", zap.String("host", a.config.HTTPHost), zap.Stringer("ip", ip), zap.Bool("isPublic", hostIsPublic), ) } - mapper := nat.NewPortMapper(log, a.config.Nat) + mapper := nat.NewPortMapper(a.log, a.config.Nat) // Open staking port we want for NAT traversal to have the external port // (config.IP.Port) to connect to our internal listening port @@ -192,7 +203,7 @@ func (a *app) Start() error { // Don't open the HTTP port if the HTTP server is private if hostIsPublic { - log.Warn("HTTP server is binding to a potentially public host. "+ + a.log.Warn("HTTP server is binding to a potentially public host. "+ "You may be vulnerable to a DoS attack if your HTTP port is publicly accessible", zap.String("host", a.config.HTTPHost), ) @@ -213,18 +224,7 @@ func (a *app) Start() error { // Regularly update our public IP. // Note that if the node config said to not dynamically resolve and // update our public IP, [p.config.IPUdater] is a no-op implementation. - go a.config.IPUpdater.Dispatch(log) - - if err := a.node.Initialize(&a.config, log, logFactory); err != nil { - log.Fatal("error initializing node", - zap.Error(err), - ) - mapper.UnmapAllPorts() - a.config.IPUpdater.Stop() - log.Stop() - logFactory.Close() - return err - } + go a.config.IPUpdater.Dispatch(a.log) // [p.ExitCode] will block until [p.exitWG.Done] is called a.exitWG.Add(1) @@ -233,8 +233,8 @@ func (a *app) Start() error { if r := recover(); r != nil { fmt.Println("caught panic", r) } - log.Stop() - logFactory.Close() + a.log.Stop() + a.logFactory.Close() a.exitWG.Done() }() defer func() { @@ -244,11 +244,11 @@ func (a *app) Start() error { // If [p.node.Dispatch()] panics, then we should log the panic and // then re-raise the panic. This is why the above defer is broken // into two parts. - log.StopOnPanic() + a.log.StopOnPanic() }() err := a.node.Dispatch() - log.Debug("dispatch returned", + a.log.Debug("dispatch returned", zap.Error(err), ) }() diff --git a/main/main.go b/main/main.go index 5d85530177dd..2b07898f9072 100644 --- a/main/main.go +++ b/main/main.go @@ -41,11 +41,16 @@ func main() { os.Exit(1) } - nodeApp := app.New(nodeConfig) // Create node wrapper if term.IsTerminal(int(os.Stdout.Fd())) { fmt.Println(app.Header) } + nodeApp, err := app.New(nodeConfig) + if err != nil { + fmt.Printf("couldn't start node: %s\n", err) + os.Exit(1) + } + exitCode := app.Run(nodeApp) os.Exit(exitCode) } diff --git a/node/node.go b/node/node.go index 49548e2fc164..04ab4a5015be 100644 --- a/node/node.go +++ b/node/node.go @@ -101,6 +101,157 @@ var ( errShuttingDown = errors.New("server shutting down") ) +// New returns an instance of Node +func New( + config *Config, + logFactory logging.Factory, + logger logging.Logger, +) (*Node, error) { + tlsCert := config.StakingTLSCert.Leaf + stakingCert := staking.CertificateFromX509(tlsCert) + if err := staking.ValidateCertificate(stakingCert); err != nil { + return nil, fmt.Errorf("invalid staking certificate: %w", err) + } + + n := &Node{ + Log: logger, + LogFactory: logFactory, + ID: ids.NodeIDFromCert(stakingCert), + Config: config, + } + + n.DoneShuttingDown.Add(1) + + pop := signer.NewProofOfPossession(n.Config.StakingSigningKey) + logger.Info("initializing node", + zap.Stringer("version", version.CurrentApp), + zap.Stringer("nodeID", n.ID), + zap.Stringer("stakingKeyType", tlsCert.PublicKeyAlgorithm), + zap.Reflect("nodePOP", pop), + zap.Reflect("providedFlags", n.Config.ProvidedFlags), + zap.Reflect("config", n.Config), + ) + + var err error + n.VMFactoryLog, err = logFactory.Make("vm-factory") + if err != nil { + return nil, fmt.Errorf("problem creating vm logger: %w", err) + } + + n.VMManager = vms.NewManager(n.VMFactoryLog, config.VMAliaser) + + if err := n.initBootstrappers(); err != nil { // Configure the bootstrappers + return nil, fmt.Errorf("problem initializing node beacons: %w", err) + } + + // Set up tracer + n.tracer, err = trace.New(n.Config.TraceConfig) + if err != nil { + return nil, fmt.Errorf("couldn't initialize tracer: %w", err) + } + + if n.Config.TraceConfig.Enabled { + n.Config.ConsensusRouter = router.Trace(n.Config.ConsensusRouter, n.tracer) + } + + n.initMetrics() + + if err := n.initAPIServer(); err != nil { // Start the API Server + return nil, fmt.Errorf("couldn't initialize API server: %w", err) + } + + if err := n.initMetricsAPI(); err != nil { // Start the Metrics API + return nil, fmt.Errorf("couldn't initialize metrics API: %w", err) + } + + if err := n.initDatabase(); err != nil { // Set up the node's database + return nil, fmt.Errorf("problem initializing database: %w", err) + } + + if err := n.initKeystoreAPI(); err != nil { // Start the Keystore API + return nil, fmt.Errorf("couldn't initialize keystore API: %w", err) + } + + n.initSharedMemory() // Initialize shared memory + + // message.Creator is shared between networking, chainManager and the engine. + // It must be initiated before networking (initNetworking), chain manager (initChainManager) + // and the engine (initChains) but after the metrics (initMetricsAPI) + // message.Creator currently record metrics under network namespace + n.networkNamespace = "network" + n.msgCreator, err = message.NewCreator( + n.Log, + n.MetricsRegisterer, + n.networkNamespace, + n.Config.NetworkConfig.CompressionType, + n.Config.NetworkConfig.MaximumInboundMessageTimeout, + ) + if err != nil { + return nil, fmt.Errorf("problem initializing message creator: %w", err) + } + + n.vdrs = validators.NewManager() + if !n.Config.SybilProtectionEnabled { + n.vdrs = newOverriddenManager(constants.PrimaryNetworkID, n.vdrs) + } + if err := n.initResourceManager(n.MetricsRegisterer); err != nil { + return nil, fmt.Errorf("problem initializing resource manager: %w", err) + } + n.initCPUTargeter(&config.CPUTargeterConfig) + n.initDiskTargeter(&config.DiskTargeterConfig) + if err := n.initNetworking(); err != nil { // Set up networking layer. + return nil, fmt.Errorf("problem initializing networking: %w", err) + } + + n.initEventDispatchers() + + // Start the Health API + // Has to be initialized before chain manager + // [n.Net] must already be set + if err := n.initHealthAPI(); err != nil { + return nil, fmt.Errorf("couldn't initialize health API: %w", err) + } + if err := n.addDefaultVMAliases(); err != nil { + return nil, fmt.Errorf("couldn't initialize API aliases: %w", err) + } + if err := n.initChainManager(n.Config.AvaxAssetID); err != nil { // Set up the chain manager + return nil, fmt.Errorf("couldn't initialize chain manager: %w", err) + } + if err := n.initVMs(); err != nil { // Initialize the VM registry. + return nil, fmt.Errorf("couldn't initialize VM registry: %w", err) + } + if err := n.initAdminAPI(); err != nil { // Start the Admin API + return nil, fmt.Errorf("couldn't initialize admin API: %w", err) + } + if err := n.initInfoAPI(); err != nil { // Start the Info API + return nil, fmt.Errorf("couldn't initialize info API: %w", err) + } + if err := n.initIPCs(); err != nil { // Start the IPCs + return nil, fmt.Errorf("couldn't initialize IPCs: %w", err) + } + if err := n.initIPCAPI(); err != nil { // Start the IPC API + return nil, fmt.Errorf("couldn't initialize the IPC API: %w", err) + } + if err := n.initChainAliases(n.Config.GenesisBytes); err != nil { + return nil, fmt.Errorf("couldn't initialize chain aliases: %w", err) + } + if err := n.initAPIAliases(n.Config.GenesisBytes); err != nil { + return nil, fmt.Errorf("couldn't initialize API aliases: %w", err) + } + if err := n.initIndexer(); err != nil { + return nil, fmt.Errorf("couldn't initialize indexer: %w", err) + } + + n.health.Start(context.TODO(), n.Config.HealthCheckFreq) + n.initProfiler() + + // Start the Platform chain + if err := n.initChains(n.Config.GenesisBytes); err != nil { + return nil, fmt.Errorf("couldn't initialize chains: %w", err) + } + return n, nil +} + // Node is an instance of an Avalanche node. type Node struct { Log logging.Logger @@ -1341,154 +1492,6 @@ func (n *Node) initDiskTargeter( ) } -// Initialize this node -func (n *Node) Initialize( - config *Config, - logger logging.Logger, - logFactory logging.Factory, -) error { - tlsCert := config.StakingTLSCert.Leaf - stakingCert := staking.CertificateFromX509(tlsCert) - if err := staking.ValidateCertificate(stakingCert); err != nil { - return fmt.Errorf("invalid staking certificate: %w", err) - } - - n.Log = logger - n.Config = config - n.ID = ids.NodeIDFromCert(stakingCert) - n.LogFactory = logFactory - n.DoneShuttingDown.Add(1) - - pop := signer.NewProofOfPossession(n.Config.StakingSigningKey) - n.Log.Info("initializing node", - zap.Stringer("version", version.CurrentApp), - zap.Stringer("nodeID", n.ID), - zap.Stringer("stakingKeyType", tlsCert.PublicKeyAlgorithm), - zap.Reflect("nodePOP", pop), - zap.Reflect("providedFlags", n.Config.ProvidedFlags), - zap.Reflect("config", n.Config), - ) - - var err error - n.VMFactoryLog, err = logFactory.Make("vm-factory") - if err != nil { - return fmt.Errorf("problem creating vm logger: %w", err) - } - - n.VMManager = vms.NewManager(n.VMFactoryLog, config.VMAliaser) - - if err := n.initBootstrappers(); err != nil { // Configure the bootstrappers - return fmt.Errorf("problem initializing node beacons: %w", err) - } - - // Set up tracer - n.tracer, err = trace.New(n.Config.TraceConfig) - if err != nil { - return fmt.Errorf("couldn't initialize tracer: %w", err) - } - - if n.Config.TraceConfig.Enabled { - n.Config.ConsensusRouter = router.Trace(n.Config.ConsensusRouter, n.tracer) - } - - n.initMetrics() - - if err := n.initAPIServer(); err != nil { // Start the API Server - return fmt.Errorf("couldn't initialize API server: %w", err) - } - - if err := n.initMetricsAPI(); err != nil { // Start the Metrics API - return fmt.Errorf("couldn't initialize metrics API: %w", err) - } - - if err := n.initDatabase(); err != nil { // Set up the node's database - return fmt.Errorf("problem initializing database: %w", err) - } - - if err := n.initKeystoreAPI(); err != nil { // Start the Keystore API - return fmt.Errorf("couldn't initialize keystore API: %w", err) - } - - n.initSharedMemory() // Initialize shared memory - - // message.Creator is shared between networking, chainManager and the engine. - // It must be initiated before networking (initNetworking), chain manager (initChainManager) - // and the engine (initChains) but after the metrics (initMetricsAPI) - // message.Creator currently record metrics under network namespace - n.networkNamespace = "network" - n.msgCreator, err = message.NewCreator( - n.Log, - n.MetricsRegisterer, - n.networkNamespace, - n.Config.NetworkConfig.CompressionType, - n.Config.NetworkConfig.MaximumInboundMessageTimeout, - ) - if err != nil { - return fmt.Errorf("problem initializing message creator: %w", err) - } - - n.vdrs = validators.NewManager() - if !n.Config.SybilProtectionEnabled { - n.vdrs = newOverriddenManager(constants.PrimaryNetworkID, n.vdrs) - } - if err := n.initResourceManager(n.MetricsRegisterer); err != nil { - return fmt.Errorf("problem initializing resource manager: %w", err) - } - n.initCPUTargeter(&config.CPUTargeterConfig) - n.initDiskTargeter(&config.DiskTargeterConfig) - if err := n.initNetworking(); err != nil { // Set up networking layer. - return fmt.Errorf("problem initializing networking: %w", err) - } - - n.initEventDispatchers() - - // Start the Health API - // Has to be initialized before chain manager - // [n.Net] must already be set - if err := n.initHealthAPI(); err != nil { - return fmt.Errorf("couldn't initialize health API: %w", err) - } - if err := n.addDefaultVMAliases(); err != nil { - return fmt.Errorf("couldn't initialize API aliases: %w", err) - } - if err := n.initChainManager(n.Config.AvaxAssetID); err != nil { // Set up the chain manager - return fmt.Errorf("couldn't initialize chain manager: %w", err) - } - if err := n.initVMs(); err != nil { // Initialize the VM registry. - return fmt.Errorf("couldn't initialize VM registry: %w", err) - } - if err := n.initAdminAPI(); err != nil { // Start the Admin API - return fmt.Errorf("couldn't initialize admin API: %w", err) - } - if err := n.initInfoAPI(); err != nil { // Start the Info API - return fmt.Errorf("couldn't initialize info API: %w", err) - } - if err := n.initIPCs(); err != nil { // Start the IPCs - return fmt.Errorf("couldn't initialize IPCs: %w", err) - } - if err := n.initIPCAPI(); err != nil { // Start the IPC API - return fmt.Errorf("couldn't initialize the IPC API: %w", err) - } - if err := n.initChainAliases(n.Config.GenesisBytes); err != nil { - return fmt.Errorf("couldn't initialize chain aliases: %w", err) - } - if err := n.initAPIAliases(n.Config.GenesisBytes); err != nil { - return fmt.Errorf("couldn't initialize API aliases: %w", err) - } - if err := n.initIndexer(); err != nil { - return fmt.Errorf("couldn't initialize indexer: %w", err) - } - - n.health.Start(context.TODO(), n.Config.HealthCheckFreq) - n.initProfiler() - - // Start the Platform chain - if err := n.initChains(n.Config.GenesisBytes); err != nil { - return fmt.Errorf("couldn't initialize chains: %w", err) - } - return nil -} - // Shutdown this node // May be called multiple times func (n *Node) Shutdown(exitCode int) { From 86201ae6bf1d3ba7119d2464aff64c3a5325a44f Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Thu, 9 Nov 2023 14:08:10 -0500 Subject: [PATCH 027/267] Remove sentinel node from MerkleDB proofs (#2106) Signed-off-by: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Co-authored-by: Stephen Buttolph Co-authored-by: Dan Laine --- x/merkledb/db.go | 60 ++++++++++++++++----------- x/merkledb/history_test.go | 17 +++++--- x/merkledb/proof_test.go | 49 +++++++++++----------- x/merkledb/trie_test.go | 18 ++++---- x/merkledb/trieview.go | 85 +++++++++++++++++++++++++++++--------- x/sync/manager.go | 24 ++++++++++- 6 files changed, 170 insertions(+), 83 deletions(-) diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 7e52e1fa9ecf..a2e71a5176da 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -41,8 +41,7 @@ const ( ) var ( - rootKey []byte - _ MerkleDB = (*merkleDB)(nil) + _ MerkleDB = (*merkleDB)(nil) codec = newCodec() @@ -54,8 +53,8 @@ var ( hadCleanShutdown = []byte{1} didNotHaveCleanShutdown = []byte{0} - errSameRoot = errors.New("start and end root are the same") - errNoNewRoot = errors.New("there was no updated root in change list") + errSameRoot = errors.New("start and end root are the same") + errNoNewSentinel = errors.New("there was no updated sentinel node in change list") ) type ChangeProofer interface { @@ -194,8 +193,10 @@ type merkleDB struct { debugTracer trace.Tracer infoTracer trace.Tracer - // The root of this trie. - root *node + // The sentinel node of this trie. + // It is the node with a nil key and is the ancestor of all nodes in the trie. + // If it has a value or has multiple children, it is also the root of the trie. + sentinelNode *node // Valid children of this trie. childViews []*trieView @@ -286,7 +287,7 @@ func newDatabase( // Deletes every intermediate node and rebuilds them by re-adding every key/value. // TODO: make this more efficient by only clearing out the stale portions of the trie. func (db *merkleDB) rebuild(ctx context.Context, cacheSize int) error { - db.root = newNode(Key{}) + db.sentinelNode = newNode(Key{}) // Delete intermediate nodes. if err := database.ClearPrefix(db.baseDB, intermediateNodePrefix, rebuildIntermediateDeletionWriteSize); err != nil { @@ -569,7 +570,20 @@ func (db *merkleDB) GetMerkleRoot(ctx context.Context) (ids.ID, error) { // Assumes [db.lock] is read locked. func (db *merkleDB) getMerkleRoot() ids.ID { - return db.root.id + if !isSentinelNodeTheRoot(db.sentinelNode) { + // if the sentinel node should be skipped, the trie's root is the nil key node's only child + for _, childEntry := range db.sentinelNode.children { + return childEntry.id + } + } + return db.sentinelNode.id +} + +// isSentinelNodeTheRoot returns true if the passed in sentinel node has a value and or multiple child nodes +// When this is true, the root of the trie is the sentinel node +// When this is false, the root of the trie is the sentinel node's single child +func isSentinelNodeTheRoot(sentinel *node) bool { + return sentinel.valueDigest.HasValue() || len(sentinel.children) != 1 } func (db *merkleDB) GetProof(ctx context.Context, key []byte) (*Proof, error) { @@ -915,9 +929,9 @@ func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *trieView) e return nil } - rootChange, ok := changes.nodes[Key{}] + sentinelChange, ok := changes.nodes[Key{}] if !ok { - return errNoNewRoot + return errNoNewSentinel } currentValueNodeBatch := db.valueNodeDB.NewBatch() @@ -959,7 +973,7 @@ func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *trieView) e // Only modify in-memory state after the commit succeeds // so that we don't need to clean up on error. - db.root = rootChange.after + db.sentinelNode = sentinelChange.after db.history.record(changes) return nil } @@ -1140,33 +1154,33 @@ func (db *merkleDB) invalidateChildrenExcept(exception *trieView) { } func (db *merkleDB) initializeRootIfNeeded() (ids.ID, error) { - // not sure if the root exists or had a value or not + // not sure if the sentinel node exists or if it had a value // check under both prefixes var err error - db.root, err = db.intermediateNodeDB.Get(Key{}) + db.sentinelNode, err = db.intermediateNodeDB.Get(Key{}) if errors.Is(err, database.ErrNotFound) { - db.root, err = db.valueNodeDB.Get(Key{}) + db.sentinelNode, err = db.valueNodeDB.Get(Key{}) } if err == nil { - // Root already exists, so calculate its id - db.root.calculateID(db.metrics) - return db.root.id, nil + // sentinel node already exists, so calculate the root ID of the trie + db.sentinelNode.calculateID(db.metrics) + return db.getMerkleRoot(), nil } if !errors.Is(err, database.ErrNotFound) { return ids.Empty, err } - // Root doesn't exist; make a new one. - db.root = newNode(Key{}) + // sentinel node doesn't exist; make a new one. + db.sentinelNode = newNode(Key{}) // update its ID - db.root.calculateID(db.metrics) + db.sentinelNode.calculateID(db.metrics) - if err := db.intermediateNodeDB.Put(Key{}, db.root); err != nil { + if err := db.intermediateNodeDB.Put(Key{}, db.sentinelNode); err != nil { return ids.Empty, err } - return db.root.id, nil + return db.sentinelNode.id, nil } // Returns a view of the trie as it was when it had root [rootID] for keys within range [start, end]. @@ -1243,7 +1257,7 @@ func (db *merkleDB) getNode(key Key, hasValue bool) (*node, error) { case db.closed: return nil, database.ErrClosed case key == Key{}: - return db.root, nil + return db.sentinelNode, nil case hasValue: return db.valueNodeDB.Get(key) } diff --git a/x/merkledb/history_test.go b/x/merkledb/history_test.go index f27c1293cde0..2ee1e5f4b31b 100644 --- a/x/merkledb/history_test.go +++ b/x/merkledb/history_test.go @@ -36,7 +36,8 @@ func Test_History_Simple(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - origRootID := db.root.id + + origRootID := db.getMerkleRoot() require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -338,7 +339,8 @@ func Test_History_RepeatedRoot(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - origRootID := db.root.id + + origRootID := db.getMerkleRoot() require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -380,7 +382,8 @@ func Test_History_ExcessDeletes(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - origRootID := db.root.id + + origRootID := db.getMerkleRoot() require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -412,7 +415,8 @@ func Test_History_DontIncludeAllNodes(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - origRootID := db.root.id + + origRootID := db.getMerkleRoot() require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -440,7 +444,7 @@ func Test_History_Branching2Nodes(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - origRootID := db.root.id + origRootID := db.getMerkleRoot() require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -468,7 +472,8 @@ func Test_History_Branching3Nodes(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - origRootID := db.root.id + + origRootID := db.getMerkleRoot() require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() diff --git a/x/merkledb/proof_test.go b/x/merkledb/proof_test.go index 508e3d545d76..b22b80ffd09d 100644 --- a/x/merkledb/proof_test.go +++ b/x/merkledb/proof_test.go @@ -60,9 +60,9 @@ func Test_Proof_Verify_Bad_Data(t *testing.T) { expectedErr: nil, }, { - name: "odd length key with value", + name: "odd length key path with value", malform: func(proof *Proof) { - proof.Path[1].ValueOrHash = maybe.Some([]byte{1, 2}) + proof.Path[0].ValueOrHash = maybe.Some([]byte{1, 2}) }, expectedErr: ErrPartialByteLengthWithValue, }, @@ -150,7 +150,7 @@ func Test_RangeProof_Extra_Value(t *testing.T) { context.Background(), maybe.Some([]byte{1}), maybe.Some([]byte{5, 5}), - db.root.id, + db.getMerkleRoot(), db.tokenSize, )) @@ -160,7 +160,7 @@ func Test_RangeProof_Extra_Value(t *testing.T) { context.Background(), maybe.Some([]byte{1}), maybe.Some([]byte{5, 5}), - db.root.id, + db.getMerkleRoot(), db.tokenSize, ) require.ErrorIs(err, ErrInvalidProof) @@ -187,9 +187,9 @@ func Test_RangeProof_Verify_Bad_Data(t *testing.T) { expectedErr: ErrProofValueDoesntMatch, }, { - name: "EndProof: odd length key with value", + name: "EndProof: odd length key path with value", malform: func(proof *RangeProof) { - proof.EndProof[1].ValueOrHash = maybe.Some([]byte{1, 2}) + proof.EndProof[0].ValueOrHash = maybe.Some([]byte{1, 2}) }, expectedErr: ErrPartialByteLengthWithValue, }, @@ -255,6 +255,7 @@ func Test_Proof(t *testing.T) { context.Background(), ViewChanges{ BatchOps: []database.BatchOp{ + {Key: []byte("key"), Value: []byte("value")}, {Key: []byte("key0"), Value: []byte("value0")}, {Key: []byte("key1"), Value: []byte("value1")}, {Key: []byte("key2"), Value: []byte("value2")}, @@ -273,12 +274,11 @@ func Test_Proof(t *testing.T) { require.Len(proof.Path, 3) + require.Equal(ToKey([]byte("key")), proof.Path[0].Key) + require.Equal(maybe.Some([]byte("value")), proof.Path[0].ValueOrHash) require.Equal(ToKey([]byte("key1")), proof.Path[2].Key) require.Equal(maybe.Some([]byte("value1")), proof.Path[2].ValueOrHash) - require.Equal(ToKey([]byte{}), proof.Path[0].Key) - require.True(proof.Path[0].ValueOrHash.IsNothing()) - expectedRootID, err := trie.GetMerkleRoot(context.Background()) require.NoError(err) require.NoError(proof.Verify(context.Background(), expectedRootID, dbTrie.tokenSize)) @@ -501,9 +501,8 @@ func Test_RangeProof(t *testing.T) { require.Equal([]byte{2}, proof.KeyValues[1].Value) require.Equal([]byte{3}, proof.KeyValues[2].Value) - require.Nil(proof.EndProof[0].Key.Bytes()) - require.Equal([]byte{0}, proof.EndProof[1].Key.Bytes()) - require.Equal([]byte{3}, proof.EndProof[2].Key.Bytes()) + require.Equal([]byte{0}, proof.EndProof[0].Key.Bytes()) + require.Equal([]byte{3}, proof.EndProof[1].Key.Bytes()) // only a single node here since others are duplicates in endproof require.Equal([]byte{1}, proof.StartProof[0].Key.Bytes()) @@ -512,7 +511,7 @@ func Test_RangeProof(t *testing.T) { context.Background(), maybe.Some([]byte{1}), maybe.Some([]byte{3, 5}), - db.root.id, + db.getMerkleRoot(), db.tokenSize, )) } @@ -557,15 +556,14 @@ func Test_RangeProof_NilStart(t *testing.T) { require.Equal([]byte("value1"), proof.KeyValues[0].Value) require.Equal([]byte("value2"), proof.KeyValues[1].Value) - require.Equal(ToKey([]byte("key2")), proof.EndProof[2].Key) - require.Equal(ToKey([]byte("key2")).Take(28), proof.EndProof[1].Key) - require.Equal(ToKey([]byte("")), proof.EndProof[0].Key) + require.Equal(ToKey([]byte("key2")), proof.EndProof[1].Key) + require.Equal(ToKey([]byte("key2")).Take(28), proof.EndProof[0].Key) require.NoError(proof.Verify( context.Background(), maybe.Nothing[[]byte](), maybe.Some([]byte("key35")), - db.root.id, + db.getMerkleRoot(), db.tokenSize, )) } @@ -592,15 +590,14 @@ func Test_RangeProof_NilEnd(t *testing.T) { require.Equal([]byte{1}, proof.StartProof[0].Key.Bytes()) - require.Nil(proof.EndProof[0].Key.Bytes()) - require.Equal([]byte{0}, proof.EndProof[1].Key.Bytes()) - require.Equal([]byte{2}, proof.EndProof[2].Key.Bytes()) + require.Equal([]byte{0}, proof.EndProof[0].Key.Bytes()) + require.Equal([]byte{2}, proof.EndProof[1].Key.Bytes()) require.NoError(proof.Verify( context.Background(), maybe.Some([]byte{1}), maybe.Nothing[[]byte](), - db.root.id, + db.getMerkleRoot(), db.tokenSize, )) } @@ -635,15 +632,15 @@ func Test_RangeProof_EmptyValues(t *testing.T) { require.Len(proof.StartProof, 1) require.Equal(ToKey([]byte("key1")), proof.StartProof[0].Key) - require.Len(proof.EndProof, 3) - require.Equal(ToKey([]byte("key2")), proof.EndProof[2].Key) - require.Equal(ToKey([]byte{}), proof.EndProof[0].Key) + require.Len(proof.EndProof, 2) + require.Equal(ToKey([]byte("key2")), proof.EndProof[1].Key) + require.Equal(ToKey([]byte("key2")).Take(28), proof.EndProof[0].Key) require.NoError(proof.Verify( context.Background(), maybe.Some([]byte("key1")), maybe.Some([]byte("key2")), - db.root.id, + db.getMerkleRoot(), db.tokenSize, )) } @@ -779,7 +776,7 @@ func Test_ChangeProof_Verify_Bad_Data(t *testing.T) { { name: "odd length key path with value", malform: func(proof *ChangeProof) { - proof.EndProof[1].ValueOrHash = maybe.Some([]byte{1, 2}) + proof.EndProof[0].ValueOrHash = maybe.Some([]byte{1, 2}) }, expectedErr: ErrPartialByteLengthWithValue, }, diff --git a/x/merkledb/trie_test.go b/x/merkledb/trie_test.go index 9bce417a7b1a..a431dd6b254d 100644 --- a/x/merkledb/trie_test.go +++ b/x/merkledb/trie_test.go @@ -126,7 +126,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { // Just the root require.Len(nodePath, 1) - require.Equal(trie.root, nodePath[0]) + require.Equal(trie.sentinelNode, nodePath[0]) // Insert a key key1 := []byte{0} @@ -151,7 +151,8 @@ func TestTrieViewVisitPathToKey(t *testing.T) { // Root and 1 value require.Len(nodePath, 2) - require.Equal(trie.root, nodePath[0]) + + require.Equal(trie.sentinelNode, nodePath[0]) require.Equal(ToKey(key1), nodePath[1].key) // Insert another key which is a child of the first @@ -175,7 +176,8 @@ func TestTrieViewVisitPathToKey(t *testing.T) { return nil })) require.Len(nodePath, 3) - require.Equal(trie.root, nodePath[0]) + + require.Equal(trie.sentinelNode, nodePath[0]) require.Equal(ToKey(key1), nodePath[1].key) require.Equal(ToKey(key2), nodePath[2].key) @@ -201,7 +203,8 @@ func TestTrieViewVisitPathToKey(t *testing.T) { })) require.Len(nodePath, 2) - require.Equal(trie.root, nodePath[0]) + + require.Equal(trie.sentinelNode, nodePath[0]) require.Equal(ToKey(key3), nodePath[1].key) // Other key path not affected @@ -211,7 +214,8 @@ func TestTrieViewVisitPathToKey(t *testing.T) { return nil })) require.Len(nodePath, 3) - require.Equal(trie.root, nodePath[0]) + + require.Equal(trie.sentinelNode, nodePath[0]) require.Equal(ToKey(key1), nodePath[1].key) require.Equal(ToKey(key2), nodePath[2].key) @@ -224,7 +228,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { })) require.Len(nodePath, 3) - require.Equal(trie.root, nodePath[0]) + require.Equal(trie.sentinelNode, nodePath[0]) require.Equal(ToKey(key1), nodePath[1].key) require.Equal(ToKey(key2), nodePath[2].key) @@ -236,7 +240,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { return nil })) require.Len(nodePath, 1) - require.Equal(trie.root, nodePath[0]) + require.Equal(trie.sentinelNode, nodePath[0]) } func Test_Trie_ViewOnCommitedView(t *testing.T) { diff --git a/x/merkledb/trieview.go b/x/merkledb/trieview.go index d8d9cfbdeb28..622bfcb11207 100644 --- a/x/merkledb/trieview.go +++ b/x/merkledb/trieview.go @@ -96,8 +96,9 @@ type trieView struct { db *merkleDB - // The root of the trie represented by this view. - root *node + // The nil key node + // It is either the root of the trie or the root of the trie is its single child node + sentinelNode *node tokenSize int } @@ -147,7 +148,7 @@ func newTrieView( parentTrie TrieView, changes ViewChanges, ) (*trieView, error) { - root, err := parentTrie.getEditableNode(Key{}, false /* hasValue */) + sentinelNode, err := parentTrie.getEditableNode(Key{}, false /* hasValue */) if err != nil { if errors.Is(err, database.ErrNotFound) { return nil, ErrNoValidRoot @@ -156,11 +157,11 @@ func newTrieView( } newView := &trieView{ - root: root, - db: db, - parentTrie: parentTrie, - changes: newChangeSummary(len(changes.BatchOps) + len(changes.MapOps)), - tokenSize: db.tokenSize, + sentinelNode: sentinelNode, + db: db, + parentTrie: parentTrie, + changes: newChangeSummary(len(changes.BatchOps) + len(changes.MapOps)), + tokenSize: db.tokenSize, } for _, op := range changes.BatchOps { @@ -200,17 +201,17 @@ func newHistoricalTrieView( return nil, ErrNoValidRoot } - passedRootChange, ok := changes.nodes[Key{}] + passedSentinelChange, ok := changes.nodes[Key{}] if !ok { return nil, ErrNoValidRoot } newView := &trieView{ - root: passedRootChange.after, - db: db, - parentTrie: db, - changes: changes, - tokenSize: db.tokenSize, + sentinelNode: passedSentinelChange.after, + db: db, + parentTrie: db, + changes: changes, + tokenSize: db.tokenSize, } // since this is a set of historical changes, all nodes have already been calculated // since no new changes have occurred, no new calculations need to be done @@ -250,9 +251,9 @@ func (t *trieView) calculateNodeIDs(ctx context.Context) error { } _ = t.db.calculateNodeIDsSema.Acquire(context.Background(), 1) - t.calculateNodeIDsHelper(t.root) + t.calculateNodeIDsHelper(t.sentinelNode) t.db.calculateNodeIDsSema.Release(1) - t.changes.rootID = t.root.id + t.changes.rootID = t.getMerkleRoot() // ensure no ancestor changes occurred during execution if t.isInvalid() { @@ -348,6 +349,22 @@ func (t *trieView) getProof(ctx context.Context, key []byte) (*Proof, error) { }); err != nil { return nil, err } + root, err := t.getRoot() + if err != nil { + return nil, err + } + + // The sentinel node is always the first node in the path. + // If the sentinel node is not the root, remove it from the proofPath. + if root != t.sentinelNode { + proof.Path = proof.Path[1:] + + // if there are no nodes in the proof path, add the root to serve as an exclusion proof + if len(proof.Path) == 0 { + proof.Path = []ProofNode{root.asProofNode()} + return proof, nil + } + } if closestNode.key == proof.Key { // There is a node with the given [key]. @@ -460,7 +477,11 @@ func (t *trieView) GetRangeProof( if len(result.StartProof) == 0 && len(result.EndProof) == 0 && len(result.KeyValues) == 0 { // If the range is empty, return the root proof. - rootProof, err := t.getProof(ctx, rootKey) + root, err := t.getRoot() + if err != nil { + return nil, err + } + rootProof, err := t.getProof(ctx, root.key.Bytes()) if err != nil { return nil, err } @@ -547,7 +568,17 @@ func (t *trieView) GetMerkleRoot(ctx context.Context) (ids.ID, error) { if err := t.calculateNodeIDs(ctx); err != nil { return ids.Empty, err } - return t.root.id, nil + return t.getMerkleRoot(), nil +} + +func (t *trieView) getMerkleRoot() ids.ID { + if !isSentinelNodeTheRoot(t.sentinelNode) { + for _, childEntry := range t.sentinelNode.children { + return childEntry.id + } + } + + return t.sentinelNode.id } func (t *trieView) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []error) { @@ -717,8 +748,8 @@ func (t *trieView) compressNodePath(parent, node *node) error { // Always returns at least the root node. func (t *trieView) visitPathToKey(key Key, visitNode func(*node) error) error { var ( - // all node paths start at the root - currentNode = t.root + // all node paths start at the sentinelNode since its nil key is a prefix of all keys + currentNode = t.sentinelNode err error ) if err := visitNode(currentNode); err != nil { @@ -889,6 +920,20 @@ func (t *trieView) recordNodeDeleted(after *node) error { return t.recordKeyChange(after.key, nil, after.hasValue(), false /* newNode */) } +func (t *trieView) getRoot() (*node, error) { + if !isSentinelNodeTheRoot(t.sentinelNode) { + // sentinelNode has one child, which is the root + for index, childEntry := range t.sentinelNode.children { + return t.getNodeWithID( + childEntry.id, + t.sentinelNode.key.Extend(ToToken(index, t.tokenSize), childEntry.compressedKey), + childEntry.hasValue) + } + } + + return t.sentinelNode, nil +} + // Records that the node associated with the given key has been changed. // If it is an existing node, record what its value was before it was changed. // Must not be called after [calculateNodeIDs] has returned. diff --git a/x/sync/manager.go b/x/sync/manager.go index 6bd81e847aee..a7a6858d5122 100644 --- a/x/sync/manager.go +++ b/x/sync/manager.go @@ -434,10 +434,32 @@ func (m *Manager) findNextKey( nextKey := maybe.Nothing[[]byte]() + // Add sentinel node back into the localProofNodes, if it is missing. + // Required to ensure that a common node exists in both proofs + if len(localProofNodes) > 0 && localProofNodes[0].Key.Length() != 0 { + sentinel := merkledb.ProofNode{ + Children: map[byte]ids.ID{ + localProofNodes[0].Key.Token(0, m.tokenSize): ids.Empty, + }, + } + localProofNodes = append([]merkledb.ProofNode{sentinel}, localProofNodes...) + } + + // Add sentinel node back into the endProof, if it is missing. + // Required to ensure that a common node exists in both proofs + if len(endProof) > 0 && endProof[0].Key.Length() != 0 { + sentinel := merkledb.ProofNode{ + Children: map[byte]ids.ID{ + endProof[0].Key.Token(0, m.tokenSize): ids.Empty, + }, + } + endProof = append([]merkledb.ProofNode{sentinel}, endProof...) + } + localProofNodeIndex := len(localProofNodes) - 1 receivedProofNodeIndex := len(endProof) - 1 - // traverse the two proofs from the deepest nodes up to the root until a difference is found + // traverse the two proofs from the deepest nodes up to the sentinel node until a difference is found for localProofNodeIndex >= 0 && receivedProofNodeIndex >= 0 && nextKey.IsNothing() { localProofNode := localProofNodes[localProofNodeIndex] receivedProofNode := endProof[receivedProofNodeIndex] From b8746dea22995ea30d7e9ae1c273160349afb910 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 9 Nov 2023 16:21:04 -0800 Subject: [PATCH 028/267] Embed `noop` handler for all unhandled messages (#2288) --- vms/platformvm/block/builder/network.go | 50 ++++--------------------- 1 file changed, 8 insertions(+), 42 deletions(-) diff --git a/vms/platformvm/block/builder/network.go b/vms/platformvm/block/builder/network.go index 3e1576d958fb..da5e122d38f4 100644 --- a/vms/platformvm/block/builder/network.go +++ b/vms/platformvm/block/builder/network.go @@ -8,7 +8,6 @@ package builder import ( "context" "fmt" - "time" "go.uber.org/zap" @@ -20,11 +19,9 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) -const ( - // We allow [recentCacheSize] to be fairly large because we only store hashes - // in the cache, not entire transactions. - recentCacheSize = 512 -) +// We allow [recentCacheSize] to be fairly large because we only store hashes +// in the cache, not entire transactions. +const recentCacheSize = 512 var _ Network = (*network)(nil) @@ -36,6 +33,9 @@ type Network interface { } type network struct { + // We embed a noop handler for all unhandled messages + common.AppHandler + ctx *snow.Context blkBuilder *builder @@ -50,6 +50,8 @@ func NewNetwork( appSender common.AppSender, ) Network { return &network{ + AppHandler: common.NewNoOpAppHandler(ctx.Log), + ctx: ctx, blkBuilder: blkBuilder, appSender: appSender, @@ -57,42 +59,6 @@ func NewNetwork( } } -func (*network) CrossChainAppRequestFailed(context.Context, ids.ID, uint32) error { - // This VM currently only supports gossiping of txs, so there are no - // requests. - return nil -} - -func (*network) CrossChainAppRequest(context.Context, ids.ID, uint32, time.Time, []byte) error { - // This VM currently only supports gossiping of txs, so there are no - // requests. - return nil -} - -func (*network) CrossChainAppResponse(context.Context, ids.ID, uint32, []byte) error { - // This VM currently only supports gossiping of txs, so there are no - // requests. - return nil -} - -func (*network) AppRequestFailed(context.Context, ids.NodeID, uint32) error { - // This VM currently only supports gossiping of txs, so there are no - // requests. - return nil -} - -func (*network) AppRequest(context.Context, ids.NodeID, uint32, time.Time, []byte) error { - // This VM currently only supports gossiping of txs, so there are no - // requests. - return nil -} - -func (*network) AppResponse(context.Context, ids.NodeID, uint32, []byte) error { - // This VM currently only supports gossiping of txs, so there are no - // requests. - return nil -} - func (n *network) AppGossip(_ context.Context, nodeID ids.NodeID, msgBytes []byte) error { n.ctx.Log.Debug("called AppGossip message handler", zap.Stringer("nodeID", nodeID), From baf0ef7df304171f6e430a836e17cc2adf874292 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Mon, 13 Nov 2023 10:33:31 -0500 Subject: [PATCH 029/267] `merkledb` -- Add `Clearer` interface (#2277) --- proto/pb/sync/sync.pb.go | 103 +++++++++++++----------- proto/pb/sync/sync_grpc.pb.go | 37 +++++++++ proto/sync/sync.proto | 2 + x/merkledb/db.go | 37 +++++++++ x/merkledb/db_test.go | 45 +++++++++++ x/merkledb/intermediate_node_db.go | 11 +++ x/merkledb/intermediate_node_db_test.go | 29 +++++++ x/merkledb/mock_db.go | 14 ++++ x/merkledb/value_node_db.go | 5 ++ x/merkledb/value_node_db_test.go | 31 +++++++ x/sync/db.go | 1 + x/sync/g_db/db_client.go | 5 ++ x/sync/g_db/db_server.go | 4 + 13 files changed, 275 insertions(+), 49 deletions(-) diff --git a/proto/pb/sync/sync.pb.go b/proto/pb/sync/sync.pb.go index 92cd3d88351e..eb72e145420a 100644 --- a/proto/pb/sync/sync.pb.go +++ b/proto/pb/sync/sync.pb.go @@ -1666,44 +1666,47 @@ var file_sync_sync_proto_rawDesc = []byte{ 0x4e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x22, 0x32, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x32, 0x8a, 0x04, 0x0a, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x32, 0xc3, 0x04, 0x0a, 0x02, 0x44, 0x42, 0x12, 0x44, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x15, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x79, - 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1b, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x54, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1e, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1e, 0x2e, 0x73, 0x79, - 0x6e, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x48, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x50, - 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1a, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, - 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1b, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, - 0x10, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, - 0x66, 0x12, 0x1d, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, - 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, - 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x43, 0x6c, 0x65, 0x61, + 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x39, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x15, 0x2e, + 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x50, + 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0e, + 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1b, + 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, + 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x73, 0x79, + 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, + 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x11, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1e, + 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4b, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, + 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1e, 0x2e, 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x48, 0x0a, 0x0d, + 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1a, 0x2e, + 0x73, 0x79, 0x6e, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x79, 0x6e, 0x63, + 0x2e, 0x47, 0x65, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x1d, 0x2e, 0x73, 0x79, 0x6e, + 0x63, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x79, + 0x6e, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1782,21 +1785,23 @@ var file_sync_sync_proto_depIdxs = []int32{ 23, // 32: sync.ProofNode.children:type_name -> sync.ProofNode.ChildrenEntry 21, // 33: sync.KeyChange.value:type_name -> sync.MaybeBytes 24, // 34: sync.DB.GetMerkleRoot:input_type -> google.protobuf.Empty - 2, // 35: sync.DB.GetProof:input_type -> sync.GetProofRequest - 7, // 36: sync.DB.GetChangeProof:input_type -> sync.GetChangeProofRequest - 9, // 37: sync.DB.VerifyChangeProof:input_type -> sync.VerifyChangeProofRequest - 11, // 38: sync.DB.CommitChangeProof:input_type -> sync.CommitChangeProofRequest - 13, // 39: sync.DB.GetRangeProof:input_type -> sync.GetRangeProofRequest - 15, // 40: sync.DB.CommitRangeProof:input_type -> sync.CommitRangeProofRequest - 1, // 41: sync.DB.GetMerkleRoot:output_type -> sync.GetMerkleRootResponse - 3, // 42: sync.DB.GetProof:output_type -> sync.GetProofResponse - 8, // 43: sync.DB.GetChangeProof:output_type -> sync.GetChangeProofResponse - 10, // 44: sync.DB.VerifyChangeProof:output_type -> sync.VerifyChangeProofResponse - 24, // 45: sync.DB.CommitChangeProof:output_type -> google.protobuf.Empty - 14, // 46: sync.DB.GetRangeProof:output_type -> sync.GetRangeProofResponse - 24, // 47: sync.DB.CommitRangeProof:output_type -> google.protobuf.Empty - 41, // [41:48] is the sub-list for method output_type - 34, // [34:41] is the sub-list for method input_type + 24, // 35: sync.DB.Clear:input_type -> google.protobuf.Empty + 2, // 36: sync.DB.GetProof:input_type -> sync.GetProofRequest + 7, // 37: sync.DB.GetChangeProof:input_type -> sync.GetChangeProofRequest + 9, // 38: sync.DB.VerifyChangeProof:input_type -> sync.VerifyChangeProofRequest + 11, // 39: sync.DB.CommitChangeProof:input_type -> sync.CommitChangeProofRequest + 13, // 40: sync.DB.GetRangeProof:input_type -> sync.GetRangeProofRequest + 15, // 41: sync.DB.CommitRangeProof:input_type -> sync.CommitRangeProofRequest + 1, // 42: sync.DB.GetMerkleRoot:output_type -> sync.GetMerkleRootResponse + 24, // 43: sync.DB.Clear:output_type -> google.protobuf.Empty + 3, // 44: sync.DB.GetProof:output_type -> sync.GetProofResponse + 8, // 45: sync.DB.GetChangeProof:output_type -> sync.GetChangeProofResponse + 10, // 46: sync.DB.VerifyChangeProof:output_type -> sync.VerifyChangeProofResponse + 24, // 47: sync.DB.CommitChangeProof:output_type -> google.protobuf.Empty + 14, // 48: sync.DB.GetRangeProof:output_type -> sync.GetRangeProofResponse + 24, // 49: sync.DB.CommitRangeProof:output_type -> google.protobuf.Empty + 42, // [42:50] is the sub-list for method output_type + 34, // [34:42] is the sub-list for method input_type 34, // [34:34] is the sub-list for extension type_name 34, // [34:34] is the sub-list for extension extendee 0, // [0:34] is the sub-list for field type_name diff --git a/proto/pb/sync/sync_grpc.pb.go b/proto/pb/sync/sync_grpc.pb.go index 3fb420c7273a..5f79687b4d01 100644 --- a/proto/pb/sync/sync_grpc.pb.go +++ b/proto/pb/sync/sync_grpc.pb.go @@ -21,6 +21,7 @@ const _ = grpc.SupportPackageIsVersion7 const ( DB_GetMerkleRoot_FullMethodName = "/sync.DB/GetMerkleRoot" + DB_Clear_FullMethodName = "/sync.DB/Clear" DB_GetProof_FullMethodName = "/sync.DB/GetProof" DB_GetChangeProof_FullMethodName = "/sync.DB/GetChangeProof" DB_VerifyChangeProof_FullMethodName = "/sync.DB/VerifyChangeProof" @@ -34,6 +35,7 @@ const ( // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type DBClient interface { GetMerkleRoot(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetMerkleRootResponse, error) + Clear(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) GetProof(ctx context.Context, in *GetProofRequest, opts ...grpc.CallOption) (*GetProofResponse, error) GetChangeProof(ctx context.Context, in *GetChangeProofRequest, opts ...grpc.CallOption) (*GetChangeProofResponse, error) VerifyChangeProof(ctx context.Context, in *VerifyChangeProofRequest, opts ...grpc.CallOption) (*VerifyChangeProofResponse, error) @@ -59,6 +61,15 @@ func (c *dBClient) GetMerkleRoot(ctx context.Context, in *emptypb.Empty, opts .. return out, nil } +func (c *dBClient) Clear(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, DB_Clear_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *dBClient) GetProof(ctx context.Context, in *GetProofRequest, opts ...grpc.CallOption) (*GetProofResponse, error) { out := new(GetProofResponse) err := c.cc.Invoke(ctx, DB_GetProof_FullMethodName, in, out, opts...) @@ -118,6 +129,7 @@ func (c *dBClient) CommitRangeProof(ctx context.Context, in *CommitRangeProofReq // for forward compatibility type DBServer interface { GetMerkleRoot(context.Context, *emptypb.Empty) (*GetMerkleRootResponse, error) + Clear(context.Context, *emptypb.Empty) (*emptypb.Empty, error) GetProof(context.Context, *GetProofRequest) (*GetProofResponse, error) GetChangeProof(context.Context, *GetChangeProofRequest) (*GetChangeProofResponse, error) VerifyChangeProof(context.Context, *VerifyChangeProofRequest) (*VerifyChangeProofResponse, error) @@ -134,6 +146,9 @@ type UnimplementedDBServer struct { func (UnimplementedDBServer) GetMerkleRoot(context.Context, *emptypb.Empty) (*GetMerkleRootResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetMerkleRoot not implemented") } +func (UnimplementedDBServer) Clear(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Clear not implemented") +} func (UnimplementedDBServer) GetProof(context.Context, *GetProofRequest) (*GetProofResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetProof not implemented") } @@ -183,6 +198,24 @@ func _DB_GetMerkleRoot_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _DB_Clear_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DBServer).Clear(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: DB_Clear_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DBServer).Clear(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + func _DB_GetProof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetProofRequest) if err := dec(in); err != nil { @@ -302,6 +335,10 @@ var DB_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetMerkleRoot", Handler: _DB_GetMerkleRoot_Handler, }, + { + MethodName: "Clear", + Handler: _DB_Clear_Handler, + }, { MethodName: "GetProof", Handler: _DB_GetProof_Handler, diff --git a/proto/sync/sync.proto b/proto/sync/sync.proto index 4c4c6f434722..1a799433d7e7 100644 --- a/proto/sync/sync.proto +++ b/proto/sync/sync.proto @@ -21,6 +21,8 @@ message Request { service DB { rpc GetMerkleRoot(google.protobuf.Empty) returns (GetMerkleRootResponse); + rpc Clear(google.protobuf.Empty) returns (google.protobuf.Empty); + rpc GetProof(GetProofRequest) returns (GetProofResponse); rpc GetChangeProof(GetChangeProofRequest) returns (GetChangeProofResponse); diff --git a/x/merkledb/db.go b/x/merkledb/db.go index a2e71a5176da..b1ee699bab97 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -36,6 +36,7 @@ const ( // TODO: name better rebuildViewSizeFractionOfCacheSize = 50 minRebuildViewSizePerCommit = 1000 + clearBatchSize = units.MiB rebuildIntermediateDeletionWriteSize = units.MiB valueNodePrefixLen = 1 ) @@ -113,6 +114,12 @@ type RangeProofer interface { CommitRangeProof(ctx context.Context, start, end maybe.Maybe[[]byte], proof *RangeProof) error } +type Clearer interface { + // Deletes all key/value pairs from the database + // and clears the change history. + Clear() error +} + type Prefetcher interface { // PrefetchPath attempts to load all trie nodes on the path of [key] // into the cache. @@ -128,6 +135,7 @@ type Prefetcher interface { type MerkleDB interface { database.Database + Clearer Trie MerkleRootGetter ProofGetter @@ -1264,6 +1272,35 @@ func (db *merkleDB) getNode(key Key, hasValue bool) (*node, error) { return db.intermediateNodeDB.Get(key) } +func (db *merkleDB) Clear() error { + db.commitLock.Lock() + defer db.commitLock.Unlock() + + db.lock.Lock() + defer db.lock.Unlock() + + // Clear nodes from disk and caches + if err := db.valueNodeDB.Clear(); err != nil { + return err + } + if err := db.intermediateNodeDB.Clear(); err != nil { + return err + } + + // Clear root + db.sentinelNode = newNode(Key{}) + db.sentinelNode.calculateID(db.metrics) + + // Clear history + db.history = newTrieHistory(db.history.maxHistoryLen) + db.history.record(&changeSummary{ + rootID: db.getMerkleRoot(), + values: map[Key]*change[maybe.Maybe[[]byte]]{}, + nodes: map[Key]*change[*node]{}, + }) + return nil +} + // Returns [key] prefixed by [prefix]. // The returned []byte is taken from [bufferPool] and // should be returned to it when the caller is done with it. diff --git a/x/merkledb/db_test.go b/x/merkledb/db_test.go index 2d6439fd294b..828a72bef7db 100644 --- a/x/merkledb/db_test.go +++ b/x/merkledb/db_test.go @@ -30,6 +30,8 @@ import ( const defaultHistoryLength = 300 +var emptyKey Key + // newDB returns a new merkle database with the underlying type so that tests can access unexported fields func newDB(ctx context.Context, db database.Database, config Config) (*merkleDB, error) { db, err := New(ctx, db, config) @@ -773,6 +775,49 @@ func Test_MerkleDB_Random_Insert_Ordering(t *testing.T) { } } +func TestMerkleDBClear(t *testing.T) { + require := require.New(t) + + // Make a database and insert some key-value pairs. + db, err := getBasicDB() + require.NoError(err) + + emptyRootID := db.getMerkleRoot() + + now := time.Now().UnixNano() + t.Logf("seed: %d", now) + r := rand.New(rand.NewSource(now)) // #nosec G404 + + insertRandomKeyValues( + require, + r, + []database.Database{db}, + 1_000, + 0.25, + ) + + // Clear the database. + require.NoError(db.Clear()) + + // Assert that the database is empty. + iter := db.NewIterator() + defer iter.Release() + require.False(iter.Next()) + require.Equal(emptyRootID, db.getMerkleRoot()) + require.Equal(emptyKey, db.sentinelNode.key) + + // Assert caches are empty. + require.Zero(db.valueNodeDB.nodeCache.Len()) + require.Zero(db.intermediateNodeDB.nodeCache.currentSize) + + // Assert history has only the clearing change. + require.Len(db.history.lastChanges, 1) + change, ok := db.history.lastChanges[emptyRootID] + require.True(ok) + require.Empty(change.nodes) + require.Empty(change.values) +} + func FuzzMerkleDBEmptyRandomizedActions(f *testing.F) { f.Fuzz( func( diff --git a/x/merkledb/intermediate_node_db.go b/x/merkledb/intermediate_node_db.go index 1602aa05bbaa..91cef6242410 100644 --- a/x/merkledb/intermediate_node_db.go +++ b/x/merkledb/intermediate_node_db.go @@ -146,3 +146,14 @@ func (db *intermediateNodeDB) Flush() error { func (db *intermediateNodeDB) Delete(key Key) error { return db.nodeCache.Put(key, nil) } + +func (db *intermediateNodeDB) Clear() error { + // Reset the cache. Note we don't flush because that would cause us to + // persist intermediate nodes we're about to delete. + db.nodeCache = newOnEvictCache( + db.nodeCache.maxSize, + db.nodeCache.size, + db.nodeCache.onEviction, + ) + return database.AtomicClearPrefix(db.baseDB, db.baseDB, intermediateNodePrefix) +} diff --git a/x/merkledb/intermediate_node_db_test.go b/x/merkledb/intermediate_node_db_test.go index 027798017e95..91709708f148 100644 --- a/x/merkledb/intermediate_node_db_test.go +++ b/x/merkledb/intermediate_node_db_test.go @@ -213,3 +213,32 @@ func Test_IntermediateNodeDB_ConstructDBKey_DirtyBuffer(t *testing.T) { require.Equal(intermediateNodePrefix, constructedKey[:len(intermediateNodePrefix)]) require.Equal(p.Extend(ToToken(1, 4)).Bytes(), constructedKey[len(intermediateNodePrefix):]) } + +func TestIntermediateNodeDBClear(t *testing.T) { + require := require.New(t) + cacheSize := 200 + evictionBatchSize := cacheSize + baseDB := memdb.New() + db := newIntermediateNodeDB( + baseDB, + &sync.Pool{ + New: func() interface{} { return make([]byte, 0) }, + }, + &mockMetrics{}, + cacheSize, + evictionBatchSize, + 4, + ) + + for _, b := range [][]byte{{1}, {2}, {3}} { + require.NoError(db.Put(ToKey(b), newNode(ToKey(b)))) + } + + require.NoError(db.Clear()) + + iter := baseDB.NewIteratorWithPrefix(intermediateNodePrefix) + defer iter.Release() + require.False(iter.Next()) + + require.Zero(db.nodeCache.currentSize) +} diff --git a/x/merkledb/mock_db.go b/x/merkledb/mock_db.go index f7e35883c177..a4d1d6b6d6f3 100644 --- a/x/merkledb/mock_db.go +++ b/x/merkledb/mock_db.go @@ -40,6 +40,20 @@ func (m *MockMerkleDB) EXPECT() *MockMerkleDBMockRecorder { return m.recorder } +// Clear mocks base method. +func (m *MockMerkleDB) Clear() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Clear") + ret0, _ := ret[0].(error) + return ret0 +} + +// Clear indicates an expected call of Clear. +func (mr *MockMerkleDBMockRecorder) Clear() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clear", reflect.TypeOf((*MockMerkleDB)(nil).Clear)) +} + // Close mocks base method. func (m *MockMerkleDB) Close() error { m.ctrl.T.Helper() diff --git a/x/merkledb/value_node_db.go b/x/merkledb/value_node_db.go index 339fa25f78f0..406c9a986dba 100644 --- a/x/merkledb/value_node_db.go +++ b/x/merkledb/value_node_db.go @@ -89,6 +89,11 @@ func (db *valueNodeDB) Get(key Key) (*node, error) { return parseNode(key, nodeBytes) } +func (db *valueNodeDB) Clear() error { + db.nodeCache.Flush() + return database.AtomicClearPrefix(db.baseDB, db.baseDB, valueNodePrefix) +} + // Batch of database operations type valueNodeBatch struct { db *valueNodeDB diff --git a/x/merkledb/value_node_db_test.go b/x/merkledb/value_node_db_test.go index 96c5b4b038cc..c87f0ab5ebf8 100644 --- a/x/merkledb/value_node_db_test.go +++ b/x/merkledb/value_node_db_test.go @@ -218,3 +218,34 @@ func TestValueNodeDBIterator(t *testing.T) { err := it.Error() require.ErrorIs(err, database.ErrClosed) } + +func TestValueNodeDBClear(t *testing.T) { + require := require.New(t) + cacheSize := 200 + baseDB := memdb.New() + db := newValueNodeDB( + baseDB, + &sync.Pool{ + New: func() interface{} { return make([]byte, 0) }, + }, + &mockMetrics{}, + cacheSize, + ) + + batch := db.NewBatch() + for _, b := range [][]byte{{1}, {2}, {3}} { + batch.Put(ToKey(b), newNode(ToKey(b))) + } + require.NoError(batch.Write()) + + // Assert the db is not empty + iter := baseDB.NewIteratorWithPrefix(valueNodePrefix) + require.True(iter.Next()) + iter.Release() + + require.NoError(db.Clear()) + + iter = baseDB.NewIteratorWithPrefix(valueNodePrefix) + defer iter.Release() + require.False(iter.Next()) +} diff --git a/x/sync/db.go b/x/sync/db.go index 94b5542e34c1..5a0a5164c6a6 100644 --- a/x/sync/db.go +++ b/x/sync/db.go @@ -6,6 +6,7 @@ package sync import "github.com/ava-labs/avalanchego/x/merkledb" type DB interface { + merkledb.Clearer merkledb.MerkleRootGetter merkledb.ProofGetter merkledb.ChangeProofer diff --git a/x/sync/g_db/db_client.go b/x/sync/g_db/db_client.go index 9ce402f5e6ca..64e63bb76652 100644 --- a/x/sync/g_db/db_client.go +++ b/x/sync/g_db/db_client.go @@ -175,3 +175,8 @@ func (c *DBClient) CommitRangeProof( }) return err } + +func (c *DBClient) Clear() error { + _, err := c.client.Clear(context.Background(), &emptypb.Empty{}) + return err +} diff --git a/x/sync/g_db/db_server.go b/x/sync/g_db/db_server.go index da454e2d77cd..820a130bb496 100644 --- a/x/sync/g_db/db_server.go +++ b/x/sync/g_db/db_server.go @@ -216,3 +216,7 @@ func (s *DBServer) CommitRangeProof( err := s.db.CommitRangeProof(ctx, start, end, &proof) return &emptypb.Empty{}, err } + +func (s *DBServer) Clear(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { + return &emptypb.Empty{}, s.db.Clear() +} From 7f70fcf9ae97520c42222b5a8387ebead2ba1b9b Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 13 Nov 2023 15:18:34 -0500 Subject: [PATCH 030/267] Simplify get server creation (#2285) Co-authored-by: Dan Laine --- chains/manager.go | 132 ++++++++++-------- .../avalanche/bootstrap/bootstrapper_test.go | 4 +- snow/engine/avalanche/getter/getter.go | 41 ++++-- snow/engine/avalanche/getter/getter_test.go | 75 +++------- snow/engine/common/config.go | 9 -- snow/engine/common/test_config.go | 1 - .../snowman/bootstrap/bootstrapper_test.go | 10 +- snow/engine/snowman/getter/getter.go | 39 ++++-- snow/engine/snowman/getter/getter_test.go | 100 +++---------- .../snowman/syncer/state_syncer_test.go | 23 ++- snow/engine/snowman/syncer/utils_test.go | 10 +- snow/engine/snowman/transitive_test.go | 10 +- vms/platformvm/vm_test.go | 17 ++- x/merkledb/db_test.go | 1 + 14 files changed, 220 insertions(+), 252 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index 85472e424222..985741e5eb3a 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -841,23 +841,14 @@ func (m *manager) createAvalancheChain( startupTracker := tracker.NewStartup(connectedBeacons, (3*bootstrapWeight+3)/4) vdrs.RegisterCallbackListener(ctx.SubnetID, startupTracker) - snowmanCommonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: sampleK, - Alpha: bootstrapWeight/2 + 1, // must be > 50% - StartupTracker: startupTracker, - Sender: snowmanMessageSender, - BootstrapTracker: sb, - Timer: h, - RetryBootstrap: m.RetryBootstrap, - RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, - MaxTimeGetAncestors: m.BootstrapMaxTimeGetAncestors, - AncestorsMaxContainersSent: m.BootstrapAncestorsMaxContainersSent, - AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, - SharedCfg: &common.SharedConfig{}, - } - snowGetHandler, err := snowgetter.New(vmWrappingProposerVM, snowmanCommonCfg) + snowGetHandler, err := snowgetter.New( + vmWrappingProposerVM, + snowmanMessageSender, + ctx.Log, + m.BootstrapMaxTimeGetAncestors, + m.BootstrapAncestorsMaxContainersSent, + ctx.Registerer, + ) if err != nil { return nil, fmt.Errorf("couldn't initialize snow base message handler: %w", err) } @@ -870,10 +861,10 @@ func (m *manager) createAvalancheChain( // Create engine, bootstrapper and state-syncer in this order, // to make sure start callbacks are duly initialized snowmanEngineConfig := smeng.Config{ - Ctx: snowmanCommonCfg.Ctx, + Ctx: ctx, AllGetsServer: snowGetHandler, VM: vmWrappingProposerVM, - Sender: snowmanCommonCfg.Sender, + Sender: snowmanMessageSender, Validators: vdrs, Params: consensusParams, Consensus: snowmanConsensus, @@ -889,7 +880,20 @@ func (m *manager) createAvalancheChain( // create bootstrap gear bootstrapCfg := smbootstrap.Config{ - Config: snowmanCommonCfg, + Config: common.Config{ + Ctx: ctx, + Beacons: vdrs, + SampleK: sampleK, + Alpha: bootstrapWeight/2 + 1, // must be > 50% + StartupTracker: startupTracker, + Sender: snowmanMessageSender, + BootstrapTracker: sb, + Timer: h, + RetryBootstrap: m.RetryBootstrap, + RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, + AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, + SharedCfg: &common.SharedConfig{}, + }, AllGetsServer: snowGetHandler, Blocked: blockBlocker, VM: vmWrappingProposerVM, @@ -906,24 +910,14 @@ func (m *manager) createAvalancheChain( snowmanBootstrapper = common.TraceBootstrapableEngine(snowmanBootstrapper, m.Tracer) } - avalancheCommonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: sampleK, - StartupTracker: startupTracker, - Alpha: bootstrapWeight/2 + 1, // must be > 50% - Sender: avalancheMessageSender, - BootstrapTracker: sb, - Timer: h, - RetryBootstrap: m.RetryBootstrap, - RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, - MaxTimeGetAncestors: m.BootstrapMaxTimeGetAncestors, - AncestorsMaxContainersSent: m.BootstrapAncestorsMaxContainersSent, - AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, - SharedCfg: &common.SharedConfig{}, - } - - avaGetHandler, err := avagetter.New(vtxManager, avalancheCommonCfg) + avaGetHandler, err := avagetter.New( + vtxManager, + avalancheMessageSender, + ctx.Log, + m.BootstrapMaxTimeGetAncestors, + m.BootstrapAncestorsMaxContainersSent, + ctx.AvalancheRegisterer, + ) if err != nil { return nil, fmt.Errorf("couldn't initialize avalanche base message handler: %w", err) } @@ -938,7 +932,20 @@ func (m *manager) createAvalancheChain( _, specifiedLinearizationTime := version.CortinaTimes[ctx.NetworkID] specifiedLinearizationTime = specifiedLinearizationTime && ctx.ChainID == m.XChainID avalancheBootstrapperConfig := avbootstrap.Config{ - Config: avalancheCommonCfg, + Config: common.Config{ + Ctx: ctx, + Beacons: vdrs, + SampleK: sampleK, + StartupTracker: startupTracker, + Alpha: bootstrapWeight/2 + 1, // must be > 50% + Sender: avalancheMessageSender, + BootstrapTracker: sb, + Timer: h, + RetryBootstrap: m.RetryBootstrap, + RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, + AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, + SharedCfg: &common.SharedConfig{}, + }, AllGetsServer: avaGetHandler, VtxBlocked: vtxBlocker, TxBlocked: txBlocker, @@ -1190,24 +1197,14 @@ func (m *manager) createSnowmanChain( startupTracker := tracker.NewStartup(connectedBeacons, (3*bootstrapWeight+3)/4) beacons.RegisterCallbackListener(ctx.SubnetID, startupTracker) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: beacons, - SampleK: sampleK, - StartupTracker: startupTracker, - Alpha: bootstrapWeight/2 + 1, // must be > 50% - Sender: messageSender, - BootstrapTracker: sb, - Timer: h, - RetryBootstrap: m.RetryBootstrap, - RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, - MaxTimeGetAncestors: m.BootstrapMaxTimeGetAncestors, - AncestorsMaxContainersSent: m.BootstrapAncestorsMaxContainersSent, - AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, - SharedCfg: &common.SharedConfig{}, - } - - snowGetHandler, err := snowgetter.New(vm, commonCfg) + snowGetHandler, err := snowgetter.New( + vm, + messageSender, + ctx.Log, + m.BootstrapMaxTimeGetAncestors, + m.BootstrapAncestorsMaxContainersSent, + ctx.Registerer, + ) if err != nil { return nil, fmt.Errorf("couldn't initialize snow base message handler: %w", err) } @@ -1220,14 +1217,14 @@ func (m *manager) createSnowmanChain( // Create engine, bootstrapper and state-syncer in this order, // to make sure start callbacks are duly initialized engineConfig := smeng.Config{ - Ctx: commonCfg.Ctx, + Ctx: ctx, AllGetsServer: snowGetHandler, VM: vm, - Sender: commonCfg.Sender, + Sender: messageSender, Validators: vdrs, Params: consensusParams, Consensus: consensus, - PartialSync: m.PartialSyncPrimaryNetwork && commonCfg.Ctx.ChainID == constants.PlatformChainID, + PartialSync: m.PartialSyncPrimaryNetwork && ctx.ChainID == constants.PlatformChainID, } engine, err := smeng.New(engineConfig) if err != nil { @@ -1238,6 +1235,21 @@ func (m *manager) createSnowmanChain( engine = smeng.TraceEngine(engine, m.Tracer) } + commonCfg := common.Config{ + Ctx: ctx, + Beacons: beacons, + SampleK: sampleK, + StartupTracker: startupTracker, + Alpha: bootstrapWeight/2 + 1, // must be > 50% + Sender: messageSender, + BootstrapTracker: sb, + Timer: h, + RetryBootstrap: m.RetryBootstrap, + RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, + AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, + SharedCfg: &common.SharedConfig{}, + } + // create bootstrap gear bootstrapCfg := smbootstrap.Config{ Config: commonCfg, diff --git a/snow/engine/avalanche/bootstrap/bootstrapper_test.go b/snow/engine/avalanche/bootstrap/bootstrapper_test.go index d5bd51a9f78c..f8a60c36bf46 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper_test.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper_test.go @@ -8,6 +8,7 @@ import ( "context" "errors" "testing" + "time" "github.com/stretchr/testify/require" @@ -102,12 +103,11 @@ func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *vertex.Te Sender: sender, BootstrapTracker: bootstrapTracker, Timer: &common.TimerTest{}, - AncestorsMaxContainersSent: 2000, AncestorsMaxContainersReceived: 2000, SharedCfg: &common.SharedConfig{}, } - avaGetHandler, err := getter.New(manager, commonConfig) + avaGetHandler, err := getter.New(manager, sender, ctx.Log, time.Second, 2000, ctx.AvalancheRegisterer) require.NoError(err) return Config{ diff --git a/snow/engine/avalanche/getter/getter.go b/snow/engine/avalanche/getter/getter.go index ebf6ef38b09f..88f485ab1118 100644 --- a/snow/engine/avalanche/getter/getter.go +++ b/snow/engine/avalanche/getter/getter.go @@ -7,6 +7,8 @@ import ( "context" "time" + "github.com/prometheus/client_golang/prometheus" + "go.uber.org/zap" "github.com/ava-labs/avalanchego/ids" @@ -25,12 +27,20 @@ import ( // Get requests are always served, regardless node state (bootstrapping or normal operations). var _ common.AllGetsServer = (*getter)(nil) -func New(storage vertex.Storage, commonCfg common.Config) (common.AllGetsServer, error) { +func New( + storage vertex.Storage, + sender common.Sender, + log logging.Logger, + maxTimeGetAncestors time.Duration, + maxContainersGetAncestors int, + reg prometheus.Registerer, +) (common.AllGetsServer, error) { gh := &getter{ - storage: storage, - sender: commonCfg.Sender, - cfg: commonCfg, - log: commonCfg.Ctx.Log, + storage: storage, + sender: sender, + log: log, + maxTimeGetAncestors: maxTimeGetAncestors, + maxContainersGetAncestors: maxContainersGetAncestors, } var err error @@ -38,17 +48,18 @@ func New(storage vertex.Storage, commonCfg common.Config) (common.AllGetsServer, "bs", "get_ancestors_vtxs", "vertices fetched in a call to GetAncestors", - commonCfg.Ctx.AvalancheRegisterer, + reg, ) return gh, err } type getter struct { - storage vertex.Storage - sender common.Sender - cfg common.Config + storage vertex.Storage + sender common.Sender + log logging.Logger + maxTimeGetAncestors time.Duration + maxContainersGetAncestors int - log logging.Logger getAncestorsVtxs metric.Averager } @@ -106,13 +117,13 @@ func (gh *getter) GetAncestors(ctx context.Context, nodeID ids.NodeID, requestID return nil // Don't have the requested vertex. Drop message. } - queue := make([]avalanche.Vertex, 1, gh.cfg.AncestorsMaxContainersSent) // for BFS + queue := make([]avalanche.Vertex, 1, gh.maxContainersGetAncestors) // for BFS queue[0] = vertex - ancestorsBytesLen := 0 // length, in bytes, of vertex and its ancestors - ancestorsBytes := make([][]byte, 0, gh.cfg.AncestorsMaxContainersSent) // vertex and its ancestors in BFS order - visited := set.Of(vertex.ID()) // IDs of vertices that have been in queue before + ancestorsBytesLen := 0 // length, in bytes, of vertex and its ancestors + ancestorsBytes := make([][]byte, 0, gh.maxContainersGetAncestors) // vertex and its ancestors in BFS order + visited := set.Of(vertex.ID()) // IDs of vertices that have been in queue before - for len(ancestorsBytes) < gh.cfg.AncestorsMaxContainersSent && len(queue) > 0 && time.Since(startTime) < gh.cfg.MaxTimeGetAncestors { + for len(ancestorsBytes) < gh.maxContainersGetAncestors && len(queue) > 0 && time.Since(startTime) < gh.maxTimeGetAncestors { var vtx avalanche.Vertex vtx, queue = queue[0], queue[1:] // pop vtxBytes := vtx.Bytes() diff --git a/snow/engine/avalanche/getter/getter_test.go b/snow/engine/avalanche/getter/getter_test.go index 93694ed5bba0..a7e679d43520 100644 --- a/snow/engine/avalanche/getter/getter_test.go +++ b/snow/engine/avalanche/getter/getter_test.go @@ -7,75 +7,49 @@ import ( "context" "errors" "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/avalanche" "github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex" "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" ) var errUnknownVertex = errors.New("unknown vertex") -func testSetup(t *testing.T) (*vertex.TestManager, *common.SenderTest, common.Config) { - vdrs := validators.NewManager() - peer := ids.GenerateTestNodeID() - require.NoError(t, vdrs.AddStaker(constants.PrimaryNetworkID, peer, nil, ids.Empty, 1)) - - sender := &common.SenderTest{T: t} - sender.Default(true) - sender.CantSendGetAcceptedFrontier = false +func newTest(t *testing.T) (common.AllGetsServer, *vertex.TestManager, *common.SenderTest) { + manager := vertex.NewTestManager(t) + manager.Default(true) - isBootstrapped := false - bootstrapTracker := &common.BootstrapTrackerTest{ + sender := &common.SenderTest{ T: t, - IsBootstrappedF: func() bool { - return isBootstrapped - }, - BootstrappedF: func(ids.ID) { - isBootstrapped = true - }, } + sender.Default(true) - totalWeight, err := vdrs.TotalWeight(constants.PrimaryNetworkID) + bs, err := New( + manager, + sender, + logging.NoLog{}, + time.Second, + 2000, + prometheus.NewRegistry(), + ) require.NoError(t, err) - commonConfig := common.Config{ - Ctx: snow.DefaultConsensusContextTest(), - Beacons: vdrs, - SampleK: vdrs.Count(constants.PrimaryNetworkID), - Alpha: totalWeight/2 + 1, - Sender: sender, - BootstrapTracker: bootstrapTracker, - Timer: &common.TimerTest{}, - AncestorsMaxContainersSent: 2000, - AncestorsMaxContainersReceived: 2000, - SharedCfg: &common.SharedConfig{}, - } - - manager := vertex.NewTestManager(t) - manager.Default(true) - - return manager, sender, commonConfig + return bs, manager, sender } func TestAcceptedFrontier(t *testing.T) { require := require.New(t) - - manager, sender, config := testSetup(t) + bs, manager, sender := newTest(t) vtxID := ids.GenerateTestID() - - bsIntf, err := New(manager, config) - require.NoError(err) - require.IsType(&getter{}, bsIntf) - bs := bsIntf.(*getter) - manager.EdgeF = func(context.Context) []ids.ID { return []ids.ID{ vtxID, @@ -92,8 +66,7 @@ func TestAcceptedFrontier(t *testing.T) { func TestFilterAccepted(t *testing.T) { require := require.New(t) - - manager, sender, config := testSetup(t) + bs, manager, sender := newTest(t) vtxID0 := ids.GenerateTestID() vtxID1 := ids.GenerateTestID() @@ -108,13 +81,6 @@ func TestFilterAccepted(t *testing.T) { StatusV: choices.Accepted, }} - bsIntf, err := New(manager, config) - require.NoError(err) - require.IsType(&getter{}, bsIntf) - bs := bsIntf.(*getter) - - vtxIDs := []ids.ID{vtxID0, vtxID1, vtxID2} - manager.GetVtxF = func(_ context.Context, vtxID ids.ID) (avalanche.Vertex, error) { switch vtxID { case vtxID0: @@ -133,6 +99,7 @@ func TestFilterAccepted(t *testing.T) { accepted = frontier } + vtxIDs := []ids.ID{vtxID0, vtxID1, vtxID2} require.NoError(bs.GetAccepted(context.Background(), ids.EmptyNodeID, 0, vtxIDs)) require.Contains(accepted, vtxID0) diff --git a/snow/engine/common/config.go b/snow/engine/common/config.go index 05eb3602f876..52d2287b37d6 100644 --- a/snow/engine/common/config.go +++ b/snow/engine/common/config.go @@ -4,8 +4,6 @@ package common import ( - "time" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/validators" @@ -31,13 +29,6 @@ type Config struct { // Max number of times to retry bootstrap before warning the node operator RetryBootstrapWarnFrequency int - // Max time to spend fetching a container and its ancestors when responding - // to a GetAncestors - MaxTimeGetAncestors time.Duration - - // Max number of containers in an ancestors message sent by this node. - AncestorsMaxContainersSent int - // This node will only consider the first [AncestorsMaxContainersReceived] // containers in an ancestors message it receives. AncestorsMaxContainersReceived int diff --git a/snow/engine/common/test_config.go b/snow/engine/common/test_config.go index d39e6078fd01..c8cfa7fc76fd 100644 --- a/snow/engine/common/test_config.go +++ b/snow/engine/common/test_config.go @@ -37,7 +37,6 @@ func DefaultConfigTest() Config { Bootstrapable: &BootstrapableTest{}, BootstrapTracker: bootstrapTracker, Timer: &TimerTest{}, - AncestorsMaxContainersSent: 2000, AncestorsMaxContainersReceived: 2000, SharedCfg: &SharedConfig{}, } diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index 81f04d44ba01..9dc53342c844 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -8,6 +8,7 @@ import ( "context" "errors" "testing" + "time" "github.com/prometheus/client_golang/prometheus" @@ -83,12 +84,11 @@ func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *block.Tes Sender: sender, BootstrapTracker: bootstrapTracker, Timer: &common.TimerTest{}, - AncestorsMaxContainersSent: 2000, AncestorsMaxContainersReceived: 2000, SharedCfg: &common.SharedConfig{}, } - snowGetHandler, err := getter.New(vm, commonConfig) + snowGetHandler, err := getter.New(vm, sender, ctx.Log, time.Second, 2000, ctx.Registerer) require.NoError(err) blocker, _ := queue.NewWithMissing(memdb.New(), "", prometheus.NewRegistry()) @@ -130,13 +130,12 @@ func TestBootstrapperStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { Sender: sender, BootstrapTracker: &common.BootstrapTrackerTest{}, Timer: &common.TimerTest{}, - AncestorsMaxContainersSent: 2000, AncestorsMaxContainersReceived: 2000, SharedCfg: &common.SharedConfig{}, } blocker, _ := queue.NewWithMissing(memdb.New(), "", prometheus.NewRegistry()) - snowGetHandler, err := getter.New(vm, commonCfg) + snowGetHandler, err := getter.New(vm, sender, ctx.Log, time.Second, 2000, ctx.Registerer) require.NoError(err) cfg := Config{ Config: commonCfg, @@ -1368,12 +1367,11 @@ func TestBootstrapNoParseOnNew(t *testing.T) { Sender: sender, BootstrapTracker: bootstrapTracker, Timer: &common.TimerTest{}, - AncestorsMaxContainersSent: 2000, AncestorsMaxContainersReceived: 2000, SharedCfg: &common.SharedConfig{}, } - snowGetHandler, err := getter.New(vm, commonConfig) + snowGetHandler, err := getter.New(vm, sender, ctx.Log, time.Second, 2000, ctx.Registerer) require.NoError(err) queueDB := memdb.New() diff --git a/snow/engine/snowman/getter/getter.go b/snow/engine/snowman/getter/getter.go index a8cb405d57ce..a582b8af4ef2 100644 --- a/snow/engine/snowman/getter/getter.go +++ b/snow/engine/snowman/getter/getter.go @@ -5,6 +5,9 @@ package getter import ( "context" + "time" + + "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" @@ -22,15 +25,20 @@ var _ common.AllGetsServer = (*getter)(nil) func New( vm block.ChainVM, - commonCfg common.Config, + sender common.Sender, + log logging.Logger, + maxTimeGetAncestors time.Duration, + maxContainersGetAncestors int, + reg prometheus.Registerer, ) (common.AllGetsServer, error) { ssVM, _ := vm.(block.StateSyncableVM) gh := &getter{ - vm: vm, - ssVM: ssVM, - sender: commonCfg.Sender, - cfg: commonCfg, - log: commonCfg.Ctx.Log, + vm: vm, + ssVM: ssVM, + sender: sender, + log: log, + maxTimeGetAncestors: maxTimeGetAncestors, + maxContainersGetAncestors: maxContainersGetAncestors, } var err error @@ -38,18 +46,23 @@ func New( "bs", "get_ancestors_blks", "blocks fetched in a call to GetAncestors", - commonCfg.Ctx.Registerer, + reg, ) return gh, err } type getter struct { - vm block.ChainVM - ssVM block.StateSyncableVM // can be nil + vm block.ChainVM + ssVM block.StateSyncableVM // can be nil + sender common.Sender - cfg common.Config + log logging.Logger + // Max time to spend fetching a container and its ancestors when responding + // to a GetAncestors + maxTimeGetAncestors time.Duration + // Max number of containers in an ancestors message sent by this node. + maxContainersGetAncestors int - log logging.Logger getAncestorsBlks metric.Averager } @@ -153,9 +166,9 @@ func (gh *getter) GetAncestors(ctx context.Context, nodeID ids.NodeID, requestID gh.log, gh.vm, blkID, - gh.cfg.AncestorsMaxContainersSent, + gh.maxContainersGetAncestors, constants.MaxContainersLen, - gh.cfg.MaxTimeGetAncestors, + gh.maxTimeGetAncestors, ) if err != nil { gh.log.Verbo("dropping GetAncestors message", diff --git a/snow/engine/snowman/getter/getter_test.go b/snow/engine/snowman/getter/getter_test.go index 35a0e11f9ebb..38dc74a2091b 100644 --- a/snow/engine/snowman/getter/getter_test.go +++ b/snow/engine/snowman/getter/getter_test.go @@ -7,19 +7,21 @@ import ( "context" "errors" "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" - "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/logging" ) var errUnknownBlock = errors.New("unknown block") @@ -29,86 +31,40 @@ type StateSyncEnabledMock struct { *mocks.MockStateSyncableVM } -func testSetup( - t *testing.T, - ctrl *gomock.Controller, -) (StateSyncEnabledMock, *common.SenderTest, common.Config) { - ctx := snow.DefaultConsensusContextTest() +func newTest(t *testing.T) (common.AllGetsServer, StateSyncEnabledMock, *common.SenderTest) { + ctrl := gomock.NewController(t) - peers := validators.NewManager() - sender := &common.SenderTest{} vm := StateSyncEnabledMock{ TestVM: &block.TestVM{}, MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), } - sender.T = t - - sender.Default(true) - - isBootstrapped := false - bootstrapTracker := &common.BootstrapTrackerTest{ + sender := &common.SenderTest{ T: t, - IsBootstrappedF: func() bool { - return isBootstrapped - }, - BootstrappedF: func(ids.ID) { - isBootstrapped = true - }, } + sender.Default(true) - sender.CantSendGetAcceptedFrontier = false - - peer := ids.GenerateTestNodeID() - require.NoError(t, peers.AddStaker(ctx.SubnetID, peer, nil, ids.Empty, 1)) - totalWeight, err := peers.TotalWeight(ctx.SubnetID) + bs, err := New( + vm, + sender, + logging.NoLog{}, + time.Second, + 2000, + prometheus.NewRegistry(), + ) require.NoError(t, err) - commonConfig := common.Config{ - Ctx: ctx, - Beacons: peers, - SampleK: peers.Count(ctx.SubnetID), - Alpha: totalWeight/2 + 1, - Sender: sender, - BootstrapTracker: bootstrapTracker, - Timer: &common.TimerTest{}, - AncestorsMaxContainersSent: 2000, - AncestorsMaxContainersReceived: 2000, - SharedCfg: &common.SharedConfig{}, - } - - return vm, sender, commonConfig + return bs, vm, sender } func TestAcceptedFrontier(t *testing.T) { require := require.New(t) - ctrl := gomock.NewController(t) - - vm, sender, config := testSetup(t, ctrl) + bs, vm, sender := newTest(t) blkID := ids.GenerateTestID() - - dummyBlk := &snowman.TestBlock{ - TestDecidable: choices.TestDecidable{ - IDV: blkID, - StatusV: choices.Accepted, - }, - HeightV: 0, - BytesV: []byte{1, 2, 3}, - } - vm.CantLastAccepted = false vm.LastAcceptedF = func(context.Context) (ids.ID, error) { return blkID, nil } - vm.GetBlockF = func(_ context.Context, bID ids.ID) (snowman.Block, error) { - require.Equal(blkID, bID) - return dummyBlk, nil - } - - bsIntf, err := New(vm, config) - require.NoError(err) - require.IsType(&getter{}, bsIntf) - bs := bsIntf.(*getter) var accepted ids.ID sender.SendAcceptedFrontierF = func(_ context.Context, _ ids.NodeID, _ uint32, containerID ids.ID) { @@ -121,9 +77,7 @@ func TestAcceptedFrontier(t *testing.T) { func TestFilterAccepted(t *testing.T) { require := require.New(t) - ctrl := gomock.NewController(t) - - vm, sender, config := testSetup(t, ctrl) + bs, vm, sender := newTest(t) blkID0 := ids.GenerateTestID() blkID1 := ids.GenerateTestID() @@ -138,21 +92,6 @@ func TestFilterAccepted(t *testing.T) { StatusV: choices.Accepted, }} - vm.CantLastAccepted = false - vm.LastAcceptedF = func(context.Context) (ids.ID, error) { - return blk1.ID(), nil - } - vm.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { - require.Equal(blk1.ID(), blkID) - return blk1, nil - } - - bsIntf, err := New(vm, config) - require.NoError(err) - require.IsType(&getter{}, bsIntf) - bs := bsIntf.(*getter) - - blkIDs := []ids.ID{blkID0, blkID1, blkID2} vm.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case blkID0: @@ -171,6 +110,7 @@ func TestFilterAccepted(t *testing.T) { accepted = frontier } + blkIDs := []ids.ID{blkID0, blkID1, blkID2} require.NoError(bs.GetAccepted(context.Background(), ids.EmptyNodeID, 0, blkIDs)) require.Len(accepted, 2) diff --git a/snow/engine/snowman/syncer/state_syncer_test.go b/snow/engine/snowman/syncer/state_syncer_test.go index 47a00e744471..ae630bf4dd52 100644 --- a/snow/engine/snowman/syncer/state_syncer_test.go +++ b/snow/engine/snowman/syncer/state_syncer_test.go @@ -9,6 +9,9 @@ import ( "errors" "math" "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -19,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/getter" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" @@ -45,7 +49,14 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { nonStateSyncableVM := &block.TestVM{ TestVM: common.TestVM{T: t}, } - dummyGetter, err := getter.New(nonStateSyncableVM, *commonCfg) + dummyGetter, err := getter.New( + nonStateSyncableVM, + sender, + logging.NoLog{}, + time.Second, + 2000, + prometheus.NewRegistry(), + ) require.NoError(err) cfg, err := NewConfig(*commonCfg, nil, dummyGetter, nonStateSyncableVM) @@ -59,8 +70,6 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { require.False(enabled) // State syncableVM case - commonCfg.Ctx = snow.DefaultConsensusContextTest() // reset metrics - fullVM := &fullVM{ TestVM: &block.TestVM{ TestVM: common.TestVM{T: t}, @@ -69,7 +78,13 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { T: t, }, } - dummyGetter, err = getter.New(fullVM, *commonCfg) + dummyGetter, err = getter.New( + fullVM, + sender, + logging.NoLog{}, + time.Second, + 2000, + prometheus.NewRegistry()) require.NoError(err) cfg, err = NewConfig(*commonCfg, nil, dummyGetter, fullVM) diff --git a/snow/engine/snowman/syncer/utils_test.go b/snow/engine/snowman/syncer/utils_test.go index f83a3006aaa1..b9a31fbc18bc 100644 --- a/snow/engine/snowman/syncer/utils_test.go +++ b/snow/engine/snowman/syncer/utils_test.go @@ -6,6 +6,7 @@ package syncer import ( "context" "testing" + "time" "github.com/stretchr/testify/require" @@ -83,7 +84,14 @@ func buildTestsObjects(t *testing.T, commonCfg *common.Config) ( T: t, }, } - dummyGetter, err := getter.New(fullVM, *commonCfg) + dummyGetter, err := getter.New( + fullVM, + commonCfg.Sender, + commonCfg.Ctx.Log, + time.Second, + 2000, + commonCfg.Ctx.Registerer, + ) require.NoError(err) cfg, err := NewConfig(*commonCfg, nil, dummyGetter, fullVM) diff --git a/snow/engine/snowman/transitive_test.go b/snow/engine/snowman/transitive_test.go index 8993a4e90f9b..96cb2d72ba76 100644 --- a/snow/engine/snowman/transitive_test.go +++ b/snow/engine/snowman/transitive_test.go @@ -8,6 +8,7 @@ import ( "context" "errors" "testing" + "time" "github.com/stretchr/testify/require" @@ -50,7 +51,14 @@ func setup(t *testing.T, commonCfg common.Config, engCfg Config) (ids.NodeID, va vm.T = t engCfg.VM = vm - snowGetHandler, err := getter.New(vm, commonCfg) + snowGetHandler, err := getter.New( + vm, + sender, + commonCfg.Ctx.Log, + time.Second, + 2000, + commonCfg.Ctx.Registerer, + ) require.NoError(err) engCfg.AllGetsServer = snowGetHandler diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index d4dcb20b4264..bb9db0cef379 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1482,7 +1482,16 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { beacons.RegisterCallbackListener(ctx.SubnetID, startup) // The engine handles consensus - consensus := &smcon.Topological{} + snowGetHandler, err := snowgetter.New( + vm, + sender, + consensusCtx.Log, + time.Second, + 2000, + consensusCtx.Registerer, + ) + require.NoError(err) + commonCfg := common.Config{ Ctx: consensusCtx, Beacons: beacons, @@ -1491,14 +1500,10 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { Alpha: (totalWeight + 1) / 2, Sender: sender, BootstrapTracker: bootstrapTracker, - AncestorsMaxContainersSent: 2000, AncestorsMaxContainersReceived: 2000, SharedCfg: &common.SharedConfig{}, } - snowGetHandler, err := snowgetter.New(vm, commonCfg) - require.NoError(err) - bootstrapConfig := bootstrap.Config{ Config: commonCfg, AllGetsServer: snowGetHandler, @@ -1545,7 +1550,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { MaxOutstandingItems: 1, MaxItemProcessingTime: 1, }, - Consensus: consensus, + Consensus: &smcon.Topological{}, } engine, err := smeng.New(engineConfig) require.NoError(err) diff --git a/x/merkledb/db_test.go b/x/merkledb/db_test.go index 828a72bef7db..1cbce5a7792d 100644 --- a/x/merkledb/db_test.go +++ b/x/merkledb/db_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/require" "golang.org/x/exp/maps" From eb21b422cc75bb99340a2294bab03f8c307685b2 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:24:01 -0800 Subject: [PATCH 031/267] Move management of platformvm preferred block to `executor.Manager` (#2292) --- vms/platformvm/block/builder/builder.go | 35 +++----------- vms/platformvm/block/builder/builder_test.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/executor/manager.go | 20 +++++++- vms/platformvm/block/executor/mock_manager.go | 28 +++++++++++ vms/platformvm/service.go | 14 ++---- vms/platformvm/service_test.go | 3 +- vms/platformvm/vm.go | 4 +- vms/platformvm/vm_regression_test.go | 23 ++++----- vms/platformvm/vm_test.go | 48 +++++++++---------- 10 files changed, 97 insertions(+), 82 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 734762215395..8b41881edca6 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -44,12 +44,6 @@ type Builder interface { mempool.BlockTimer Network - // set preferred block on top of which we'll build next - SetPreference(blockID ids.ID) - - // get preferred block on top of which we'll build next - Preferred() (snowman.Block, error) - // AddUnverifiedTx verifier the tx before adding it to mempool AddUnverifiedTx(tx *txs.Tx) error @@ -70,9 +64,6 @@ type builder struct { txExecutorBackend *txexecutor.Backend blkManager blockexecutor.Manager - // ID of the preferred block to build on top of - preferredBlockID ids.ID - // channel to send messages to the consensus engine toEngine chan<- common.Message @@ -110,19 +101,6 @@ func New( return builder } -func (b *builder) SetPreference(blockID ids.ID) { - if blockID == b.preferredBlockID { - // If the preference didn't change, then this is a noop - return - } - b.preferredBlockID = blockID - b.ResetBlockTimer() -} - -func (b *builder) Preferred() (snowman.Block, error) { - return b.blkManager.GetBlock(b.preferredBlockID) -} - // AddUnverifiedTx verifies a transaction and attempts to add it to the mempool func (b *builder) AddUnverifiedTx(tx *txs.Tx) error { if !b.txExecutorBackend.Bootstrapped.Get() { @@ -138,7 +116,7 @@ func (b *builder) AddUnverifiedTx(tx *txs.Tx) error { verifier := txexecutor.MempoolTxVerifier{ Backend: b.txExecutorBackend, - ParentID: b.preferredBlockID, // We want to build off of the preferred block + ParentID: b.blkManager.Preferred(), // We want to build off of the preferred block StateVersions: b.blkManager, Tx: tx, } @@ -186,11 +164,11 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { // Only modifies state to remove expired proposal txs. func (b *builder) buildBlock() (block.Block, error) { // Get the block to build on top of and retrieve the new block's context. - preferred, err := b.Preferred() + preferredID := b.blkManager.Preferred() + preferred, err := b.blkManager.GetBlock(preferredID) if err != nil { return nil, err } - preferredID := preferred.ID() nextHeight := preferred.Height() + 1 preferredState, ok := b.blkManager.GetState(preferredID) if !ok { @@ -266,11 +244,12 @@ func (b *builder) setNextBuildBlockTime() { } // Wake up when it's time to add/remove the next validator/delegator - preferredState, ok := b.blkManager.GetState(b.preferredBlockID) + preferredID := b.blkManager.Preferred() + preferredState, ok := b.blkManager.GetState(preferredID) if !ok { // The preferred block should always be a decision block ctx.Log.Error("couldn't get preferred block state", - zap.Stringer("preferredID", b.preferredBlockID), + zap.Stringer("preferredID", preferredID), zap.Stringer("lastAcceptedID", b.blkManager.LastAccepted()), ) return @@ -279,7 +258,7 @@ func (b *builder) setNextBuildBlockTime() { nextStakerChangeTime, err := txexecutor.GetNextStakerChangeTime(preferredState) if err != nil { ctx.Log.Error("couldn't get next staker change time", - zap.Stringer("preferredID", b.preferredBlockID), + zap.Stringer("preferredID", preferredID), zap.Stringer("lastAcceptedID", b.blkManager.LastAccepted()), zap.Error(err), ) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index d945c3555c12..f34faa70e318 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -110,7 +110,7 @@ func TestNoErrorOnUnexpectedSetPreferenceDuringBootstrapping(t *testing.T) { require.NoError(t, shutdownEnvironment(env)) }() - env.Builder.SetPreference(ids.GenerateTestID()) // should not panic + require.False(t, env.blkManager.SetPreference(ids.GenerateTestID())) // should not panic } func TestGetNextStakerToReward(t *testing.T) { diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 8da4c45b4639..acd7d872e9ac 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -177,7 +177,7 @@ func newEnvironment(t *testing.T) *environment { res.sender, ) - res.Builder.SetPreference(genesisID) + res.blkManager.SetPreference(genesisID) addSubnet(t, res) return res diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index ea3609349b74..1472e2f40b3d 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -21,6 +21,10 @@ type Manager interface { // Returns the ID of the most recently accepted block. LastAccepted() ids.ID + + SetPreference(blkID ids.ID) (updated bool) + Preferred() ids.ID + GetBlock(blkID ids.ID) (snowman.Block, error) GetStatelessBlock(blkID ids.ID) (block.Block, error) NewBlock(block.Block) snowman.Block @@ -33,9 +37,10 @@ func NewManager( txExecutorBackend *executor.Backend, validatorManager validators.Manager, ) Manager { + lastAccepted := s.GetLastAccepted() backend := &backend{ Mempool: mempool, - lastAccepted: s.GetLastAccepted(), + lastAccepted: lastAccepted, state: s, ctx: txExecutorBackend.Ctx, blkIDToState: map[ids.ID]*blockState{}, @@ -57,6 +62,7 @@ func NewManager( backend: backend, addTxsToMempool: !txExecutorBackend.Config.PartialSyncPrimaryNetwork, }, + preferred: lastAccepted, } } @@ -65,6 +71,8 @@ type manager struct { verifier block.Visitor acceptor block.Visitor rejector block.Visitor + + preferred ids.ID } func (m *manager) GetBlock(blkID ids.ID) (snowman.Block, error) { @@ -85,3 +93,13 @@ func (m *manager) NewBlock(blk block.Block) snowman.Block { Block: blk, } } + +func (m *manager) SetPreference(blockID ids.ID) (updated bool) { + updated = m.preferred == blockID + m.preferred = blockID + return updated +} + +func (m *manager) Preferred() ids.ID { + return m.preferred +} diff --git a/vms/platformvm/block/executor/mock_manager.go b/vms/platformvm/block/executor/mock_manager.go index 07f163fad635..8755325a0fdc 100644 --- a/vms/platformvm/block/executor/mock_manager.go +++ b/vms/platformvm/block/executor/mock_manager.go @@ -112,3 +112,31 @@ func (mr *MockManagerMockRecorder) NewBlock(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBlock", reflect.TypeOf((*MockManager)(nil).NewBlock), arg0) } + +// Preferred mocks base method. +func (m *MockManager) Preferred() ids.ID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Preferred") + ret0, _ := ret[0].(ids.ID) + return ret0 +} + +// Preferred indicates an expected call of Preferred. +func (mr *MockManagerMockRecorder) Preferred() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Preferred", reflect.TypeOf((*MockManager)(nil).Preferred)) +} + +// SetPreference mocks base method. +func (m *MockManager) SetPreference(arg0 ids.ID) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetPreference", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// SetPreference indicates an expected call of SetPreference. +func (mr *MockManagerMockRecorder) SetPreference(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockManager)(nil).SetPreference), arg0) +} diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 7619ee01d250..a9c8a039d753 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -1943,11 +1943,8 @@ func (s *Service) GetBlockchainStatus(r *http.Request, args *GetBlockchainStatus return nil } - preferredBlk, err := s.vm.Preferred() - if err != nil { - return fmt.Errorf("could not retrieve preferred block, err %w", err) - } - preferred, err := s.chainExists(ctx, preferredBlk.ID(), blockchainID) + preferredBlkID := s.vm.manager.Preferred() + preferred, err := s.chainExists(ctx, preferredBlkID, blockchainID) if err != nil { return fmt.Errorf("problem looking up blockchain: %w", err) } @@ -2246,12 +2243,7 @@ func (s *Service) GetTxStatus(_ *http.Request, args *GetTxStatusArgs, response * // The status of this transaction is not in the database - check if the tx // is in the preferred block's db. If so, return that it's processing. - prefBlk, err := s.vm.Preferred() - if err != nil { - return err - } - - preferredID := prefBlk.ID() + preferredID := s.vm.manager.Preferred() onAccept, ok := s.vm.manager.GetState(preferredID) if !ok { return fmt.Errorf("could not retrieve state for block %s", preferredID) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index b3eebf31659d..692b7afdb405 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -784,7 +784,8 @@ func TestGetBlock(t *testing.T) { ) require.NoError(err) - preferred, err := service.vm.Builder.Preferred() + preferredID := service.vm.manager.Preferred() + preferred, err := service.vm.manager.GetBlock(preferredID) require.NoError(err) statelessBlock, err := block.NewBanffStandardBlock( diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 72201c16e42f..4d4b382534df 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -393,7 +393,9 @@ func (vm *VM) LastAccepted(context.Context) (ids.ID, error) { // SetPreference sets the preferred block to be the one with ID [blkID] func (vm *VM) SetPreference(_ context.Context, blkID ids.ID) error { - vm.Builder.SetPreference(blkID) + if vm.manager.SetPreference(blkID) { + vm.Builder.ResetBlockTimer() + } return nil } diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index e94a0ea99406..ca8735e18e3e 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -410,11 +410,10 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { ) require.NoError(err) - preferred, err := vm.Builder.Preferred() + preferredID := vm.manager.Preferred() + preferred, err := vm.manager.GetBlock(preferredID) require.NoError(err) - preferredChainTime := preferred.Timestamp() - preferredID := preferred.ID() preferredHeight := preferred.Height() statelessStandardBlk, err := block.NewBanffStandardBlock( @@ -493,11 +492,10 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { require.NoError(err) // Create the standard block to add the new validator - preferred, err := vm.Builder.Preferred() + preferredID := vm.manager.Preferred() + preferred, err := vm.manager.GetBlock(preferredID) require.NoError(err) - preferredChainTime := preferred.Timestamp() - preferredID := preferred.ID() preferredHeight := preferred.Height() statelessBlk, err := block.NewBanffStandardBlock( @@ -706,11 +704,10 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { require.NoError(err) // Create the standard block to add the first new validator - preferred, err := vm.Builder.Preferred() + preferredID := vm.manager.Preferred() + preferred, err := vm.manager.GetBlock(preferredID) require.NoError(err) - preferredChainTime := preferred.Timestamp() - preferredID := preferred.ID() preferredHeight := preferred.Height() statelessAddValidatorStandardBlk0, err := block.NewBanffStandardBlock( @@ -1044,11 +1041,10 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { require.NoError(err) // Create the standard block to add the first new validator - preferred, err := vm.Builder.Preferred() + preferredID := vm.manager.Preferred() + preferred, err := vm.manager.GetBlock(preferredID) require.NoError(err) - preferredChainTime := preferred.Timestamp() - preferredID := preferred.ID() preferredHeight := preferred.Height() statelessStandardBlk, err := block.NewBanffStandardBlock( @@ -1081,7 +1077,8 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { // Create the standard block that moves the first new validator from the // pending validator set into the current validator set. - preferred, err = vm.Builder.Preferred() + preferredID = vm.manager.Preferred() + preferred, err = vm.manager.GetBlock(preferredID) require.NoError(err) preferredID = preferred.ID() preferredHeight = preferred.Height() diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index bb9db0cef379..e9478e293099 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -505,11 +505,11 @@ func TestInvalidAddValidatorCommit(t *testing.T) { ) require.NoError(err) - preferred, err := vm.Builder.Preferred() + preferredID := vm.manager.Preferred() + preferred, err := vm.manager.GetBlock(preferredID) require.NoError(err) - - preferredID := preferred.ID() preferredHeight := preferred.Height() + statelessBlk, err := block.NewBanffStandardBlock( preferred.Timestamp(), preferredID, @@ -1136,10 +1136,9 @@ func TestOptimisticAtomicImport(t *testing.T) { }} require.NoError(tx.Initialize(txs.Codec)) - preferred, err := vm.Builder.Preferred() + preferredID := vm.manager.Preferred() + preferred, err := vm.manager.GetBlock(preferredID) require.NoError(err) - - preferredID := preferred.ID() preferredHeight := preferred.Height() statelessBlk, err := block.NewApricotAtomicBlock( @@ -1215,13 +1214,6 @@ func TestRestartFullyAccepted(t *testing.T) { genesisID, err := firstVM.LastAccepted(context.Background()) require.NoError(err) - nextChainTime := initialClkTime.Add(time.Second) - firstVM.clock.Set(initialClkTime) - preferred, err := firstVM.Builder.Preferred() - require.NoError(err) - preferredID := preferred.ID() - preferredHeight := preferred.Height() - // include a tx to make the block be accepted tx := &txs.Tx{Unsigned: &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ @@ -1242,6 +1234,14 @@ func TestRestartFullyAccepted(t *testing.T) { }} require.NoError(tx.Initialize(txs.Codec)) + nextChainTime := initialClkTime.Add(time.Second) + firstVM.clock.Set(initialClkTime) + + preferredID := firstVM.manager.Preferred() + preferred, err := firstVM.manager.GetBlock(preferredID) + require.NoError(err) + preferredHeight := preferred.Height() + statelessBlk, err := block.NewBanffStandardBlock( nextChainTime, preferredID, @@ -1348,9 +1348,6 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { nil, )) - preferred, err := vm.Builder.Preferred() - require.NoError(err) - // include a tx to make the block be accepted tx := &txs.Tx{Unsigned: &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ @@ -1372,8 +1369,12 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { require.NoError(tx.Initialize(txs.Codec)) nextChainTime := initialClkTime.Add(time.Second) - preferredID := preferred.ID() + + preferredID := vm.manager.Preferred() + preferred, err := vm.manager.GetBlock(preferredID) + require.NoError(err) preferredHeight := preferred.Height() + statelessBlk, err := block.NewBanffStandardBlock( nextChainTime, preferredID, @@ -1621,11 +1622,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { externalSender.CantSend = false require.NoError(bootstrapper.Ancestors(context.Background(), peerID, reqID, [][]byte{advanceTimeBlkBytes})) - - preferred, err = vm.Builder.Preferred() - require.NoError(err) - - require.Equal(advanceTimeBlk.ID(), preferred.ID()) + require.Equal(advanceTimeBlk.ID(), vm.manager.Preferred()) ctx.Lock.Unlock() chainRouter.Shutdown(context.Background()) @@ -1687,10 +1684,11 @@ func TestUnverifiedParent(t *testing.T) { }} require.NoError(tx1.Initialize(txs.Codec)) - preferred, err := vm.Builder.Preferred() - require.NoError(err) nextChainTime := initialClkTime.Add(time.Second) - preferredID := preferred.ID() + + preferredID := vm.manager.Preferred() + preferred, err := vm.manager.GetBlock(preferredID) + require.NoError(err) preferredHeight := preferred.Height() statelessBlk, err := block.NewBanffStandardBlock( From 72d2fae887ba9205502a8061dfddcf9f076fa972 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 14 Nov 2023 10:26:39 -0800 Subject: [PATCH 032/267] Add `recentTxsLock` to platform `network` struct (#2294) --- vms/avm/network/network.go | 2 -- vms/platformvm/block/builder/builder.go | 2 +- vms/platformvm/block/builder/network.go | 45 ++++++++++++++++++------- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index 1c3e7e5558ae..a1d3337ddb23 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -180,8 +180,6 @@ func (n *network) issueTx(tx *txs.Tx) error { } func (n *network) gossipTx(ctx context.Context, txID ids.ID, msgBytes []byte) { - // This lock is just to ensure there isn't racy behavior between checking if - // the tx was gossiped and marking the tx as gossiped. n.recentTxsLock.Lock() _, has := n.recentTxs.Get(txID) n.recentTxs.Put(txID, struct{}{}) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 8b41881edca6..aecc4c358f10 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -132,7 +132,7 @@ func (b *builder) AddUnverifiedTx(tx *txs.Tx) error { return err } } - return b.GossipTx(tx) + return b.GossipTx(context.TODO(), tx) } // BuildBlock builds a block to be added to consensus. diff --git a/vms/platformvm/block/builder/network.go b/vms/platformvm/block/builder/network.go index da5e122d38f4..d263561bfe74 100644 --- a/vms/platformvm/block/builder/network.go +++ b/vms/platformvm/block/builder/network.go @@ -7,7 +7,7 @@ package builder import ( "context" - "fmt" + "sync" "go.uber.org/zap" @@ -29,7 +29,7 @@ type Network interface { common.AppHandler // GossipTx gossips the transaction to some of the connected peers - GossipTx(tx *txs.Tx) error + GossipTx(ctx context.Context, tx *txs.Tx) error } type network struct { @@ -38,10 +38,11 @@ type network struct { ctx *snow.Context blkBuilder *builder + appSender common.AppSender // gossip related attributes - appSender common.AppSender - recentTxs *cache.LRU[ids.ID, struct{}] + recentTxsLock sync.Mutex + recentTxs *cache.LRU[ids.ID, struct{}] } func NewNetwork( @@ -120,22 +121,40 @@ func (n *network) AppGossip(_ context.Context, nodeID ids.NodeID, msgBytes []byt return nil } -func (n *network) GossipTx(tx *txs.Tx) error { +func (n *network) GossipTx(ctx context.Context, tx *txs.Tx) error { + txBytes := tx.Bytes() + msg := &message.Tx{ + Tx: txBytes, + } + msgBytes, err := message.Build(msg) + if err != nil { + return err + } + txID := tx.ID() + n.gossipTx(ctx, txID, msgBytes) + return nil +} + +func (n *network) gossipTx(ctx context.Context, txID ids.ID, msgBytes []byte) { + n.recentTxsLock.Lock() + _, has := n.recentTxs.Get(txID) + n.recentTxs.Put(txID, struct{}{}) + n.recentTxsLock.Unlock() + // Don't gossip a transaction if it has been recently gossiped. - if _, has := n.recentTxs.Get(txID); has { - return nil + if has { + return } - n.recentTxs.Put(txID, struct{}{}) n.ctx.Log.Debug("gossiping tx", zap.Stringer("txID", txID), ) - msg := &message.Tx{Tx: tx.Bytes()} - msgBytes, err := message.Build(msg) - if err != nil { - return fmt.Errorf("GossipTx: failed to build Tx message: %w", err) + if err := n.appSender.SendAppGossip(ctx, msgBytes); err != nil { + n.ctx.Log.Error("failed to gossip tx", + zap.Stringer("txID", txID), + zap.Error(err), + ) } - return n.appSender.SendAppGossip(context.TODO(), msgBytes) } From 29f86e96beb400f08966a8ec4f998dced96979e6 Mon Sep 17 00:00:00 2001 From: marun Date: Tue, 14 Nov 2023 21:25:25 +0100 Subject: [PATCH 033/267] e2e: More fixture refinement in support of coreth integration testing (#2275) --- tests/e2e/ignore.go | 13 +++++++++++++ tests/fixture/e2e/helpers.go | 21 +++++++++++++++++++-- tests/fixture/testnet/local/network.go | 14 +++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 tests/e2e/ignore.go diff --git a/tests/e2e/ignore.go b/tests/e2e/ignore.go new file mode 100644 index 000000000000..50332a1ac80e --- /dev/null +++ b/tests/e2e/ignore.go @@ -0,0 +1,13 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package e2e + +// This file is required by ginkgo to accurately report compilation errors in test packages. Without +// it, the following error will mask the actual errors: +// +// ``` +// Failed to compile e2e: +// +// github.com/ava-labs/avalanchego/tests/e2e: no non-test Go files in /path/to/avalanchego/tests/e2e +// ``` diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index cc1e22ae3aa9..15da611324e0 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -146,7 +146,10 @@ func AddEphemeralNode(network testnet.Network, flags testnet.FlagsMap) testnet.N // Wait for the given node to report healthy. func WaitForHealthy(node testnet.Node) { - require.NoError(ginkgo.GinkgoT(), testnet.WaitForHealthy(DefaultContext(), node)) + // Need to use explicit context (vs DefaultContext()) to support use with DeferCleanup + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() + require.NoError(ginkgo.GinkgoT(), testnet.WaitForHealthy(ctx, node)) } // Sends an eth transaction, waits for the transaction receipt to be issued @@ -195,12 +198,26 @@ func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network testnet.Network) { + require := require.New(ginkgo.GinkgoT()) + if len(os.Getenv(SkipBootstrapChecksEnvName)) > 0 { tests.Outf("{{yellow}}Skipping bootstrap check due to the %s env var being set", SkipBootstrapChecksEnvName) return } ginkgo.By("checking if bootstrap is possible with the current network state") - node := AddEphemeralNode(network, testnet.FlagsMap{}) + + // Call network.AddEphemeralNode instead of AddEphemeralNode to support + // checking for bootstrap implicitly on teardown via a function registered + // with ginkgo.DeferCleanup. It's not possible to call DeferCleanup from + // within a function called by DeferCleanup. + node, err := network.AddEphemeralNode(ginkgo.GinkgoWriter, testnet.FlagsMap{}) + require.NoError(err) + + defer func() { + tests.Outf("Shutting down ephemeral node %s\n", node.GetID()) + require.NoError(node.Stop()) + }() + WaitForHealthy(node) } diff --git a/tests/fixture/testnet/local/network.go b/tests/fixture/testnet/local/network.go index 4f83a7fb0869..836a1489c2dd 100644 --- a/tests/fixture/testnet/local/network.go +++ b/tests/fixture/testnet/local/network.go @@ -673,7 +673,19 @@ func (ln *LocalNetwork) AddLocalNode(w io.Writer, node *LocalNode, isEphemeral b if err := node.WriteConfig(); err != nil { return nil, err } - return node, node.Start(w, ln.ExecPath) + + err = node.Start(w, ln.ExecPath) + if err != nil { + // Attempt to stop an unhealthy node to provide some assurance to the caller + // that an error condition will not result in a lingering process. + stopErr := node.Stop() + if stopErr != nil { + err = errors.Join(err, stopErr) + } + return nil, err + } + + return node, nil } func (ln *LocalNetwork) GetBootstrapIPsAndIDs() ([]string, []string, error) { From 5dff15390e71c5ce73a48a27aeb904917b9bde62 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 14 Nov 2023 12:47:06 -0800 Subject: [PATCH 034/267] Add `VerifyTx` to `executor.Manager` (#2293) --- vms/avm/block/executor/manager.go | 4 +-- vms/platformvm/block/builder/builder.go | 13 +------- vms/platformvm/block/executor/manager.go | 32 +++++++++++++++++-- vms/platformvm/block/executor/mock_manager.go | 15 +++++++++ 4 files changed, 47 insertions(+), 17 deletions(-) diff --git a/vms/avm/block/executor/manager.go b/vms/avm/block/executor/manager.go index aa99ede6392f..dd9b8bfab400 100644 --- a/vms/avm/block/executor/manager.go +++ b/vms/avm/block/executor/manager.go @@ -39,8 +39,8 @@ type Manager interface { GetStatelessBlock(blkID ids.ID) (block.Block, error) NewBlock(block.Block) snowman.Block - // VerifyTx verifies that the transaction can be issued based on the - // currently preferred state. + // VerifyTx verifies that the transaction can be issued based on the currently + // preferred state. This should *not* be used to verify transactions in a block. VerifyTx(tx *txs.Tx) error // VerifyUniqueInputs verifies that the inputs are not duplicated in the diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index aecc4c358f10..4d8ad96d132a 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -36,7 +36,6 @@ var ( ErrEndOfTime = errors.New("program time is suspiciously far in the future") ErrNoPendingBlocks = errors.New("no pending blocks") - ErrChainNotSynced = errors.New("chain not synced") ) type Builder interface { @@ -103,10 +102,6 @@ func New( // AddUnverifiedTx verifies a transaction and attempts to add it to the mempool func (b *builder) AddUnverifiedTx(tx *txs.Tx) error { - if !b.txExecutorBackend.Bootstrapped.Get() { - return ErrChainNotSynced - } - txID := tx.ID() if b.Mempool.Has(txID) { // If the transaction is already in the mempool - then it looks the same @@ -114,13 +109,7 @@ func (b *builder) AddUnverifiedTx(tx *txs.Tx) error { return nil } - verifier := txexecutor.MempoolTxVerifier{ - Backend: b.txExecutorBackend, - ParentID: b.blkManager.Preferred(), // We want to build off of the preferred block - StateVersions: b.blkManager, - Tx: tx, - } - if err := tx.Unsigned.Visit(&verifier); err != nil { + if err := b.blkManager.VerifyTx(tx); err != nil { b.MarkDropped(txID, err) return err } diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 1472e2f40b3d..9af9cbce2c4a 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -4,17 +4,24 @@ package executor import ( + "errors" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "github.com/ava-labs/avalanchego/vms/platformvm/state" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" "github.com/ava-labs/avalanchego/vms/platformvm/validators" ) -var _ Manager = (*manager)(nil) +var ( + _ Manager = (*manager)(nil) + + ErrChainNotSynced = errors.New("chain not synced") +) type Manager interface { state.Versions @@ -28,6 +35,10 @@ type Manager interface { GetBlock(blkID ids.ID) (snowman.Block, error) GetStatelessBlock(blkID ids.ID) (block.Block, error) NewBlock(block.Block) snowman.Block + + // VerifyTx verifies that the transaction can be issued based on the currently + // preferred state. This should *not* be used to verify transactions in a block. + VerifyTx(tx *txs.Tx) error } func NewManager( @@ -62,7 +73,8 @@ func NewManager( backend: backend, addTxsToMempool: !txExecutorBackend.Config.PartialSyncPrimaryNetwork, }, - preferred: lastAccepted, + preferred: lastAccepted, + txExecutorBackend: txExecutorBackend, } } @@ -72,7 +84,8 @@ type manager struct { acceptor block.Visitor rejector block.Visitor - preferred ids.ID + preferred ids.ID + txExecutorBackend *executor.Backend } func (m *manager) GetBlock(blkID ids.ID) (snowman.Block, error) { @@ -103,3 +116,16 @@ func (m *manager) SetPreference(blockID ids.ID) (updated bool) { func (m *manager) Preferred() ids.ID { return m.preferred } + +func (m *manager) VerifyTx(tx *txs.Tx) error { + if !m.txExecutorBackend.Bootstrapped.Get() { + return ErrChainNotSynced + } + + return tx.Unsigned.Visit(&executor.MempoolTxVerifier{ + Backend: m.txExecutorBackend, + ParentID: m.preferred, + StateVersions: m, + Tx: tx, + }) +} diff --git a/vms/platformvm/block/executor/mock_manager.go b/vms/platformvm/block/executor/mock_manager.go index 8755325a0fdc..f5b2bcb3608c 100644 --- a/vms/platformvm/block/executor/mock_manager.go +++ b/vms/platformvm/block/executor/mock_manager.go @@ -14,6 +14,7 @@ import ( snowman "github.com/ava-labs/avalanchego/snow/consensus/snowman" block "github.com/ava-labs/avalanchego/vms/platformvm/block" state "github.com/ava-labs/avalanchego/vms/platformvm/state" + txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" gomock "go.uber.org/mock/gomock" ) @@ -140,3 +141,17 @@ func (mr *MockManagerMockRecorder) SetPreference(arg0 interface{}) *gomock.Call mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockManager)(nil).SetPreference), arg0) } + +// VerifyTx mocks base method. +func (m *MockManager) VerifyTx(arg0 *txs.Tx) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VerifyTx", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// VerifyTx indicates an expected call of VerifyTx. +func (mr *MockManagerMockRecorder) VerifyTx(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyTx", reflect.TypeOf((*MockManager)(nil).VerifyTx), arg0) +} From d00b67fdb6e6ce92dc092b3b946c669c59d4ad6c Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 15 Nov 2023 11:43:17 -0500 Subject: [PATCH 035/267] Simplify avalanche bootstrapping (#2286) --- chains/manager.go | 35 +- node/node.go | 2 +- .../avalanche/bootstrap/bootstrapper.go | 141 ++---- .../avalanche/bootstrap/bootstrapper_test.go | 456 ++---------------- snow/engine/avalanche/bootstrap/config.go | 24 +- snow/engine/avalanche/getter/getter.go | 3 + version/constants.go | 33 +- 7 files changed, 154 insertions(+), 540 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index 985741e5eb3a..3d5792fad843 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -929,29 +929,20 @@ func (m *manager) createAvalancheChain( } // create bootstrap gear - _, specifiedLinearizationTime := version.CortinaTimes[ctx.NetworkID] - specifiedLinearizationTime = specifiedLinearizationTime && ctx.ChainID == m.XChainID avalancheBootstrapperConfig := avbootstrap.Config{ - Config: common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: sampleK, - StartupTracker: startupTracker, - Alpha: bootstrapWeight/2 + 1, // must be > 50% - Sender: avalancheMessageSender, - BootstrapTracker: sb, - Timer: h, - RetryBootstrap: m.RetryBootstrap, - RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, - AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, - SharedCfg: &common.SharedConfig{}, - }, - AllGetsServer: avaGetHandler, - VtxBlocked: vtxBlocker, - TxBlocked: txBlocker, - Manager: vtxManager, - VM: linearizableVM, - LinearizeOnStartup: !specifiedLinearizationTime, + AllGetsServer: avaGetHandler, + Ctx: ctx, + Beacons: vdrs, + StartupTracker: startupTracker, + Sender: avalancheMessageSender, + AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, + VtxBlocked: vtxBlocker, + TxBlocked: txBlocker, + Manager: vtxManager, + VM: linearizableVM, + } + if ctx.ChainID == m.XChainID { + avalancheBootstrapperConfig.StopVertexID = version.CortinaXChainStopVertexID[ctx.NetworkID] } avalancheBootstrapper, err := avbootstrap.New( diff --git a/node/node.go b/node/node.go index 04ab4a5015be..ba876d09b2d4 100644 --- a/node/node.go +++ b/node/node.go @@ -1022,7 +1022,7 @@ func (n *Node) initChainManager(avaxAssetID ids.ID) error { BootstrapAncestorsMaxContainersSent: n.Config.BootstrapAncestorsMaxContainersSent, BootstrapAncestorsMaxContainersReceived: n.Config.BootstrapAncestorsMaxContainersReceived, ApricotPhase4Time: version.GetApricotPhase4Time(n.Config.NetworkID), - ApricotPhase4MinPChainHeight: version.GetApricotPhase4MinPChainHeight(n.Config.NetworkID), + ApricotPhase4MinPChainHeight: version.ApricotPhase4MinPChainHeight[n.Config.NetworkID], ResourceTracker: n.resourceTracker, StateSyncBeacons: n.Config.StateSyncIDs, TracingEnabled: n.Config.TraceConfig.Enabled, diff --git a/snow/engine/avalanche/bootstrap/bootstrapper.go b/snow/engine/avalanche/bootstrap/bootstrapper.go index 0f8a2484a4e2..e58538b541ba 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper.go @@ -42,6 +42,8 @@ func New( StateSummaryFrontierHandler: common.NewNoOpStateSummaryFrontierHandler(config.Ctx.Log), AcceptedStateSummaryHandler: common.NewNoOpAcceptedStateSummaryHandler(config.Ctx.Log), + AcceptedFrontierHandler: common.NewNoOpAcceptedFrontierHandler(config.Ctx.Log), + AcceptedHandler: common.NewNoOpAcceptedHandler(config.Ctx.Log), PutHandler: common.NewNoOpPutHandler(config.Ctx.Log), QueryHandler: common.NewNoOpQueryHandler(config.Ctx.Log), ChitsHandler: common.NewNoOpChitsHandler(config.Ctx.Log), @@ -52,41 +54,41 @@ func New( OnFinished: onFinished, }, } - - if err := b.metrics.Initialize("bs", config.Ctx.AvalancheRegisterer); err != nil { - return nil, err - } - - config.Config.Bootstrapable = b - b.Bootstrapper = common.NewCommonBootstrapper(config.Config) - return b, nil + return b, b.metrics.Initialize("bs", config.Ctx.AvalancheRegisterer) } // Note: To align with the Snowman invariant, it should be guaranteed the VM is // not used until after the bootstrapper has been Started. type bootstrapper struct { Config + common.Halter // list of NoOpsHandler for messages dropped by bootstrapper common.StateSummaryFrontierHandler common.AcceptedStateSummaryHandler + common.AcceptedFrontierHandler + common.AcceptedHandler common.PutHandler common.QueryHandler common.ChitsHandler common.AppHandler - common.Bootstrapper common.Fetcher metrics - started bool - // IDs of vertices that we will send a GetAncestors request for once we are // not at the max number of outstanding requests needToFetch set.Set[ids.ID] // Contains IDs of vertices that have recently been processed processedCache *cache.LRU[ids.ID, struct{}] + + // Tracks the last requestID that was used in a request + requestID uint32 +} + +func (b *bootstrapper) Context() *snow.ConsensusContext { + return b.Ctx } func (b *bootstrapper) Clear(context.Context) error { @@ -256,16 +258,7 @@ func (b *bootstrapper) Connected( return err } - if err := b.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - - if b.started || !b.StartupTracker.ShouldStart() { - return nil - } - - b.started = true - return b.Startup(ctx) + return b.StartupTracker.Connected(ctx, nodeID, nodeVersion) } func (b *bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) error { @@ -327,7 +320,7 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { return err } - b.Config.SharedCfg.RequestID = startReqID + b.requestID = startReqID // If the network was already linearized, don't attempt to linearize it // again. @@ -336,38 +329,38 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { return fmt.Errorf("failed to get linearization status: %w", err) } if linearized { - edge := b.Manager.Edge(ctx) - return b.ForceAccepted(ctx, edge) + return b.ForceAccepted(ctx, nil) } - // If requested, assume the currently accepted state is what was linearized. - // - // Note: This is used to linearize networks that were created after the - // linearization occurred. - if b.Config.LinearizeOnStartup { - edge := b.Manager.Edge(ctx) - stopVertex, err := b.Manager.BuildStopVtx(ctx, edge) - if err != nil { - return fmt.Errorf("failed to create stop vertex: %w", err) - } - if err := stopVertex.Accept(ctx); err != nil { - return fmt.Errorf("failed to accept stop vertex: %w", err) - } - - stopVertexID := stopVertex.ID() - b.Ctx.Log.Info("accepted stop vertex", - zap.Stringer("vtxID", stopVertexID), + // If a stop vertex is well known, accept that. + if b.Config.StopVertexID != ids.Empty { + b.Ctx.Log.Info("using well known stop vertex", + zap.Stringer("vtxID", b.Config.StopVertexID), ) - return b.ForceAccepted(ctx, []ids.ID{stopVertexID}) + return b.ForceAccepted(ctx, []ids.ID{b.Config.StopVertexID}) } - if !b.StartupTracker.ShouldStart() { - return nil + // If a stop vertex isn't well known, treat the current state as the final + // DAG state. + // + // Note: This is used to linearize networks that were created after the + // linearization occurred. + edge := b.Manager.Edge(ctx) + stopVertex, err := b.Manager.BuildStopVtx(ctx, edge) + if err != nil { + return fmt.Errorf("failed to create stop vertex: %w", err) + } + if err := stopVertex.Accept(ctx); err != nil { + return fmt.Errorf("failed to accept stop vertex: %w", err) } - b.started = true - return b.Startup(ctx) + stopVertexID := stopVertex.ID() + b.Ctx.Log.Info("generated stop vertex", + zap.Stringer("vtxID", stopVertexID), + ) + + return b.ForceAccepted(ctx, nil) } func (b *bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { @@ -410,10 +403,10 @@ func (b *bootstrapper) fetch(ctx context.Context, vtxIDs ...ids.ID) error { return fmt.Errorf("dropping request for %s as there are no validators", vtxID) } validatorID := validatorIDs[0] - b.Config.SharedCfg.RequestID++ + b.requestID++ - b.OutstandingRequests.Add(validatorID, b.Config.SharedCfg.RequestID, vtxID) - b.Config.Sender.SendGetAncestors(ctx, validatorID, b.Config.SharedCfg.RequestID, vtxID) // request vertex and ancestors + b.OutstandingRequests.Add(validatorID, b.requestID, vtxID) + b.Config.Sender.SendGetAncestors(ctx, validatorID, b.requestID, vtxID) // request vertex and ancestors } return b.checkFinish(ctx) } @@ -498,15 +491,9 @@ func (b *bootstrapper) process(ctx context.Context, vtxs ...avalanche.Vertex) er verticesFetchedSoFar := b.VtxBlocked.Jobs.PendingJobs() if verticesFetchedSoFar%common.StatusUpdateFrequency == 0 { // Periodically print progress - if !b.Config.SharedCfg.Restarted { - b.Ctx.Log.Info("fetched vertices", - zap.Uint64("numVerticesFetched", verticesFetchedSoFar), - ) - } else { - b.Ctx.Log.Debug("fetched vertices", - zap.Uint64("numVerticesFetched", verticesFetchedSoFar), - ) - } + b.Ctx.Log.Info("fetched vertices", + zap.Uint64("numVerticesFetched", verticesFetchedSoFar), + ) } parents, err := vtx.Parents() @@ -578,58 +565,36 @@ func (b *bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs [ // checkFinish repeatedly executes pending transactions and requests new frontier blocks until there aren't any new ones // after which it finishes the bootstrap process func (b *bootstrapper) checkFinish(ctx context.Context) error { - // If there are outstanding requests for vertices or we still need to fetch vertices, we can't finish - pendingJobs := b.VtxBlocked.MissingIDs() - if b.IsBootstrapped() || len(pendingJobs) > 0 { + // If we still need to fetch vertices, we can't finish + if len(b.VtxBlocked.MissingIDs()) > 0 { return nil } - if !b.Config.SharedCfg.Restarted { - b.Ctx.Log.Info("executing transactions") - } else { - b.Ctx.Log.Debug("executing transactions") - } - + b.Ctx.Log.Info("executing transactions") _, err := b.TxBlocked.ExecuteAll( ctx, b.Config.Ctx, b, - b.Config.SharedCfg.Restarted, + false, b.Ctx.TxAcceptor, ) if err != nil || b.Halted() { return err } - if !b.Config.SharedCfg.Restarted { - b.Ctx.Log.Info("executing vertices") - } else { - b.Ctx.Log.Debug("executing vertices") - } - + b.Ctx.Log.Info("executing vertices") _, err = b.VtxBlocked.ExecuteAll( ctx, b.Config.Ctx, b, - b.Config.SharedCfg.Restarted, + false, b.Ctx.VertexAcceptor, ) if err != nil || b.Halted() { return err } - // If the chain is linearized, we should immediately move on to start - // bootstrapping snowman. - linearized, err := b.Manager.StopVertexAccepted(ctx) - if err != nil { - return err - } - if !linearized { - b.Ctx.Log.Debug("checking for stop vertex before finishing bootstrapping") - return b.Restart(ctx, true) - } - - // Invariant: edge will only be the stop vertex after its acceptance. + // Invariant: edge will only be the stop vertex edge := b.Manager.Edge(ctx) stopVertexID := edge[0] if err := b.VM.Linearize(ctx, stopVertexID); err != nil { @@ -637,7 +602,7 @@ func (b *bootstrapper) checkFinish(ctx context.Context) error { } b.processedCache.Flush() - return b.OnFinished(ctx, b.Config.SharedCfg.RequestID) + return b.OnFinished(ctx, b.requestID) } // A vertex is less than another vertex if it is unknown. Ties are broken by diff --git a/snow/engine/avalanche/bootstrap/bootstrapper_test.go b/snow/engine/avalanche/bootstrap/bootstrapper_test.go index f8a60c36bf46..4e61e9b137ee 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper_test.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper_test.go @@ -12,6 +12,8 @@ import ( "github.com/stretchr/testify/require" + "golang.org/x/exp/maps" + "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/ids" @@ -62,23 +64,10 @@ func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *vertex.Te vm := &vertex.TestVM{} vm.T = t - isBootstrapped := false - bootstrapTracker := &common.BootstrapTrackerTest{ - T: t, - IsBootstrappedF: func() bool { - return isBootstrapped - }, - BootstrappedF: func(ids.ID) { - isBootstrapped = true - }, - } - sender.Default(true) manager.Default(true) vm.Default(true) - sender.CantSendGetAcceptedFrontier = false - peer := ids.GenerateTestNodeID() require.NoError(vdrs.AddStaker(constants.PrimaryNetworkID, peer, nil, ids.Empty, 1)) @@ -94,29 +83,20 @@ func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *vertex.Te startupTracker := tracker.NewStartup(peerTracker, totalWeight/2+1) vdrs.RegisterCallbackListener(constants.PrimaryNetworkID, startupTracker) - commonConfig := common.Config{ + avaGetHandler, err := getter.New(manager, sender, ctx.Log, time.Second, 2000, ctx.AvalancheRegisterer) + require.NoError(err) + + return Config{ + AllGetsServer: avaGetHandler, Ctx: ctx, Beacons: vdrs, - SampleK: vdrs.Count(constants.PrimaryNetworkID), - Alpha: totalWeight/2 + 1, StartupTracker: startupTracker, Sender: sender, - BootstrapTracker: bootstrapTracker, - Timer: &common.TimerTest{}, AncestorsMaxContainersReceived: 2000, - SharedCfg: &common.SharedConfig{}, - } - - avaGetHandler, err := getter.New(manager, sender, ctx.Log, time.Second, 2000, ctx.AvalancheRegisterer) - require.NoError(err) - - return Config{ - Config: commonConfig, - AllGetsServer: avaGetHandler, - VtxBlocked: vtxBlocker, - TxBlocked: txBlocker, - Manager: manager, - VM: vm, + VtxBlocked: vtxBlocker, + TxBlocked: txBlocker, + Manager: manager, + VM: vm, }, peer, sender, manager, vm } @@ -148,7 +128,10 @@ func TestBootstrapperSingleFrontier(t *testing.T) { IDV: vtxID1, StatusV: choices.Processing, }, - HeightV: 0, + ParentsV: []avalanche.Vertex{ + vtx0, + }, + HeightV: 1, BytesV: vtxBytes1, } vtx2 := &avalanche.TestVertex{ // vtx2 is the stop vertex @@ -156,10 +139,14 @@ func TestBootstrapperSingleFrontier(t *testing.T) { IDV: vtxID2, StatusV: choices.Processing, }, - HeightV: 0, + ParentsV: []avalanche.Vertex{ + vtx1, + }, + HeightV: 2, BytesV: vtxBytes2, } + config.StopVertexID = vtxID2 bs, err := New( config, func(context.Context, uint32) error { @@ -172,11 +159,6 @@ func TestBootstrapperSingleFrontier(t *testing.T) { ) require.NoError(err) - vm.CantSetState = false - require.NoError(bs.Start(context.Background(), 0)) - - acceptedIDs := []ids.ID{vtxID0, vtxID1, vtxID2} - manager.GetVtxF = func(_ context.Context, vtxID ids.ID) (avalanche.Vertex, error) { switch vtxID { case vtxID0: @@ -219,7 +201,8 @@ func TestBootstrapperSingleFrontier(t *testing.T) { return nil } - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) + vm.CantSetState = false + require.NoError(bs.Start(context.Background(), 0)) require.Equal(snow.NormalOp, config.Ctx.State.Get().State) require.Equal(choices.Accepted, vtx0.Status()) require.Equal(choices.Accepted, vtx1.Status()) @@ -269,6 +252,7 @@ func TestBootstrapperByzantineResponses(t *testing.T) { BytesV: vtxBytes2, } + config.StopVertexID = vtxID1 bs, err := New( config, func(context.Context, uint32) error { @@ -281,10 +265,6 @@ func TestBootstrapperByzantineResponses(t *testing.T) { ) require.NoError(err) - vm.CantSetState = false - require.NoError(bs.Start(context.Background(), 0)) - - acceptedIDs := []ids.ID{vtxID1} manager.GetVtxF = func(_ context.Context, vtxID ids.ID) (avalanche.Vertex, error) { switch vtxID { case vtxID1: @@ -324,7 +304,8 @@ func TestBootstrapperByzantineResponses(t *testing.T) { } } - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) // should request vtx0 + vm.CantSetState = false + require.NoError(bs.Start(context.Background(), 0)) // should request vtx0 require.Equal(vtxID0, reqVtxID) oldReqID := *requestID @@ -437,6 +418,7 @@ func TestBootstrapperTxDependencies(t *testing.T) { BytesV: vtxBytes1, } + config.StopVertexID = vtxID1 bs, err := New( config, func(context.Context, uint32) error { @@ -449,11 +431,6 @@ func TestBootstrapperTxDependencies(t *testing.T) { ) require.NoError(err) - vm.CantSetState = false - require.NoError(bs.Start(context.Background(), 0)) - - acceptedIDs := []ids.ID{vtxID1} - manager.ParseVtxF = func(_ context.Context, vtxBytes []byte) (avalanche.Vertex, error) { switch { case bytes.Equal(vtxBytes, vtxBytes1): @@ -485,7 +462,8 @@ func TestBootstrapperTxDependencies(t *testing.T) { *reqIDPtr = reqID } - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) // should request vtx0 + vm.CantSetState = false + require.NoError(bs.Start(context.Background(), 0)) manager.ParseVtxF = func(_ context.Context, vtxBytes []byte) (avalanche.Vertex, error) { switch { @@ -563,6 +541,7 @@ func TestBootstrapperIncompleteAncestors(t *testing.T) { BytesV: vtxBytes2, } + config.StopVertexID = vtxID2 bs, err := New( config, func(context.Context, uint32) error { @@ -575,10 +554,6 @@ func TestBootstrapperIncompleteAncestors(t *testing.T) { ) require.NoError(err) - vm.CantSetState = false - require.NoError(bs.Start(context.Background(), 0)) - - acceptedIDs := []ids.ID{vtxID2} manager.GetVtxF = func(_ context.Context, vtxID ids.ID) (avalanche.Vertex, error) { switch { case vtxID == vtxID0: @@ -617,7 +592,8 @@ func TestBootstrapperIncompleteAncestors(t *testing.T) { requested = vtxID } - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) // should request vtx1 + vm.CantSetState = false + require.NoError(bs.Start(context.Background(), 0)) // should request vtx1 require.Equal(vtxID1, requested) require.NoError(bs.Ancestors(context.Background(), peerID, *reqIDPtr, [][]byte{vtxBytes1})) // Provide vtx1; should request vtx0 @@ -645,7 +621,7 @@ func TestBootstrapperIncompleteAncestors(t *testing.T) { require.Equal(choices.Accepted, vtx2.Status()) } -func TestBootstrapperFinalized(t *testing.T) { +func TestBootstrapperUnexpectedVertex(t *testing.T) { require := require.New(t) config, peerID, sender, manager, vm := newConfig(t) @@ -674,6 +650,7 @@ func TestBootstrapperFinalized(t *testing.T) { BytesV: vtxBytes1, } + config.StopVertexID = vtxID1 bs, err := New( config, func(context.Context, uint32) error { @@ -686,10 +663,6 @@ func TestBootstrapperFinalized(t *testing.T) { ) require.NoError(err) - vm.CantSetState = false - require.NoError(bs.Start(context.Background(), 0)) - - acceptedIDs := []ids.ID{vtxID0, vtxID1} parsedVtx0 := false parsedVtx1 := false manager.GetVtxF = func(_ context.Context, vtxID ids.ID) (avalanche.Vertex, error) { @@ -728,20 +701,17 @@ func TestBootstrapperFinalized(t *testing.T) { requestIDs := map[ids.ID]uint32{} sender.SendGetAncestorsF = func(_ context.Context, vdr ids.NodeID, reqID uint32, vtxID ids.ID) { require.Equal(peerID, vdr) - requestIDs[vtxID] = reqID } - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) // should request vtx0 and vtx1 + vm.CantSetState = false + require.NoError(bs.Start(context.Background(), 0)) // should request vtx1 require.Contains(requestIDs, vtxID1) reqID := requestIDs[vtxID1] - require.NoError(bs.Ancestors(context.Background(), peerID, reqID, [][]byte{vtxBytes1, vtxBytes0})) - require.Contains(requestIDs, vtxID0) - - manager.StopVertexAcceptedF = func(context.Context) (bool, error) { - return vtx1.Status() == choices.Accepted, nil - } + maps.Clear(requestIDs) + require.NoError(bs.Ancestors(context.Background(), peerID, reqID, [][]byte{vtxBytes0})) + require.Contains(requestIDs, vtxID1) manager.EdgeF = func(context.Context) []ids.ID { require.Equal(choices.Accepted, vtx1.Status()) @@ -753,356 +723,8 @@ func TestBootstrapperFinalized(t *testing.T) { return nil } - reqID = requestIDs[vtxID0] - require.NoError(bs.GetAncestorsFailed(context.Background(), peerID, reqID)) - require.Equal(snow.NormalOp, config.Ctx.State.Get().State) - require.Equal(choices.Accepted, vtx0.Status()) - require.Equal(choices.Accepted, vtx1.Status()) -} - -// Test that Ancestors accepts the parents of the first vertex returned -func TestBootstrapperAcceptsAncestorsParents(t *testing.T) { - require := require.New(t) - - config, peerID, sender, manager, vm := newConfig(t) - - vtxID0 := ids.Empty.Prefix(0) - vtxID1 := ids.Empty.Prefix(1) - vtxID2 := ids.Empty.Prefix(2) - - vtxBytes0 := []byte{0} - vtxBytes1 := []byte{1} - vtxBytes2 := []byte{2} - - vtx0 := &avalanche.TestVertex{ - TestDecidable: choices.TestDecidable{ - IDV: vtxID0, - StatusV: choices.Unknown, - }, - HeightV: 0, - BytesV: vtxBytes0, - } - vtx1 := &avalanche.TestVertex{ - TestDecidable: choices.TestDecidable{ - IDV: vtxID1, - StatusV: choices.Unknown, - }, - ParentsV: []avalanche.Vertex{vtx0}, - HeightV: 1, - BytesV: vtxBytes1, - } - vtx2 := &avalanche.TestVertex{ // vtx2 is the stop vertex - TestDecidable: choices.TestDecidable{ - IDV: vtxID2, - StatusV: choices.Unknown, - }, - ParentsV: []avalanche.Vertex{vtx1}, - HeightV: 2, - BytesV: vtxBytes2, - } - - bs, err := New( - config, - func(context.Context, uint32) error { - config.Ctx.State.Set(snow.EngineState{ - Type: p2p.EngineType_ENGINE_TYPE_AVALANCHE, - State: snow.NormalOp, - }) - return nil - }, - ) - require.NoError(err) - - vm.CantSetState = false - require.NoError(bs.Start(context.Background(), 0)) - - acceptedIDs := []ids.ID{vtxID2} - parsedVtx0 := false - parsedVtx1 := false - parsedVtx2 := false - manager.GetVtxF = func(_ context.Context, vtxID ids.ID) (avalanche.Vertex, error) { - switch vtxID { - case vtxID0: - if parsedVtx0 { - return vtx0, nil - } - case vtxID1: - if parsedVtx1 { - return vtx1, nil - } - case vtxID2: - if parsedVtx2 { - return vtx2, nil - } - default: - require.FailNow(errUnknownVertex.Error()) - return nil, errUnknownVertex - } - return nil, errUnknownVertex - } - manager.ParseVtxF = func(_ context.Context, vtxBytes []byte) (avalanche.Vertex, error) { - switch { - case bytes.Equal(vtxBytes, vtxBytes0): - vtx0.StatusV = choices.Processing - parsedVtx0 = true - return vtx0, nil - case bytes.Equal(vtxBytes, vtxBytes1): - vtx1.StatusV = choices.Processing - parsedVtx1 = true - return vtx1, nil - case bytes.Equal(vtxBytes, vtxBytes2): - vtx2.StatusV = choices.Processing - parsedVtx2 = true - return vtx2, nil - default: - require.FailNow(errUnknownVertex.Error()) - return nil, errUnknownVertex - } - } - - requestIDs := map[ids.ID]uint32{} - sender.SendGetAncestorsF = func(_ context.Context, vdr ids.NodeID, reqID uint32, vtxID ids.ID) { - require.Equal(peerID, vdr) - - requestIDs[vtxID] = reqID - } - - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) // should request vtx2 - require.Contains(requestIDs, vtxID2) - - manager.StopVertexAcceptedF = func(context.Context) (bool, error) { - return vtx2.Status() == choices.Accepted, nil - } - - manager.EdgeF = func(context.Context) []ids.ID { - require.Equal(choices.Accepted, vtx2.Status()) - return []ids.ID{vtxID2} - } - - vm.LinearizeF = func(_ context.Context, stopVertexID ids.ID) error { - require.Equal(vtxID2, stopVertexID) - return nil - } - - reqID := requestIDs[vtxID2] - require.NoError(bs.Ancestors(context.Background(), peerID, reqID, [][]byte{vtxBytes2, vtxBytes1, vtxBytes0})) - require.Equal(snow.NormalOp, config.Ctx.State.Get().State) + require.NoError(bs.Ancestors(context.Background(), peerID, reqID, [][]byte{vtxBytes1, vtxBytes0})) require.Equal(choices.Accepted, vtx0.Status()) require.Equal(choices.Accepted, vtx1.Status()) - require.Equal(choices.Accepted, vtx2.Status()) -} - -func TestRestartBootstrapping(t *testing.T) { - require := require.New(t) - - config, peerID, sender, manager, vm := newConfig(t) - - vtxID0 := ids.GenerateTestID() - vtxID1 := ids.GenerateTestID() - vtxID2 := ids.GenerateTestID() - vtxID3 := ids.GenerateTestID() - vtxID4 := ids.GenerateTestID() - vtxID5 := ids.GenerateTestID() - - vtxBytes0 := []byte{0} - vtxBytes1 := []byte{1} - vtxBytes2 := []byte{2} - vtxBytes3 := []byte{3} - vtxBytes4 := []byte{4} - vtxBytes5 := []byte{5} - - vtx0 := &avalanche.TestVertex{ - TestDecidable: choices.TestDecidable{ - IDV: vtxID0, - StatusV: choices.Unknown, - }, - HeightV: 0, - BytesV: vtxBytes0, - } - vtx1 := &avalanche.TestVertex{ - TestDecidable: choices.TestDecidable{ - IDV: vtxID1, - StatusV: choices.Unknown, - }, - ParentsV: []avalanche.Vertex{vtx0}, - HeightV: 1, - BytesV: vtxBytes1, - } - vtx2 := &avalanche.TestVertex{ - TestDecidable: choices.TestDecidable{ - IDV: vtxID2, - StatusV: choices.Unknown, - }, - ParentsV: []avalanche.Vertex{vtx1}, - HeightV: 2, - BytesV: vtxBytes2, - } - vtx3 := &avalanche.TestVertex{ - TestDecidable: choices.TestDecidable{ - IDV: vtxID3, - StatusV: choices.Unknown, - }, - ParentsV: []avalanche.Vertex{vtx2}, - HeightV: 3, - BytesV: vtxBytes3, - } - vtx4 := &avalanche.TestVertex{ - TestDecidable: choices.TestDecidable{ - IDV: vtxID4, - StatusV: choices.Unknown, - }, - ParentsV: []avalanche.Vertex{vtx2}, - HeightV: 3, - BytesV: vtxBytes4, - } - vtx5 := &avalanche.TestVertex{ // vtx5 is the stop vertex - TestDecidable: choices.TestDecidable{ - IDV: vtxID5, - StatusV: choices.Unknown, - }, - ParentsV: []avalanche.Vertex{vtx3, vtx4}, - HeightV: 4, - BytesV: vtxBytes5, - } - - bsIntf, err := New( - config, - func(context.Context, uint32) error { - config.Ctx.State.Set(snow.EngineState{ - Type: p2p.EngineType_ENGINE_TYPE_AVALANCHE, - State: snow.NormalOp, - }) - return nil - }, - ) - require.NoError(err) - - bs := bsIntf.(*bootstrapper) - - vm.CantSetState = false - require.NoError(bs.Start(context.Background(), 0)) - - parsedVtx0 := false - parsedVtx1 := false - parsedVtx2 := false - parsedVtx3 := false - parsedVtx4 := false - parsedVtx5 := false - manager.GetVtxF = func(_ context.Context, vtxID ids.ID) (avalanche.Vertex, error) { - switch vtxID { - case vtxID0: - if parsedVtx0 { - return vtx0, nil - } - case vtxID1: - if parsedVtx1 { - return vtx1, nil - } - case vtxID2: - if parsedVtx2 { - return vtx2, nil - } - case vtxID3: - if parsedVtx3 { - return vtx3, nil - } - case vtxID4: - if parsedVtx4 { - return vtx4, nil - } - case vtxID5: - if parsedVtx5 { - return vtx5, nil - } - default: - require.FailNow(errUnknownVertex.Error()) - return nil, errUnknownVertex - } - return nil, errUnknownVertex - } - manager.ParseVtxF = func(_ context.Context, vtxBytes []byte) (avalanche.Vertex, error) { - switch { - case bytes.Equal(vtxBytes, vtxBytes0): - vtx0.StatusV = choices.Processing - parsedVtx0 = true - return vtx0, nil - case bytes.Equal(vtxBytes, vtxBytes1): - vtx1.StatusV = choices.Processing - parsedVtx1 = true - return vtx1, nil - case bytes.Equal(vtxBytes, vtxBytes2): - vtx2.StatusV = choices.Processing - parsedVtx2 = true - return vtx2, nil - case bytes.Equal(vtxBytes, vtxBytes3): - vtx3.StatusV = choices.Processing - parsedVtx3 = true - return vtx3, nil - case bytes.Equal(vtxBytes, vtxBytes4): - vtx4.StatusV = choices.Processing - parsedVtx4 = true - return vtx4, nil - case bytes.Equal(vtxBytes, vtxBytes5): - vtx5.StatusV = choices.Processing - parsedVtx5 = true - return vtx5, nil - default: - require.FailNow(errUnknownVertex.Error()) - return nil, errUnknownVertex - } - } - - requestIDs := map[ids.ID]uint32{} - sender.SendGetAncestorsF = func(_ context.Context, vdr ids.NodeID, reqID uint32, vtxID ids.ID) { - require.Equal(peerID, vdr) - - requestIDs[vtxID] = reqID - } - - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{vtxID3, vtxID4})) // should request vtx3 and vtx4 - require.Contains(requestIDs, vtxID3) - require.Contains(requestIDs, vtxID4) - - vtx3ReqID := requestIDs[vtxID3] - require.NoError(bs.Ancestors(context.Background(), peerID, vtx3ReqID, [][]byte{vtxBytes3, vtxBytes2})) - require.Contains(requestIDs, vtxID1) - require.True(bs.OutstandingRequests.RemoveAny(vtxID4)) - require.True(bs.OutstandingRequests.RemoveAny(vtxID1)) - - bs.needToFetch.Clear() - requestIDs = map[ids.ID]uint32{} - - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{vtxID5, vtxID3})) - require.Contains(requestIDs, vtxID1) - require.Contains(requestIDs, vtxID4) - require.Contains(requestIDs, vtxID5) - require.NotContains(requestIDs, vtxID3) - - vtx5ReqID := requestIDs[vtxID5] - require.NoError(bs.Ancestors(context.Background(), peerID, vtx5ReqID, [][]byte{vtxBytes5, vtxBytes4, vtxBytes2, vtxBytes1})) - require.Contains(requestIDs, vtxID0) - - manager.StopVertexAcceptedF = func(context.Context) (bool, error) { - return vtx5.Status() == choices.Accepted, nil - } - - manager.EdgeF = func(context.Context) []ids.ID { - require.Equal(choices.Accepted, vtx5.Status()) - return []ids.ID{vtxID5} - } - - vm.LinearizeF = func(_ context.Context, stopVertexID ids.ID) error { - require.Equal(vtxID5, stopVertexID) - return nil - } - - vtx1ReqID := requestIDs[vtxID1] - require.NoError(bs.Ancestors(context.Background(), peerID, vtx1ReqID, [][]byte{vtxBytes1, vtxBytes0})) require.Equal(snow.NormalOp, config.Ctx.State.Get().State) - require.Equal(choices.Accepted, vtx0.Status()) - require.Equal(choices.Accepted, vtx1.Status()) - require.Equal(choices.Accepted, vtx2.Status()) - require.Equal(choices.Accepted, vtx3.Status()) - require.Equal(choices.Accepted, vtx4.Status()) - require.Equal(choices.Accepted, vtx5.Status()) } diff --git a/snow/engine/avalanche/bootstrap/config.go b/snow/engine/avalanche/bootstrap/config.go index 0569342cc328..54fe7f2e45fa 100644 --- a/snow/engine/avalanche/bootstrap/config.go +++ b/snow/engine/avalanche/bootstrap/config.go @@ -4,21 +4,37 @@ package bootstrap import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/common/queue" + "github.com/ava-labs/avalanchego/snow/engine/common/tracker" + "github.com/ava-labs/avalanchego/snow/validators" ) type Config struct { - common.Config common.AllGetsServer + Ctx *snow.ConsensusContext + Beacons validators.Manager + + StartupTracker tracker.Startup + Sender common.Sender + + // This node will only consider the first [AncestorsMaxContainersReceived] + // containers in an ancestors message it receives. + AncestorsMaxContainersReceived int + // VtxBlocked tracks operations that are blocked on vertices VtxBlocked *queue.JobsWithMissing // TxBlocked tracks operations that are blocked on transactions TxBlocked *queue.Jobs - Manager vertex.Manager - VM vertex.LinearizableVM - LinearizeOnStartup bool + Manager vertex.Manager + VM vertex.LinearizableVM + + // If StopVertexID is empty, the engine will generate the stop vertex based + // on the current state. + StopVertexID ids.ID } diff --git a/snow/engine/avalanche/getter/getter.go b/snow/engine/avalanche/getter/getter.go index 88f485ab1118..3796bd9888b5 100644 --- a/snow/engine/avalanche/getter/getter.go +++ b/snow/engine/avalanche/getter/getter.go @@ -83,6 +83,8 @@ func (gh *getter) GetAcceptedStateSummary(_ context.Context, nodeID ids.NodeID, return nil } +// TODO: Remove support for GetAcceptedFrontier messages after v1.11.x is +// activated. func (gh *getter) GetAcceptedFrontier(ctx context.Context, validatorID ids.NodeID, requestID uint32) error { acceptedFrontier := gh.storage.Edge(ctx) // Since all the DAGs are linearized, we only need to return the stop @@ -93,6 +95,7 @@ func (gh *getter) GetAcceptedFrontier(ctx context.Context, validatorID ids.NodeI return nil } +// TODO: Remove support for GetAccepted messages after v1.11.x is activated. func (gh *getter) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { acceptedVtxIDs := make([]ids.ID, 0, len(containerIDs)) for _, vtxID := range containerIDs { diff --git a/version/constants.go b/version/constants.go index 690e68b3505f..25cedb5b73c1 100644 --- a/version/constants.go +++ b/version/constants.go @@ -9,6 +9,7 @@ import ( _ "embed" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" ) @@ -75,7 +76,6 @@ var ( constants.MainnetID: 793005, constants.FujiID: 47437, } - ApricotPhase4DefaultMinPChainHeight uint64 ApricotPhase5Times = map[uint32]time.Time{ constants.MainnetID: time.Date(2021, time.December, 2, 18, 0, 0, 0, time.UTC), @@ -96,6 +96,7 @@ var ( constants.MainnetID: time.Date(2023, time.April, 25, 15, 0, 0, 0, time.UTC), constants.FujiID: time.Date(2023, time.April, 6, 15, 0, 0, 0, time.UTC), } + CortinaXChainStopVertexID map[uint32]ids.ID // TODO: update this before release DTimes = map[uint32]time.Time{ @@ -123,6 +124,29 @@ func init() { } RPCChainVMProtocolCompatibility[rpcChainVMProtocol] = versions } + + // The mainnet stop vertex is well known. It can be verified on any fully + // synced node by looking at the parentID of the genesis block. + // + // Ref: https://subnets.avax.network/x-chain/block/0 + mainnetXChainStopVertexID, err := ids.FromString("jrGWDh5Po9FMj54depyunNixpia5PN4aAYxfmNzU8n752Rjga") + if err != nil { + panic(err) + } + + // The fuji stop vertex is well known. It can be verified on any fully + // synced node by looking at the parentID of the genesis block. + // + // Ref: https://subnets-test.avax.network/x-chain/block/0 + fujiXChainStopVertexID, err := ids.FromString("2D1cmbiG36BqQMRyHt4kFhWarmatA1ighSpND3FeFgz3vFVtCZ") + if err != nil { + panic(err) + } + + CortinaXChainStopVertexID = map[uint32]ids.ID{ + constants.MainnetID: mainnetXChainStopVertexID, + constants.FujiID: fujiXChainStopVertexID, + } } func GetApricotPhase3Time(networkID uint32) time.Time { @@ -139,13 +163,6 @@ func GetApricotPhase4Time(networkID uint32) time.Time { return DefaultUpgradeTime } -func GetApricotPhase4MinPChainHeight(networkID uint32) uint64 { - if minHeight, exists := ApricotPhase4MinPChainHeight[networkID]; exists { - return minHeight - } - return ApricotPhase4DefaultMinPChainHeight -} - func GetApricotPhase5Time(networkID uint32) time.Time { if upgradeTime, exists := ApricotPhase5Times[networkID]; exists { return upgradeTime From 44f3aba31269e9eb2a66ae974115081024566ce6 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 15 Nov 2023 17:12:57 -0500 Subject: [PATCH 036/267] Replace unique slices with sets in the engine interface (#2317) --- snow/engine/avalanche/getter/getter.go | 8 +++--- snow/engine/avalanche/getter/getter_test.go | 3 ++- snow/engine/common/bootstrapper.go | 4 +-- snow/engine/common/engine.go | 9 ++++--- snow/engine/common/no_ops_handlers.go | 5 ++-- snow/engine/common/test_engine.go | 15 +++++------ snow/engine/common/traced_engine.go | 17 +++++++------ snow/engine/snowman/getter/getter.go | 15 +++++------ snow/engine/snowman/getter/getter_test.go | 3 ++- snow/engine/snowman/syncer/state_syncer.go | 6 ++--- .../snowman/syncer/state_syncer_test.go | 20 +++++++-------- snow/networking/handler/handler.go | 15 ++--------- snow/networking/handler/handler_test.go | 5 ++-- snow/networking/handler/parser.go | 17 +++---------- utils/sorting.go | 13 ---------- utils/sorting_test.go | 25 ------------------- vms/platformvm/vm_test.go | 2 +- 17 files changed, 66 insertions(+), 116 deletions(-) diff --git a/snow/engine/avalanche/getter/getter.go b/snow/engine/avalanche/getter/getter.go index 3796bd9888b5..a93d2f1d069e 100644 --- a/snow/engine/avalanche/getter/getter.go +++ b/snow/engine/avalanche/getter/getter.go @@ -73,7 +73,7 @@ func (gh *getter) GetStateSummaryFrontier(_ context.Context, nodeID ids.NodeID, return nil } -func (gh *getter) GetAcceptedStateSummary(_ context.Context, nodeID ids.NodeID, requestID uint32, _ []uint64) error { +func (gh *getter) GetAcceptedStateSummary(_ context.Context, nodeID ids.NodeID, requestID uint32, _ set.Set[uint64]) error { gh.log.Debug("dropping request", zap.String("reason", "unhandled by this gear"), zap.Stringer("messageOp", message.GetAcceptedStateSummaryOp), @@ -96,9 +96,9 @@ func (gh *getter) GetAcceptedFrontier(ctx context.Context, validatorID ids.NodeI } // TODO: Remove support for GetAccepted messages after v1.11.x is activated. -func (gh *getter) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { - acceptedVtxIDs := make([]ids.ID, 0, len(containerIDs)) - for _, vtxID := range containerIDs { +func (gh *getter) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { + acceptedVtxIDs := make([]ids.ID, 0, containerIDs.Len()) + for vtxID := range containerIDs { if vtx, err := gh.storage.GetVtx(ctx, vtxID); err == nil && vtx.Status() == choices.Accepted { acceptedVtxIDs = append(acceptedVtxIDs, vtxID) } diff --git a/snow/engine/avalanche/getter/getter_test.go b/snow/engine/avalanche/getter/getter_test.go index a7e679d43520..4d25e29f296b 100644 --- a/snow/engine/avalanche/getter/getter_test.go +++ b/snow/engine/avalanche/getter/getter_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" ) var errUnknownVertex = errors.New("unknown vertex") @@ -99,7 +100,7 @@ func TestFilterAccepted(t *testing.T) { accepted = frontier } - vtxIDs := []ids.ID{vtxID0, vtxID1, vtxID2} + vtxIDs := set.Of(vtxID0, vtxID1, vtxID2) require.NoError(bs.GetAccepted(context.Background(), ids.EmptyNodeID, 0, vtxIDs)) require.Contains(accepted, vtxID0) diff --git a/snow/engine/common/bootstrapper.go b/snow/engine/common/bootstrapper.go index aca219130478..c567db5ee2d0 100644 --- a/snow/engine/common/bootstrapper.go +++ b/snow/engine/common/bootstrapper.go @@ -184,7 +184,7 @@ func (b *bootstrapper) markAcceptedFrontierReceived(ctx context.Context, nodeID return nil } -func (b *bootstrapper) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { +func (b *bootstrapper) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { // ignores any late responses if requestID != b.Config.SharedCfg.RequestID { b.Ctx.Log.Debug("received out-of-sync Accepted message", @@ -205,7 +205,7 @@ func (b *bootstrapper) Accepted(ctx context.Context, nodeID ids.NodeID, requestI b.pendingReceiveAccepted.Remove(nodeID) weight := b.Beacons.GetWeight(b.Ctx.SubnetID, nodeID) - for _, containerID := range containerIDs { + for containerID := range containerIDs { previousWeight := b.acceptedVotes[containerID] newWeight, err := safemath.Add64(weight, previousWeight) if err != nil { diff --git a/snow/engine/common/engine.go b/snow/engine/common/engine.go index 4c8213a432f6..d92911ff1f7f 100644 --- a/snow/engine/common/engine.go +++ b/snow/engine/common/engine.go @@ -11,6 +11,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/set" ) // Engine describes the standard interface of a consensus engine. @@ -108,7 +109,7 @@ type GetAcceptedStateSummaryHandler interface { ctx context.Context, nodeID ids.NodeID, requestID uint32, - heights []uint64, + heights set.Set[uint64], ) error } @@ -122,7 +123,7 @@ type AcceptedStateSummaryHandler interface { ctx context.Context, nodeID ids.NodeID, requestID uint32, - summaryIDs []ids.ID, + summaryIDs set.Set[ids.ID], ) error // Notify this engine that a GetAcceptedStateSummary request it issued has @@ -182,7 +183,7 @@ type GetAcceptedHandler interface { ctx context.Context, nodeID ids.NodeID, requestID uint32, - containerIDs []ids.ID, + containerIDs set.Set[ids.ID], ) error } @@ -196,7 +197,7 @@ type AcceptedHandler interface { ctx context.Context, nodeID ids.NodeID, requestID uint32, - containerIDs []ids.ID, + containerIDs set.Set[ids.ID], ) error // Notify this engine that a GetAccepted request it issued has failed. diff --git a/snow/engine/common/no_ops_handlers.go b/snow/engine/common/no_ops_handlers.go index 9530600177bb..716d1d5111b3 100644 --- a/snow/engine/common/no_ops_handlers.go +++ b/snow/engine/common/no_ops_handlers.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" ) @@ -65,7 +66,7 @@ func NewNoOpAcceptedStateSummaryHandler(log logging.Logger) AcceptedStateSummary return &noOpAcceptedStateSummaryHandler{log: log} } -func (nop *noOpAcceptedStateSummaryHandler) AcceptedStateSummary(_ context.Context, nodeID ids.NodeID, requestID uint32, _ []ids.ID) error { +func (nop *noOpAcceptedStateSummaryHandler) AcceptedStateSummary(_ context.Context, nodeID ids.NodeID, requestID uint32, _ set.Set[ids.ID]) error { nop.log.Debug("dropping request", zap.String("reason", "unhandled by this gear"), zap.Stringer("messageOp", message.AcceptedStateSummaryOp), @@ -122,7 +123,7 @@ func NewNoOpAcceptedHandler(log logging.Logger) AcceptedHandler { return &noOpAcceptedHandler{log: log} } -func (nop *noOpAcceptedHandler) Accepted(_ context.Context, nodeID ids.NodeID, requestID uint32, _ []ids.ID) error { +func (nop *noOpAcceptedHandler) Accepted(_ context.Context, nodeID ids.NodeID, requestID uint32, _ set.Set[ids.ID]) error { nop.log.Debug("dropping request", zap.String("reason", "unhandled by this gear"), zap.Stringer("messageOp", message.AcceptedOp), diff --git a/snow/engine/common/test_engine.go b/snow/engine/common/test_engine.go index 579f2ca94c9d..3eb376de8e32 100644 --- a/snow/engine/common/test_engine.go +++ b/snow/engine/common/test_engine.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" ) @@ -119,15 +120,15 @@ type EngineTest struct { PushQueryF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, container []byte, requestedHeight uint64) error AncestorsF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, containers [][]byte) error AcceptedFrontierF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error - GetAcceptedF, AcceptedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredIDs []ids.ID) error + GetAcceptedF, AcceptedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredIDs set.Set[ids.ID]) error ChitsF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, preferredIDAtHeight ids.ID, acceptedID ids.ID) error GetStateSummaryFrontierF, GetStateSummaryFrontierFailedF, GetAcceptedStateSummaryFailedF, GetAcceptedFrontierF, GetFailedF, GetAncestorsFailedF, QueryFailedF, GetAcceptedFrontierFailedF, GetAcceptedFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32) error AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32) error StateSummaryFrontierF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, summary []byte) error - GetAcceptedStateSummaryF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, keys []uint64) error - AcceptedStateSummaryF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs []ids.ID) error + GetAcceptedStateSummaryF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, keys set.Set[uint64]) error + AcceptedStateSummaryF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs set.Set[ids.ID]) error ConnectedF func(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error DisconnectedF func(ctx context.Context, nodeID ids.NodeID) error HealthF func(context.Context) (interface{}, error) @@ -314,7 +315,7 @@ func (e *EngineTest) GetStateSummaryFrontierFailed(ctx context.Context, validato return errGetStateSummaryFrontierFailed } -func (e *EngineTest) GetAcceptedStateSummary(ctx context.Context, validatorID ids.NodeID, requestID uint32, keys []uint64) error { +func (e *EngineTest) GetAcceptedStateSummary(ctx context.Context, validatorID ids.NodeID, requestID uint32, keys set.Set[uint64]) error { if e.GetAcceptedStateSummaryF != nil { return e.GetAcceptedStateSummaryF(ctx, validatorID, requestID, keys) } @@ -327,7 +328,7 @@ func (e *EngineTest) GetAcceptedStateSummary(ctx context.Context, validatorID id return errGetAcceptedStateSummary } -func (e *EngineTest) AcceptedStateSummary(ctx context.Context, validatorID ids.NodeID, requestID uint32, summaryIDs []ids.ID) error { +func (e *EngineTest) AcceptedStateSummary(ctx context.Context, validatorID ids.NodeID, requestID uint32, summaryIDs set.Set[ids.ID]) error { if e.AcceptedStateSummaryF != nil { return e.AcceptedStateSummaryF(ctx, validatorID, requestID, summaryIDs) } @@ -392,7 +393,7 @@ func (e *EngineTest) AcceptedFrontier(ctx context.Context, nodeID ids.NodeID, re return errAcceptedFrontier } -func (e *EngineTest) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { +func (e *EngineTest) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { if e.GetAcceptedF != nil { return e.GetAcceptedF(ctx, nodeID, requestID, containerIDs) } @@ -418,7 +419,7 @@ func (e *EngineTest) GetAcceptedFailed(ctx context.Context, nodeID ids.NodeID, r return errGetAcceptedFailed } -func (e *EngineTest) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { +func (e *EngineTest) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { if e.AcceptedF != nil { return e.AcceptedF(ctx, nodeID, requestID, containerIDs) } diff --git a/snow/engine/common/traced_engine.go b/snow/engine/common/traced_engine.go index 387ee8289e2a..9050f29cd1e1 100644 --- a/snow/engine/common/traced_engine.go +++ b/snow/engine/common/traced_engine.go @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/trace" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" ) @@ -62,22 +63,22 @@ func (e *tracedEngine) GetStateSummaryFrontierFailed(ctx context.Context, nodeID return e.engine.GetStateSummaryFrontierFailed(ctx, nodeID, requestID) } -func (e *tracedEngine) GetAcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, heights []uint64) error { +func (e *tracedEngine) GetAcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, heights set.Set[uint64]) error { ctx, span := e.tracer.Start(ctx, "tracedEngine.GetAcceptedStateSummary", oteltrace.WithAttributes( attribute.Stringer("nodeID", nodeID), attribute.Int64("requestID", int64(requestID)), - attribute.Int("numHeights", len(heights)), + attribute.Int("numHeights", heights.Len()), )) defer span.End() return e.engine.GetAcceptedStateSummary(ctx, nodeID, requestID, heights) } -func (e *tracedEngine) AcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs []ids.ID) error { +func (e *tracedEngine) AcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs set.Set[ids.ID]) error { ctx, span := e.tracer.Start(ctx, "tracedEngine.AcceptedStateSummary", oteltrace.WithAttributes( attribute.Stringer("nodeID", nodeID), attribute.Int64("requestID", int64(requestID)), - attribute.Int("numSummaryIDs", len(summaryIDs)), + attribute.Int("numSummaryIDs", summaryIDs.Len()), )) defer span.End() @@ -125,22 +126,22 @@ func (e *tracedEngine) GetAcceptedFrontierFailed(ctx context.Context, nodeID ids return e.engine.GetAcceptedFrontierFailed(ctx, nodeID, requestID) } -func (e *tracedEngine) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { +func (e *tracedEngine) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { ctx, span := e.tracer.Start(ctx, "tracedEngine.GetAccepted", oteltrace.WithAttributes( attribute.Stringer("nodeID", nodeID), attribute.Int64("requestID", int64(requestID)), - attribute.Int("numContainerIDs", len(containerIDs)), + attribute.Int("numContainerIDs", containerIDs.Len()), )) defer span.End() return e.engine.GetAccepted(ctx, nodeID, requestID, containerIDs) } -func (e *tracedEngine) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { +func (e *tracedEngine) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { ctx, span := e.tracer.Start(ctx, "tracedEngine.Accepted", oteltrace.WithAttributes( attribute.Stringer("nodeID", nodeID), attribute.Int64("requestID", int64(requestID)), - attribute.Int("numContainerIDs", len(containerIDs)), + attribute.Int("numContainerIDs", containerIDs.Len()), )) defer span.End() diff --git a/snow/engine/snowman/getter/getter.go b/snow/engine/snowman/getter/getter.go index a582b8af4ef2..0f9dc40b0a19 100644 --- a/snow/engine/snowman/getter/getter.go +++ b/snow/engine/snowman/getter/getter.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/metric" + "github.com/ava-labs/avalanchego/utils/set" ) // Get requests are always served, regardless node state (bootstrapping or normal operations). @@ -94,10 +95,10 @@ func (gh *getter) GetStateSummaryFrontier(ctx context.Context, nodeID ids.NodeID return nil } -func (gh *getter) GetAcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, heights []uint64) error { +func (gh *getter) GetAcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, heights set.Set[uint64]) error { // If there are no requested heights, then we can return the result // immediately, regardless of if the underlying VM implements state sync. - if len(heights) == 0 { + if heights.Len() == 0 { gh.sender.SendAcceptedStateSummary(ctx, nodeID, requestID, nil) return nil } @@ -114,8 +115,8 @@ func (gh *getter) GetAcceptedStateSummary(ctx context.Context, nodeID ids.NodeID return nil } - summaryIDs := make([]ids.ID, 0, len(heights)) - for _, height := range heights { + summaryIDs := make([]ids.ID, 0, heights.Len()) + for height := range heights { summary, err := gh.ssVM.GetStateSummary(ctx, height) if err == block.ErrStateSyncableVMNotImplemented { gh.log.Debug("dropping GetAcceptedStateSummary message", @@ -148,9 +149,9 @@ func (gh *getter) GetAcceptedFrontier(ctx context.Context, nodeID ids.NodeID, re return nil } -func (gh *getter) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { - acceptedIDs := make([]ids.ID, 0, len(containerIDs)) - for _, blkID := range containerIDs { +func (gh *getter) GetAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { + acceptedIDs := make([]ids.ID, 0, containerIDs.Len()) + for blkID := range containerIDs { blk, err := gh.vm.GetBlock(ctx, blkID) if err == nil && blk.Status() == choices.Accepted { acceptedIDs = append(acceptedIDs, blkID) diff --git a/snow/engine/snowman/getter/getter_test.go b/snow/engine/snowman/getter/getter_test.go index 38dc74a2091b..12ecd1abdd80 100644 --- a/snow/engine/snowman/getter/getter_test.go +++ b/snow/engine/snowman/getter/getter_test.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" ) var errUnknownBlock = errors.New("unknown block") @@ -110,7 +111,7 @@ func TestFilterAccepted(t *testing.T) { accepted = frontier } - blkIDs := []ids.ID{blkID0, blkID1, blkID2} + blkIDs := set.Of(blkID0, blkID1, blkID2) require.NoError(bs.GetAccepted(context.Background(), ids.EmptyNodeID, 0, blkIDs)) require.Len(accepted, 2) diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index 87e6d1786173..91c1150b8dbf 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -223,7 +223,7 @@ func (ss *stateSyncer) receivedStateSummaryFrontier(ctx context.Context) error { return nil } -func (ss *stateSyncer) AcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs []ids.ID) error { +func (ss *stateSyncer) AcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs set.Set[ids.ID]) error { // ignores any late responses if requestID != ss.requestID { ss.Ctx.Log.Debug("received out-of-sync AcceptedStateSummary message", @@ -248,10 +248,10 @@ func (ss *stateSyncer) AcceptedStateSummary(ctx context.Context, nodeID ids.Node ss.Ctx.Log.Debug("adding weight to summaries", zap.Stringer("nodeID", nodeID), zap.Stringer("subnetID", ss.Ctx.SubnetID), - zap.Stringers("summaryIDs", summaryIDs), + zap.Reflect("summaryIDs", summaryIDs), zap.Uint64("nodeWeight", nodeWeight), ) - for _, summaryID := range summaryIDs { + for summaryID := range summaryIDs { ws, ok := ss.weightedSummaries[summaryID] if !ok { ss.Ctx.Log.Debug("skipping summary", diff --git a/snow/engine/snowman/syncer/state_syncer_test.go b/snow/engine/snowman/syncer/state_syncer_test.go index ae630bf4dd52..d3f26b129907 100644 --- a/snow/engine/snowman/syncer/state_syncer_test.go +++ b/snow/engine/snowman/syncer/state_syncer_test.go @@ -805,7 +805,7 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { context.Background(), responsiveVoterID, math.MaxInt32, - []ids.ID{summaryID}, + set.Of(summaryID), )) // responsiveVoter still pending @@ -818,7 +818,7 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { context.Background(), unsolicitedVoterID, responsiveVoterReqID, - []ids.ID{summaryID}, + set.Of(summaryID), )) require.Zero(syncer.weightedSummaries[summaryID].weight) @@ -827,7 +827,7 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { context.Background(), responsiveVoterID, responsiveVoterReqID, - []ids.ID{summaryID}, + set.Of(summaryID), )) // responsiveBeacon not pending anymore @@ -928,7 +928,7 @@ func TestVotesForUnknownSummariesAreDropped(t *testing.T) { context.Background(), responsiveVoterID, responsiveVoterReqID, - []ids.ID{unknownSummaryID}, + set.Of(unknownSummaryID), )) _, found = syncer.weightedSummaries[unknownSummaryID] require.False(found) @@ -939,7 +939,7 @@ func TestVotesForUnknownSummariesAreDropped(t *testing.T) { context.Background(), responsiveVoterID, responsiveVoterReqID, - []ids.ID{summaryID}, + set.Of(summaryID), )) require.Zero(syncer.weightedSummaries[summaryID].weight) @@ -1073,7 +1073,7 @@ func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { context.Background(), voterID, reqID, - []ids.ID{summaryID, minoritySummaryID}, + set.Of(summaryID, minoritySummaryID), )) cumulatedWeight += vdrs.GetWeight(ctx.SubnetID, voterID) @@ -1082,7 +1082,7 @@ func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { context.Background(), voterID, reqID, - []ids.ID{summaryID}, + set.Of(summaryID), )) cumulatedWeight += vdrs.GetWeight(ctx.SubnetID, voterID) @@ -1200,7 +1200,7 @@ func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { context.Background(), voterID, reqID, - []ids.ID{summaryID}, + set.Of(summaryID), )) } } @@ -1343,7 +1343,7 @@ func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing. context.Background(), voterID, reqID, - []ids.ID{minoritySummary1.ID(), minoritySummary2.ID()}, + set.Of(minoritySummary1.ID(), minoritySummary2.ID()), )) votingWeightStake += vdrs.GetWeight(ctx.SubnetID, voterID) @@ -1352,7 +1352,7 @@ func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing. context.Background(), voterID, reqID, - []ids.ID{{'u', 'n', 'k', 'n', 'o', 'w', 'n', 'I', 'D'}}, + set.Of(ids.ID{'u', 'n', 'k', 'n', 'o', 'w', 'n', 'I', 'D'}), )) votingWeightStake += vdrs.GetWeight(ctx.SubnetID, voterID) } diff --git a/snow/networking/handler/handler.go b/snow/networking/handler/handler.go index 1a9a1d89b6ae..dc3f95689ab0 100644 --- a/snow/networking/handler/handler.go +++ b/snow/networking/handler/handler.go @@ -31,6 +31,7 @@ import ( "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" commontracker "github.com/ava-labs/avalanchego/snow/engine/common/tracker" @@ -556,23 +557,11 @@ func (h *handler) handleSyncMsg(ctx context.Context, msg Message) error { return engine.GetStateSummaryFrontierFailed(ctx, nodeID, msg.RequestID) case *p2p.GetAcceptedStateSummary: - // TODO: Enforce that the numbers are sorted to make this verification - // more efficient. - if !utils.IsUnique(msg.Heights) { - h.ctx.Log.Debug("message with invalid field", - zap.Stringer("nodeID", nodeID), - zap.Stringer("messageOp", message.GetAcceptedStateSummaryOp), - zap.Uint32("requestID", msg.RequestId), - zap.String("field", "Heights"), - ) - return engine.GetAcceptedStateSummaryFailed(ctx, nodeID, msg.RequestId) - } - return engine.GetAcceptedStateSummary( ctx, nodeID, msg.RequestId, - msg.Heights, + set.Of(msg.Heights...), ) case *p2p.AcceptedStateSummary: diff --git a/snow/networking/handler/handler_test.go b/snow/networking/handler/handler_test.go index c28da4bc8b71..0c87ed752f8b 100644 --- a/snow/networking/handler/handler_test.go +++ b/snow/networking/handler/handler_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/utils/math/meter" "github.com/ava-labs/avalanchego/utils/resource" + "github.com/ava-labs/avalanchego/utils/set" commontracker "github.com/ava-labs/avalanchego/snow/engine/common/tracker" ) @@ -78,11 +79,11 @@ func TestHandlerDropsTimedOutMessages(t *testing.T) { bootstrapper.ContextF = func() *snow.ConsensusContext { return ctx } - bootstrapper.GetAcceptedFrontierF = func(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + bootstrapper.GetAcceptedFrontierF = func(context.Context, ids.NodeID, uint32) error { require.FailNow("GetAcceptedFrontier message should have timed out") return nil } - bootstrapper.GetAcceptedF = func(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) error { + bootstrapper.GetAcceptedF = func(context.Context, ids.NodeID, uint32, set.Set[ids.ID]) error { called <- struct{}{} return nil } diff --git a/snow/networking/handler/parser.go b/snow/networking/handler/parser.go index 9349b073fbb6..148572484ef5 100644 --- a/snow/networking/handler/parser.go +++ b/snow/networking/handler/parser.go @@ -4,27 +4,18 @@ package handler import ( - "errors" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" ) -var errDuplicatedID = errors.New("inbound message contains duplicated ID") - -func getIDs(idsBytes [][]byte) ([]ids.ID, error) { - res := make([]ids.ID, len(idsBytes)) - idSet := set.NewSet[ids.ID](len(idsBytes)) - for i, bytes := range idsBytes { +func getIDs(idsBytes [][]byte) (set.Set[ids.ID], error) { + var res set.Set[ids.ID] + for _, bytes := range idsBytes { id, err := ids.ToID(bytes) if err != nil { return nil, err } - if idSet.Contains(id) { - return nil, errDuplicatedID - } - res[i] = id - idSet.Add(id) + res.Add(id) } return res, nil } diff --git a/utils/sorting.go b/utils/sorting.go index a448b8f5e7ee..74f24abeb69f 100644 --- a/utils/sorting.go +++ b/utils/sorting.go @@ -87,16 +87,3 @@ func IsSortedAndUniqueByHash[T ~[]byte](s []T) bool { } return true } - -// Returns true iff the elements in [s] are unique. -func IsUnique[T comparable](s []T) bool { - // Can't use set.Set because it'd be a circular import. - asMap := make(map[T]struct{}, len(s)) - for _, elt := range s { - if _, ok := asMap[elt]; ok { - return false - } - asMap[elt] = struct{}{} - } - return true -} diff --git a/utils/sorting_test.go b/utils/sorting_test.go index 714fd7d87ec6..464959dd9588 100644 --- a/utils/sorting_test.go +++ b/utils/sorting_test.go @@ -104,31 +104,6 @@ func TestIsSortedAndUniqueSortable(t *testing.T) { require.False(IsSortedAndUnique(s)) } -func TestIsUnique(t *testing.T) { - require := require.New(t) - - var s []int - require.True(IsUnique(s)) - - s = []int{} - require.True(IsUnique(s)) - - s = []int{1} - require.True(IsUnique(s)) - - s = []int{1, 2} - require.True(IsUnique(s)) - - s = []int{1, 1} - require.False(IsUnique(s)) - - s = []int{2, 1} - require.True(IsUnique(s)) - - s = []int{1, 2, 1} - require.False(IsUnique(s)) -} - func TestSortByHash(t *testing.T) { require := require.New(t) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index e9478e293099..cd443a03c326 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1615,7 +1615,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { return nodeIDs } - frontier := []ids.ID{advanceTimeBlkID} + frontier := set.Of(advanceTimeBlkID) require.NoError(bootstrapper.Accepted(context.Background(), peerID, reqID, frontier)) externalSender.SendF = nil From dcc6ea863146e119e5ce6e2695967e565df44c52 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 15 Nov 2023 17:13:19 -0500 Subject: [PATCH 037/267] Use zap.Stringer rather than zap.Any (#2320) --- snow/networking/handler/handler.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/snow/networking/handler/handler.go b/snow/networking/handler/handler.go index dc3f95689ab0..68ec1e5a0f36 100644 --- a/snow/networking/handler/handler.go +++ b/snow/networking/handler/handler.go @@ -455,7 +455,7 @@ func (h *handler) handleSyncMsg(ctx context.Context, msg Message) error { h.ctx.Log.Verbo("forwarding sync message to consensus", zap.Stringer("nodeID", nodeID), zap.Stringer("messageOp", op), - zap.Any("message", body), + zap.Stringer("message", body), ) } else { h.ctx.Log.Debug("forwarding sync message to consensus", @@ -488,7 +488,7 @@ func (h *handler) handleSyncMsg(ctx context.Context, msg Message) error { zap.Duration("msgHandlingTime", msgHandlingTime), zap.Stringer("nodeID", nodeID), zap.Stringer("messageOp", op), - zap.Any("message", body), + zap.Stringer("message", body), ) } }() @@ -793,7 +793,7 @@ func (h *handler) executeAsyncMsg(ctx context.Context, msg Message) error { h.ctx.Log.Verbo("forwarding async message to consensus", zap.Stringer("nodeID", nodeID), zap.Stringer("messageOp", op), - zap.Any("message", body), + zap.Stringer("message", body), ) } else { h.ctx.Log.Debug("forwarding async message to consensus", @@ -893,7 +893,7 @@ func (h *handler) handleChanMsg(msg message.InboundMessage) error { if h.ctx.Log.Enabled(logging.Verbo) { h.ctx.Log.Verbo("forwarding chan message to consensus", zap.Stringer("messageOp", op), - zap.Any("message", body), + zap.Stringer("message", body), ) } else { h.ctx.Log.Debug("forwarding chan message to consensus", @@ -922,7 +922,7 @@ func (h *handler) handleChanMsg(msg message.InboundMessage) error { zap.Duration("processingTime", processingTime), zap.Duration("msgHandlingTime", msgHandlingTime), zap.Stringer("messageOp", op), - zap.Any("message", body), + zap.Stringer("message", body), ) } }() From e8ef4ad2a20e1f5e817068bc2101090f49a2124d Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:15:17 -0800 Subject: [PATCH 038/267] Move `AddUnverifiedTx` logic to `network.IssueTx` (#2310) --- vms/platformvm/block/builder/builder.go | 21 +---------------- vms/platformvm/block/builder/network.go | 30 +++++++++++++++++++++---- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 4d8ad96d132a..63ae6dcb6fea 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -102,26 +102,7 @@ func New( // AddUnverifiedTx verifies a transaction and attempts to add it to the mempool func (b *builder) AddUnverifiedTx(tx *txs.Tx) error { - txID := tx.ID() - if b.Mempool.Has(txID) { - // If the transaction is already in the mempool - then it looks the same - // as if it was successfully added - return nil - } - - if err := b.blkManager.VerifyTx(tx); err != nil { - b.MarkDropped(txID, err) - return err - } - - // If we are partially syncing the Primary Network, we should not be - // maintaining the transaction mempool locally. - if !b.txExecutorBackend.Config.PartialSyncPrimaryNetwork { - if err := b.Mempool.Add(tx); err != nil { - return err - } - } - return b.GossipTx(context.TODO(), tx) + return b.Network.IssueTx(context.TODO(), tx) } // BuildBlock builds a block to be added to consensus. diff --git a/vms/platformvm/block/builder/network.go b/vms/platformvm/block/builder/network.go index d263561bfe74..30896e146ff8 100644 --- a/vms/platformvm/block/builder/network.go +++ b/vms/platformvm/block/builder/network.go @@ -28,8 +28,11 @@ var _ Network = (*network)(nil) type Network interface { common.AppHandler - // GossipTx gossips the transaction to some of the connected peers - GossipTx(ctx context.Context, tx *txs.Tx) error + // IssueTx verifies the transaction at the currently preferred state, adds + // it to the mempool, and gossips it to the network. + // + // Invariant: Assumes the context lock is held. + IssueTx(ctx context.Context, tx *txs.Tx) error } type network struct { @@ -121,7 +124,27 @@ func (n *network) AppGossip(_ context.Context, nodeID ids.NodeID, msgBytes []byt return nil } -func (n *network) GossipTx(ctx context.Context, tx *txs.Tx) error { +func (n *network) IssueTx(ctx context.Context, tx *txs.Tx) error { + txID := tx.ID() + if n.blkBuilder.Mempool.Has(txID) { + // If the transaction is already in the mempool - then it looks the same + // as if it was successfully added + return nil + } + + if err := n.blkBuilder.blkManager.VerifyTx(tx); err != nil { + n.blkBuilder.Mempool.MarkDropped(txID, err) + return err + } + + // If we are partially syncing the Primary Network, we should not be + // maintaining the transaction mempool locally. + if !n.blkBuilder.txExecutorBackend.Config.PartialSyncPrimaryNetwork { + if err := n.blkBuilder.Mempool.Add(tx); err != nil { + return err + } + } + txBytes := tx.Bytes() msg := &message.Tx{ Tx: txBytes, @@ -131,7 +154,6 @@ func (n *network) GossipTx(ctx context.Context, tx *txs.Tx) error { return err } - txID := tx.ID() n.gossipTx(ctx, txID, msgBytes) return nil } From 01a1bbe788905d822a1f8ccccf6a9c6834b75e9a Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 15 Nov 2023 16:01:29 -0800 Subject: [PATCH 039/267] Remove `AddUnverifiedTx` from `Builder` (#2311) --- vms/platformvm/block/builder/builder.go | 8 --- vms/platformvm/block/builder/builder_test.go | 2 +- vms/platformvm/block/builder/network.go | 4 +- vms/platformvm/block/builder/network_test.go | 2 +- vms/platformvm/service.go | 32 +++++----- vms/platformvm/service_test.go | 6 +- vms/platformvm/validator_set_property_test.go | 4 +- vms/platformvm/vm_regression_test.go | 60 +++++++++---------- vms/platformvm/vm_test.go | 30 +++++----- 9 files changed, 70 insertions(+), 78 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 63ae6dcb6fea..f15d012124c4 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -43,9 +43,6 @@ type Builder interface { mempool.BlockTimer Network - // AddUnverifiedTx verifier the tx before adding it to mempool - AddUnverifiedTx(tx *txs.Tx) error - // BuildBlock is called on timer clock to attempt to create // next block BuildBlock(context.Context) (snowman.Block, error) @@ -100,11 +97,6 @@ func New( return builder } -// AddUnverifiedTx verifies a transaction and attempts to add it to the mempool -func (b *builder) AddUnverifiedTx(tx *txs.Tx) error { - return b.Network.IssueTx(context.TODO(), tx) -} - // BuildBlock builds a block to be added to consensus. // This method removes the transactions from the returned // blocks from the mempool. diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index f34faa70e318..79dababd4cb9 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -51,7 +51,7 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { env.sender.SendAppGossipF = func(context.Context, []byte) error { return nil } - require.NoError(env.Builder.AddUnverifiedTx(tx)) + require.NoError(env.Builder.IssueTx(context.Background(), tx)) require.True(env.mempool.Has(txID)) // show that build block include that tx and removes it from mempool diff --git a/vms/platformvm/block/builder/network.go b/vms/platformvm/block/builder/network.go index 30896e146ff8..d58865589a9a 100644 --- a/vms/platformvm/block/builder/network.go +++ b/vms/platformvm/block/builder/network.go @@ -63,7 +63,7 @@ func NewNetwork( } } -func (n *network) AppGossip(_ context.Context, nodeID ids.NodeID, msgBytes []byte) error { +func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []byte) error { n.ctx.Log.Debug("called AppGossip message handler", zap.Stringer("nodeID", nodeID), zap.Int("messageLen", len(msgBytes)), @@ -115,7 +115,7 @@ func (n *network) AppGossip(_ context.Context, nodeID ids.NodeID, msgBytes []byt } // add to mempool - if err := n.blkBuilder.AddUnverifiedTx(tx); err != nil { + if err := n.IssueTx(ctx, tx); err != nil { n.ctx.Log.Debug("tx failed verification", zap.Stringer("nodeID", nodeID), zap.Error(err), diff --git a/vms/platformvm/block/builder/network_test.go b/vms/platformvm/block/builder/network_test.go index 365fc130553a..d5d75e88317c 100644 --- a/vms/platformvm/block/builder/network_test.go +++ b/vms/platformvm/block/builder/network_test.go @@ -125,7 +125,7 @@ func TestMempoolNewLocaTxIsGossiped(t *testing.T) { tx := getValidTx(env.txBuilder, t) txID := tx.ID() - require.NoError(env.Builder.AddUnverifiedTx(tx)) + require.NoError(env.Builder.IssueTx(context.Background(), tx)) require.NotNil(gossipedBytes) // show gossiped bytes can be decoded to the original tx diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index a9c8a039d753..f75171b1007d 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -1185,7 +1185,7 @@ type AddValidatorArgs struct { // AddValidator creates and signs and issues a transaction to add a validator to // the primary network -func (s *Service) AddValidator(_ *http.Request, args *AddValidatorArgs, reply *api.JSONTxIDChangeAddr) error { +func (s *Service) AddValidator(req *http.Request, args *AddValidatorArgs, reply *api.JSONTxIDChangeAddr) error { s.vm.ctx.Log.Warn("deprecated API called", zap.String("service", "platform"), zap.String("method", "addValidator"), @@ -1284,7 +1284,7 @@ func (s *Service) AddValidator(_ *http.Request, args *AddValidatorArgs, reply *a return utils.Err( err, - s.vm.Builder.AddUnverifiedTx(tx), + s.vm.Builder.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1299,7 +1299,7 @@ type AddDelegatorArgs struct { // AddDelegator creates and signs and issues a transaction to add a delegator to // the primary network -func (s *Service) AddDelegator(_ *http.Request, args *AddDelegatorArgs, reply *api.JSONTxIDChangeAddr) error { +func (s *Service) AddDelegator(req *http.Request, args *AddDelegatorArgs, reply *api.JSONTxIDChangeAddr) error { s.vm.ctx.Log.Warn("deprecated API called", zap.String("service", "platform"), zap.String("method", "addDelegator"), @@ -1394,7 +1394,7 @@ func (s *Service) AddDelegator(_ *http.Request, args *AddDelegatorArgs, reply *a return utils.Err( err, - s.vm.Builder.AddUnverifiedTx(tx), + s.vm.Builder.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1410,7 +1410,7 @@ type AddSubnetValidatorArgs struct { // AddSubnetValidator creates and signs and issues a transaction to add a // validator to a subnet other than the primary network -func (s *Service) AddSubnetValidator(_ *http.Request, args *AddSubnetValidatorArgs, response *api.JSONTxIDChangeAddr) error { +func (s *Service) AddSubnetValidator(req *http.Request, args *AddSubnetValidatorArgs, response *api.JSONTxIDChangeAddr) error { s.vm.ctx.Log.Warn("deprecated API called", zap.String("service", "platform"), zap.String("method", "addSubnetValidator"), @@ -1500,7 +1500,7 @@ func (s *Service) AddSubnetValidator(_ *http.Request, args *AddSubnetValidatorAr return utils.Err( err, - s.vm.Builder.AddUnverifiedTx(tx), + s.vm.Builder.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1515,7 +1515,7 @@ type CreateSubnetArgs struct { // CreateSubnet creates and signs and issues a transaction to create a new // subnet -func (s *Service) CreateSubnet(_ *http.Request, args *CreateSubnetArgs, response *api.JSONTxIDChangeAddr) error { +func (s *Service) CreateSubnet(req *http.Request, args *CreateSubnetArgs, response *api.JSONTxIDChangeAddr) error { s.vm.ctx.Log.Warn("deprecated API called", zap.String("service", "platform"), zap.String("method", "createSubnet"), @@ -1576,7 +1576,7 @@ func (s *Service) CreateSubnet(_ *http.Request, args *CreateSubnetArgs, response return utils.Err( err, - s.vm.Builder.AddUnverifiedTx(tx), + s.vm.Builder.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1599,7 +1599,7 @@ type ExportAVAXArgs struct { // ExportAVAX exports AVAX from the P-Chain to the X-Chain // It must be imported on the X-Chain to complete the transfer -func (s *Service) ExportAVAX(_ *http.Request, args *ExportAVAXArgs, response *api.JSONTxIDChangeAddr) error { +func (s *Service) ExportAVAX(req *http.Request, args *ExportAVAXArgs, response *api.JSONTxIDChangeAddr) error { s.vm.ctx.Log.Warn("deprecated API called", zap.String("service", "platform"), zap.String("method", "exportAVAX"), @@ -1672,7 +1672,7 @@ func (s *Service) ExportAVAX(_ *http.Request, args *ExportAVAXArgs, response *ap return utils.Err( err, - s.vm.Builder.AddUnverifiedTx(tx), + s.vm.Builder.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1691,7 +1691,7 @@ type ImportAVAXArgs struct { // ImportAVAX issues a transaction to import AVAX from the X-chain. The AVAX // must have already been exported from the X-Chain. -func (s *Service) ImportAVAX(_ *http.Request, args *ImportAVAXArgs, response *api.JSONTxIDChangeAddr) error { +func (s *Service) ImportAVAX(req *http.Request, args *ImportAVAXArgs, response *api.JSONTxIDChangeAddr) error { s.vm.ctx.Log.Warn("deprecated API called", zap.String("service", "platform"), zap.String("method", "importAVAX"), @@ -1757,7 +1757,7 @@ func (s *Service) ImportAVAX(_ *http.Request, args *ImportAVAXArgs, response *ap return utils.Err( err, - s.vm.Builder.AddUnverifiedTx(tx), + s.vm.Builder.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1787,7 +1787,7 @@ type CreateBlockchainArgs struct { } // CreateBlockchain issues a transaction to create a new blockchain -func (s *Service) CreateBlockchain(_ *http.Request, args *CreateBlockchainArgs, response *api.JSONTxIDChangeAddr) error { +func (s *Service) CreateBlockchain(req *http.Request, args *CreateBlockchainArgs, response *api.JSONTxIDChangeAddr) error { s.vm.ctx.Log.Warn("deprecated API called", zap.String("service", "platform"), zap.String("method", "createBlockchain"), @@ -1881,7 +1881,7 @@ func (s *Service) CreateBlockchain(_ *http.Request, args *CreateBlockchainArgs, return utils.Err( err, - s.vm.Builder.AddUnverifiedTx(tx), + s.vm.Builder.IssueTx(req.Context(), tx), user.Close(), ) } @@ -2155,7 +2155,7 @@ func (s *Service) GetBlockchains(_ *http.Request, _ *struct{}, response *GetBloc return nil } -func (s *Service) IssueTx(_ *http.Request, args *api.FormattedTx, response *api.JSONTxID) error { +func (s *Service) IssueTx(req *http.Request, args *api.FormattedTx, response *api.JSONTxID) error { s.vm.ctx.Log.Debug("API called", zap.String("service", "platform"), zap.String("method", "issueTx"), @@ -2173,7 +2173,7 @@ func (s *Service) IssueTx(_ *http.Request, args *api.FormattedTx, response *api. s.vm.ctx.Lock.Lock() defer s.vm.ctx.Lock.Unlock() - if err := s.vm.Builder.AddUnverifiedTx(tx); err != nil { + if err := s.vm.Builder.IssueTx(req.Context(), tx); err != nil { return fmt.Errorf("couldn't issue tx: %w", err) } diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 692b7afdb405..e206a1228a2f 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -238,12 +238,12 @@ func TestGetTxStatus(t *testing.T) { service.vm.ctx.Lock.Lock() // put the chain in existing chain list - err = service.vm.Builder.AddUnverifiedTx(tx) + err = service.vm.Builder.IssueTx(context.Background(), tx) require.ErrorIs(err, database.ErrNotFound) // Missing shared memory UTXO mutableSharedMemory.SharedMemory = sm - require.NoError(service.vm.Builder.AddUnverifiedTx(tx)) + require.NoError(service.vm.Builder.IssueTx(context.Background(), tx)) block, err := service.vm.BuildBlock(context.Background()) require.NoError(err) @@ -339,7 +339,7 @@ func TestGetTx(t *testing.T) { service.vm.ctx.Lock.Lock() - require.NoError(service.vm.Builder.AddUnverifiedTx(tx)) + require.NoError(service.vm.Builder.IssueTx(context.Background(), tx)) blk, err := service.vm.BuildBlock(context.Background()) require.NoError(err) diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index be3962f36701..35135bb49f3d 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -374,7 +374,7 @@ func addPrimaryValidatorWithoutBLSKey(vm *VM, data *validatorInputData) (*state. func internalAddValidator(vm *VM, signedTx *txs.Tx) (*state.Staker, error) { stakerTx := signedTx.Unsigned.(txs.StakerTx) - if err := vm.Builder.AddUnverifiedTx(signedTx); err != nil { + if err := vm.Builder.IssueTx(context.Background(), signedTx); err != nil { return nil, fmt.Errorf("could not add tx to mempool: %w", err) } @@ -802,7 +802,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { if err != nil { return nil, ids.Empty, err } - if err := vm.Builder.AddUnverifiedTx(testSubnet1); err != nil { + if err := vm.Builder.IssueTx(context.Background(), testSubnet1); err != nil { return nil, ids.Empty, err } diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index ca8735e18e3e..00c2d18a0c13 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -72,7 +72,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.AddUnverifiedTx(addValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -104,7 +104,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.AddUnverifiedTx(addFirstDelegatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addFirstDelegatorTx)) addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -138,7 +138,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.AddUnverifiedTx(addSecondDelegatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addSecondDelegatorTx)) addSecondDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -162,7 +162,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - err = vm.Builder.AddUnverifiedTx(addThirdDelegatorTx) + err = vm.Builder.IssueTx(context.Background(), addThirdDelegatorTx) require.ErrorIs(err, executor.ErrOverDelegated) } @@ -235,7 +235,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the add validator tx - require.NoError(vm.Builder.AddUnverifiedTx(addValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -257,7 +257,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the first add delegator tx - require.NoError(vm.Builder.AddUnverifiedTx(addFirstDelegatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addFirstDelegatorTx)) // trigger block creation for the first add delegator tx addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -279,7 +279,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the second add delegator tx - require.NoError(vm.Builder.AddUnverifiedTx(addSecondDelegatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addSecondDelegatorTx)) // trigger block creation for the second add delegator tx addSecondDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -301,7 +301,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the third add delegator tx - require.NoError(vm.Builder.AddUnverifiedTx(addThirdDelegatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addThirdDelegatorTx)) // trigger block creation for the third add delegator tx addThirdDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -323,7 +323,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the fourth add delegator tx - require.NoError(vm.Builder.AddUnverifiedTx(addFourthDelegatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addFourthDelegatorTx)) // trigger block creation for the fourth add delegator tx addFourthDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1166,7 +1166,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require.NoError(err) // issue the add validator tx - require.NoError(vm.Builder.AddUnverifiedTx(addValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1188,7 +1188,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require.NoError(err) // issue the first add delegator tx - require.NoError(vm.Builder.AddUnverifiedTx(addFirstDelegatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addFirstDelegatorTx)) // trigger block creation for the first add delegator tx addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1211,7 +1211,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { // attempting to issue the second add delegator tx should fail because the // total stake weight would go over the limit. - err = vm.Builder.AddUnverifiedTx(addSecondDelegatorTx) + err = vm.Builder.IssueTx(context.Background(), addSecondDelegatorTx) require.ErrorIs(err, executor.ErrOverDelegated) } @@ -1248,7 +1248,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(addValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1265,7 +1265,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(createSubnetTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1285,7 +1285,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(addSubnetValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addSubnetValidatorTx)) // trigger block creation for the validator tx addSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1314,7 +1314,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t // validator set into the current validator set. vm.clock.Set(validatorStartTime) - require.NoError(vm.Builder.AddUnverifiedTx(removeSubnetValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), removeSubnetValidatorTx)) // trigger block creation for the validator tx removeSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1365,7 +1365,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(addValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1382,7 +1382,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(createSubnetTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1402,7 +1402,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(addSubnetValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addSubnetValidatorTx)) // trigger block creation for the validator tx addSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1423,7 +1423,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t // validator set into the current validator set. vm.clock.Set(validatorStartTime) - require.NoError(vm.Builder.AddUnverifiedTx(removeSubnetValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), removeSubnetValidatorTx)) // trigger block creation for the validator tx removeSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1517,7 +1517,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NoError(primaryTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Builder.AddUnverifiedTx(primaryTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), primaryTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1544,7 +1544,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(subnetTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), subnetTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current @@ -1648,7 +1648,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Builder.AddUnverifiedTx(primaryRestartTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), primaryRestartTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -1756,7 +1756,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(primaryTx1)) + require.NoError(vm.Builder.IssueTx(context.Background(), primaryTx1)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1848,7 +1848,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Builder.AddUnverifiedTx(primaryRestartTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), primaryRestartTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -1919,7 +1919,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(primaryTx1)) + require.NoError(vm.Builder.IssueTx(context.Background(), primaryTx1)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1946,7 +1946,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(subnetTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), subnetTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current @@ -2050,7 +2050,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Builder.AddUnverifiedTx(primaryRestartTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), primaryRestartTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -2128,7 +2128,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(primaryTx1)) + require.NoError(vm.Builder.IssueTx(context.Background(), primaryTx1)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -2152,7 +2152,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(subnetTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), subnetTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index cd443a03c326..bdd3e39fc24b 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -364,7 +364,7 @@ func defaultVM(t *testing.T) (*VM, database.Database, *mutableSharedMemory) { keys[0].PublicKey().Address(), // change addr ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(testSubnet1)) + require.NoError(vm.Builder.IssueTx(context.Background(), testSubnet1)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) require.NoError(blk.Verify(context.Background())) @@ -460,7 +460,7 @@ func TestAddValidatorCommit(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.AddUnverifiedTx(tx)) + require.NoError(vm.Builder.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -560,7 +560,7 @@ func TestAddValidatorReject(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.AddUnverifiedTx(tx)) + require.NoError(vm.Builder.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -605,7 +605,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { require.NoError(err) // trigger block creation - err = vm.Builder.AddUnverifiedTx(tx) + err = vm.Builder.IssueTx(context.Background(), tx) require.ErrorIs(err, txexecutor.ErrAlreadyValidator) } @@ -638,7 +638,7 @@ func TestAddSubnetValidatorAccept(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.AddUnverifiedTx(tx)) + require.NoError(vm.Builder.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -684,7 +684,7 @@ func TestAddSubnetValidatorReject(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.AddUnverifiedTx(tx)) + require.NoError(vm.Builder.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -879,7 +879,7 @@ func TestCreateChain(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(tx)) + require.NoError(vm.Builder.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) // should contain proposal to create chain @@ -932,7 +932,7 @@ func TestCreateSubnet(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(createSubnetTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) // should contain proposal to create subnet blk, err := vm.Builder.BuildBlock(context.Background()) @@ -973,7 +973,7 @@ func TestCreateSubnet(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(addValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) blk, err = vm.Builder.BuildBlock(context.Background()) // should add validator to the new subnet require.NoError(err) @@ -1089,7 +1089,7 @@ func TestAtomicImport(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(tx)) + require.NoError(vm.Builder.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2050,7 +2050,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(addValidatorTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -2067,7 +2067,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(createSubnetTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -2136,7 +2136,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { require.NoError(err) subnetID := createSubnetTx.ID() - require.NoError(vm.Builder.AddUnverifiedTx(createSubnetTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2168,7 +2168,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(transferSubnetOwnershipTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), transferSubnetOwnershipTx)) transferSubnetOwnershipBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2254,7 +2254,7 @@ func TestBaseTx(t *testing.T) { require.Equal(vm.TxFee, totalInputAmt-totalOutputAmt) require.Equal(sendAmt, key1OutputAmt) - require.NoError(vm.Builder.AddUnverifiedTx(baseTx)) + require.NoError(vm.Builder.IssueTx(context.Background(), baseTx)) baseTxBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) From 3d0611ce0103ecfa763ebe1e292d78f98e99c70c Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed, 15 Nov 2023 19:24:10 -0500 Subject: [PATCH 040/267] Remove error from SDK AppGossip handler (#2252) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- go.mod | 2 +- go.sum | 4 +- network/p2p/handler.go | 31 +++++-------- network/p2p/handler_test.go | 20 ++++++--- network/p2p/mocks/mock_handler.go | 6 +-- network/p2p/router.go | 2 +- network/p2p/throttler_handler.go | 11 +++-- network/p2p/throttler_handler_test.go | 65 ++++++++++++++++++++++----- 8 files changed, 91 insertions(+), 50 deletions(-) diff --git a/go.mod b/go.mod index 0c161de4a463..1d267ea33bd5 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.8-rc.1 + github.com/ava-labs/coreth v0.12.9-rc.0 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 164a7e96d6c0..a0ace68aff35 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.8-rc.1 h1:tvJcxQTQzxIQqx8TnrxdyMhZYbdsMaiy6AEiOyjvaa4= -github.com/ava-labs/coreth v0.12.8-rc.1/go.mod h1:GBH5SxHZdScSp95IijDs9+Gxw/QDIWvfoLKiJMNYLsE= +github.com/ava-labs/coreth v0.12.9-rc.0 h1:Xvk/iJTY2MSBkkiOs9Eo92nxd67VXzRjaC/WmQXRIb0= +github.com/ava-labs/coreth v0.12.9-rc.0/go.mod h1:rECKQfGFDeodrwGPlJSvFUJDbVr30jSMIVjQLi6pNX4= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/network/p2p/handler.go b/network/p2p/handler.go index 3e08c356eea8..b85195a5255c 100644 --- a/network/p2p/handler.go +++ b/network/p2p/handler.go @@ -30,7 +30,7 @@ type Handler interface { ctx context.Context, nodeID ids.NodeID, gossipBytes []byte, - ) error + ) // AppRequest is called when handling an AppRequest message. // Returns the bytes for the response corresponding to [requestBytes] AppRequest( @@ -53,9 +53,7 @@ type Handler interface { // NoOpHandler drops all messages type NoOpHandler struct{} -func (NoOpHandler) AppGossip(context.Context, ids.NodeID, []byte) error { - return nil -} +func (NoOpHandler) AppGossip(context.Context, ids.NodeID, []byte) {} func (NoOpHandler) AppRequest(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { return nil, nil @@ -69,14 +67,16 @@ func (NoOpHandler) CrossChainAppRequest(context.Context, ids.ID, time.Time, []by type ValidatorHandler struct { Handler ValidatorSet ValidatorSet + Log logging.Logger } -func (v ValidatorHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) error { +func (v ValidatorHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { if !v.ValidatorSet.Has(ctx, nodeID) { - return ErrNotValidator + v.Log.Debug("dropping message", zap.Stringer("nodeID", nodeID)) + return } - return v.Handler.AppGossip(ctx, nodeID, gossipBytes) + v.Handler.AppGossip(ctx, nodeID, gossipBytes) } func (v ValidatorHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { @@ -89,15 +89,15 @@ func (v ValidatorHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, dea // responder automatically sends the response for a given request type responder struct { + Handler handlerID uint64 - handler Handler log logging.Logger sender common.AppSender } // AppRequest calls the underlying handler and sends back the response to nodeID func (r *responder) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { - appResponse, err := r.handler.AppRequest(ctx, nodeID, deadline, request) + appResponse, err := r.Handler.AppRequest(ctx, nodeID, deadline, request) if err != nil { r.log.Debug("failed to handle message", zap.Stringer("messageOp", message.AppRequestOp), @@ -113,21 +113,10 @@ func (r *responder) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID return r.sender.SendAppResponse(ctx, nodeID, requestID, appResponse) } -func (r *responder) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte) { - if err := r.handler.AppGossip(ctx, nodeID, msg); err != nil { - r.log.Debug("failed to handle message", - zap.Stringer("messageOp", message.AppGossipOp), - zap.Stringer("nodeID", nodeID), - zap.Uint64("handlerID", r.handlerID), - zap.Binary("message", msg), - ) - } -} - // CrossChainAppRequest calls the underlying handler and sends back the response // to chainID func (r *responder) CrossChainAppRequest(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, request []byte) error { - appResponse, err := r.handler.CrossChainAppRequest(ctx, chainID, deadline, request) + appResponse, err := r.Handler.CrossChainAppRequest(ctx, chainID, deadline, request) if err != nil { r.log.Debug("failed to handle message", zap.Stringer("messageOp", message.CrossChainAppRequestOp), diff --git a/network/p2p/handler_test.go b/network/p2p/handler_test.go index 539076cb7062..b7a1b6bec899 100644 --- a/network/p2p/handler_test.go +++ b/network/p2p/handler_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" ) @@ -32,20 +33,20 @@ func TestValidatorHandlerAppGossip(t *testing.T) { name string validatorSet ValidatorSet nodeID ids.NodeID - expected error + expected bool }{ { name: "message dropped", validatorSet: testValidatorSet{}, nodeID: nodeID, - expected: ErrNotValidator, }, { name: "message handled", validatorSet: testValidatorSet{ validators: validatorSet, }, - nodeID: nodeID, + nodeID: nodeID, + expected: true, }, } @@ -53,13 +54,19 @@ func TestValidatorHandlerAppGossip(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) + called := false handler := ValidatorHandler{ - Handler: NoOpHandler{}, + Handler: testHandler{ + appGossipF: func(context.Context, ids.NodeID, []byte) { + called = true + }, + }, ValidatorSet: tt.validatorSet, + Log: logging.NoLog{}, } - err := handler.AppGossip(context.Background(), tt.nodeID, []byte("foobar")) - require.ErrorIs(err, tt.expected) + handler.AppGossip(context.Background(), tt.nodeID, []byte("foobar")) + require.Equal(tt.expected, called) }) } } @@ -96,6 +103,7 @@ func TestValidatorHandlerAppRequest(t *testing.T) { handler := ValidatorHandler{ Handler: NoOpHandler{}, ValidatorSet: tt.validatorSet, + Log: logging.NoLog{}, } _, err := handler.AppRequest(context.Background(), tt.nodeID, time.Time{}, []byte("foobar")) diff --git a/network/p2p/mocks/mock_handler.go b/network/p2p/mocks/mock_handler.go index b15c77b79896..0d4147d23183 100644 --- a/network/p2p/mocks/mock_handler.go +++ b/network/p2p/mocks/mock_handler.go @@ -40,11 +40,9 @@ func (m *MockHandler) EXPECT() *MockHandlerMockRecorder { } // AppGossip mocks base method. -func (m *MockHandler) AppGossip(arg0 context.Context, arg1 ids.NodeID, arg2 []byte) error { +func (m *MockHandler) AppGossip(arg0 context.Context, arg1 ids.NodeID, arg2 []byte) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppGossip", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.Call(m, "AppGossip", arg0, arg1, arg2) } // AppGossip indicates an expected call of AppGossip. diff --git a/network/p2p/router.go b/network/p2p/router.go index e872152195db..b689b7ae1a17 100644 --- a/network/p2p/router.go +++ b/network/p2p/router.go @@ -174,8 +174,8 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp r.handlers[handlerID] = &meteredHandler{ responder: &responder{ + Handler: handler, handlerID: handlerID, - handler: handler, log: r.log, sender: r.sender, }, diff --git a/network/p2p/throttler_handler.go b/network/p2p/throttler_handler.go index e7b4d8f26082..4dd142c400c1 100644 --- a/network/p2p/throttler_handler.go +++ b/network/p2p/throttler_handler.go @@ -9,7 +9,10 @@ import ( "fmt" "time" + "go.uber.org/zap" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" ) var ( @@ -20,14 +23,16 @@ var ( type ThrottlerHandler struct { Handler Throttler Throttler + Log logging.Logger } -func (t ThrottlerHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) error { +func (t ThrottlerHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { if !t.Throttler.Handle(nodeID) { - return fmt.Errorf("dropping message from %s: %w", nodeID, ErrThrottled) + t.Log.Debug("dropping message", zap.Stringer("nodeID", nodeID)) + return } - return t.Handler.AppGossip(ctx, nodeID, gossipBytes) + t.Handler.AppGossip(ctx, nodeID, gossipBytes) } func (t ThrottlerHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { diff --git a/network/p2p/throttler_handler_test.go b/network/p2p/throttler_handler_test.go index af9c3fda7194..1e4ed9578bf6 100644 --- a/network/p2p/throttler_handler_test.go +++ b/network/p2p/throttler_handler_test.go @@ -11,34 +11,44 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" ) +var _ Handler = (*testHandler)(nil) + func TestThrottlerHandlerAppGossip(t *testing.T) { tests := []struct { - name string - Throttler Throttler - expectedErr error + name string + Throttler Throttler + expected bool }{ { - name: "throttled", + name: "not throttled", Throttler: NewSlidingWindowThrottler(time.Second, 1), + expected: true, }, { - name: "throttler errors", - Throttler: NewSlidingWindowThrottler(time.Second, 0), - expectedErr: ErrThrottled, + name: "throttled", + Throttler: NewSlidingWindowThrottler(time.Second, 0), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { require := require.New(t) + called := false handler := ThrottlerHandler{ - Handler: NoOpHandler{}, + Handler: testHandler{ + appGossipF: func(context.Context, ids.NodeID, []byte) { + called = true + }, + }, Throttler: tt.Throttler, + Log: logging.NoLog{}, } - err := handler.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte("foobar")) - require.ErrorIs(err, tt.expectedErr) + + handler.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte("foobar")) + require.Equal(tt.expected, called) }) } } @@ -50,11 +60,11 @@ func TestThrottlerHandlerAppRequest(t *testing.T) { expectedErr error }{ { - name: "throttled", + name: "not throttled", Throttler: NewSlidingWindowThrottler(time.Second, 1), }, { - name: "throttler errors", + name: "throttled", Throttler: NewSlidingWindowThrottler(time.Second, 0), expectedErr: ErrThrottled, }, @@ -66,9 +76,40 @@ func TestThrottlerHandlerAppRequest(t *testing.T) { handler := ThrottlerHandler{ Handler: NoOpHandler{}, Throttler: tt.Throttler, + Log: logging.NoLog{}, } _, err := handler.AppRequest(context.Background(), ids.GenerateTestNodeID(), time.Time{}, []byte("foobar")) require.ErrorIs(err, tt.expectedErr) }) } } + +type testHandler struct { + appGossipF func(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) + appRequestF func(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) + crossChainAppRequestF func(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) +} + +func (t testHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { + if t.appGossipF == nil { + return + } + + t.appGossipF(ctx, nodeID, gossipBytes) +} + +func (t testHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { + if t.appRequestF == nil { + return nil, nil + } + + return t.appRequestF(ctx, nodeID, deadline, requestBytes) +} + +func (t testHandler) CrossChainAppRequest(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) { + if t.crossChainAppRequestF == nil { + return nil, nil + } + + return t.crossChainAppRequestF(ctx, chainID, deadline, requestBytes) +} From 6484de4fa06323afa11e206a3b960916019250fd Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Thu, 16 Nov 2023 04:31:34 -0500 Subject: [PATCH 041/267] Rename AppRequestFailed to AppError (#2321) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- proto/p2p/p2p.proto | 8 +- proto/pb/p2p/p2p.pb.go | 486 ++++++++++++++++++++--------------------- 2 files changed, 246 insertions(+), 248 deletions(-) diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 9d355688bd49..09618923a866 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -58,7 +58,7 @@ message Message { AppGossip app_gossip = 32; PeerListAck peer_list_ack = 33; - AppRequestFailed app_request_failed = 34; + AppError app_error = 34; } } @@ -387,7 +387,7 @@ message Chits { // AppRequest is a VM-defined request. // // Remote peers must respond to AppRequest with a corresponding AppResponse or -// AppRequestFailed +// AppError message AppRequest { // Chain being requested from bytes chain_id = 1; @@ -409,8 +409,8 @@ message AppResponse { bytes app_bytes = 3; } -// AppRequestFailed is a VM-defined error sent in response to AppRequest -message AppRequestFailed { +// AppError is a VM-defined error sent in response to AppRequest +message AppError { // Chain the message is for bytes chain_id = 1; // Request id of the original AppRequest diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index 89fb2e201520..e2761bed03aa 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -109,7 +109,7 @@ type Message struct { // *Message_AppResponse // *Message_AppGossip // *Message_PeerListAck - // *Message_AppRequestFailed + // *Message_AppError Message isMessage_Message `protobuf_oneof:"message"` } @@ -327,9 +327,9 @@ func (x *Message) GetPeerListAck() *PeerListAck { return nil } -func (x *Message) GetAppRequestFailed() *AppRequestFailed { - if x, ok := x.GetMessage().(*Message_AppRequestFailed); ok { - return x.AppRequestFailed +func (x *Message) GetAppError() *AppError { + if x, ok := x.GetMessage().(*Message_AppError); ok { + return x.AppError } return nil } @@ -449,8 +449,8 @@ type Message_PeerListAck struct { PeerListAck *PeerListAck `protobuf:"bytes,33,opt,name=peer_list_ack,json=peerListAck,proto3,oneof"` } -type Message_AppRequestFailed struct { - AppRequestFailed *AppRequestFailed `protobuf:"bytes,34,opt,name=app_request_failed,json=appRequestFailed,proto3,oneof"` +type Message_AppError struct { + AppError *AppError `protobuf:"bytes,34,opt,name=app_error,json=appError,proto3,oneof"` } func (*Message_CompressedGzip) isMessage_Message() {} @@ -503,7 +503,7 @@ func (*Message_AppGossip) isMessage_Message() {} func (*Message_PeerListAck) isMessage_Message() {} -func (*Message_AppRequestFailed) isMessage_Message() {} +func (*Message_AppError) isMessage_Message() {} // Ping reports a peer's perceived uptime percentage. // @@ -2241,7 +2241,7 @@ func (x *Chits) GetPreferredIdAtHeight() []byte { // AppRequest is a VM-defined request. // // Remote peers must respond to AppRequest with a corresponding AppResponse or -// AppRequestFailed +// AppError type AppRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2384,8 +2384,8 @@ func (x *AppResponse) GetAppBytes() []byte { return nil } -// AppRequestFailed is a VM-defined error sent in response to AppRequest -type AppRequestFailed struct { +// AppError is a VM-defined error sent in response to AppRequest +type AppError struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -2400,8 +2400,8 @@ type AppRequestFailed struct { ErrorMessage string `protobuf:"bytes,4,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` } -func (x *AppRequestFailed) Reset() { - *x = AppRequestFailed{} +func (x *AppError) Reset() { + *x = AppError{} if protoimpl.UnsafeEnabled { mi := &file_p2p_p2p_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2409,13 +2409,13 @@ func (x *AppRequestFailed) Reset() { } } -func (x *AppRequestFailed) String() string { +func (x *AppError) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AppRequestFailed) ProtoMessage() {} +func (*AppError) ProtoMessage() {} -func (x *AppRequestFailed) ProtoReflect() protoreflect.Message { +func (x *AppError) ProtoReflect() protoreflect.Message { mi := &file_p2p_p2p_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2427,33 +2427,33 @@ func (x *AppRequestFailed) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AppRequestFailed.ProtoReflect.Descriptor instead. -func (*AppRequestFailed) Descriptor() ([]byte, []int) { +// Deprecated: Use AppError.ProtoReflect.Descriptor instead. +func (*AppError) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{26} } -func (x *AppRequestFailed) GetChainId() []byte { +func (x *AppError) GetChainId() []byte { if x != nil { return x.ChainId } return nil } -func (x *AppRequestFailed) GetRequestId() uint32 { +func (x *AppError) GetRequestId() uint32 { if x != nil { return x.RequestId } return 0 } -func (x *AppRequestFailed) GetErrorCode() uint32 { +func (x *AppError) GetErrorCode() uint32 { if x != nil { return x.ErrorCode } return 0 } -func (x *AppRequestFailed) GetErrorMessage() string { +func (x *AppError) GetErrorMessage() string { if x != nil { return x.ErrorMessage } @@ -2522,7 +2522,7 @@ var File_p2p_p2p_proto protoreflect.FileDescriptor var file_p2p_p2p_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x03, 0x70, 0x32, 0x70, 0x22, 0xa5, 0x0b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x03, 0x70, 0x32, 0x70, 0x22, 0x8c, 0x0b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x7a, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x47, 0x7a, 0x69, 0x70, 0x12, 0x29, 0x0a, 0x0f, 0x63, @@ -2607,250 +2607,248 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x69, 0x70, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0b, 0x70, - 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x45, 0x0a, 0x12, 0x61, 0x70, - 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x48, 0x00, 0x52, - 0x10, 0x61, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, - 0x64, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x58, 0x0a, 0x04, - 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, - 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, - 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, - 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, - 0x6f, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, - 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0xf5, 0x01, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, - 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x06, 0x6d, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, - 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, - 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x79, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x03, 0x73, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, - 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, - 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x22, 0xbd, 0x01, - 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, - 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, - 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, - 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, - 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, - 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, - 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, - 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, - 0x63, 0x6b, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3e, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, - 0x74, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x41, 0x63, 0x6b, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, - 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x2c, 0x0a, 0x09, 0x61, 0x70, + 0x70, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x08, + 0x61, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, + 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0x43, 0x0a, + 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, + 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, + 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0xf5, 0x01, 0x0a, + 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x79, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, + 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, + 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x79, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, + 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, + 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, + 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, + 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, + 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0e, + 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x3c, + 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3e, 0x0a, 0x0b, + 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x09, 0x70, + 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x52, 0x08, 0x70, 0x65, + 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6f, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, + 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, + 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, - 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x75, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, + 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, + 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6f, 0x0a, 0x08, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb9, 0x01, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, - 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x6e, 0x63, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, - 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, + 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, + 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, 0x75, + 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x09, + 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, - 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x75, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, + 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x09, 0x50, + 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, - 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6f, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, - 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, + 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xba, + 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, + 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, + 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, - 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, + 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, - 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, - 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, - 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, - 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, - 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, - 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x90, 0x01, 0x0a, 0x10, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, - 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, - 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, - 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, - 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, - 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, - 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, + 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, + 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, + 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, + 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, + 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2895,7 +2893,7 @@ var file_p2p_p2p_proto_goTypes = []interface{}{ (*Chits)(nil), // 24: p2p.Chits (*AppRequest)(nil), // 25: p2p.AppRequest (*AppResponse)(nil), // 26: p2p.AppResponse - (*AppRequestFailed)(nil), // 27: p2p.AppRequestFailed + (*AppError)(nil), // 27: p2p.AppError (*AppGossip)(nil), // 28: p2p.AppGossip } var file_p2p_p2p_proto_depIdxs = []int32{ @@ -2922,7 +2920,7 @@ var file_p2p_p2p_proto_depIdxs = []int32{ 26, // 20: p2p.Message.app_response:type_name -> p2p.AppResponse 28, // 21: p2p.Message.app_gossip:type_name -> p2p.AppGossip 9, // 22: p2p.Message.peer_list_ack:type_name -> p2p.PeerListAck - 27, // 23: p2p.Message.app_request_failed:type_name -> p2p.AppRequestFailed + 27, // 23: p2p.Message.app_error:type_name -> p2p.AppError 3, // 24: p2p.Ping.subnet_uptimes:type_name -> p2p.SubnetUptime 3, // 25: p2p.Pong.subnet_uptimes:type_name -> p2p.SubnetUptime 6, // 26: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort @@ -3260,7 +3258,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AppRequestFailed); i { + switch v := v.(*AppError); i { case 0: return &v.state case 1: @@ -3310,7 +3308,7 @@ func file_p2p_p2p_proto_init() { (*Message_AppResponse)(nil), (*Message_AppGossip)(nil), (*Message_PeerListAck)(nil), - (*Message_AppRequestFailed)(nil), + (*Message_AppError)(nil), } type x struct{} out := protoimpl.TypeBuilder{ From 348f842050fb8772a206ddde3fd9cc48565e3566 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 16 Nov 2023 08:39:03 -0800 Subject: [PATCH 042/267] Remove `Network` interface from `Builder` (#2312) --- vms/platformvm/block/builder/builder.go | 9 --- vms/platformvm/block/builder/builder_test.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 10 +++- vms/platformvm/block/builder/network.go | 38 +++++++----- vms/platformvm/block/builder/network_test.go | 6 +- vms/platformvm/service.go | 16 ++--- vms/platformvm/service_test.go | 6 +- vms/platformvm/validator_set_property_test.go | 4 +- vms/platformvm/vm.go | 9 ++- vms/platformvm/vm_regression_test.go | 60 +++++++++---------- vms/platformvm/vm_test.go | 30 +++++----- 11 files changed, 102 insertions(+), 88 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index f15d012124c4..13a1c7902b6d 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -41,7 +41,6 @@ var ( type Builder interface { mempool.Mempool mempool.BlockTimer - Network // BuildBlock is called on timer clock to attempt to create // next block @@ -54,7 +53,6 @@ type Builder interface { // builder implements a simple builder to convert txs into valid blocks type builder struct { mempool.Mempool - Network txBuilder txbuilder.Builder txExecutorBackend *txexecutor.Backend @@ -75,7 +73,6 @@ func New( txExecutorBackend *txexecutor.Backend, blkManager blockexecutor.Manager, toEngine chan<- common.Message, - appSender common.AppSender, ) Builder { builder := &builder{ Mempool: mempool, @@ -87,12 +84,6 @@ func New( builder.timer = timer.NewTimer(builder.setNextBuildBlockTime) - builder.Network = NewNetwork( - txExecutorBackend.Ctx, - builder, - appSender, - ) - go txExecutorBackend.Ctx.Log.RecoverAndPanic(builder.timer.Dispatch) return builder } diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 79dababd4cb9..2bf97a8c8ef2 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -51,7 +51,7 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { env.sender.SendAppGossipF = func(context.Context, []byte) error { return nil } - require.NoError(env.Builder.IssueTx(context.Background(), tx)) + require.NoError(env.network.IssueTx(context.Background(), tx)) require.True(env.mempool.Has(txID)) // show that build block include that tx and removes it from mempool diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index acd7d872e9ac..e3ea9f40845b 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -87,6 +87,7 @@ type environment struct { Builder blkManager blockexecutor.Manager mempool mempool.Mempool + network Network sender *common.SenderTest isBootstrapped *utils.Atomic[bool] @@ -168,13 +169,20 @@ func newEnvironment(t *testing.T) *environment { pvalidators.TestManager, ) + res.network = NewNetwork( + res.backend.Ctx, + res.blkManager, + res.mempool, + res.backend.Config.PartialSyncPrimaryNetwork, + res.sender, + ) + res.Builder = New( res.mempool, res.txBuilder, &res.backend, res.blkManager, nil, // toEngine, - res.sender, ) res.blkManager.SetPreference(genesisID) diff --git a/vms/platformvm/block/builder/network.go b/vms/platformvm/block/builder/network.go index d58865589a9a..14ba87b5bce0 100644 --- a/vms/platformvm/block/builder/network.go +++ b/vms/platformvm/block/builder/network.go @@ -16,7 +16,9 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/vms/components/message" + "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) // We allow [recentCacheSize] to be fairly large because we only store hashes @@ -39,9 +41,11 @@ type network struct { // We embed a noop handler for all unhandled messages common.AppHandler - ctx *snow.Context - blkBuilder *builder - appSender common.AppSender + ctx *snow.Context + manager executor.Manager + mempool mempool.Mempool + partialSyncPrimaryNetwork bool + appSender common.AppSender // gossip related attributes recentTxsLock sync.Mutex @@ -50,16 +54,20 @@ type network struct { func NewNetwork( ctx *snow.Context, - blkBuilder *builder, + manager executor.Manager, + mempool mempool.Mempool, + partialSyncPrimaryNetwork bool, appSender common.AppSender, ) Network { return &network{ AppHandler: common.NewNoOpAppHandler(ctx.Log), - ctx: ctx, - blkBuilder: blkBuilder, - appSender: appSender, - recentTxs: &cache.LRU[ids.ID, struct{}]{Size: recentCacheSize}, + ctx: ctx, + manager: manager, + mempool: mempool, + partialSyncPrimaryNetwork: partialSyncPrimaryNetwork, + appSender: appSender, + recentTxs: &cache.LRU[ids.ID, struct{}]{Size: recentCacheSize}, } } @@ -69,7 +77,7 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b zap.Int("messageLen", len(msgBytes)), ) - if n.blkBuilder.txExecutorBackend.Config.PartialSyncPrimaryNetwork { + if n.partialSyncPrimaryNetwork { n.ctx.Log.Debug("dropping AppGossip message", zap.String("reason", "primary network is not being fully synced"), ) @@ -109,7 +117,7 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b n.ctx.Lock.Lock() defer n.ctx.Lock.Unlock() - if reason := n.blkBuilder.GetDropReason(txID); reason != nil { + if reason := n.mempool.GetDropReason(txID); reason != nil { // If the tx is being dropped - just ignore it return nil } @@ -126,21 +134,21 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b func (n *network) IssueTx(ctx context.Context, tx *txs.Tx) error { txID := tx.ID() - if n.blkBuilder.Mempool.Has(txID) { + if n.mempool.Has(txID) { // If the transaction is already in the mempool - then it looks the same // as if it was successfully added return nil } - if err := n.blkBuilder.blkManager.VerifyTx(tx); err != nil { - n.blkBuilder.Mempool.MarkDropped(txID, err) + if err := n.manager.VerifyTx(tx); err != nil { + n.mempool.MarkDropped(txID, err) return err } // If we are partially syncing the Primary Network, we should not be // maintaining the transaction mempool locally. - if !n.blkBuilder.txExecutorBackend.Config.PartialSyncPrimaryNetwork { - if err := n.blkBuilder.Mempool.Add(tx); err != nil { + if !n.partialSyncPrimaryNetwork { + if err := n.mempool.Add(tx); err != nil { return err } } diff --git a/vms/platformvm/block/builder/network_test.go b/vms/platformvm/block/builder/network_test.go index d5d75e88317c..5421ee2b43f5 100644 --- a/vms/platformvm/block/builder/network_test.go +++ b/vms/platformvm/block/builder/network_test.go @@ -60,7 +60,7 @@ func TestMempoolValidGossipedTxIsAddedToMempool(t *testing.T) { // Free lock because [AppGossip] waits for the context lock env.ctx.Lock.Unlock() // show that unknown tx is added to mempool - require.NoError(env.AppGossip(context.Background(), nodeID, msgBytes)) + require.NoError(env.network.AppGossip(context.Background(), nodeID, msgBytes)) require.True(env.Builder.Has(txID)) // Grab lock back env.ctx.Lock.Lock() @@ -100,7 +100,7 @@ func TestMempoolInvalidGossipedTxIsNotAddedToMempool(t *testing.T) { msgBytes, err := message.Build(&msg) require.NoError(err) env.ctx.Lock.Unlock() - require.NoError(env.AppGossip(context.Background(), nodeID, msgBytes)) + require.NoError(env.network.AppGossip(context.Background(), nodeID, msgBytes)) env.ctx.Lock.Lock() require.False(env.Builder.Has(txID)) } @@ -125,7 +125,7 @@ func TestMempoolNewLocaTxIsGossiped(t *testing.T) { tx := getValidTx(env.txBuilder, t) txID := tx.ID() - require.NoError(env.Builder.IssueTx(context.Background(), tx)) + require.NoError(env.network.IssueTx(context.Background(), tx)) require.NotNil(gossipedBytes) // show gossiped bytes can be decoded to the original tx diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index f75171b1007d..fe9fa66f7b4c 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -1284,7 +1284,7 @@ func (s *Service) AddValidator(req *http.Request, args *AddValidatorArgs, reply return utils.Err( err, - s.vm.Builder.IssueTx(req.Context(), tx), + s.vm.Network.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1394,7 +1394,7 @@ func (s *Service) AddDelegator(req *http.Request, args *AddDelegatorArgs, reply return utils.Err( err, - s.vm.Builder.IssueTx(req.Context(), tx), + s.vm.Network.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1500,7 +1500,7 @@ func (s *Service) AddSubnetValidator(req *http.Request, args *AddSubnetValidator return utils.Err( err, - s.vm.Builder.IssueTx(req.Context(), tx), + s.vm.Network.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1576,7 +1576,7 @@ func (s *Service) CreateSubnet(req *http.Request, args *CreateSubnetArgs, respon return utils.Err( err, - s.vm.Builder.IssueTx(req.Context(), tx), + s.vm.Network.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1672,7 +1672,7 @@ func (s *Service) ExportAVAX(req *http.Request, args *ExportAVAXArgs, response * return utils.Err( err, - s.vm.Builder.IssueTx(req.Context(), tx), + s.vm.Network.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1757,7 +1757,7 @@ func (s *Service) ImportAVAX(req *http.Request, args *ImportAVAXArgs, response * return utils.Err( err, - s.vm.Builder.IssueTx(req.Context(), tx), + s.vm.Network.IssueTx(req.Context(), tx), user.Close(), ) } @@ -1881,7 +1881,7 @@ func (s *Service) CreateBlockchain(req *http.Request, args *CreateBlockchainArgs return utils.Err( err, - s.vm.Builder.IssueTx(req.Context(), tx), + s.vm.Network.IssueTx(req.Context(), tx), user.Close(), ) } @@ -2173,7 +2173,7 @@ func (s *Service) IssueTx(req *http.Request, args *api.FormattedTx, response *ap s.vm.ctx.Lock.Lock() defer s.vm.ctx.Lock.Unlock() - if err := s.vm.Builder.IssueTx(req.Context(), tx); err != nil { + if err := s.vm.Network.IssueTx(req.Context(), tx); err != nil { return fmt.Errorf("couldn't issue tx: %w", err) } diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index e206a1228a2f..4baaf6361d4b 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -238,12 +238,12 @@ func TestGetTxStatus(t *testing.T) { service.vm.ctx.Lock.Lock() // put the chain in existing chain list - err = service.vm.Builder.IssueTx(context.Background(), tx) + err = service.vm.Network.IssueTx(context.Background(), tx) require.ErrorIs(err, database.ErrNotFound) // Missing shared memory UTXO mutableSharedMemory.SharedMemory = sm - require.NoError(service.vm.Builder.IssueTx(context.Background(), tx)) + require.NoError(service.vm.Network.IssueTx(context.Background(), tx)) block, err := service.vm.BuildBlock(context.Background()) require.NoError(err) @@ -339,7 +339,7 @@ func TestGetTx(t *testing.T) { service.vm.ctx.Lock.Lock() - require.NoError(service.vm.Builder.IssueTx(context.Background(), tx)) + require.NoError(service.vm.Network.IssueTx(context.Background(), tx)) blk, err := service.vm.BuildBlock(context.Background()) require.NoError(err) diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 35135bb49f3d..01453c60db4c 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -374,7 +374,7 @@ func addPrimaryValidatorWithoutBLSKey(vm *VM, data *validatorInputData) (*state. func internalAddValidator(vm *VM, signedTx *txs.Tx) (*state.Staker, error) { stakerTx := signedTx.Unsigned.(txs.StakerTx) - if err := vm.Builder.IssueTx(context.Background(), signedTx); err != nil { + if err := vm.Network.IssueTx(context.Background(), signedTx); err != nil { return nil, fmt.Errorf("could not add tx to mempool: %w", err) } @@ -802,7 +802,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { if err != nil { return nil, ids.Empty, err } - if err := vm.Builder.IssueTx(context.Background(), testSubnet1); err != nil { + if err := vm.Network.IssueTx(context.Background(), testSubnet1); err != nil { return nil, ids.Empty, err } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 4d4b382534df..7a53250169cb 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -61,6 +61,7 @@ var ( type VM struct { config.Config blockbuilder.Builder + blockbuilder.Network validators.State metrics metrics.Metrics @@ -189,13 +190,19 @@ func (vm *VM) Initialize( txExecutorBackend, validatorManager, ) + vm.Network = blockbuilder.NewNetwork( + txExecutorBackend.Ctx, + vm.manager, + mempool, + txExecutorBackend.Config.PartialSyncPrimaryNetwork, + appSender, + ) vm.Builder = blockbuilder.New( mempool, vm.txBuilder, txExecutorBackend, vm.manager, toEngine, - appSender, ) // Create all of the chains that the database says exist diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 00c2d18a0c13..6220f1c43016 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -72,7 +72,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -104,7 +104,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.IssueTx(context.Background(), addFirstDelegatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addFirstDelegatorTx)) addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -138,7 +138,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.IssueTx(context.Background(), addSecondDelegatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addSecondDelegatorTx)) addSecondDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -162,7 +162,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - err = vm.Builder.IssueTx(context.Background(), addThirdDelegatorTx) + err = vm.Network.IssueTx(context.Background(), addThirdDelegatorTx) require.ErrorIs(err, executor.ErrOverDelegated) } @@ -235,7 +235,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the add validator tx - require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -257,7 +257,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the first add delegator tx - require.NoError(vm.Builder.IssueTx(context.Background(), addFirstDelegatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addFirstDelegatorTx)) // trigger block creation for the first add delegator tx addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -279,7 +279,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the second add delegator tx - require.NoError(vm.Builder.IssueTx(context.Background(), addSecondDelegatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addSecondDelegatorTx)) // trigger block creation for the second add delegator tx addSecondDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -301,7 +301,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the third add delegator tx - require.NoError(vm.Builder.IssueTx(context.Background(), addThirdDelegatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addThirdDelegatorTx)) // trigger block creation for the third add delegator tx addThirdDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -323,7 +323,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the fourth add delegator tx - require.NoError(vm.Builder.IssueTx(context.Background(), addFourthDelegatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addFourthDelegatorTx)) // trigger block creation for the fourth add delegator tx addFourthDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1166,7 +1166,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require.NoError(err) // issue the add validator tx - require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1188,7 +1188,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require.NoError(err) // issue the first add delegator tx - require.NoError(vm.Builder.IssueTx(context.Background(), addFirstDelegatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addFirstDelegatorTx)) // trigger block creation for the first add delegator tx addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1211,7 +1211,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { // attempting to issue the second add delegator tx should fail because the // total stake weight would go over the limit. - err = vm.Builder.IssueTx(context.Background(), addSecondDelegatorTx) + err = vm.Network.IssueTx(context.Background(), addSecondDelegatorTx) require.ErrorIs(err, executor.ErrOverDelegated) } @@ -1248,7 +1248,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1265,7 +1265,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) + require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1285,7 +1285,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), addSubnetValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addSubnetValidatorTx)) // trigger block creation for the validator tx addSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1314,7 +1314,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t // validator set into the current validator set. vm.clock.Set(validatorStartTime) - require.NoError(vm.Builder.IssueTx(context.Background(), removeSubnetValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), removeSubnetValidatorTx)) // trigger block creation for the validator tx removeSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1365,7 +1365,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1382,7 +1382,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) + require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1402,7 +1402,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), addSubnetValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addSubnetValidatorTx)) // trigger block creation for the validator tx addSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1423,7 +1423,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t // validator set into the current validator set. vm.clock.Set(validatorStartTime) - require.NoError(vm.Builder.IssueTx(context.Background(), removeSubnetValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), removeSubnetValidatorTx)) // trigger block creation for the validator tx removeSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1517,7 +1517,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NoError(primaryTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Builder.IssueTx(context.Background(), primaryTx)) + require.NoError(vm.Network.IssueTx(context.Background(), primaryTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1544,7 +1544,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), subnetTx)) + require.NoError(vm.Network.IssueTx(context.Background(), subnetTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current @@ -1648,7 +1648,7 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Builder.IssueTx(context.Background(), primaryRestartTx)) + require.NoError(vm.Network.IssueTx(context.Background(), primaryRestartTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -1756,7 +1756,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), primaryTx1)) + require.NoError(vm.Network.IssueTx(context.Background(), primaryTx1)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1848,7 +1848,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Builder.IssueTx(context.Background(), primaryRestartTx)) + require.NoError(vm.Network.IssueTx(context.Background(), primaryRestartTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -1919,7 +1919,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), primaryTx1)) + require.NoError(vm.Network.IssueTx(context.Background(), primaryTx1)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1946,7 +1946,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), subnetTx)) + require.NoError(vm.Network.IssueTx(context.Background(), subnetTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current @@ -2050,7 +2050,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Builder.IssueTx(context.Background(), primaryRestartTx)) + require.NoError(vm.Network.IssueTx(context.Background(), primaryRestartTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -2128,7 +2128,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), primaryTx1)) + require.NoError(vm.Network.IssueTx(context.Background(), primaryTx1)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -2152,7 +2152,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), subnetTx)) + require.NoError(vm.Network.IssueTx(context.Background(), subnetTx)) require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index bdd3e39fc24b..96f6f59711a6 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -364,7 +364,7 @@ func defaultVM(t *testing.T) (*VM, database.Database, *mutableSharedMemory) { keys[0].PublicKey().Address(), // change addr ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), testSubnet1)) + require.NoError(vm.Network.IssueTx(context.Background(), testSubnet1)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) require.NoError(blk.Verify(context.Background())) @@ -460,7 +460,7 @@ func TestAddValidatorCommit(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.IssueTx(context.Background(), tx)) + require.NoError(vm.Network.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -560,7 +560,7 @@ func TestAddValidatorReject(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.IssueTx(context.Background(), tx)) + require.NoError(vm.Network.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -605,7 +605,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { require.NoError(err) // trigger block creation - err = vm.Builder.IssueTx(context.Background(), tx) + err = vm.Network.IssueTx(context.Background(), tx) require.ErrorIs(err, txexecutor.ErrAlreadyValidator) } @@ -638,7 +638,7 @@ func TestAddSubnetValidatorAccept(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.IssueTx(context.Background(), tx)) + require.NoError(vm.Network.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -684,7 +684,7 @@ func TestAddSubnetValidatorReject(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Builder.IssueTx(context.Background(), tx)) + require.NoError(vm.Network.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -879,7 +879,7 @@ func TestCreateChain(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), tx)) + require.NoError(vm.Network.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) // should contain proposal to create chain @@ -932,7 +932,7 @@ func TestCreateSubnet(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) + require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) // should contain proposal to create subnet blk, err := vm.Builder.BuildBlock(context.Background()) @@ -973,7 +973,7 @@ func TestCreateSubnet(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) blk, err = vm.Builder.BuildBlock(context.Background()) // should add validator to the new subnet require.NoError(err) @@ -1089,7 +1089,7 @@ func TestAtomicImport(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), tx)) + require.NoError(vm.Network.IssueTx(context.Background(), tx)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2050,7 +2050,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), addValidatorTx)) + require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -2067,7 +2067,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) + require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -2136,7 +2136,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { require.NoError(err) subnetID := createSubnetTx.ID() - require.NoError(vm.Builder.IssueTx(context.Background(), createSubnetTx)) + require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2168,7 +2168,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Builder.IssueTx(context.Background(), transferSubnetOwnershipTx)) + require.NoError(vm.Network.IssueTx(context.Background(), transferSubnetOwnershipTx)) transferSubnetOwnershipBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2254,7 +2254,7 @@ func TestBaseTx(t *testing.T) { require.Equal(vm.TxFee, totalInputAmt-totalOutputAmt) require.Equal(sendAmt, key1OutputAmt) - require.NoError(vm.Builder.IssueTx(context.Background(), baseTx)) + require.NoError(vm.Network.IssueTx(context.Background(), baseTx)) baseTxBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) From f1ec30c3427ce506dd51457c9189cc8089f2e4e5 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Thu, 16 Nov 2023 12:03:00 -0500 Subject: [PATCH 043/267] Update `error_code` to be int32 instead of uint32. (#2322) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- proto/p2p/p2p.proto | 4 ++-- proto/pb/p2p/p2p.pb.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 09618923a866..9b45148e3344 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -415,8 +415,8 @@ message AppError { bytes chain_id = 1; // Request id of the original AppRequest uint32 request_id = 2; - // VM defined error code - uint32 error_code = 3; + // VM defined error code. VMs may define error codes > 0. + sint32 error_code = 3; // VM defined error message string error_message = 4; } diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index e2761bed03aa..8b804d1ceb02 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -2394,8 +2394,8 @@ type AppError struct { ChainId []byte `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` // Request id of the original AppRequest RequestId uint32 `protobuf:"varint,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` - // VM defined error code - ErrorCode uint32 `protobuf:"varint,3,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` + // VM defined error code. VMs may define error codes > 0. + ErrorCode int32 `protobuf:"zigzag32,3,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` // VM defined error message ErrorMessage string `protobuf:"bytes,4,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` } @@ -2446,7 +2446,7 @@ func (x *AppError) GetRequestId() uint32 { return 0 } -func (x *AppError) GetErrorCode() uint32 { +func (x *AppError) GetErrorCode() int32 { if x != nil { return x.ErrorCode } @@ -2831,7 +2831,7 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, + 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, From 043644f969ff1a4af0d302fd25cce84506aaa99e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 16 Nov 2023 12:13:09 -0500 Subject: [PATCH 044/267] Refactor bootstrapper implementation into consensus (#2300) Co-authored-by: Dan Laine --- .../snowman/bootstrapper/majority.go | 110 +++++ .../snowman/bootstrapper/majority_test.go | 396 ++++++++++++++++++ .../snowman/bootstrapper/minority.go | 77 ++++ .../snowman/bootstrapper/minority_test.go | 242 +++++++++++ snow/consensus/snowman/bootstrapper/noop.go | 27 ++ .../snowman/bootstrapper/noop_test.go | 23 + snow/consensus/snowman/bootstrapper/poll.go | 23 + .../snowman/bootstrapper/poll_test.go | 15 + .../snowman/bootstrapper/requests.go | 48 +++ .../consensus/snowman/bootstrapper/sampler.go | 49 +++ .../snowman/bootstrapper/sampler_test.go | 75 ++++ snow/engine/common/bootstrapper.go | 332 ++++----------- 12 files changed, 1166 insertions(+), 251 deletions(-) create mode 100644 snow/consensus/snowman/bootstrapper/majority.go create mode 100644 snow/consensus/snowman/bootstrapper/majority_test.go create mode 100644 snow/consensus/snowman/bootstrapper/minority.go create mode 100644 snow/consensus/snowman/bootstrapper/minority_test.go create mode 100644 snow/consensus/snowman/bootstrapper/noop.go create mode 100644 snow/consensus/snowman/bootstrapper/noop_test.go create mode 100644 snow/consensus/snowman/bootstrapper/poll.go create mode 100644 snow/consensus/snowman/bootstrapper/poll_test.go create mode 100644 snow/consensus/snowman/bootstrapper/requests.go create mode 100644 snow/consensus/snowman/bootstrapper/sampler.go create mode 100644 snow/consensus/snowman/bootstrapper/sampler_test.go diff --git a/snow/consensus/snowman/bootstrapper/majority.go b/snow/consensus/snowman/bootstrapper/majority.go new file mode 100644 index 000000000000..1decb837ef40 --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/majority.go @@ -0,0 +1,110 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "context" + + "go.uber.org/zap" + + "golang.org/x/exp/maps" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" +) + +var _ Poll = (*Majority)(nil) + +// Majority implements the bootstrapping poll to filter the initial set of +// potentially accaptable blocks into a set of accepted blocks to sync to. +// +// Once the last accepted blocks have been fetched from the initial set of +// peers, the set of blocks are sent to all peers. Each peer is expected to +// filter the provided blocks and report which of them they consider accepted. +// If a majority of the peers report that a block is accepted, then the node +// will consider that block to be accepted by the network. This assumes that a +// majority of the network is correct. If a majority of the network is +// malicious, the node may accept an incorrect block. +type Majority struct { + requests + + log logging.Logger + nodeWeights map[ids.NodeID]uint64 + + // received maps the blockID to the total sum of weight that has reported + // that block as accepted. + received map[ids.ID]uint64 + accepted []ids.ID +} + +func NewMajority( + log logging.Logger, + nodeWeights map[ids.NodeID]uint64, + maxOutstanding int, +) *Majority { + return &Majority{ + requests: requests{ + maxOutstanding: maxOutstanding, + pendingSend: set.Of(maps.Keys(nodeWeights)...), + }, + log: log, + nodeWeights: nodeWeights, + received: make(map[ids.ID]uint64), + } +} + +func (m *Majority) RecordOpinion(_ context.Context, nodeID ids.NodeID, blkIDs set.Set[ids.ID]) error { + if !m.recordResponse(nodeID) { + // The chain router should have already dropped unexpected messages. + m.log.Error("received unexpected opinion", + zap.String("pollType", "majority"), + zap.Stringer("nodeID", nodeID), + zap.Reflect("blkIDs", blkIDs), + ) + return nil + } + + weight := m.nodeWeights[nodeID] + for blkID := range blkIDs { + newWeight, err := math.Add64(m.received[blkID], weight) + if err != nil { + return err + } + m.received[blkID] = newWeight + } + + if !m.finished() { + return nil + } + + var ( + totalWeight uint64 + err error + ) + for _, weight := range m.nodeWeights { + totalWeight, err = math.Add64(totalWeight, weight) + if err != nil { + return err + } + } + + requiredWeight := totalWeight/2 + 1 + for blkID, weight := range m.received { + if weight >= requiredWeight { + m.accepted = append(m.accepted, blkID) + } + } + + m.log.Debug("finalized bootstrapping poll", + zap.String("pollType", "majority"), + zap.Stringers("accepted", m.accepted), + ) + return nil +} + +func (m *Majority) Result(context.Context) ([]ids.ID, bool) { + return m.accepted, m.finished() +} diff --git a/snow/consensus/snowman/bootstrapper/majority_test.go b/snow/consensus/snowman/bootstrapper/majority_test.go new file mode 100644 index 000000000000..d276566fb910 --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/majority_test.go @@ -0,0 +1,396 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "context" + "math" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) + +func TestNewMajority(t *testing.T) { + majority := NewMajority( + logging.NoLog{}, // log + map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, // nodeWeights + 2, // maxOutstanding + ) + + expectedMajority := &Majority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Of(nodeID0, nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: make(map[ids.ID]uint64), + } + require.Equal(t, expectedMajority, majority) +} + +func TestMajorityGetPeers(t *testing.T) { + tests := []struct { + name string + majority Poll + expectedState Poll + expectedPeers set.Set[ids.NodeID] + }{ + { + name: "max outstanding", + majority: &Majority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: make(map[ids.ID]uint64), + }, + expectedState: &Majority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: make(map[ids.ID]uint64), + }, + expectedPeers: nil, + }, + { + name: "send until max outstanding", + majority: &Majority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Of(nodeID0, nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: make(map[ids.ID]uint64), + }, + expectedState: &Majority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Set[ids.NodeID]{}, + outstanding: set.Of(nodeID0, nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: make(map[ids.ID]uint64), + }, + expectedPeers: set.Of(nodeID0, nodeID1), + }, + { + name: "send until no more to send", + majority: &Majority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Of(nodeID0), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + }, + received: make(map[ids.ID]uint64), + }, + expectedState: &Majority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Set[ids.NodeID]{}, + outstanding: set.Of(nodeID0), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + }, + received: make(map[ids.ID]uint64), + }, + expectedPeers: set.Of(nodeID0), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + peers := test.majority.GetPeers(context.Background()) + require.Equal(test.expectedState, test.majority) + require.Equal(test.expectedPeers, peers) + }) + } +} + +func TestMajorityRecordOpinion(t *testing.T) { + tests := []struct { + name string + majority Poll + nodeID ids.NodeID + blkIDs set.Set[ids.ID] + expectedState Poll + expectedErr error + }{ + { + name: "unexpected response", + majority: &Majority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: make(map[ids.ID]uint64), + }, + nodeID: nodeID0, + blkIDs: nil, + expectedState: &Majority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: make(map[ids.ID]uint64), + }, + expectedErr: nil, + }, + { + name: "unfinished after response", + majority: &Majority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 2, + nodeID1: 3, + }, + received: make(map[ids.ID]uint64), + }, + nodeID: nodeID1, + blkIDs: set.Of(blkID0), + expectedState: &Majority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Set[ids.NodeID]{}, + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 2, + nodeID1: 3, + }, + received: map[ids.ID]uint64{ + blkID0: 3, + }, + }, + expectedErr: nil, + }, + { + name: "overflow during response", + majority: &Majority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: math.MaxUint64, + }, + received: map[ids.ID]uint64{ + blkID0: 1, + }, + }, + nodeID: nodeID1, + blkIDs: set.Of(blkID0), + expectedState: &Majority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Set[ids.NodeID]{}, + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: math.MaxUint64, + }, + received: map[ids.ID]uint64{ + blkID0: 1, + }, + }, + expectedErr: safemath.ErrOverflow, + }, + { + name: "overflow during final response", + majority: &Majority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: math.MaxUint64, + }, + received: make(map[ids.ID]uint64), + }, + nodeID: nodeID1, + blkIDs: set.Of(blkID0), + expectedState: &Majority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Set[ids.NodeID]{}, + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: math.MaxUint64, + }, + received: map[ids.ID]uint64{ + blkID0: math.MaxUint64, + }, + }, + expectedErr: safemath.ErrOverflow, + }, + { + name: "finished after response", + majority: &Majority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Of(nodeID2), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + nodeID2: 1, + }, + received: map[ids.ID]uint64{ + blkID0: 1, + blkID1: 1, + }, + }, + nodeID: nodeID2, + blkIDs: set.Of(blkID1), + expectedState: &Majority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Set[ids.NodeID]{}, + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + nodeID2: 1, + }, + received: map[ids.ID]uint64{ + blkID0: 1, + blkID1: 2, + }, + accepted: []ids.ID{blkID1}, + }, + expectedErr: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + err := test.majority.RecordOpinion(context.Background(), test.nodeID, test.blkIDs) + require.Equal(test.expectedState, test.majority) + require.ErrorIs(err, test.expectedErr) + }) + } +} + +func TestMajorityResult(t *testing.T) { + tests := []struct { + name string + majority Poll + expectedAccepted []ids.ID + expectedFinalized bool + }{ + { + name: "not finalized", + majority: &Majority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: make(map[ids.ID]uint64), + accepted: nil, + }, + expectedAccepted: nil, + expectedFinalized: false, + }, + { + name: "finalized", + majority: &Majority{ + requests: requests{ + maxOutstanding: 1, + }, + log: logging.NoLog{}, + nodeWeights: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + received: map[ids.ID]uint64{ + blkID0: 2, + }, + accepted: []ids.ID{blkID0}, + }, + expectedAccepted: []ids.ID{blkID0}, + expectedFinalized: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + accepted, finalized := test.majority.Result(context.Background()) + require.Equal(test.expectedAccepted, accepted) + require.Equal(test.expectedFinalized, finalized) + }) + } +} diff --git a/snow/consensus/snowman/bootstrapper/minority.go b/snow/consensus/snowman/bootstrapper/minority.go new file mode 100644 index 000000000000..52b45c4407ba --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/minority.go @@ -0,0 +1,77 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "context" + + "go.uber.org/zap" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" +) + +var _ Poll = (*Minority)(nil) + +// Minority implements the bootstrapping poll to determine the initial set of +// potentially accaptable blocks. +// +// This poll fetches the last accepted block from an initial set of peers. In +// order for the protocol to find a recently accepted block, there must be at +// least one correct node in this set of peers. If there is not a correct node +// in the set of peers, the node will not accept an incorrect block. However, +// the node may be unable to find an acceptable block. +type Minority struct { + requests + + log logging.Logger + + receivedSet set.Set[ids.ID] + received []ids.ID +} + +func NewMinority( + log logging.Logger, + frontierNodes set.Set[ids.NodeID], + maxOutstanding int, +) *Minority { + return &Minority{ + requests: requests{ + maxOutstanding: maxOutstanding, + pendingSend: frontierNodes, + }, + log: log, + } +} + +func (m *Minority) RecordOpinion(_ context.Context, nodeID ids.NodeID, blkIDs set.Set[ids.ID]) error { + if !m.recordResponse(nodeID) { + // The chain router should have already dropped unexpected messages. + m.log.Error("received unexpected opinion", + zap.String("pollType", "minority"), + zap.Stringer("nodeID", nodeID), + zap.Reflect("blkIDs", blkIDs), + ) + return nil + } + + m.receivedSet.Union(blkIDs) + + if !m.finished() { + return nil + } + + m.received = m.receivedSet.List() + + m.log.Debug("finalized bootstrapping poll", + zap.String("pollType", "minority"), + zap.Stringers("frontier", m.received), + ) + return nil +} + +func (m *Minority) Result(context.Context) ([]ids.ID, bool) { + return m.received, m.finished() +} diff --git a/snow/consensus/snowman/bootstrapper/minority_test.go b/snow/consensus/snowman/bootstrapper/minority_test.go new file mode 100644 index 000000000000..f720ee18025a --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/minority_test.go @@ -0,0 +1,242 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" +) + +func TestNewMinority(t *testing.T) { + minority := NewMinority( + logging.NoLog{}, // log + set.Of(nodeID0), // frontierNodes + 2, // maxOutstanding + ) + + expectedMinority := &Minority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Of(nodeID0), + }, + log: logging.NoLog{}, + } + require.Equal(t, expectedMinority, minority) +} + +func TestMinorityGetPeers(t *testing.T) { + tests := []struct { + name string + minority Poll + expectedState Poll + expectedPeers set.Set[ids.NodeID] + }{ + { + name: "max outstanding", + minority: &Minority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + }, + expectedState: &Minority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + }, + expectedPeers: nil, + }, + { + name: "send until max outstanding", + minority: &Minority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Of(nodeID0, nodeID1), + }, + log: logging.NoLog{}, + }, + expectedState: &Minority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Set[ids.NodeID]{}, + outstanding: set.Of(nodeID0, nodeID1), + }, + log: logging.NoLog{}, + }, + expectedPeers: set.Of(nodeID0, nodeID1), + }, + { + name: "send until no more to send", + minority: &Minority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Of(nodeID0), + }, + log: logging.NoLog{}, + }, + expectedState: &Minority{ + requests: requests{ + maxOutstanding: 2, + pendingSend: set.Set[ids.NodeID]{}, + outstanding: set.Of(nodeID0), + }, + log: logging.NoLog{}, + }, + expectedPeers: set.Of(nodeID0), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + peers := test.minority.GetPeers(context.Background()) + require.Equal(test.expectedState, test.minority) + require.Equal(test.expectedPeers, peers) + }) + } +} + +func TestMinorityRecordOpinion(t *testing.T) { + tests := []struct { + name string + minority Poll + nodeID ids.NodeID + blkIDs set.Set[ids.ID] + expectedState Poll + expectedErr error + }{ + { + name: "unexpected response", + minority: &Minority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + }, + nodeID: nodeID0, + blkIDs: nil, + expectedState: &Minority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + }, + expectedErr: nil, + }, + { + name: "unfinished after response", + minority: &Minority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + }, + nodeID: nodeID1, + blkIDs: set.Of(blkID0), + expectedState: &Minority{ + requests: requests{ + maxOutstanding: 1, + pendingSend: set.Of(nodeID0), + outstanding: set.Set[ids.NodeID]{}, + }, + log: logging.NoLog{}, + receivedSet: set.Of(blkID0), + }, + expectedErr: nil, + }, + { + name: "finished after response", + minority: &Minority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Of(nodeID2), + }, + log: logging.NoLog{}, + }, + nodeID: nodeID2, + blkIDs: set.Of(blkID1), + expectedState: &Minority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Set[ids.NodeID]{}, + }, + log: logging.NoLog{}, + receivedSet: set.Of(blkID1), + received: []ids.ID{blkID1}, + }, + expectedErr: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + err := test.minority.RecordOpinion(context.Background(), test.nodeID, test.blkIDs) + require.Equal(test.expectedState, test.minority) + require.ErrorIs(err, test.expectedErr) + }) + } +} + +func TestMinorityResult(t *testing.T) { + tests := []struct { + name string + minority Poll + expectedAccepted []ids.ID + expectedFinalized bool + }{ + { + name: "not finalized", + minority: &Minority{ + requests: requests{ + maxOutstanding: 1, + outstanding: set.Of(nodeID1), + }, + log: logging.NoLog{}, + received: nil, + }, + expectedAccepted: nil, + expectedFinalized: false, + }, + { + name: "finalized", + minority: &Minority{ + requests: requests{ + maxOutstanding: 1, + }, + log: logging.NoLog{}, + receivedSet: set.Of(blkID0), + received: []ids.ID{blkID0}, + }, + expectedAccepted: []ids.ID{blkID0}, + expectedFinalized: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + accepted, finalized := test.minority.Result(context.Background()) + require.Equal(test.expectedAccepted, accepted) + require.Equal(test.expectedFinalized, finalized) + }) + } +} diff --git a/snow/consensus/snowman/bootstrapper/noop.go b/snow/consensus/snowman/bootstrapper/noop.go new file mode 100644 index 000000000000..1cd3bffd58b7 --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/noop.go @@ -0,0 +1,27 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "context" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/set" +) + +var Noop Poll = noop{} + +type noop struct{} + +func (noop) GetPeers(context.Context) set.Set[ids.NodeID] { + return nil +} + +func (noop) RecordOpinion(context.Context, ids.NodeID, set.Set[ids.ID]) error { + return nil +} + +func (noop) Result(context.Context) ([]ids.ID, bool) { + return nil, false +} diff --git a/snow/consensus/snowman/bootstrapper/noop_test.go b/snow/consensus/snowman/bootstrapper/noop_test.go new file mode 100644 index 000000000000..0a485a8fae76 --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/noop_test.go @@ -0,0 +1,23 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNoop(t *testing.T) { + require := require.New(t) + + require.Empty(Noop.GetPeers(context.Background())) + + require.NoError(Noop.RecordOpinion(context.Background(), nodeID0, nil)) + + blkIDs, finalized := Noop.Result(context.Background()) + require.Empty(blkIDs) + require.False(finalized) +} diff --git a/snow/consensus/snowman/bootstrapper/poll.go b/snow/consensus/snowman/bootstrapper/poll.go new file mode 100644 index 000000000000..450341d9d64d --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/poll.go @@ -0,0 +1,23 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "context" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/set" +) + +type Poll interface { + // GetPeers returns the set of peers whose opinion should be requested. It + // is expected to repeatedly call this function along with [RecordOpinion] + // until [Result] returns finalized. + GetPeers(ctx context.Context) (peers set.Set[ids.NodeID]) + // RecordOpinion of a node whose opinion was requested. + RecordOpinion(ctx context.Context, nodeID ids.NodeID, blkIDs set.Set[ids.ID]) error + // Result returns the evaluation of all the peer's opinions along with a + // flag to identify that the result has finished being calculated. + Result(ctx context.Context) (blkIDs []ids.ID, finalized bool) +} diff --git a/snow/consensus/snowman/bootstrapper/poll_test.go b/snow/consensus/snowman/bootstrapper/poll_test.go new file mode 100644 index 000000000000..134867ae1822 --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/poll_test.go @@ -0,0 +1,15 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import "github.com/ava-labs/avalanchego/ids" + +var ( + nodeID0 = ids.GenerateTestNodeID() + nodeID1 = ids.GenerateTestNodeID() + nodeID2 = ids.GenerateTestNodeID() + + blkID0 = ids.GenerateTestID() + blkID1 = ids.GenerateTestID() +) diff --git a/snow/consensus/snowman/bootstrapper/requests.go b/snow/consensus/snowman/bootstrapper/requests.go new file mode 100644 index 000000000000..28fc25ce1643 --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/requests.go @@ -0,0 +1,48 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "context" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" +) + +type requests struct { + maxOutstanding int + + pendingSend set.Set[ids.NodeID] + outstanding set.Set[ids.NodeID] +} + +func (r *requests) GetPeers(context.Context) set.Set[ids.NodeID] { + numPending := r.outstanding.Len() + if numPending >= r.maxOutstanding { + return nil + } + + numToSend := math.Min( + r.maxOutstanding-numPending, + r.pendingSend.Len(), + ) + nodeIDs := set.NewSet[ids.NodeID](numToSend) + for i := 0; i < numToSend; i++ { + nodeID, _ := r.pendingSend.Pop() + nodeIDs.Add(nodeID) + } + r.outstanding.Union(nodeIDs) + return nodeIDs +} + +func (r *requests) recordResponse(nodeID ids.NodeID) bool { + wasOutstanding := r.outstanding.Contains(nodeID) + r.outstanding.Remove(nodeID) + return wasOutstanding +} + +func (r *requests) finished() bool { + return r.pendingSend.Len() == 0 && r.outstanding.Len() == 0 +} diff --git a/snow/consensus/snowman/bootstrapper/sampler.go b/snow/consensus/snowman/bootstrapper/sampler.go new file mode 100644 index 000000000000..9511a1e4243f --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/sampler.go @@ -0,0 +1,49 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/sampler" + "github.com/ava-labs/avalanchego/utils/set" +) + +// Sample keys from [elements] uniformly by weight without replacement. The +// returned set will have size less than or equal to [maxSize]. This function +// will error if the sum of all weights overflows. +func Sample[T comparable](elements map[T]uint64, maxSize int) (set.Set[T], error) { + var ( + keys = make([]T, len(elements)) + weights = make([]uint64, len(elements)) + totalWeight uint64 + err error + ) + i := 0 + for key, weight := range elements { + keys[i] = key + weights[i] = weight + totalWeight, err = math.Add64(totalWeight, weight) + if err != nil { + return nil, err + } + i++ + } + + sampler := sampler.NewWeightedWithoutReplacement() + if err := sampler.Initialize(weights); err != nil { + return nil, err + } + + maxSize = int(math.Min(uint64(maxSize), totalWeight)) + indices, err := sampler.Sample(maxSize) + if err != nil { + return nil, err + } + + sampledElements := set.NewSet[T](maxSize) + for _, index := range indices { + sampledElements.Add(keys[index]) + } + return sampledElements, nil +} diff --git a/snow/consensus/snowman/bootstrapper/sampler_test.go b/snow/consensus/snowman/bootstrapper/sampler_test.go new file mode 100644 index 000000000000..1b9e366decc7 --- /dev/null +++ b/snow/consensus/snowman/bootstrapper/sampler_test.go @@ -0,0 +1,75 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bootstrapper + +import ( + "math" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/set" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) + +func TestSample(t *testing.T) { + tests := []struct { + name string + elements map[ids.NodeID]uint64 + maxSize int + expectedSampled set.Set[ids.NodeID] + expectedErr error + }{ + { + name: "sample everything", + elements: map[ids.NodeID]uint64{ + nodeID0: 1, + nodeID1: 1, + }, + maxSize: 2, + expectedSampled: set.Of(nodeID0, nodeID1), + expectedErr: nil, + }, + { + name: "limit sample due to too few elements", + elements: map[ids.NodeID]uint64{ + nodeID0: 1, + }, + maxSize: 2, + expectedSampled: set.Of(nodeID0), + expectedErr: nil, + }, + { + name: "limit sample", + elements: map[ids.NodeID]uint64{ + nodeID0: math.MaxUint64 - 1, + nodeID1: 1, + }, + maxSize: 1, + expectedSampled: set.Of(nodeID0), + expectedErr: nil, + }, + { + name: "overflow", + elements: map[ids.NodeID]uint64{ + nodeID0: math.MaxUint64, + nodeID1: 1, + }, + maxSize: 1, + expectedSampled: nil, + expectedErr: safemath.ErrOverflow, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + sampled, err := Sample(test.elements, test.maxSize) + require.ErrorIs(err, test.expectedErr) + require.Equal(test.expectedSampled, sampled) + }) + } +} diff --git a/snow/engine/common/bootstrapper.go b/snow/engine/common/bootstrapper.go index c567db5ee2d0..0455a46cc203 100644 --- a/snow/engine/common/bootstrapper.go +++ b/snow/engine/common/bootstrapper.go @@ -5,16 +5,13 @@ package common import ( "context" - "fmt" - "math" "go.uber.org/zap" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/set" - safemath "github.com/ava-labs/avalanchego/utils/math" + smbootstrapper "github.com/ava-labs/avalanchego/snow/consensus/snowman/bootstrapper" ) const ( @@ -46,30 +43,8 @@ type bootstrapper struct { Config Halter - // Holds the beacons that were sampled for the accepted frontier - sampledBeacons validators.Manager - // IDs of validators we should request an accepted frontier from - pendingSendAcceptedFrontier set.Set[ids.NodeID] - // IDs of validators we requested an accepted frontier from but haven't - // received a reply yet - pendingReceiveAcceptedFrontier set.Set[ids.NodeID] - // IDs of validators that failed to respond with their accepted frontier - failedAcceptedFrontier set.Set[ids.NodeID] - // IDs of all the returned accepted frontiers - acceptedFrontierSet set.Set[ids.ID] - - // IDs of validators we should request filtering the accepted frontier from - pendingSendAccepted set.Set[ids.NodeID] - // IDs of validators we requested filtering the accepted frontier from but - // haven't received a reply yet - pendingReceiveAccepted set.Set[ids.NodeID] - // IDs of validators that failed to respond with their filtered accepted - // frontier - failedAccepted set.Set[ids.NodeID] - // IDs of the returned accepted containers and the stake weight that has - // marked them as accepted - acceptedVotes map[ids.ID]uint64 - acceptedFrontier []ids.ID + minority smbootstrapper.Poll + majority smbootstrapper.Poll // number of times the bootstrap has been attempted bootstrapAttempts int @@ -77,12 +52,13 @@ type bootstrapper struct { func NewCommonBootstrapper(config Config) Bootstrapper { return &bootstrapper{ - Config: config, + Config: config, + minority: smbootstrapper.Noop, + majority: smbootstrapper.Noop, } } func (b *bootstrapper) AcceptedFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error { - // ignores any late responses if requestID != b.Config.SharedCfg.RequestID { b.Ctx.Log.Debug("received out-of-sync AcceptedFrontier message", zap.Stringer("nodeID", nodeID), @@ -92,21 +68,13 @@ func (b *bootstrapper) AcceptedFrontier(ctx context.Context, nodeID ids.NodeID, return nil } - if !b.pendingReceiveAcceptedFrontier.Contains(nodeID) { - b.Ctx.Log.Debug("received unexpected AcceptedFrontier message", - zap.Stringer("nodeID", nodeID), - ) - return nil + if err := b.minority.RecordOpinion(ctx, nodeID, set.Of(containerID)); err != nil { + return err } - - // Union the reported accepted frontier from [nodeID] with the accepted - // frontier we got from others - b.acceptedFrontierSet.Add(containerID) - return b.markAcceptedFrontierReceived(ctx, nodeID) + return b.sendMessagesOrFinish(ctx) } func (b *bootstrapper) GetAcceptedFrontierFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - // ignores any late responses if requestID != b.Config.SharedCfg.RequestID { b.Ctx.Log.Debug("received out-of-sync GetAcceptedFrontierFailed message", zap.Stringer("nodeID", nodeID), @@ -116,76 +84,13 @@ func (b *bootstrapper) GetAcceptedFrontierFailed(ctx context.Context, nodeID ids return nil } - if !b.pendingReceiveAcceptedFrontier.Contains(nodeID) { - b.Ctx.Log.Debug("received unexpected GetAcceptedFrontierFailed message", - zap.Stringer("nodeID", nodeID), - ) - return nil - } - - // If we can't get a response from [nodeID], act as though they said their - // accepted frontier is empty and we add the validator to the failed list - b.failedAcceptedFrontier.Add(nodeID) - return b.markAcceptedFrontierReceived(ctx, nodeID) -} - -func (b *bootstrapper) markAcceptedFrontierReceived(ctx context.Context, nodeID ids.NodeID) error { - // Mark that we received a response from [nodeID] - b.pendingReceiveAcceptedFrontier.Remove(nodeID) - - b.sendGetAcceptedFrontiers(ctx) - - // still waiting on requests - if b.pendingReceiveAcceptedFrontier.Len() != 0 { - return nil - } - - // We've received the accepted frontier from every bootstrap validator - // Ask each bootstrap validator to filter the list of containers that we were - // told are on the accepted frontier such that the list only contains containers - // they think are accepted. - totalSampledWeight, err := b.sampledBeacons.TotalWeight(b.Ctx.SubnetID) - if err != nil { - return fmt.Errorf("failed to get total weight of sampled beacons for subnet %s: %w", b.Ctx.SubnetID, err) - } - beaconsTotalWeight, err := b.Beacons.TotalWeight(b.Ctx.SubnetID) - if err != nil { - return fmt.Errorf("failed to get total weight of beacons for subnet %s: %w", b.Ctx.SubnetID, err) - } - newAlpha := float64(totalSampledWeight*b.Alpha) / float64(beaconsTotalWeight) - - failedBeaconWeight, err := b.Beacons.SubsetWeight(b.Ctx.SubnetID, b.failedAcceptedFrontier) - if err != nil { - return fmt.Errorf("failed to get total weight of failed beacons: %w", err) - } - - // fail the bootstrap if the weight is not enough to bootstrap - if float64(totalSampledWeight)-newAlpha < float64(failedBeaconWeight) { - if b.Config.RetryBootstrap { - b.Ctx.Log.Debug("restarting bootstrap", - zap.String("reason", "not enough frontiers received"), - zap.Int("numBeacons", b.Beacons.Count(b.Ctx.SubnetID)), - zap.Int("numFailedBootstrappers", b.failedAcceptedFrontier.Len()), - zap.Int("numBootstrapAttemps", b.bootstrapAttempts), - ) - return b.Restart(ctx, false) - } - - b.Ctx.Log.Debug("didn't receive enough frontiers", - zap.Int("numFailedValidators", b.failedAcceptedFrontier.Len()), - zap.Int("numBootstrapAttempts", b.bootstrapAttempts), - ) + if err := b.minority.RecordOpinion(ctx, nodeID, nil); err != nil { + return err } - - b.Config.SharedCfg.RequestID++ - b.acceptedFrontier = b.acceptedFrontierSet.List() - - b.sendGetAccepted(ctx) - return nil + return b.sendMessagesOrFinish(ctx) } func (b *bootstrapper) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { - // ignores any late responses if requestID != b.Config.SharedCfg.RequestID { b.Ctx.Log.Debug("received out-of-sync Accepted message", zap.Stringer("nodeID", nodeID), @@ -195,90 +100,13 @@ func (b *bootstrapper) Accepted(ctx context.Context, nodeID ids.NodeID, requestI return nil } - if !b.pendingReceiveAccepted.Contains(nodeID) { - b.Ctx.Log.Debug("received unexpected Accepted message", - zap.Stringer("nodeID", nodeID), - ) - return nil - } - // Mark that we received a response from [nodeID] - b.pendingReceiveAccepted.Remove(nodeID) - - weight := b.Beacons.GetWeight(b.Ctx.SubnetID, nodeID) - for containerID := range containerIDs { - previousWeight := b.acceptedVotes[containerID] - newWeight, err := safemath.Add64(weight, previousWeight) - if err != nil { - b.Ctx.Log.Error("failed calculating the Accepted votes", - zap.Uint64("weight", weight), - zap.Uint64("previousWeight", previousWeight), - zap.Error(err), - ) - newWeight = math.MaxUint64 - } - b.acceptedVotes[containerID] = newWeight - } - - b.sendGetAccepted(ctx) - - // wait on pending responses - if b.pendingReceiveAccepted.Len() != 0 { - return nil - } - - // We've received the filtered accepted frontier from every bootstrap validator - // Accept all containers that have a sufficient weight behind them - accepted := make([]ids.ID, 0, len(b.acceptedVotes)) - for containerID, weight := range b.acceptedVotes { - if weight >= b.Alpha { - accepted = append(accepted, containerID) - } - } - - // if we don't have enough weight for the bootstrap to be accepted then - // retry or fail the bootstrap - size := len(accepted) - if size == 0 && b.Beacons.Count(b.Ctx.SubnetID) > 0 { - // if we had too many timeouts when asking for validator votes, we - // should restart bootstrap hoping for the network problems to go away; - // otherwise, we received enough (>= b.Alpha) responses, but no frontier - // was supported by a majority of validators (i.e. votes are split - // between minorities supporting different frontiers). - beaconTotalWeight, err := b.Beacons.TotalWeight(b.Ctx.SubnetID) - if err != nil { - return fmt.Errorf("failed to get total weight of beacons for subnet %s: %w", b.Ctx.SubnetID, err) - } - failedBeaconWeight, err := b.Beacons.SubsetWeight(b.Ctx.SubnetID, b.failedAccepted) - if err != nil { - return fmt.Errorf("failed to get total weight of failed beacons for subnet %s: %w", b.Ctx.SubnetID, err) - } - votingStakes := beaconTotalWeight - failedBeaconWeight - if b.Config.RetryBootstrap && votingStakes < b.Alpha { - b.Ctx.Log.Debug("restarting bootstrap", - zap.String("reason", "not enough votes received"), - zap.Int("numBeacons", b.Beacons.Count(b.Ctx.SubnetID)), - zap.Int("numFailedBootstrappers", b.failedAccepted.Len()), - zap.Int("numBootstrapAttempts", b.bootstrapAttempts), - ) - return b.Restart(ctx, false) - } - } - - if !b.Config.SharedCfg.Restarted { - b.Ctx.Log.Info("bootstrapping started syncing", - zap.Int("numVerticesInFrontier", size), - ) - } else { - b.Ctx.Log.Debug("bootstrapping started syncing", - zap.Int("numVerticesInFrontier", size), - ) + if err := b.majority.RecordOpinion(ctx, nodeID, containerIDs); err != nil { + return err } - - return b.Bootstrapable.ForceAccepted(ctx, accepted) + return b.sendMessagesOrFinish(ctx) } func (b *bootstrapper) GetAcceptedFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - // ignores any late responses if requestID != b.Config.SharedCfg.RequestID { b.Ctx.Log.Debug("received out-of-sync GetAcceptedFailed message", zap.Stringer("nodeID", nodeID), @@ -288,58 +116,50 @@ func (b *bootstrapper) GetAcceptedFailed(ctx context.Context, nodeID ids.NodeID, return nil } - // If we can't get a response from [nodeID], act as though they said that - // they think none of the containers we sent them in GetAccepted are - // accepted - b.failedAccepted.Add(nodeID) - return b.Accepted(ctx, nodeID, requestID, nil) + if err := b.majority.RecordOpinion(ctx, nodeID, nil); err != nil { + return err + } + return b.sendMessagesOrFinish(ctx) } func (b *bootstrapper) Startup(ctx context.Context) error { - beaconIDs, err := b.Beacons.Sample(b.Ctx.SubnetID, b.Config.SampleK) - if err != nil { - return err + currentBeacons := b.Beacons.GetMap(b.Ctx.SubnetID) + nodeWeights := make(map[ids.NodeID]uint64, len(currentBeacons)) + for nodeID, beacon := range currentBeacons { + nodeWeights[nodeID] = beacon.Weight } - b.sampledBeacons = validators.NewManager() - b.pendingSendAcceptedFrontier.Clear() - for _, nodeID := range beaconIDs { - if _, ok := b.sampledBeacons.GetValidator(b.Ctx.SubnetID, nodeID); !ok { - // Invariant: We never use the TxID or BLS keys populated here. - err = b.sampledBeacons.AddStaker(b.Ctx.SubnetID, nodeID, nil, ids.Empty, 1) - } else { - err = b.sampledBeacons.AddWeight(b.Ctx.SubnetID, nodeID, 1) - } - if err != nil { - return err - } - b.pendingSendAcceptedFrontier.Add(nodeID) + frontierNodes, err := smbootstrapper.Sample(nodeWeights, b.SampleK) + if err != nil { + return err } - b.pendingReceiveAcceptedFrontier.Clear() - b.failedAcceptedFrontier.Clear() - b.acceptedFrontierSet.Clear() + b.Ctx.Log.Debug("sampled nodes to seed bootstrapping frontier", + zap.Reflect("sampledNodes", frontierNodes), + zap.Int("numNodes", len(nodeWeights)), + ) - b.pendingSendAccepted.Clear() - for _, nodeID := range b.Beacons.GetValidatorIDs(b.Ctx.SubnetID) { - b.pendingSendAccepted.Add(nodeID) - } - - b.pendingReceiveAccepted.Clear() - b.failedAccepted.Clear() - b.acceptedVotes = make(map[ids.ID]uint64) + b.minority = smbootstrapper.NewMinority( + b.Ctx.Log, + frontierNodes, + MaxOutstandingBroadcastRequests, + ) + b.majority = smbootstrapper.NewMajority( + b.Ctx.Log, + nodeWeights, + MaxOutstandingBroadcastRequests, + ) b.bootstrapAttempts++ - if b.pendingSendAcceptedFrontier.Len() == 0 { + if accepted, finalized := b.majority.Result(ctx); finalized { b.Ctx.Log.Info("bootstrapping skipped", zap.String("reason", "no provided bootstraps"), ) - return b.Bootstrapable.ForceAccepted(ctx, nil) + return b.Bootstrapable.ForceAccepted(ctx, accepted) } b.Config.SharedCfg.RequestID++ - b.sendGetAcceptedFrontiers(ctx) - return nil + return b.sendMessagesOrFinish(ctx) } func (b *bootstrapper) Restart(ctx context.Context, reset bool) error { @@ -361,40 +181,50 @@ func (b *bootstrapper) Restart(ctx context.Context, reset bool) error { return b.Startup(ctx) } -// Ask up to [MaxOutstandingBroadcastRequests] bootstrap validators to send -// their accepted frontier with the current accepted frontier -func (b *bootstrapper) sendGetAcceptedFrontiers(ctx context.Context) { - vdrs := set.NewSet[ids.NodeID](1) - for b.pendingSendAcceptedFrontier.Len() > 0 && b.pendingReceiveAcceptedFrontier.Len() < MaxOutstandingBroadcastRequests { - vdr, _ := b.pendingSendAcceptedFrontier.Pop() - // Add the validator to the set to send the messages to - vdrs.Add(vdr) - // Add the validator to send pending receipt set - b.pendingReceiveAcceptedFrontier.Add(vdr) +func (b *bootstrapper) sendMessagesOrFinish(ctx context.Context) error { + if peers := b.minority.GetPeers(ctx); peers.Len() > 0 { + b.Sender.SendGetAcceptedFrontier(ctx, peers, b.Config.SharedCfg.RequestID) + return nil } - if vdrs.Len() > 0 { - b.Sender.SendGetAcceptedFrontier(ctx, vdrs, b.Config.SharedCfg.RequestID) + potentialAccepted, finalized := b.minority.Result(ctx) + if !finalized { + // We haven't finalized the accepted frontier, so we should wait for the + // outstanding requests. + return nil + } + + if peers := b.majority.GetPeers(ctx); peers.Len() > 0 { + b.Sender.SendGetAccepted(ctx, peers, b.Config.SharedCfg.RequestID, potentialAccepted) + return nil + } + + accepted, finalized := b.majority.Result(ctx) + if !finalized { + // We haven't finalized the accepted set, so we should wait for the + // outstanding requests. + return nil } -} -// Ask up to [MaxOutstandingBroadcastRequests] bootstrap validators to send -// their filtered accepted frontier -func (b *bootstrapper) sendGetAccepted(ctx context.Context) { - vdrs := set.NewSet[ids.NodeID](1) - for b.pendingSendAccepted.Len() > 0 && b.pendingReceiveAccepted.Len() < MaxOutstandingBroadcastRequests { - vdr, _ := b.pendingSendAccepted.Pop() - // Add the validator to the set to send the messages to - vdrs.Add(vdr) - // Add the validator to send pending receipt set - b.pendingReceiveAccepted.Add(vdr) + numAccepted := len(accepted) + if numAccepted == 0 { + b.Ctx.Log.Debug("restarting bootstrap", + zap.String("reason", "no blocks accepted"), + zap.Int("numBeacons", b.Beacons.Count(b.Ctx.SubnetID)), + zap.Int("numBootstrapAttempts", b.bootstrapAttempts), + ) + return b.Restart(ctx, false /*=reset*/) } - if vdrs.Len() > 0 { - b.Ctx.Log.Debug("sent GetAccepted messages", - zap.Int("numSent", vdrs.Len()), - zap.Int("numPending", b.pendingSendAccepted.Len()), + if !b.Config.SharedCfg.Restarted { + b.Ctx.Log.Info("bootstrapping started syncing", + zap.Int("numAccepted", numAccepted), + ) + } else { + b.Ctx.Log.Debug("bootstrapping started syncing", + zap.Int("numAccepted", numAccepted), ) - b.Sender.SendGetAccepted(ctx, vdrs, b.Config.SharedCfg.RequestID, b.acceptedFrontier) } + + return b.Bootstrapable.ForceAccepted(ctx, accepted) } From 35fbb3a6f05f387bbb3dd17416e552674a0b3b63 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 16 Nov 2023 10:33:18 -0700 Subject: [PATCH 045/267] Pchain - Cleanup NodeID generation in UTs (#2291) Co-authored-by: Dan Laine Co-authored-by: Stephen Buttolph --- tests/e2e/static-handlers/suites.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 15 +++- vms/platformvm/block/executor/helpers_test.go | 15 +++- .../block/executor/proposal_block_test.go | 68 +++++++-------- .../block/executor/standard_block_test.go | 46 ++++++---- vms/platformvm/service_test.go | 4 +- .../txs/executor/advance_time_test.go | 13 ++- vms/platformvm/txs/executor/helpers_test.go | 15 +++- .../txs/executor/proposal_tx_executor_test.go | 42 +++++----- .../txs/executor/standard_tx_executor_test.go | 42 +++++----- vms/platformvm/txs/validator_test.go | 10 +-- vms/platformvm/validator_set_property_test.go | 2 +- vms/platformvm/vm_regression_test.go | 84 +++++++++---------- vms/platformvm/vm_test.go | 54 +++++++----- 14 files changed, 220 insertions(+), 192 deletions(-) diff --git a/tests/e2e/static-handlers/suites.go b/tests/e2e/static-handlers/suites.go index 2351b32e09ed..67b12a0cbb04 100644 --- a/tests/e2e/static-handlers/suites.go +++ b/tests/e2e/static-handlers/suites.go @@ -150,7 +150,7 @@ var _ = ginkgo.Describe("[StaticHandlers]", func() { GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(time.Date(1997, 1, 1, 0, 0, 0, 0, time.UTC).Unix()), EndTime: json.Uint64(time.Date(1997, 1, 30, 0, 0, 0, 0, time.UTC).Unix()), - NodeID: ids.NodeID(id), + NodeID: ids.BuildTestNodeID(id[:]), }, RewardOwner: &api.Owner{ Threshold: 1, diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index e3ea9f40845b..1d2e57804e96 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -76,9 +76,19 @@ var ( testSubnet1 *txs.Tx testSubnet1ControlKeys = preFundedKeys[0:3] + // Node IDs of genesis validators. Initialized in init function + genesisNodeIDs []ids.NodeID + errMissing = errors.New("missing") ) +func init() { + genesisNodeIDs = make([]ids.NodeID, len(preFundedKeys)) + for i := range preFundedKeys { + genesisNodeIDs[i] = ids.GenerateTestNodeID() + } +} + type mutableSharedMemory struct { atomic.SharedMemory } @@ -365,9 +375,8 @@ func buildGenesisTest(t *testing.T, ctx *snow.Context) []byte { } } - genesisValidators := make([]api.GenesisPermissionlessValidator, len(preFundedKeys)) - for i, key := range preFundedKeys { - nodeID := ids.NodeID(key.PublicKey().Address()) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(genesisNodeIDs)) + for i, nodeID := range genesisNodeIDs { addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) genesisValidators[i] = api.GenesisPermissionlessValidator{ diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 4f452f1144c0..9c9135fe6f9f 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -81,9 +81,19 @@ var ( genesisBlkID ids.ID testSubnet1 *txs.Tx + // Node IDs of genesis validators. Initialized in init function + genesisNodeIDs []ids.NodeID + errMissing = errors.New("missing") ) +func init() { + genesisNodeIDs = make([]ids.NodeID, len(preFundedKeys)) + for i := range preFundedKeys { + genesisNodeIDs[i] = ids.GenerateTestNodeID() + } +} + type stakerStatus uint type staker struct { @@ -399,9 +409,8 @@ func buildGenesisTest(ctx *snow.Context) []byte { } } - genesisValidators := make([]api.GenesisPermissionlessValidator, len(preFundedKeys)) - for i, key := range preFundedKeys { - nodeID := ids.NodeID(key.PublicKey().Address()) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(genesisNodeIDs)) + for i, nodeID := range genesisNodeIDs { addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) if err != nil { panic(err) diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 4300ad9606d9..b69708f8ca9f 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -392,57 +392,52 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { // Staker5: |--------------------| // Staker0 it's here just to allow to issue a proposal block with the chosen endTime. - staker0RewardAddress := ids.ShortID{2} + + // In this test multiple stakers may join and leave the staker set at the same time. + // The order in which they do it is asserted; the order may depend on the staker.TxID, + // which in turns depend on every feature of the transaction creating the staker. + // So in this test we avoid ids.GenerateTestNodeID, in favour of ids.BuildTestNodeID + // so that TxID does not depend on the order we run tests. staker0 := staker{ - nodeID: ids.NodeID(staker0RewardAddress), - rewardAddress: staker0RewardAddress, + nodeID: ids.BuildTestNodeID([]byte{0xf0}), + rewardAddress: ids.ShortID{0xf0}, startTime: defaultGenesisTime, endTime: time.Time{}, // actual endTime depends on specific test } - staker1RewardAddress := ids.GenerateTestShortID() staker1 := staker{ - nodeID: ids.NodeID(staker1RewardAddress), - rewardAddress: staker1RewardAddress, + nodeID: ids.BuildTestNodeID([]byte{0xf1}), + rewardAddress: ids.ShortID{0xf1}, startTime: defaultGenesisTime.Add(1 * time.Minute), endTime: defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute), } - - staker2RewardAddress := ids.ShortID{1} staker2 := staker{ - nodeID: ids.NodeID(staker2RewardAddress), - rewardAddress: staker2RewardAddress, + nodeID: ids.BuildTestNodeID([]byte{0xf2}), + rewardAddress: ids.ShortID{0xf2}, startTime: staker1.startTime.Add(1 * time.Minute), endTime: staker1.startTime.Add(1 * time.Minute).Add(defaultMinStakingDuration), } - - staker3RewardAddress := ids.GenerateTestShortID() staker3 := staker{ - nodeID: ids.NodeID(staker3RewardAddress), - rewardAddress: staker3RewardAddress, + nodeID: ids.BuildTestNodeID([]byte{0xf3}), + rewardAddress: ids.ShortID{0xf3}, startTime: staker2.startTime.Add(1 * time.Minute), endTime: staker2.endTime.Add(1 * time.Minute), } - staker3Sub := staker{ - nodeID: staker3.nodeID, - rewardAddress: staker3.rewardAddress, + nodeID: ids.BuildTestNodeID([]byte{0xf3}), + rewardAddress: ids.ShortID{0xff}, startTime: staker3.startTime.Add(1 * time.Minute), endTime: staker3.endTime.Add(-1 * time.Minute), } - - staker4RewardAddress := ids.GenerateTestShortID() staker4 := staker{ - nodeID: ids.NodeID(staker4RewardAddress), - rewardAddress: staker4RewardAddress, + nodeID: ids.BuildTestNodeID([]byte{0xf4}), + rewardAddress: ids.ShortID{0xf4}, startTime: staker3.startTime, endTime: staker3.endTime, } - - staker5RewardAddress := ids.GenerateTestShortID() staker5 := staker{ - nodeID: ids.NodeID(staker5RewardAddress), - rewardAddress: staker5RewardAddress, + nodeID: ids.BuildTestNodeID([]byte{0xf5}), + rewardAddress: ids.ShortID{0xf5}, startTime: staker2.endTime, endTime: staker2.endTime.Add(defaultMinStakingDuration), } @@ -541,15 +536,19 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { }, }, { - description: "advance time to staker5 end", + description: "advance time to staker5 start", stakers: []staker{staker1, staker2, staker3, staker4, staker5}, advanceTimeTo: []time.Time{staker1.startTime, staker2.startTime, staker3.startTime, staker5.startTime}, expectedStakers: map[ids.NodeID]stakerStatus{ staker1.nodeID: current, - // given its txID, staker2 will be - // rewarded and moved out of current stakers set - // staker2.nodeID: current, + // Staker2's end time matches staker5's start time, so typically + // the block builder would produce a ProposalBlock to remove + // staker2 when advancing the time. However, this test injects + // staker0 into the staker set artificially to advance the time. + // This means that staker2 is not removed by the ProposalBlock + // when advancing the time. + staker2.nodeID: current, staker3.nodeID: current, staker4.nodeID: current, staker5.nodeID: current, @@ -564,7 +563,6 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { defer func() { require.NoError(shutdownEnvironment(env)) }() - env.config.BanffTime = time.Time{} // activate Banff subnetID := testSubnet1.ID() @@ -721,8 +719,7 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { env.config.TrackedSubnets.Add(subnetID) // Add a subnet validator to the staker set - subnetValidatorNodeID := ids.NodeID(preFundedKeys[0].PublicKey().Address()) - // Starts after the corre + subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) tx, err := env.txBuilder.NewAddSubnetValidatorTx( @@ -750,7 +747,7 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { // The above validator is now part of the staking set // Queue a staker that joins the staker set after the above validator leaves - subnetVdr2NodeID := ids.NodeID(preFundedKeys[1].PublicKey().Address()) + subnetVdr2NodeID := genesisNodeIDs[1] tx, err = env.txBuilder.NewAddSubnetValidatorTx( 1, // Weight uint64(subnetVdr1EndTime.Add(time.Second).Unix()), // Start time @@ -862,8 +859,7 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { } // Add a subnet validator to the staker set - subnetValidatorNodeID := ids.NodeID(preFundedKeys[0].PublicKey().Address()) - + subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultGenesisTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) tx, err := env.txBuilder.NewAddSubnetValidatorTx( @@ -1145,7 +1141,7 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { pendingValidatorEndTime := pendingValidatorStartTime.Add(defaultMinStakingDuration) nodeIDKey, _ := secp256k1.NewPrivateKey() rewardAddress := nodeIDKey.PublicKey().Address() - nodeID := ids.NodeID(rewardAddress) + nodeID := ids.BuildTestNodeID(rewardAddress[:]) _, err := addPendingValidator( env, diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 110def5c5987..af1a7562cdd0 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -363,39 +363,45 @@ func TestBanffStandardBlockUpdateStakers(t *testing.T) { // Staker3sub: |----------------| // Staker4: |------------------------| // Staker5: |--------------------| + + // In this test multiple stakers may join and leave the staker set at the same time. + // The order in which they do it is asserted; the order may depend on the staker.TxID, + // which in turns depend on every feature of the transaction creating the staker. + // So in this test we avoid ids.GenerateTestNodeID, in favour of ids.BuildTestNodeID + // so that TxID does not depend on the order we run tests. staker1 := staker{ - nodeID: ids.GenerateTestNodeID(), - rewardAddress: ids.GenerateTestShortID(), + nodeID: ids.BuildTestNodeID([]byte{0xf1}), + rewardAddress: ids.ShortID{0xf1}, startTime: defaultGenesisTime.Add(1 * time.Minute), endTime: defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute), } staker2 := staker{ - nodeID: ids.GenerateTestNodeID(), - rewardAddress: ids.GenerateTestShortID(), + nodeID: ids.BuildTestNodeID([]byte{0xf2}), + rewardAddress: ids.ShortID{0xf2}, startTime: staker1.startTime.Add(1 * time.Minute), endTime: staker1.startTime.Add(1 * time.Minute).Add(defaultMinStakingDuration), } staker3 := staker{ - nodeID: ids.GenerateTestNodeID(), - rewardAddress: ids.GenerateTestShortID(), + nodeID: ids.BuildTestNodeID([]byte{0xf3}), + rewardAddress: ids.ShortID{0xf3}, startTime: staker2.startTime.Add(1 * time.Minute), endTime: staker2.endTime.Add(1 * time.Minute), } staker3Sub := staker{ - nodeID: staker3.nodeID, - rewardAddress: ids.GenerateTestShortID(), + nodeID: ids.BuildTestNodeID([]byte{0xf3}), + rewardAddress: ids.ShortID{0xff}, startTime: staker3.startTime.Add(1 * time.Minute), endTime: staker3.endTime.Add(-1 * time.Minute), } staker4 := staker{ - nodeID: ids.GenerateTestNodeID(), - rewardAddress: ids.GenerateTestShortID(), + nodeID: ids.BuildTestNodeID([]byte{0xf4}), + rewardAddress: ids.ShortID{0xf4}, startTime: staker3.startTime, endTime: staker3.endTime, } staker5 := staker{ - nodeID: ids.GenerateTestNodeID(), - rewardAddress: ids.GenerateTestShortID(), + nodeID: ids.BuildTestNodeID([]byte{0xf5}), + rewardAddress: ids.ShortID{0xf5}, startTime: staker2.endTime, endTime: staker2.endTime.Add(defaultMinStakingDuration), } @@ -474,11 +480,17 @@ func TestBanffStandardBlockUpdateStakers(t *testing.T) { }, }, { - description: "advance time to staker5 end", + description: "advance time to staker5 start", stakers: []staker{staker1, staker2, staker3, staker4, staker5}, advanceTimeTo: []time.Time{staker1.startTime, staker2.startTime, staker3.startTime, staker5.startTime}, expectedStakers: map[ids.NodeID]stakerStatus{ staker1.nodeID: current, + + // Staker2's end time matches staker5's start time, so typically + // the block builder would produce a ProposalBlock to remove + // staker2 when advancing the time. However, it is valid to only + // advance the time with a StandardBlock and not remove staker2, + // which is what this test does. staker2.nodeID: current, staker3.nodeID: current, staker4.nodeID: current, @@ -602,8 +614,7 @@ func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { env.config.TrackedSubnets.Add(subnetID) // Add a subnet validator to the staker set - subnetValidatorNodeID := ids.NodeID(preFundedKeys[0].PublicKey().Address()) - // Starts after the corre + subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) tx, err := env.txBuilder.NewAddSubnetValidatorTx( @@ -631,7 +642,7 @@ func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { // The above validator is now part of the staking set // Queue a staker that joins the staker set after the above validator leaves - subnetVdr2NodeID := ids.NodeID(preFundedKeys[1].PublicKey().Address()) + subnetVdr2NodeID := genesisNodeIDs[1] tx, err = env.txBuilder.NewAddSubnetValidatorTx( 1, // Weight uint64(subnetVdr1EndTime.Add(time.Second).Unix()), // Start time @@ -702,8 +713,7 @@ func TestBanffStandardBlockTrackedSubnet(t *testing.T) { } // Add a subnet validator to the staker set - subnetValidatorNodeID := ids.NodeID(preFundedKeys[0].PublicKey().Address()) - + subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultGenesisTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) tx, err := env.txBuilder.NewAddSubnetValidatorTx( diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 4baaf6361d4b..8e2cc3790fc3 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -494,7 +494,7 @@ func TestGetStake(t *testing.T) { // Add a delegator stakeAmount := service.vm.MinDelegatorStake + 12345 - delegatorNodeID := ids.NodeID(keys[0].PublicKey().Address()) + delegatorNodeID := genesisNodeIDs[0] delegatorEndTime := uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix()) tx, err := service.vm.txBuilder.NewAddDelegatorTx( stakeAmount, @@ -626,7 +626,7 @@ func TestGetCurrentValidators(t *testing.T) { // Add a delegator stakeAmount := service.vm.MinDelegatorStake + 12345 - validatorNodeID := ids.NodeID(keys[1].PublicKey().Address()) + validatorNodeID := genesisNodeIDs[1] delegatorStartTime := uint64(defaultValidateStartTime.Unix()) delegatorEndTime := uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix()) diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 5f9eabe0553c..694d6b7ff7fa 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -462,8 +462,7 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { dummyHeight := uint64(1) // Add a subnet validator to the staker set - subnetValidatorNodeID := ids.NodeID(preFundedKeys[0].PublicKey().Address()) - // Starts after the corre + subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultValidateStartTime subnetVdr1EndTime := defaultValidateStartTime.Add(defaultMinStakingDuration) tx, err := env.txBuilder.NewAddSubnetValidatorTx( @@ -492,7 +491,7 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { // The above validator is now part of the staking set // Queue a staker that joins the staker set after the above validator leaves - subnetVdr2NodeID := ids.NodeID(preFundedKeys[1].PublicKey().Address()) + subnetVdr2NodeID := genesisNodeIDs[1] tx, err = env.txBuilder.NewAddSubnetValidatorTx( 1, // Weight uint64(subnetVdr1EndTime.Add(time.Second).Unix()), // Start time @@ -567,7 +566,7 @@ func TestTrackedSubnet(t *testing.T) { } // Add a subnet validator to the staker set - subnetValidatorNodeID := preFundedKeys[0].PublicKey().Address() + subnetValidatorNodeID := genesisNodeIDs[0] subnetVdr1StartTime := defaultGenesisTime.Add(1 * time.Minute) subnetVdr1EndTime := defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) @@ -575,7 +574,7 @@ func TestTrackedSubnet(t *testing.T) { 1, // Weight uint64(subnetVdr1StartTime.Unix()), // Start time uint64(subnetVdr1EndTime.Unix()), // end time - ids.NodeID(subnetValidatorNodeID), // Node ID + subnetValidatorNodeID, // Node ID subnetID, // Subnet ID []*secp256k1.PrivateKey{preFundedKeys[0], preFundedKeys[1]}, ids.ShortEmpty, @@ -616,7 +615,7 @@ func TestTrackedSubnet(t *testing.T) { env.state.SetHeight(dummyHeight) require.NoError(env.state.Commit()) - _, ok := env.config.Validators.GetValidator(subnetID, ids.NodeID(subnetValidatorNodeID)) + _, ok := env.config.Validators.GetValidator(subnetID, subnetValidatorNodeID) require.True(ok) }) } @@ -923,7 +922,7 @@ func addPendingValidator( uint64(startTime.Unix()), uint64(endTime.Unix()), nodeID, - ids.ShortID(nodeID), + ids.GenerateTestShortID(), reward.PercentDenominator, keys, ids.ShortEmpty, diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 409fe79c7002..c26a865bdc6f 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -73,9 +73,19 @@ var ( testSubnet1 *txs.Tx testSubnet1ControlKeys = preFundedKeys[0:3] + // Node IDs of genesis validators. Initialized in init function + genesisNodeIDs []ids.NodeID + errMissing = errors.New("missing") ) +func init() { + genesisNodeIDs = make([]ids.NodeID, len(preFundedKeys)) + for i := range preFundedKeys { + genesisNodeIDs[i] = ids.GenerateTestNodeID() + } +} + type mutableSharedMemory struct { atomic.SharedMemory } @@ -366,9 +376,8 @@ func buildGenesisTest(ctx *snow.Context) []byte { } } - genesisValidators := make([]api.GenesisPermissionlessValidator, len(preFundedKeys)) - for i, key := range preFundedKeys { - nodeID := ids.NodeID(key.PublicKey().Address()) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(genesisNodeIDs)) + for i, nodeID := range genesisNodeIDs { addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) if err != nil { panic(err) diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index 0044d27a32ea..bc95f3ed39b2 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -25,7 +25,7 @@ import ( func TestProposalTxExecuteAddDelegator(t *testing.T) { dummyHeight := uint64(1) rewardAddress := preFundedKeys[0].PublicKey().Address() - nodeID := ids.NodeID(rewardAddress) + nodeID := genesisNodeIDs[0] newValidatorID := ids.GenerateTestNodeID() newValidatorStartTime := uint64(defaultValidateStartTime.Add(5 * time.Second).Unix()) @@ -288,8 +288,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { require.NoError(shutdownEnvironment(env)) }() - nodeID := preFundedKeys[0].PublicKey().Address() - + nodeID := genesisNodeIDs[0] { // Case: Proposed validator currently validating primary network // but stops validating subnet after stops validating primary network @@ -298,7 +297,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { defaultWeight, uint64(defaultValidateStartTime.Unix())+1, uint64(defaultValidateEndTime.Unix())+1, - ids.NodeID(nodeID), + nodeID, testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr @@ -330,7 +329,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { defaultWeight, uint64(defaultValidateStartTime.Unix())+1, uint64(defaultValidateEndTime.Unix()), - ids.NodeID(nodeID), + nodeID, testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr @@ -353,11 +352,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { } // Add a validator to pending validator set of primary network - key, err := secp256k1.NewPrivateKey() - require.NoError(err) - pendingDSValidatorID := ids.NodeID(key.PublicKey().Address()) - - // starts validating primary network 10 seconds after genesis + // Starts validating primary network 10 seconds after genesis + pendingDSValidatorID := ids.GenerateTestNodeID() dsStartTime := defaultGenesisTime.Add(10 * time.Second) dsEndTime := dsStartTime.Add(5 * defaultMinStakingDuration) @@ -366,7 +362,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { uint64(dsStartTime.Unix()), // start time uint64(dsEndTime.Unix()), // end time pendingDSValidatorID, // node ID - nodeID, // reward address + ids.GenerateTestShortID(), // reward address reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, @@ -516,8 +512,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(newTimestamp.Unix()), // start time uint64(newTimestamp.Add(defaultMinStakingDuration).Unix()), // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr ) @@ -548,7 +544,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(defaultValidateStartTime.Unix()), // start time uint64(defaultValidateEndTime.Unix()), // end time - ids.NodeID(nodeID), // node ID + nodeID, // node ID testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, @@ -573,7 +569,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(defaultValidateStartTime.Unix())+1, // start time uint64(defaultValidateEndTime.Unix()), // end time - ids.NodeID(nodeID), // node ID + nodeID, // node ID testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr @@ -606,8 +602,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(defaultGenesisTime.Unix())+1, // start time uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix())+1, // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]}, ids.ShortEmpty, // change addr ) @@ -642,8 +638,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(defaultGenesisTime.Unix())+1, // start time uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix())+1, // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], preFundedKeys[1]}, ids.ShortEmpty, // change addr ) @@ -677,8 +673,8 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(defaultGenesisTime.Unix())+1, // start time uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix())+1, // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr ) @@ -784,12 +780,14 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { } { + nodeID := genesisNodeIDs[0] + // Case: Validator already validating primary network tx, err := env.txBuilder.NewAddValidatorTx( env.config.MinValidatorStake, uint64(defaultValidateStartTime.Unix())+1, uint64(defaultValidateEndTime.Unix()), - ids.NodeID(preFundedKeys[0].Address()), + nodeID, ids.ShortEmpty, reward.PercentDenominator, []*secp256k1.PrivateKey{preFundedKeys[0]}, diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 5cfc420b1705..78e15078e133 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -99,7 +99,7 @@ func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { func TestStandardTxExecutorAddDelegator(t *testing.T) { dummyHeight := uint64(1) rewardAddress := preFundedKeys[0].PublicKey().Address() - nodeID := ids.NodeID(rewardAddress) + nodeID := genesisNodeIDs[0] newValidatorID := ids.GenerateTestNodeID() newValidatorStartTime := uint64(defaultValidateStartTime.Add(5 * time.Second).Unix()) @@ -380,7 +380,7 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { require.NoError(shutdownEnvironment(env)) }() - nodeID := preFundedKeys[0].PublicKey().Address() + nodeID := genesisNodeIDs[0] env.config.BanffTime = env.state.GetTimestamp() { @@ -392,7 +392,7 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, uint64(startTime.Unix()), uint64(defaultValidateEndTime.Unix())+1, - ids.NodeID(nodeID), + nodeID, testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr @@ -420,7 +420,7 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, uint64(defaultValidateStartTime.Unix()+1), uint64(defaultValidateEndTime.Unix()), - ids.NodeID(nodeID), + nodeID, testSubnet1.ID(), []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr @@ -439,12 +439,8 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { } // Add a validator to pending validator set of primary network - key, err := secp256k1.NewPrivateKey() - require.NoError(err) - - pendingDSValidatorID := ids.NodeID(key.PublicKey().Address()) - - // starts validating primary network 10 seconds after genesis + // Starts validating primary network 10 seconds after genesis + pendingDSValidatorID := ids.GenerateTestNodeID() dsStartTime := defaultGenesisTime.Add(10 * time.Second) dsEndTime := dsStartTime.Add(5 * defaultMinStakingDuration) @@ -453,7 +449,7 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { uint64(dsStartTime.Unix()), // start time uint64(dsEndTime.Unix()), // end time pendingDSValidatorID, // node ID - nodeID, // reward address + ids.GenerateTestShortID(), // reward address reward.PercentDenominator, // shares []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, @@ -586,8 +582,8 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(newTimestamp.Unix()), // start time uint64(newTimestamp.Add(defaultMinStakingDuration).Unix()), // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr ) @@ -614,7 +610,7 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(defaultValidateStartTime.Unix()), // start time uint64(defaultValidateEndTime.Unix()), // end time - ids.NodeID(nodeID), // node ID + nodeID, // node ID testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, @@ -640,7 +636,7 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(startTime.Unix()), // start time uint64(defaultValidateEndTime.Unix()), // end time - ids.NodeID(nodeID), // node ID + nodeID, // node ID testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr @@ -670,8 +666,8 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(startTime.Unix()), // start time uint64(startTime.Add(defaultMinStakingDuration).Unix())+1, // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1], testSubnet1ControlKeys[2]}, ids.ShortEmpty, // change addr ) @@ -703,8 +699,8 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(startTime.Unix()), // start time uint64(startTime.Add(defaultMinStakingDuration).Unix()), // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]}, ids.ShortEmpty, // change addr ) @@ -736,8 +732,8 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(startTime.Unix()), // start time uint64(startTime.Add(defaultMinStakingDuration).Unix()), // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], preFundedKeys[1]}, ids.ShortEmpty, // change addr ) @@ -768,8 +764,8 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { defaultWeight, // weight uint64(startTime.Unix())+1, // start time uint64(startTime.Add(defaultMinStakingDuration).Unix())+1, // end time - ids.NodeID(nodeID), // node ID - testSubnet1.ID(), // subnet ID + nodeID, // node ID + testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, ids.ShortEmpty, // change addr ) diff --git a/vms/platformvm/txs/validator_test.go b/vms/platformvm/txs/validator_test.go index 3361d11939b4..fbef50981a14 100644 --- a/vms/platformvm/txs/validator_test.go +++ b/vms/platformvm/txs/validator_test.go @@ -9,22 +9,20 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" ) const defaultWeight = 10000 -// each key controls an address that has [defaultBalance] AVAX at genesis -var keys = secp256k1.TestKeys() - func TestBoundedBy(t *testing.T) { require := require.New(t) + nodeID := ids.GenerateTestNodeID() + // case 1: a starts, a finishes, b starts, b finishes aStartTime := uint64(0) aEndTIme := uint64(1) a := &Validator{ - NodeID: ids.NodeID(keys[0].PublicKey().Address()), + NodeID: nodeID, Start: aStartTime, End: aEndTIme, Wght: defaultWeight, @@ -33,7 +31,7 @@ func TestBoundedBy(t *testing.T) { bStartTime := uint64(2) bEndTime := uint64(3) b := &Validator{ - NodeID: ids.NodeID(keys[0].PublicKey().Address()), + NodeID: nodeID, Start: bStartTime, End: bEndTime, Wght: defaultWeight, diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 01453c60db4c..2ac0d4358d7d 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -841,7 +841,7 @@ func buildCustomGenesis() ([]byte, error) { // won't find next staker to promote/evict from stakers set. Contrary to // what happens with production code we push such validator at the end of // times, so to avoid interference with our tests - nodeID := ids.NodeID(keys[len(keys)-1].PublicKey().Address()) + nodeID := genesisNodeIDs[len(genesisNodeIDs)-1] addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) if err != nil { return nil, err diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 6220f1c43016..5b50c9895622 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -219,6 +219,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) id := key.PublicKey().Address() + nodeID := ids.GenerateTestNodeID() changeAddr := keys[0].PublicKey().Address() // create valid tx @@ -226,7 +227,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { validatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), - ids.NodeID(id), + nodeID, id, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, @@ -249,7 +250,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { delegator1Stake, uint64(delegator1StartTime.Unix()), uint64(delegator1EndTime.Unix()), - ids.NodeID(id), + nodeID, keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -271,7 +272,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { delegator2Stake, uint64(delegator2StartTime.Unix()), uint64(delegator2EndTime.Unix()), - ids.NodeID(id), + nodeID, keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -293,7 +294,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { delegator3Stake, uint64(delegator3StartTime.Unix()), uint64(delegator3EndTime.Unix()), - ids.NodeID(id), + nodeID, keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -315,7 +316,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { delegator4Stake, uint64(delegator4StartTime.Unix()), uint64(delegator4EndTime.Unix()), - ids.NodeID(id), + nodeID, keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -470,21 +471,17 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { vm.ctx.Lock.Unlock() }() + nodeID := ids.GenerateTestNodeID() newValidatorStartTime := vm.clock.Time().Add(executor.SyncBound).Add(1 * time.Second) newValidatorEndTime := newValidatorStartTime.Add(defaultMinStakingDuration) - key, err := secp256k1.NewPrivateKey() - require.NoError(err) - - nodeID := ids.NodeID(key.PublicKey().Address()) - // Create the tx to add a new validator addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( vm.MinValidatorStake, uint64(newValidatorStartTime.Unix()), uint64(newValidatorEndTime.Unix()), nodeID, - ids.ShortID(nodeID), + ids.GenerateTestShortID(), reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, @@ -688,7 +685,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { newValidatorStartTime0 := vm.clock.Time().Add(executor.SyncBound).Add(1 * time.Second) newValidatorEndTime0 := newValidatorStartTime0.Add(defaultMaxStakingDuration) - nodeID0 := ids.NodeID(ids.GenerateTestShortID()) + nodeID0 := ids.GenerateTestNodeID() // Create the tx to add the first new validator addValidatorTx0, err := vm.txBuilder.NewAddValidatorTx( @@ -696,7 +693,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { uint64(newValidatorStartTime0.Unix()), uint64(newValidatorEndTime0.Unix()), nodeID0, - ids.ShortID(nodeID0), + ids.GenerateTestShortID(), reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, @@ -860,7 +857,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { newValidatorStartTime1 := newValidatorStartTime0.Add(executor.SyncBound).Add(1 * time.Second) newValidatorEndTime1 := newValidatorStartTime1.Add(defaultMaxStakingDuration) - nodeID1 := ids.NodeID(ids.GenerateTestShortID()) + nodeID1 := ids.GenerateTestNodeID() // Create the tx to add the second new validator addValidatorTx1, err := vm.txBuilder.NewAddValidatorTx( @@ -868,7 +865,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { uint64(newValidatorStartTime1.Unix()), uint64(newValidatorEndTime1.Unix()), nodeID1, - ids.ShortID(nodeID1), + ids.GenerateTestShortID(), reward.PercentDenominator, []*secp256k1.PrivateKey{keys[1]}, ids.ShortEmpty, @@ -999,22 +996,16 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { vm.ctx.Lock.Unlock() }() - nodeID0 := ids.NodeID(keys[0].PublicKey().Address()) - nodeID1 := ids.NodeID(keys[1].PublicKey().Address()) - nodeID2 := ids.NodeID(keys[2].PublicKey().Address()) - nodeID3 := ids.NodeID(keys[3].PublicKey().Address()) - nodeID4 := ids.NodeID(keys[4].PublicKey().Address()) - currentHeight, err := vm.GetCurrentHeight(context.Background()) require.NoError(err) require.Equal(uint64(1), currentHeight) expectedValidators1 := map[ids.NodeID]uint64{ - nodeID0: defaultWeight, - nodeID1: defaultWeight, - nodeID2: defaultWeight, - nodeID3: defaultWeight, - nodeID4: defaultWeight, + genesisNodeIDs[0]: defaultWeight, + genesisNodeIDs[1]: defaultWeight, + genesisNodeIDs[2]: defaultWeight, + genesisNodeIDs[3]: defaultWeight, + genesisNodeIDs[4]: defaultWeight, } validators, err := vm.GetValidatorSet(context.Background(), 1, constants.PrimaryNetworkID) require.NoError(err) @@ -1025,14 +1016,14 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { newValidatorStartTime0 := vm.clock.Time().Add(executor.SyncBound).Add(1 * time.Second) newValidatorEndTime0 := newValidatorStartTime0.Add(defaultMaxStakingDuration) - nodeID5 := ids.GenerateTestNodeID() + extraNodeID := ids.GenerateTestNodeID() // Create the tx to add the first new validator addValidatorTx0, err := vm.txBuilder.NewAddValidatorTx( vm.MaxValidatorStake, uint64(newValidatorStartTime0.Unix()), uint64(newValidatorEndTime0.Unix()), - nodeID5, + extraNodeID, ids.GenerateTestShortID(), reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, @@ -1108,12 +1099,12 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { } expectedValidators2 := map[ids.NodeID]uint64{ - nodeID0: defaultWeight, - nodeID1: defaultWeight, - nodeID2: defaultWeight, - nodeID3: defaultWeight, - nodeID4: defaultWeight, - nodeID5: vm.MaxValidatorStake, + genesisNodeIDs[0]: defaultWeight, + genesisNodeIDs[1]: defaultWeight, + genesisNodeIDs[2]: defaultWeight, + genesisNodeIDs[3]: defaultWeight, + genesisNodeIDs[4]: defaultWeight, + extraNodeID: vm.MaxValidatorStake, } validators, err = vm.GetValidatorSet(context.Background(), 3, constants.PrimaryNetworkID) require.NoError(err) @@ -1149,7 +1140,8 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { key, err := secp256k1.NewPrivateKey() require.NoError(err) - id := key.PublicKey().Address() + id := key.Address() + nodeID := ids.GenerateTestNodeID() changeAddr := keys[0].PublicKey().Address() // create valid tx @@ -1157,7 +1149,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { validatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), - ids.NodeID(id), + nodeID, id, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, @@ -1180,7 +1172,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { delegator1Stake, uint64(delegator1StartTime.Unix()), uint64(delegator1EndTime.Unix()), - ids.NodeID(id), + nodeID, keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -1202,7 +1194,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { delegator2Stake, uint64(delegator2StartTime.Unix()), uint64(delegator2EndTime.Unix()), - ids.NodeID(id), + nodeID, keys[0].PublicKey().Address(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -1233,14 +1225,15 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t key, err := secp256k1.NewPrivateKey() require.NoError(err) - id := key.PublicKey().Address() + id := key.Address() + nodeID := ids.GenerateTestNodeID() changeAddr := keys[0].PublicKey().Address() addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), - ids.NodeID(id), + nodeID, id, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, @@ -1278,7 +1271,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), - ids.NodeID(id), + nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -1303,7 +1296,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t require.Empty(emptyValidatorSet) removeSubnetValidatorTx, err := vm.txBuilder.NewRemoveSubnetValidatorTx( - ids.NodeID(id), + nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -1351,13 +1344,14 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t require.NoError(err) id := key.PublicKey().Address() + nodeID := ids.GenerateTestNodeID() changeAddr := keys[0].PublicKey().Address() addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), - ids.NodeID(id), + nodeID, id, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0], keys[1]}, @@ -1395,7 +1389,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), - ids.NodeID(id), + nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, @@ -1412,7 +1406,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) removeSubnetValidatorTx, err := vm.txBuilder.NewRemoveSubnetValidatorTx( - ids.NodeID(id), + nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{keys[0], keys[1]}, changeAddr, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 96f6f59711a6..c8f849ecea1a 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -100,6 +100,9 @@ var ( // each key controls an address that has [defaultBalance] AVAX at genesis keys = secp256k1.TestKeys() + // Node IDs of genesis validators. Initialized in init function + genesisNodeIDs []ids.NodeID + defaultMinValidatorStake = 5 * units.MilliAvax defaultMaxValidatorStake = 500 * units.MilliAvax defaultMinDelegatorStake = 1 * units.MilliAvax @@ -119,6 +122,17 @@ var ( errMissing = errors.New("missing") ) +func init() { + for _, key := range keys { + // TODO: use ids.GenerateTestNodeID() instead of ids.BuildTestNodeID + // Can be done when TestGetState is refactored + nodeBytes := key.PublicKey().Address() + nodeID := ids.BuildTestNodeID(nodeBytes[:]) + + genesisNodeIDs = append(genesisNodeIDs, nodeID) + } +} + type mutableSharedMemory struct { atomic.SharedMemory } @@ -175,9 +189,8 @@ func defaultGenesis(t *testing.T) (*api.BuildGenesisArgs, []byte) { } } - genesisValidators := make([]api.GenesisPermissionlessValidator, len(keys)) - for i, key := range keys { - nodeID := ids.NodeID(key.PublicKey().Address()) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(genesisNodeIDs)) + for i, nodeID := range genesisNodeIDs { addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) genesisValidators[i] = api.GenesisPermissionlessValidator{ @@ -243,9 +256,8 @@ func BuildGenesisTestWithArgs(t *testing.T, args *api.BuildGenesisArgs) (*api.Bu } } - genesisValidators := make([]api.GenesisPermissionlessValidator, len(keys)) - for i, key := range keys { - nodeID := ids.NodeID(key.PublicKey().Address()) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(genesisNodeIDs)) + for i, nodeID := range genesisNodeIDs { addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) require.NoError(err) @@ -420,8 +432,7 @@ func TestGenesis(t *testing.T) { // Ensure current validator set of primary network is correct require.Len(genesisState.Validators, vm.Validators.Count(constants.PrimaryNetworkID)) - for _, key := range keys { - nodeID := ids.NodeID(key.PublicKey().Address()) + for _, nodeID := range genesisNodeIDs { _, ok := vm.Validators.GetValidator(constants.PrimaryNetworkID, nodeID) require.True(ok) } @@ -487,10 +498,9 @@ func TestInvalidAddValidatorCommit(t *testing.T) { vm.ctx.Lock.Unlock() }() + nodeID := ids.GenerateTestNodeID() startTime := defaultGenesisTime.Add(-txexecutor.SyncBound).Add(-1 * time.Second) endTime := startTime.Add(defaultMinStakingDuration) - key, _ := secp256k1.NewPrivateKey() - nodeID := ids.NodeID(key.PublicKey().Address()) // create invalid tx tx, err := vm.txBuilder.NewAddValidatorTx( @@ -498,7 +508,7 @@ func TestInvalidAddValidatorCommit(t *testing.T) { uint64(startTime.Unix()), uint64(endTime.Unix()), nodeID, - ids.ShortID(nodeID), + ids.GenerateTestShortID(), reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr @@ -586,7 +596,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { }() // Use nodeID that is already in the genesis - repeatNodeID := ids.NodeID(keys[0].PublicKey().Address()) + repeatNodeID := genesisNodeIDs[0] startTime := banffForkTime.Add(txexecutor.SyncBound).Add(1 * time.Second) endTime := startTime.Add(defaultMinStakingDuration) @@ -597,7 +607,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { uint64(startTime.Unix()), uint64(endTime.Unix()), repeatNodeID, - ids.ShortID(repeatNodeID), + ids.GenerateTestShortID(), reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, ids.ShortEmpty, // change addr @@ -621,7 +631,7 @@ func TestAddSubnetValidatorAccept(t *testing.T) { startTime := vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) endTime := startTime.Add(defaultMinStakingDuration) - nodeID := ids.NodeID(keys[0].PublicKey().Address()) + nodeID := genesisNodeIDs[0] // create valid tx // note that [startTime, endTime] is a subset of time that keys[0] @@ -667,7 +677,7 @@ func TestAddSubnetValidatorReject(t *testing.T) { startTime := vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) endTime := startTime.Add(defaultMinStakingDuration) - nodeID := ids.NodeID(keys[0].PublicKey().Address()) + nodeID := genesisNodeIDs[0] // create valid tx // note that [startTime, endTime] is a subset of time that keys[0] @@ -919,8 +929,7 @@ func TestCreateSubnet(t *testing.T) { vm.ctx.Lock.Unlock() }() - nodeID := ids.NodeID(keys[0].PublicKey().Address()) - + nodeID := genesisNodeIDs[0] createSubnetTx, err := vm.txBuilder.NewCreateSubnetTx( 1, // threshold []ids.ShortID{ // control keys @@ -1743,7 +1752,7 @@ func TestMaxStakeAmount(t *testing.T) { vm.ctx.Lock.Unlock() }() - nodeID := ids.NodeID(keys[0].PublicKey().Address()) + nodeID := genesisNodeIDs[0] tests := []struct { description string @@ -2037,12 +2046,13 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(err) id := key.PublicKey().Address() + nodeID := ids.GenerateTestNodeID() addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), - ids.NodeID(id), + nodeID, id, reward.PercentDenominator, []*secp256k1.PrivateKey{keys[0]}, @@ -2080,7 +2090,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { defaultMaxValidatorStake, uint64(validatorStartTime.Unix()), uint64(validatorEndTime.Unix()), - ids.NodeID(id), + nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{key, keys[1]}, keys[1].Address(), @@ -2088,7 +2098,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(err) removeSubnetValidatorTx, err := vm.txBuilder.NewRemoveSubnetValidatorTx( - ids.NodeID(id), + nodeID, createSubnetTx.ID(), []*secp256k1.PrivateKey{key, keys[2]}, keys[2].Address(), @@ -2113,7 +2123,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require.NoError(block.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - _, err = vm.state.GetPendingValidator(createSubnetTx.ID(), ids.NodeID(id)) + _, err = vm.state.GetPendingValidator(createSubnetTx.ID(), nodeID) require.ErrorIs(err, database.ErrNotFound) } From 6900e72a28c38886ce615eb90148654c90194f7c Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 16 Nov 2023 15:20:19 -0500 Subject: [PATCH 046/267] nit: loop --> variadic (#2316) --- snow/engine/snowman/syncer/state_syncer.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index 91c1150b8dbf..8909b96c7d39 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -484,9 +484,7 @@ func (ss *stateSyncer) startup(ctx context.Context) error { } // list all beacons, to reach them for voting on frontier - for _, nodeID := range ss.StateSyncBeacons.GetValidatorIDs(ss.Ctx.SubnetID) { - ss.targetVoters.Add(nodeID) - } + ss.targetVoters.Add(ss.StateSyncBeacons.GetValidatorIDs(ss.Ctx.SubnetID)...) // check if there is an ongoing state sync; if so add its state summary // to the frontier to request votes on From e7ca38b5268d2762e30839ad039333ac6841724c Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 16 Nov 2023 16:03:17 -0500 Subject: [PATCH 047/267] Update zap dependency to v1.26.0 (#2325) --- go.mod | 6 ++---- go.sum | 13 ++++--------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 1d267ea33bd5..bf06bbc74e83 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( go.opentelemetry.io/otel/trace v1.11.0 go.uber.org/goleak v1.2.1 go.uber.org/mock v0.2.0 - go.uber.org/zap v1.24.0 + go.uber.org/zap v1.26.0 golang.org/x/crypto v0.14.0 golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df golang.org/x/net v0.17.0 @@ -76,7 +76,6 @@ require ( github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/VictoriaMetrics/fastcache v1.10.0 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -145,8 +144,7 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/multierr v1.10.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect diff --git a/go.sum b/go.sum index a0ace68aff35..573d618f19cb 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,6 @@ github.com/ava-labs/coreth v0.12.9-rc.0/go.mod h1:rECKQfGFDeodrwGPlJSvFUJDbVr30j github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -669,19 +667,16 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= From 5236d7280da25fe83f3e90594da17b316d1ca1d8 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 16 Nov 2023 20:08:57 -0500 Subject: [PATCH 048/267] Remove useless anon functions (#2326) --- snow/engine/snowman/bootstrap/bootstrapper.go | 4 +--- snow/networking/timeout/manager.go | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index f6725aa00ba5..8212d5d8cf60 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -594,9 +594,7 @@ func (b *bootstrapper) checkFinish(ctx context.Context) error { // If there is an additional callback, notify them that this chain has been // synced. if b.Bootstrapped != nil { - b.bootstrappedOnce.Do(func() { - b.Bootstrapped() - }) + b.bootstrappedOnce.Do(b.Bootstrapped) } // Notify the subnet that this chain is synced diff --git a/snow/networking/timeout/manager.go b/snow/networking/timeout/manager.go index d94c34a1f663..f1db8a1e01a0 100644 --- a/snow/networking/timeout/manager.go +++ b/snow/networking/timeout/manager.go @@ -163,7 +163,5 @@ func (m *manager) RegisterRequestToUnreachableValidator() { } func (m *manager) Stop() { - m.stopOnce.Do(func() { - m.tm.Stop() - }) + m.stopOnce.Do(m.tm.Stop) } From 85201128fbbb05e85e5164dda8fb3355390234a3 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 16 Nov 2023 20:53:10 -0800 Subject: [PATCH 049/267] Move `network` implementation to separate package (#2296) Signed-off-by: Stephen Buttolph Co-authored-by: Stephen Buttolph --- vms/platformvm/block/builder/helpers_test.go | 19 +- vms/platformvm/block/builder/network_test.go | 147 -------- vms/platformvm/network/main_test.go | 14 + .../{block/builder => network}/network.go | 70 ++-- vms/platformvm/network/network_test.go | 353 ++++++++++++++++++ vms/platformvm/vm.go | 5 +- 6 files changed, 431 insertions(+), 177 deletions(-) delete mode 100644 vms/platformvm/block/builder/network_test.go create mode 100644 vms/platformvm/network/main_test.go rename vms/platformvm/{block/builder => network}/network.go (84%) create mode 100644 vms/platformvm/network/network_test.go diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 1d2e57804e96..f419c38c4ac0 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -40,6 +40,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" + "github.com/ava-labs/avalanchego/vms/platformvm/network" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -97,7 +98,7 @@ type environment struct { Builder blkManager blockexecutor.Manager mempool mempool.Mempool - network Network + network network.Network sender *common.SenderTest isBootstrapped *utils.Atomic[bool] @@ -179,7 +180,7 @@ func newEnvironment(t *testing.T) *environment { pvalidators.TestManager, ) - res.network = NewNetwork( + res.network = network.New( res.backend.Ctx, res.blkManager, res.mempool, @@ -437,3 +438,17 @@ func shutdownEnvironment(env *environment) error { env.baseDB.Close(), ) } + +func getValidTx(txBuilder txbuilder.Builder, t *testing.T) *txs.Tx { + tx, err := txBuilder.NewCreateChainTx( + testSubnet1.ID(), + nil, + constants.AVMID, + nil, + "chain name", + []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, + ids.ShortEmpty, + ) + require.NoError(t, err) + return tx +} diff --git a/vms/platformvm/block/builder/network_test.go b/vms/platformvm/block/builder/network_test.go deleted file mode 100644 index 5421ee2b43f5..000000000000 --- a/vms/platformvm/block/builder/network_test.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package builder - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/vms/components/message" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" -) - -func getValidTx(txBuilder txbuilder.Builder, t *testing.T) *txs.Tx { - tx, err := txBuilder.NewCreateChainTx( - testSubnet1.ID(), - nil, - constants.AVMID, - nil, - "chain name", - []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - ) - require.NoError(t, err) - return tx -} - -// show that a tx learned from gossip is validated and added to mempool -func TestMempoolValidGossipedTxIsAddedToMempool(t *testing.T) { - require := require.New(t) - - env := newEnvironment(t) - env.ctx.Lock.Lock() - defer func() { - require.NoError(shutdownEnvironment(env)) - }() - - var gossipedBytes []byte - env.sender.SendAppGossipF = func(_ context.Context, b []byte) error { - gossipedBytes = b - return nil - } - - nodeID := ids.GenerateTestNodeID() - - // create a tx - tx := getValidTx(env.txBuilder, t) - txID := tx.ID() - - msg := message.Tx{Tx: tx.Bytes()} - msgBytes, err := message.Build(&msg) - require.NoError(err) - // Free lock because [AppGossip] waits for the context lock - env.ctx.Lock.Unlock() - // show that unknown tx is added to mempool - require.NoError(env.network.AppGossip(context.Background(), nodeID, msgBytes)) - require.True(env.Builder.Has(txID)) - // Grab lock back - env.ctx.Lock.Lock() - - // and gossiped if it has just been discovered - require.NotNil(gossipedBytes) - - // show gossiped bytes can be decoded to the original tx - replyIntf, err := message.Parse(gossipedBytes) - require.NoError(err) - - reply := replyIntf.(*message.Tx) - retrivedTx, err := txs.Parse(txs.Codec, reply.Tx) - require.NoError(err) - - require.Equal(txID, retrivedTx.ID()) -} - -// show that txs already marked as invalid are not re-requested on gossiping -func TestMempoolInvalidGossipedTxIsNotAddedToMempool(t *testing.T) { - require := require.New(t) - - env := newEnvironment(t) - env.ctx.Lock.Lock() - defer func() { - require.NoError(shutdownEnvironment(env)) - }() - - // create a tx and mark as invalid - tx := getValidTx(env.txBuilder, t) - txID := tx.ID() - env.Builder.MarkDropped(txID, errTestingDropped) - - // show that the invalid tx is not requested - nodeID := ids.GenerateTestNodeID() - msg := message.Tx{Tx: tx.Bytes()} - msgBytes, err := message.Build(&msg) - require.NoError(err) - env.ctx.Lock.Unlock() - require.NoError(env.network.AppGossip(context.Background(), nodeID, msgBytes)) - env.ctx.Lock.Lock() - require.False(env.Builder.Has(txID)) -} - -// show that locally generated txs are gossiped -func TestMempoolNewLocaTxIsGossiped(t *testing.T) { - require := require.New(t) - - env := newEnvironment(t) - env.ctx.Lock.Lock() - defer func() { - require.NoError(shutdownEnvironment(env)) - }() - - var gossipedBytes []byte - env.sender.SendAppGossipF = func(_ context.Context, b []byte) error { - gossipedBytes = b - return nil - } - - // add a tx to the mempool and show it gets gossiped - tx := getValidTx(env.txBuilder, t) - txID := tx.ID() - - require.NoError(env.network.IssueTx(context.Background(), tx)) - require.NotNil(gossipedBytes) - - // show gossiped bytes can be decoded to the original tx - replyIntf, err := message.Parse(gossipedBytes) - require.NoError(err) - - reply := replyIntf.(*message.Tx) - retrivedTx, err := txs.Parse(txs.Codec, reply.Tx) - require.NoError(err) - - require.Equal(txID, retrivedTx.ID()) - - // show that transaction is not re-gossiped is recently added to mempool - gossipedBytes = nil - env.Builder.Remove([]*txs.Tx{tx}) - require.NoError(env.Builder.Add(tx)) - - require.Nil(gossipedBytes) -} diff --git a/vms/platformvm/network/main_test.go b/vms/platformvm/network/main_test.go new file mode 100644 index 000000000000..be0fab18f587 --- /dev/null +++ b/vms/platformvm/network/main_test.go @@ -0,0 +1,14 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "testing" + + "go.uber.org/goleak" +) + +func TestMain(m *testing.M) { + goleak.VerifyTestMain(m) +} diff --git a/vms/platformvm/block/builder/network.go b/vms/platformvm/network/network.go similarity index 84% rename from vms/platformvm/block/builder/network.go rename to vms/platformvm/network/network.go index 14ba87b5bce0..0bbfc4f86eaf 100644 --- a/vms/platformvm/block/builder/network.go +++ b/vms/platformvm/network/network.go @@ -1,9 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -// TODO: consider moving the network implementation to a separate package - -package builder +package network import ( "context" @@ -34,7 +32,7 @@ type Network interface { // it to the mempool, and gossips it to the network. // // Invariant: Assumes the context lock is held. - IssueTx(ctx context.Context, tx *txs.Tx) error + IssueTx(context.Context, *txs.Tx) error } type network struct { @@ -52,7 +50,7 @@ type network struct { recentTxs *cache.LRU[ids.ID, struct{}] } -func NewNetwork( +func New( ctx *snow.Context, manager executor.Manager, mempool mempool.Mempool, @@ -109,11 +107,13 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b ) return nil } - txID := tx.ID() // We need to grab the context lock here to avoid racy behavior with // transaction verification + mempool modifications. + // + // Invariant: tx should not be referenced again without the context lock + // held to avoid any data races. n.ctx.Lock.Lock() defer n.ctx.Lock.Unlock() @@ -121,48 +121,66 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b // If the tx is being dropped - just ignore it return nil } - - // add to mempool - if err := n.IssueTx(ctx, tx); err != nil { - n.ctx.Log.Debug("tx failed verification", - zap.Stringer("nodeID", nodeID), - zap.Error(err), - ) + if err := n.issueTx(tx); err == nil { + n.gossipTx(ctx, txID, msgBytes) } return nil } func (n *network) IssueTx(ctx context.Context, tx *txs.Tx) error { + if err := n.issueTx(tx); err != nil { + return err + } + + txBytes := tx.Bytes() + msg := &message.Tx{ + Tx: txBytes, + } + msgBytes, err := message.Build(msg) + if err != nil { + return err + } + + txID := tx.ID() + n.gossipTx(ctx, txID, msgBytes) + return nil +} + +// returns nil if the tx is in the mempool +func (n *network) issueTx(tx *txs.Tx) error { txID := tx.ID() if n.mempool.Has(txID) { - // If the transaction is already in the mempool - then it looks the same - // as if it was successfully added + // The tx is already in the mempool return nil } + // Verify the tx at the currently preferred state if err := n.manager.VerifyTx(tx); err != nil { + n.ctx.Log.Debug("tx failed verification", + zap.Stringer("txID", txID), + zap.Error(err), + ) + n.mempool.MarkDropped(txID, err) return err } // If we are partially syncing the Primary Network, we should not be // maintaining the transaction mempool locally. - if !n.partialSyncPrimaryNetwork { - if err := n.mempool.Add(tx); err != nil { - return err - } + if n.partialSyncPrimaryNetwork { + return nil } - txBytes := tx.Bytes() - msg := &message.Tx{ - Tx: txBytes, - } - msgBytes, err := message.Build(msg) - if err != nil { + if err := n.mempool.Add(tx); err != nil { + n.ctx.Log.Debug("tx failed to be added to the mempool", + zap.Stringer("txID", txID), + zap.Error(err), + ) + + n.mempool.MarkDropped(txID, err) return err } - n.gossipTx(ctx, txID, msgBytes) return nil } diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go new file mode 100644 index 000000000000..8c17bb0491b5 --- /dev/null +++ b/vms/platformvm/network/network_test.go @@ -0,0 +1,353 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/require" + + "go.uber.org/mock/gomock" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/message" + "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" +) + +var errTest = errors.New("test error") + +func TestNetworkAppGossip(t *testing.T) { + testTx := &txs.Tx{ + Unsigned: &txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: 1, + BlockchainID: ids.GenerateTestID(), + Ins: []*avax.TransferableInput{}, + Outs: []*avax.TransferableOutput{}, + }, + }, + } + require.NoError(t, testTx.Initialize(txs.Codec)) + + type test struct { + name string + msgBytesFunc func() []byte + mempoolFunc func(*gomock.Controller) mempool.Mempool + partialSyncPrimaryNetwork bool + appSenderFunc func(*gomock.Controller) common.AppSender + } + + tests := []test{ + { + // Shouldn't attempt to issue or gossip the tx + name: "invalid message bytes", + msgBytesFunc: func() []byte { + return []byte{0x00} + }, + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + // Unused in this test + return nil + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Unused in this test + return nil + }, + }, + { + // Shouldn't attempt to issue or gossip the tx + name: "invalid tx bytes", + msgBytesFunc: func() []byte { + msg := message.Tx{ + Tx: []byte{0x00}, + } + msgBytes, err := message.Build(&msg) + require.NoError(t, err) + return msgBytes + }, + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + // Unused in this test + return mempool.NewMockMempool(ctrl) + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Unused in this test + return common.NewMockSender(ctrl) + }, + }, + { + // Issue returns nil because mempool has tx. We should gossip the tx. + name: "issuance succeeds", + msgBytesFunc: func() []byte { + msg := message.Tx{ + Tx: testTx.Bytes(), + } + msgBytes, err := message.Build(&msg) + require.NoError(t, err) + return msgBytes + }, + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Has(gomock.Any()).Return(true) + mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) + return mempool + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + appSender := common.NewMockSender(ctrl) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()) + return appSender + }, + }, + { + // Issue returns error because tx was dropped. We shouldn't gossip the tx. + name: "issuance fails", + msgBytesFunc: func() []byte { + msg := message.Tx{ + Tx: testTx.Bytes(), + } + msgBytes, err := message.Build(&msg) + require.NoError(t, err) + return msgBytes + }, + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().GetDropReason(gomock.Any()).Return(errTest) + return mempool + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Unused in this test + return common.NewMockSender(ctrl) + }, + }, + { + name: "should AppGossip if primary network is not being fully synced", + msgBytesFunc: func() []byte { + msg := message.Tx{ + Tx: testTx.Bytes(), + } + msgBytes, err := message.Build(&msg) + require.NoError(t, err) + return msgBytes + }, + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + // mempool.EXPECT().Has(gomock.Any()).Return(true) + return mempool + }, + partialSyncPrimaryNetwork: true, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + appSender := common.NewMockSender(ctrl) + // appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()) + return appSender + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + n := New( + &snow.Context{ + Log: logging.NoLog{}, + }, + executor.NewMockManager(ctrl), // Manager is unused in this test + tt.mempoolFunc(ctrl), + tt.partialSyncPrimaryNetwork, + tt.appSenderFunc(ctrl), + ) + require.NoError(n.AppGossip(context.Background(), ids.GenerateTestNodeID(), tt.msgBytesFunc())) + }) + } +} + +func TestNetworkIssueTx(t *testing.T) { + type test struct { + name string + mempoolFunc func(*gomock.Controller) mempool.Mempool + managerFunc func(*gomock.Controller) executor.Manager + partialSyncPrimaryNetwork bool + appSenderFunc func(*gomock.Controller) common.AppSender + expectedErr error + } + + tests := []test{ + { + name: "mempool has transaction", + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Has(gomock.Any()).Return(true) + return mempool + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + // Unused in this test + return executor.NewMockManager(ctrl) + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Should gossip the tx + appSender := common.NewMockSender(ctrl) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + return appSender + }, + expectedErr: nil, + }, + { + name: "transaction marked as dropped in mempool", + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) + return mempool + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + manager := executor.NewMockManager(ctrl) + manager.EXPECT().VerifyTx(gomock.Any()).Return(errTest) + return manager + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Shouldn't gossip the tx + return common.NewMockSender(ctrl) + }, + expectedErr: errTest, + }, + { + name: "transaction invalid", + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) + return mempool + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + manager := executor.NewMockManager(ctrl) + manager.EXPECT().VerifyTx(gomock.Any()).Return(errTest) + return manager + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Shouldn't gossip the tx + return common.NewMockSender(ctrl) + }, + expectedErr: errTest, + }, + { + name: "can't add transaction to mempool", + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Add(gomock.Any()).Return(errTest) + mempool.EXPECT().MarkDropped(gomock.Any(), errTest) + return mempool + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + manager := executor.NewMockManager(ctrl) + manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) + return manager + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Shouldn't gossip the tx + return common.NewMockSender(ctrl) + }, + expectedErr: errTest, + }, + { + name: "AppGossip tx but do not add to mempool if primary network is not being fully synced", + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Has(gomock.Any()).Return(false) + return mempool + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + manager := executor.NewMockManager(ctrl) + manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) + return manager + }, + partialSyncPrimaryNetwork: true, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Should gossip the tx + appSender := common.NewMockSender(ctrl) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + return appSender + }, + expectedErr: nil, + }, + { + name: "happy path", + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Add(gomock.Any()).Return(nil) + return mempool + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + manager := executor.NewMockManager(ctrl) + manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) + return manager + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // Should gossip the tx + appSender := common.NewMockSender(ctrl) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + return appSender + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + n := New( + &snow.Context{ + Log: logging.NoLog{}, + }, + tt.managerFunc(ctrl), + tt.mempoolFunc(ctrl), + tt.partialSyncPrimaryNetwork, + tt.appSenderFunc(ctrl), + ) + err := n.IssueTx(context.Background(), &txs.Tx{}) + require.ErrorIs(err, tt.expectedErr) + }) + } +} + +func TestNetworkGossipTx(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + appSender := common.NewMockSender(ctrl) + + nIntf := New( + &snow.Context{ + Log: logging.NoLog{}, + }, + executor.NewMockManager(ctrl), + mempool.NewMockMempool(ctrl), + false, + appSender, + ) + require.IsType(&network{}, nIntf) + n := nIntf.(*network) + + // Case: Tx was recently gossiped + txID := ids.GenerateTestID() + n.recentTxs.Put(txID, struct{}{}) + n.gossipTx(context.Background(), txID, []byte{}) + // Didn't make a call to SendAppGossip + + // Case: Tx was not recently gossiped + msgBytes := []byte{1, 2, 3} + appSender.EXPECT().SendAppGossip(gomock.Any(), msgBytes).Return(nil) + n.gossipTx(context.Background(), ids.GenerateTestID(), msgBytes) + // Did make a call to SendAppGossip +} diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 7a53250169cb..7f7568deb813 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -36,6 +36,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" + "github.com/ava-labs/avalanchego/vms/platformvm/network" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -61,7 +62,7 @@ var ( type VM struct { config.Config blockbuilder.Builder - blockbuilder.Network + network.Network validators.State metrics metrics.Metrics @@ -190,7 +191,7 @@ func (vm *VM) Initialize( txExecutorBackend, validatorManager, ) - vm.Network = blockbuilder.NewNetwork( + vm.Network = network.New( txExecutorBackend.Ctx, vm.manager, mempool, From 585424e6a4e4dc7eec52017a90b3026704ebc01e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 17 Nov 2023 00:39:46 -0500 Subject: [PATCH 050/267] Unexport avalanche constant from common package (#2327) --- snow/engine/avalanche/bootstrap/bootstrapper.go | 6 +++++- snow/engine/common/bootstrapper.go | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/snow/engine/avalanche/bootstrap/bootstrapper.go b/snow/engine/avalanche/bootstrap/bootstrapper.go index e58538b541ba..c6ef6513b668 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper.go @@ -29,6 +29,10 @@ const ( stripeDistance = 2000 stripeWidth = 5 cacheSize = 100000 + + // maxOutstandingGetAncestorsRequests is the maximum number of GetAncestors + // sent but not yet responded to/failed + maxOutstandingGetAncestorsRequests = 10 ) var _ common.BootstrapableEngine = (*bootstrapper)(nil) @@ -384,7 +388,7 @@ func (b *bootstrapper) GetVM() common.VM { // to fetch or we are at the maximum number of outstanding requests. func (b *bootstrapper) fetch(ctx context.Context, vtxIDs ...ids.ID) error { b.needToFetch.Add(vtxIDs...) - for b.needToFetch.Len() > 0 && b.OutstandingRequests.Len() < common.MaxOutstandingGetAncestorsRequests { + for b.needToFetch.Len() > 0 && b.OutstandingRequests.Len() < maxOutstandingGetAncestorsRequests { vtxID := b.needToFetch.CappedList(1)[0] b.needToFetch.Remove(vtxID) diff --git a/snow/engine/common/bootstrapper.go b/snow/engine/common/bootstrapper.go index 0455a46cc203..befb3628771b 100644 --- a/snow/engine/common/bootstrapper.go +++ b/snow/engine/common/bootstrapper.go @@ -19,10 +19,6 @@ const ( // logs StatusUpdateFrequency = 5000 - // MaxOutstandingGetAncestorsRequests is the maximum number of GetAncestors - // sent but not responded to/failed - MaxOutstandingGetAncestorsRequests = 10 - // MaxOutstandingBroadcastRequests is the maximum number of requests to have // outstanding when broadcasting. MaxOutstandingBroadcastRequests = 50 From fe72c5b91d09d8c73486e7ce71cfdd50a517449a Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 17 Nov 2023 01:23:21 -0500 Subject: [PATCH 051/267] Remove `common.Config` functions (#2328) --- snow/engine/common/config.go | 9 --------- snow/engine/snowman/bootstrap/bootstrapper.go | 6 +++++- snow/engine/snowman/syncer/state_syncer.go | 4 ++++ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/snow/engine/common/config.go b/snow/engine/common/config.go index 52d2287b37d6..f513c8f29655 100644 --- a/snow/engine/common/config.go +++ b/snow/engine/common/config.go @@ -36,15 +36,6 @@ type Config struct { SharedCfg *SharedConfig } -func (c *Config) Context() *snow.ConsensusContext { - return c.Ctx -} - -// IsBootstrapped returns true iff this chain is done bootstrapping -func (c *Config) IsBootstrapped() bool { - return c.Ctx.State.Get().State == snow.NormalOp -} - // Shared among common.bootstrapper and snowman/avalanche bootstrapper type SharedConfig struct { // Tracks the last requestID that was used in a request diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index 8212d5d8cf60..ad1d3d901bcd 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -111,6 +111,10 @@ func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) e return b, nil } +func (b *bootstrapper) Context() *snow.ConsensusContext { + return b.Ctx +} + func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { b.Ctx.Log.Info("starting bootstrapper") @@ -556,7 +560,7 @@ func (b *bootstrapper) checkFinish(ctx context.Context) error { return nil } - if b.IsBootstrapped() || b.awaitingTimeout { + if b.Ctx.State.Get().State == snow.NormalOp || b.awaitingTimeout { return nil } diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index 8909b96c7d39..c912bbd12093 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -108,6 +108,10 @@ func New( } } +func (ss *stateSyncer) Context() *snow.ConsensusContext { + return ss.Ctx +} + func (ss *stateSyncer) StateSummaryFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryBytes []byte) error { // ignores any late responses if requestID != ss.requestID { From 392b31318ea1d40721f9d26f065ff9b6f214680f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 17 Nov 2023 12:43:15 -0500 Subject: [PATCH 052/267] Move engine startup into helper function (#2329) --- snow/engine/snowman/bootstrap/bootstrapper.go | 71 +++++++------- snow/engine/snowman/syncer/state_syncer.go | 93 ++++++++++--------- 2 files changed, 83 insertions(+), 81 deletions(-) diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index ad1d3d901bcd..0f0a516539af 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -149,7 +149,42 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { b.startingHeight = lastAccepted.Height() b.Config.SharedCfg.RequestID = startReqID - if !b.StartupTracker.ShouldStart() { + return b.tryStartBootstrapping(ctx) +} + +func (b *bootstrapper) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { + if err := b.VM.Connected(ctx, nodeID, nodeVersion); err != nil { + return err + } + + if err := b.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { + return err + } + // Ensure fetchFrom reflects proper validator list + if _, ok := b.Beacons.GetValidator(b.Ctx.SubnetID, nodeID); ok { + b.fetchFrom.Add(nodeID) + } + + return b.tryStartBootstrapping(ctx) +} + +func (b *bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) error { + if err := b.VM.Disconnected(ctx, nodeID); err != nil { + return err + } + + if err := b.StartupTracker.Disconnected(ctx, nodeID); err != nil { + return err + } + + b.markUnavailable(nodeID) + return nil +} + +// tryStartBootstrapping will start bootstrapping the first time it is called +// while the startupTracker is reporting that the protocol should start. +func (b *bootstrapper) tryStartBootstrapping(ctx context.Context) error { + if b.started || !b.StartupTracker.ShouldStart() { return nil } @@ -246,40 +281,6 @@ func (b *bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID return b.fetch(ctx, blkID) } -func (b *bootstrapper) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { - if err := b.VM.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - - if err := b.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - // Ensure fetchFrom reflects proper validator list - if _, ok := b.Beacons.GetValidator(b.Ctx.SubnetID, nodeID); ok { - b.fetchFrom.Add(nodeID) - } - - if b.started || !b.StartupTracker.ShouldStart() { - return nil - } - - b.started = true - return b.Startup(ctx) -} - -func (b *bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) error { - if err := b.VM.Disconnected(ctx, nodeID); err != nil { - return err - } - - if err := b.StartupTracker.Disconnected(ctx, nodeID); err != nil { - return err - } - - b.markUnavailable(nodeID) - return nil -} - func (b *bootstrapper) Timeout(ctx context.Context) error { if !b.awaitingTimeout { return errUnexpectedTimeout diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index c912bbd12093..da377bdcc046 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -112,6 +112,53 @@ func (ss *stateSyncer) Context() *snow.ConsensusContext { return ss.Ctx } +func (ss *stateSyncer) Start(ctx context.Context, startReqID uint32) error { + ss.Ctx.Log.Info("starting state sync") + + ss.Ctx.State.Set(snow.EngineState{ + Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, + State: snow.StateSyncing, + }) + if err := ss.VM.SetState(ctx, snow.StateSyncing); err != nil { + return fmt.Errorf("failed to notify VM that state syncing has started: %w", err) + } + + ss.requestID = startReqID + + return ss.tryStartSyncing(ctx) +} + +func (ss *stateSyncer) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { + if err := ss.VM.Connected(ctx, nodeID, nodeVersion); err != nil { + return err + } + + if err := ss.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { + return err + } + + return ss.tryStartSyncing(ctx) +} + +func (ss *stateSyncer) Disconnected(ctx context.Context, nodeID ids.NodeID) error { + if err := ss.VM.Disconnected(ctx, nodeID); err != nil { + return err + } + + return ss.StartupTracker.Disconnected(ctx, nodeID) +} + +// tryStartSyncing will start syncing the first time it is called while the +// startupTracker is reporting that the protocol should start. +func (ss *stateSyncer) tryStartSyncing(ctx context.Context) error { + if ss.started || !ss.StartupTracker.ShouldStart() { + return nil + } + + ss.started = true + return ss.startup(ctx) +} + func (ss *stateSyncer) StateSummaryFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryBytes []byte) error { // ignores any late responses if requestID != ss.requestID { @@ -426,27 +473,6 @@ func (ss *stateSyncer) GetAcceptedStateSummaryFailed(ctx context.Context, nodeID return ss.AcceptedStateSummary(ctx, nodeID, requestID, nil) } -func (ss *stateSyncer) Start(ctx context.Context, startReqID uint32) error { - ss.Ctx.Log.Info("starting state sync") - - ss.Ctx.State.Set(snow.EngineState{ - Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, - State: snow.StateSyncing, - }) - if err := ss.VM.SetState(ctx, snow.StateSyncing); err != nil { - return fmt.Errorf("failed to notify VM that state syncing has started: %w", err) - } - - ss.requestID = startReqID - - if !ss.StartupTracker.ShouldStart() { - return nil - } - - ss.started = true - return ss.startup(ctx) -} - // startup do start the whole state sync process by // sampling frontier seeders, listing state syncers to request votes to // and reaching out frontier seeders if any. Otherwise, it moves immediately @@ -580,31 +606,6 @@ func (ss *stateSyncer) Notify(ctx context.Context, msg common.Message) error { return ss.onDoneStateSyncing(ctx, ss.requestID) } -func (ss *stateSyncer) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { - if err := ss.VM.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - - if err := ss.StartupTracker.Connected(ctx, nodeID, nodeVersion); err != nil { - return err - } - - if ss.started || !ss.StartupTracker.ShouldStart() { - return nil - } - - ss.started = true - return ss.startup(ctx) -} - -func (ss *stateSyncer) Disconnected(ctx context.Context, nodeID ids.NodeID) error { - if err := ss.VM.Disconnected(ctx, nodeID); err != nil { - return err - } - - return ss.StartupTracker.Disconnected(ctx, nodeID) -} - func (*stateSyncer) Gossip(context.Context) error { return nil } From 4768ed4b04b938a1384125db6769acf8de56ddd1 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 17 Nov 2023 12:50:07 -0500 Subject: [PATCH 053/267] Remove bootstrapping retry config (#2301) --- chains/manager.go | 58 ++++++++-------- config/config.go | 2 - config/flags.go | 2 - config/keys.go | 2 - node/config.go | 6 -- node/node.go | 2 - snow/engine/common/bootstrapper.go | 28 ++------ snow/engine/common/config.go | 6 -- snow/engine/snowman/bootstrap/bootstrapper.go | 20 +++++- .../snowman/bootstrap/bootstrapper_test.go | 48 ++++++++------ snow/engine/snowman/syncer/state_syncer.go | 29 ++------ .../snowman/syncer/state_syncer_test.go | 36 +++++----- vms/platformvm/vm_test.go | 66 ++++++++++++------- 13 files changed, 139 insertions(+), 166 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index 3d5792fad843..9121123e313f 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -174,34 +174,32 @@ type ManagerConfig struct { StakingBLSKey *bls.SecretKey TracingEnabled bool // Must not be used unless [TracingEnabled] is true as this may be nil. - Tracer trace.Tracer - Log logging.Logger - LogFactory logging.Factory - VMManager vms.Manager // Manage mappings from vm ID --> vm - BlockAcceptorGroup snow.AcceptorGroup - TxAcceptorGroup snow.AcceptorGroup - VertexAcceptorGroup snow.AcceptorGroup - DB database.Database - MsgCreator message.OutboundMsgBuilder // message creator, shared with network - Router router.Router // Routes incoming messages to the appropriate chain - Net network.Network // Sends consensus messages to other validators - Validators validators.Manager // Validators validating on this chain - NodeID ids.NodeID // The ID of this node - NetworkID uint32 // ID of the network this node is connected to - PartialSyncPrimaryNetwork bool - Server server.Server // Handles HTTP API calls - Keystore keystore.Keystore - AtomicMemory *atomic.Memory - AVAXAssetID ids.ID - XChainID ids.ID // ID of the X-Chain, - CChainID ids.ID // ID of the C-Chain, - CriticalChains set.Set[ids.ID] // Chains that can't exit gracefully - TimeoutManager timeout.Manager // Manages request timeouts when sending messages to other validators - Health health.Registerer - RetryBootstrap bool // Should Bootstrap be retried - RetryBootstrapWarnFrequency int // Max number of times to retry bootstrap before warning the node operator - SubnetConfigs map[ids.ID]subnets.Config // ID -> SubnetConfig - ChainConfigs map[string]ChainConfig // alias -> ChainConfig + Tracer trace.Tracer + Log logging.Logger + LogFactory logging.Factory + VMManager vms.Manager // Manage mappings from vm ID --> vm + BlockAcceptorGroup snow.AcceptorGroup + TxAcceptorGroup snow.AcceptorGroup + VertexAcceptorGroup snow.AcceptorGroup + DB database.Database + MsgCreator message.OutboundMsgBuilder // message creator, shared with network + Router router.Router // Routes incoming messages to the appropriate chain + Net network.Network // Sends consensus messages to other validators + Validators validators.Manager // Validators validating on this chain + NodeID ids.NodeID // The ID of this node + NetworkID uint32 // ID of the network this node is connected to + PartialSyncPrimaryNetwork bool + Server server.Server // Handles HTTP API calls + Keystore keystore.Keystore + AtomicMemory *atomic.Memory + AVAXAssetID ids.ID + XChainID ids.ID // ID of the X-Chain, + CChainID ids.ID // ID of the C-Chain, + CriticalChains set.Set[ids.ID] // Chains that can't exit gracefully + TimeoutManager timeout.Manager // Manages request timeouts when sending messages to other validators + Health health.Registerer + SubnetConfigs map[ids.ID]subnets.Config // ID -> SubnetConfig + ChainConfigs map[string]ChainConfig // alias -> ChainConfig // ShutdownNodeFunc allows the chain manager to issue a request to shutdown the node ShutdownNodeFunc func(exitCode int) MeterVMEnabled bool // Should each VM be wrapped with a MeterVM @@ -889,8 +887,6 @@ func (m *manager) createAvalancheChain( Sender: snowmanMessageSender, BootstrapTracker: sb, Timer: h, - RetryBootstrap: m.RetryBootstrap, - RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, SharedCfg: &common.SharedConfig{}, }, @@ -1235,8 +1231,6 @@ func (m *manager) createSnowmanChain( Sender: messageSender, BootstrapTracker: sb, Timer: h, - RetryBootstrap: m.RetryBootstrap, - RetryBootstrapWarnFrequency: m.RetryBootstrapWarnFrequency, AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, SharedCfg: &common.SharedConfig{}, } diff --git a/config/config.go b/config/config.go index 1b0eff0f96a4..db080ec2514a 100644 --- a/config/config.go +++ b/config/config.go @@ -521,8 +521,6 @@ func getStateSyncConfig(v *viper.Viper) (node.StateSyncConfig, error) { func getBootstrapConfig(v *viper.Viper, networkID uint32) (node.BootstrapConfig, error) { config := node.BootstrapConfig{ - RetryBootstrap: v.GetBool(RetryBootstrapKey), - RetryBootstrapWarnFrequency: v.GetInt(RetryBootstrapWarnFrequencyKey), BootstrapBeaconConnectionTimeout: v.GetDuration(BootstrapBeaconConnectionTimeoutKey), BootstrapMaxTimeGetAncestors: v.GetDuration(BootstrapMaxTimeGetAncestorsKey), BootstrapAncestorsMaxContainersSent: int(v.GetUint(BootstrapAncestorsMaxContainersSentKey)), diff --git a/config/flags.go b/config/flags.go index edece3ada4a3..20f42381320f 100644 --- a/config/flags.go +++ b/config/flags.go @@ -292,8 +292,6 @@ func addNodeFlags(fs *pflag.FlagSet) { // TODO: combine "BootstrapIPsKey" and "BootstrapIDsKey" into one flag fs.String(BootstrapIPsKey, "", "Comma separated list of bootstrap peer ips to connect to. Example: 127.0.0.1:9630,127.0.0.1:9631") fs.String(BootstrapIDsKey, "", "Comma separated list of bootstrap peer ids to connect to. Example: NodeID-JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,NodeID-8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z") - fs.Bool(RetryBootstrapKey, true, "Specifies whether bootstrap should be retried") - fs.Int(RetryBootstrapWarnFrequencyKey, 50, "Specifies how many times bootstrap should be retried before warning the operator") fs.Duration(BootstrapBeaconConnectionTimeoutKey, time.Minute, "Timeout before emitting a warn log when connecting to bootstrapping beacons") fs.Duration(BootstrapMaxTimeGetAncestorsKey, 50*time.Millisecond, "Max Time to spend fetching a container and its ancestors when responding to a GetAncestors") fs.Uint(BootstrapAncestorsMaxContainersSentKey, 2000, "Max number of containers in an Ancestors message sent by this node") diff --git a/config/keys.go b/config/keys.go index 7263cf0a6bdd..1fe19cd2424a 100644 --- a/config/keys.go +++ b/config/keys.go @@ -163,8 +163,6 @@ const ( RouterHealthMaxOutstandingRequestsKey = "router-health-max-outstanding-requests" HealthCheckFreqKey = "health-check-frequency" HealthCheckAveragerHalflifeKey = "health-check-averager-halflife" - RetryBootstrapKey = "bootstrap-retry-enabled" - RetryBootstrapWarnFrequencyKey = "bootstrap-retry-warn-frequency" PluginDirKey = "plugin-dir" BootstrapBeaconConnectionTimeoutKey = "bootstrap-beacon-connection-timeout" BootstrapMaxTimeGetAncestorsKey = "bootstrap-max-time-get-ancestors" diff --git a/node/config.go b/node/config.go index 736bf08b74dc..87783bd9935b 100644 --- a/node/config.go +++ b/node/config.go @@ -107,12 +107,6 @@ type StateSyncConfig struct { } type BootstrapConfig struct { - // Should Bootstrap be retried - RetryBootstrap bool `json:"retryBootstrap"` - - // Max number of times to retry bootstrap before warning the node operator - RetryBootstrapWarnFrequency int `json:"retryBootstrapWarnFrequency"` - // Timeout before emitting a warn log when connecting to bootstrapping beacons BootstrapBeaconConnectionTimeout time.Duration `json:"bootstrapBeaconConnectionTimeout"` diff --git a/node/node.go b/node/node.go index ba876d09b2d4..06544e8f9e6b 100644 --- a/node/node.go +++ b/node/node.go @@ -1009,8 +1009,6 @@ func (n *Node) initChainManager(avaxAssetID ids.ID) error { CriticalChains: criticalChains, TimeoutManager: n.timeoutManager, Health: n.health, - RetryBootstrap: n.Config.RetryBootstrap, - RetryBootstrapWarnFrequency: n.Config.RetryBootstrapWarnFrequency, ShutdownNodeFunc: n.Shutdown, MeterVMEnabled: n.Config.MeterVMEnabled, Metrics: n.MetricsGatherer, diff --git a/snow/engine/common/bootstrapper.go b/snow/engine/common/bootstrapper.go index befb3628771b..d4c8f041a8d2 100644 --- a/snow/engine/common/bootstrapper.go +++ b/snow/engine/common/bootstrapper.go @@ -31,7 +31,7 @@ type Bootstrapper interface { AcceptedHandler Haltable Startup(context.Context) error - Restart(ctx context.Context, reset bool) error + Restart(ctx context.Context) error } // It collects mechanisms common to both snowman and avalanche bootstrappers @@ -41,9 +41,6 @@ type bootstrapper struct { minority smbootstrapper.Poll majority smbootstrapper.Poll - - // number of times the bootstrap has been attempted - bootstrapAttempts int } func NewCommonBootstrapper(config Config) Bootstrapper { @@ -146,7 +143,6 @@ func (b *bootstrapper) Startup(ctx context.Context) error { MaxOutstandingBroadcastRequests, ) - b.bootstrapAttempts++ if accepted, finalized := b.majority.Result(ctx); finalized { b.Ctx.Log.Info("bootstrapping skipped", zap.String("reason", "no provided bootstraps"), @@ -158,22 +154,9 @@ func (b *bootstrapper) Startup(ctx context.Context) error { return b.sendMessagesOrFinish(ctx) } -func (b *bootstrapper) Restart(ctx context.Context, reset bool) error { - // resets the attempts when we're pulling blocks/vertices we don't want to - // fail the bootstrap at that stage - if reset { - b.Ctx.Log.Debug("Checking for new frontiers") - - b.Config.SharedCfg.Restarted = true - b.bootstrapAttempts = 0 - } - - if b.bootstrapAttempts > 0 && b.bootstrapAttempts%b.RetryBootstrapWarnFrequency == 0 { - b.Ctx.Log.Debug("check internet connection", - zap.Int("numBootstrapAttempts", b.bootstrapAttempts), - ) - } - +func (b *bootstrapper) Restart(ctx context.Context) error { + b.Ctx.Log.Debug("Checking for new frontiers") + b.Config.SharedCfg.Restarted = true return b.Startup(ctx) } @@ -207,9 +190,8 @@ func (b *bootstrapper) sendMessagesOrFinish(ctx context.Context) error { b.Ctx.Log.Debug("restarting bootstrap", zap.String("reason", "no blocks accepted"), zap.Int("numBeacons", b.Beacons.Count(b.Ctx.SubnetID)), - zap.Int("numBootstrapAttempts", b.bootstrapAttempts), ) - return b.Restart(ctx, false /*=reset*/) + return b.Startup(ctx) } if !b.Config.SharedCfg.Restarted { diff --git a/snow/engine/common/config.go b/snow/engine/common/config.go index f513c8f29655..5ac9052f0593 100644 --- a/snow/engine/common/config.go +++ b/snow/engine/common/config.go @@ -23,12 +23,6 @@ type Config struct { BootstrapTracker BootstrapTracker Timer Timer - // Should Bootstrap be retried - RetryBootstrap bool - - // Max number of times to retry bootstrap before warning the node operator - RetryBootstrapWarnFrequency int - // This node will only consider the first [AncestorsMaxContainersReceived] // containers in an ancestors message it receives. AncestorsMaxContainersReceived int diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index 0f0a516539af..c0644fc5170a 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -34,6 +34,20 @@ var ( errUnexpectedTimeout = errors.New("unexpected timeout fired") ) +// bootstrapper repeatedly performs the bootstrapping protocol. +// +// 1. Wait until a sufficient amount of stake is connected. +// 2. Sample a small number of nodes to get the last accepted block ID +// 3. Verify against the full network that the last accepted block ID received +// in step 2 is an accepted block. +// 4. Sync the full ancestry of the last accepted block. +// 5. Execute all the fetched blocks that haven't already been executed. +// 6. Restart the bootstrapping protocol until the number of blocks being +// accepted during a bootstrapping round stops decreasing. +// +// Note: Because of step 6, the bootstrapping protocol will generally be +// performed multiple times. +// // Invariant: The VM is not guaranteed to be initialized until Start has been // called, so it must be guaranteed the VM is not used until after Start. type bootstrapper struct { @@ -288,7 +302,7 @@ func (b *bootstrapper) Timeout(ctx context.Context) error { b.awaitingTimeout = false if !b.Config.BootstrapTracker.IsBootstrapped() { - return b.Restart(ctx, true) + return b.Restart(ctx) } b.fetchETA.Set(0) return b.OnFinished(ctx, b.Config.SharedCfg.RequestID) @@ -592,8 +606,8 @@ func (b *bootstrapper) checkFinish(ctx context.Context) error { // Note that executedBlocks < c*previouslyExecuted ( 0 <= c < 1 ) is enforced // so that the bootstrapping process will terminate even as new blocks are // being issued. - if b.Config.RetryBootstrap && executedBlocks > 0 && executedBlocks < previouslyExecuted/2 { - return b.Restart(ctx, true) + if executedBlocks > 0 && executedBlocks < previouslyExecuted/2 { + return b.Restart(ctx) } // If there is an additional callback, notify them that this chain has been diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index 9dc53342c844..8bafa18fe5e1 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -356,8 +356,6 @@ func TestBootstrapperUnknownByzantineResponse(t *testing.T) { require.NoError(bs.Start(context.Background(), 0)) - acceptedIDs := []ids.ID{blkID2} - parsedBlk1 := false vm.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { @@ -390,31 +388,29 @@ func TestBootstrapperUnknownByzantineResponse(t *testing.T) { return nil, errUnknownBlock } - requestID := new(uint32) + var requestID uint32 sender.SendGetAncestorsF = func(_ context.Context, vdr ids.NodeID, reqID uint32, blkID ids.ID) { require.Equal(peerID, vdr) require.Equal(blkID1, blkID) - *requestID = reqID + requestID = reqID } vm.CantSetState = false - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) // should request blk1 - - oldReqID := *requestID - require.NoError(bs.Ancestors(context.Background(), peerID, *requestID+1, [][]byte{blkBytes1})) // respond with wrong request ID - require.Equal(oldReqID, *requestID) + require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID2})) // should request blk1 - require.NoError(bs.Ancestors(context.Background(), ids.BuildTestNodeID([]byte{1, 2, 3}), *requestID, [][]byte{blkBytes1})) // respond from wrong peer - require.Equal(oldReqID, *requestID) + oldReqID := requestID + require.NoError(bs.Ancestors(context.Background(), peerID, requestID, [][]byte{blkBytes0})) // respond with wrong block + require.NotEqual(oldReqID, requestID) - require.NoError(bs.Ancestors(context.Background(), peerID, *requestID, [][]byte{blkBytes0})) // respond with wrong block - require.NotEqual(oldReqID, *requestID) + require.NoError(bs.Ancestors(context.Background(), peerID, requestID, [][]byte{blkBytes1})) - require.NoError(bs.Ancestors(context.Background(), peerID, *requestID, [][]byte{blkBytes1})) - require.Equal(snow.NormalOp, config.Ctx.State.Get().State) + require.Equal(snow.Bootstrapping, config.Ctx.State.Get().State) require.Equal(choices.Accepted, blk0.Status()) require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) + + require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID2})) + require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } // There are multiple needed blocks and Ancestors returns one at a time @@ -554,10 +550,13 @@ func TestBootstrapperPartialFetch(t *testing.T) { require.NoError(bs.Ancestors(context.Background(), peerID, *requestID, [][]byte{blkBytes1})) // respond with blk1 require.Equal(blkID1, requested) - require.Equal(snow.NormalOp, config.Ctx.State.Get().State) + require.Equal(snow.Bootstrapping, config.Ctx.State.Get().State) require.Equal(choices.Accepted, blk0.Status()) require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) + + require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) + require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } // There are multiple needed blocks and some validators do not have all the blocks @@ -714,7 +713,7 @@ func TestBootstrapperEmptyResponse(t *testing.T) { require.NoError(bs.Ancestors(context.Background(), requestedVdr, requestID, [][]byte{blkBytes1})) // respond with blk1 - require.Equal(snow.NormalOp, config.Ctx.State.Get().State) + require.Equal(snow.Bootstrapping, config.Ctx.State.Get().State) require.Equal(choices.Accepted, blk0.Status()) require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) @@ -856,10 +855,13 @@ func TestBootstrapperAncestors(t *testing.T) { require.NoError(bs.Ancestors(context.Background(), peerID, *requestID, [][]byte{blkBytes2, blkBytes1})) // respond with blk2 and blk1 require.Equal(blkID2, requested) - require.Equal(snow.NormalOp, config.Ctx.State.Get().State) + require.Equal(snow.Bootstrapping, config.Ctx.State.Get().State) require.Equal(choices.Accepted, blk0.Status()) require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) + + require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) + require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } func TestBootstrapperFinalized(t *testing.T) { @@ -976,10 +978,13 @@ func TestBootstrapperFinalized(t *testing.T) { require.NoError(bs.Ancestors(context.Background(), peerID, reqIDBlk2, [][]byte{blkBytes2, blkBytes1})) - require.Equal(snow.NormalOp, config.Ctx.State.Get().State) + require.Equal(snow.Bootstrapping, config.Ctx.State.Get().State) require.Equal(choices.Accepted, blk0.Status()) require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) + + require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID2})) + require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } func TestRestartBootstrapping(t *testing.T) { @@ -1156,12 +1161,15 @@ func TestRestartBootstrapping(t *testing.T) { require.NoError(bs.Ancestors(context.Background(), peerID, blk4RequestID, [][]byte{blkBytes4})) - require.Equal(snow.NormalOp, config.Ctx.State.Get().State) + require.Equal(snow.Bootstrapping, config.Ctx.State.Get().State) require.Equal(choices.Accepted, blk0.Status()) require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) require.Equal(choices.Accepted, blk3.Status()) require.Equal(choices.Accepted, blk4.Status()) + + require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID4})) + require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } func TestBootstrapOldBlockAfterStateSync(t *testing.T) { diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index da377bdcc046..89c839a25dcd 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -84,9 +84,6 @@ type stateSyncer struct { // we keep a list of deduplicated height ready for voting summariesHeights set.Set[uint64] uniqueSummariesHeights []uint64 - - // number of times the state sync has been attempted - attempts int } func New( @@ -258,15 +255,11 @@ func (ss *stateSyncer) receivedStateSummaryFrontier(ctx context.Context) error { frontierStake := frontiersTotalWeight - failedBeaconWeight if float64(frontierStake) < frontierAlpha { - ss.Ctx.Log.Debug("didn't receive enough frontiers", + ss.Ctx.Log.Debug("restarting state sync", + zap.String("reason", "didn't receive enough frontiers"), zap.Int("numFailedValidators", ss.failedSeeders.Len()), - zap.Int("numStateSyncAttempts", ss.attempts), ) - - if ss.Config.RetryBootstrap { - ss.Ctx.Log.Debug("restarting state sync") - return ss.restart(ctx) - } + return ss.startup(ctx) } ss.requestID++ @@ -377,14 +370,13 @@ func (ss *stateSyncer) AcceptedStateSummary(ctx context.Context, nodeID ids.Node return fmt.Errorf("failed to get total weight of state sync beacons for subnet %s: %w", ss.Ctx.SubnetID, err) } votingStakes := beaconsTotalWeight - failedVotersWeight - if ss.Config.RetryBootstrap && votingStakes < ss.Alpha { + if votingStakes < ss.Alpha { ss.Ctx.Log.Debug("restarting state sync", zap.String("reason", "not enough votes received"), zap.Int("numBeacons", ss.StateSyncBeacons.Count(ss.Ctx.SubnetID)), zap.Int("numFailedSyncers", ss.failedVoters.Len()), - zap.Int("numAttempts", ss.attempts), ) - return ss.restart(ctx) + return ss.startup(ctx) } ss.Ctx.Log.Info("skipping state sync", @@ -537,7 +529,6 @@ func (ss *stateSyncer) startup(ctx context.Context) error { } // initiate messages exchange - ss.attempts++ if ss.targetSeeders.Len() == 0 { ss.Ctx.Log.Info("State syncing skipped due to no provided syncers") return ss.onDoneStateSyncing(ctx, ss.requestID) @@ -548,16 +539,6 @@ func (ss *stateSyncer) startup(ctx context.Context) error { return nil } -func (ss *stateSyncer) restart(ctx context.Context) error { - if ss.attempts > 0 && ss.attempts%ss.RetryBootstrapWarnFrequency == 0 { - ss.Ctx.Log.Debug("check internet connection", - zap.Int("numSyncAttempts", ss.attempts), - ) - } - - return ss.startup(ctx) -} - // Ask up to [common.MaxOutstandingBroadcastRequests] state sync validators at a time // to send their accepted state summary. It is called again until there are // no more seeders to be reached in the pending set diff --git a/snow/engine/snowman/syncer/state_syncer_test.go b/snow/engine/snowman/syncer/state_syncer_test.go index d3f26b129907..84a1ce01a0a2 100644 --- a/snow/engine/snowman/syncer/state_syncer_test.go +++ b/snow/engine/snowman/syncer/state_syncer_test.go @@ -558,13 +558,11 @@ func TestStateSyncIsRestartedIfTooManyFrontierSeedersTimeout(t *testing.T) { vdrs.RegisterCallbackListener(ctx.SubnetID, startup) commonCfg := common.Config{ - Ctx: snow.DefaultConsensusContextTest(), - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - RetryBootstrap: true, - RetryBootstrapWarnFrequency: 1, + Ctx: snow.DefaultConsensusContextTest(), + Beacons: vdrs, + SampleK: vdrs.Count(ctx.SubnetID), + Alpha: (totalWeight + 1) / 2, + StartupTracker: startup, } syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) @@ -1114,13 +1112,11 @@ func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { vdrs.RegisterCallbackListener(ctx.SubnetID, startup) commonCfg := common.Config{ - Ctx: snow.DefaultConsensusContextTest(), - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - RetryBootstrap: true, // this sets RetryStateSyncing too - RetryBootstrapWarnFrequency: 1, // this sets RetrySyncingWarnFrequency too + Ctx: snow.DefaultConsensusContextTest(), + Beacons: vdrs, + SampleK: vdrs.Count(ctx.SubnetID), + Alpha: (totalWeight + 1) / 2, + StartupTracker: startup, } syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) @@ -1378,13 +1374,11 @@ func TestStateSyncIsDoneOnceVMNotifies(t *testing.T) { vdrs.RegisterCallbackListener(ctx.SubnetID, startup) commonCfg := common.Config{ - Ctx: snow.DefaultConsensusContextTest(), - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - RetryBootstrap: true, // this sets RetryStateSyncing too - RetryBootstrapWarnFrequency: 1, // this sets RetrySyncingWarnFrequency too + Ctx: snow.DefaultConsensusContextTest(), + Beacons: vdrs, + SampleK: vdrs.Count(ctx.SubnetID), + Alpha: (totalWeight + 1) / 2, + StartupTracker: startup, } syncer, fullVM, _ := buildTestsObjects(t, &commonCfg) _ = fullVM diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index c8f849ecea1a..454aff29fe6d 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1198,10 +1198,7 @@ func TestRestartFullyAccepted(t *testing.T) { baseDB := memdb.New() atomicDB := prefixdb.New([]byte{1}, baseDB) m := atomic.NewMemory(atomicDB) - msm := &mutableSharedMemory{ - SharedMemory: m.NewSharedMemory(firstCtx.ChainID), - } - firstCtx.SharedMemory = msm + firstCtx.SharedMemory = m.NewSharedMemory(firstCtx.ChainID) initialClkTime := banffForkTime.Add(time.Second) firstVM.clock.Set(initialClkTime) @@ -1280,7 +1277,7 @@ func TestRestartFullyAccepted(t *testing.T) { }} secondCtx := defaultContext(t) - secondCtx.SharedMemory = msm + secondCtx.SharedMemory = firstCtx.SharedMemory secondVM.clock.Set(initialClkTime) secondCtx.Lock.Lock() defer func() { @@ -1335,10 +1332,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { atomicDB := prefixdb.New([]byte{1}, baseDB) m := atomic.NewMemory(atomicDB) - msm := &mutableSharedMemory{ - SharedMemory: m.NewSharedMemory(ctx.ChainID), - } - ctx.SharedMemory = msm + ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) consensusCtx := snow.DefaultConsensusContextTest() consensusCtx.Context = ctx @@ -1461,19 +1455,6 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { ) require.NoError(err) - var reqID uint32 - externalSender.SendF = func(msg message.OutboundMessage, nodeIDs set.Set[ids.NodeID], _ ids.ID, _ subnets.Allower) set.Set[ids.NodeID] { - inMsg, err := mc.Parse(msg.Bytes(), ctx.NodeID, func() {}) - require.NoError(err) - require.Equal(message.GetAcceptedFrontierOp, inMsg.Op()) - - requestID, ok := message.GetRequestID(inMsg.Message()) - require.True(ok) - - reqID = requestID - return nodeIDs - } - isBootstrapped := false bootstrapTracker := &common.BootstrapTrackerTest{ T: t, @@ -1596,6 +1577,19 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { h.Start(context.Background(), false) ctx.Lock.Lock() + var reqID uint32 + externalSender.SendF = func(msg message.OutboundMessage, nodeIDs set.Set[ids.NodeID], _ ids.ID, _ subnets.Allower) set.Set[ids.NodeID] { + inMsg, err := mc.Parse(msg.Bytes(), ctx.NodeID, func() {}) + require.NoError(err) + require.Equal(message.GetAcceptedFrontierOp, inMsg.Op()) + + requestID, ok := message.GetRequestID(inMsg.Message()) + require.True(ok) + + reqID = requestID + return nodeIDs + } + require.NoError(bootstrapper.Connected(context.Background(), peerID, version.CurrentApp)) externalSender.SendF = func(msg message.OutboundMessage, nodeIDs set.Set[ids.NodeID], _ ids.ID, _ subnets.Allower) set.Set[ids.NodeID] { @@ -1627,10 +1621,36 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { frontier := set.Of(advanceTimeBlkID) require.NoError(bootstrapper.Accepted(context.Background(), peerID, reqID, frontier)) + externalSender.SendF = func(msg message.OutboundMessage, nodeIDs set.Set[ids.NodeID], _ ids.ID, _ subnets.Allower) set.Set[ids.NodeID] { + inMsg, err := mc.Parse(msg.Bytes(), ctx.NodeID, func() {}) + require.NoError(err) + require.Equal(message.GetAcceptedFrontierOp, inMsg.Op()) + + requestID, ok := message.GetRequestID(inMsg.Message()) + require.True(ok) + + reqID = requestID + return nodeIDs + } + + require.NoError(bootstrapper.Ancestors(context.Background(), peerID, reqID, [][]byte{advanceTimeBlkBytes})) + + externalSender.SendF = func(msg message.OutboundMessage, nodeIDs set.Set[ids.NodeID], _ ids.ID, _ subnets.Allower) set.Set[ids.NodeID] { + inMsgIntf, err := mc.Parse(msg.Bytes(), ctx.NodeID, func() {}) + require.NoError(err) + require.Equal(message.GetAcceptedOp, inMsgIntf.Op()) + inMsg := inMsgIntf.Message().(*p2p.GetAccepted) + + reqID = inMsg.RequestId + return nodeIDs + } + + require.NoError(bootstrapper.AcceptedFrontier(context.Background(), peerID, reqID, advanceTimeBlkID)) + externalSender.SendF = nil externalSender.CantSend = false - require.NoError(bootstrapper.Ancestors(context.Background(), peerID, reqID, [][]byte{advanceTimeBlkBytes})) + require.NoError(bootstrapper.Accepted(context.Background(), peerID, reqID, frontier)) require.Equal(advanceTimeBlk.ID(), vm.manager.Preferred()) ctx.Lock.Unlock() From dbc209cacb9028741e80ab060403533fb9217905 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 17 Nov 2023 14:48:54 -0500 Subject: [PATCH 054/267] Export snowman bootstrapper (#2331) --- chains/manager.go | 6 ++- snow/engine/snowman/bootstrap/bootstrapper.go | 46 +++++++++---------- .../snowman/bootstrap/bootstrapper_test.go | 18 +++----- 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index 9121123e313f..aeb4e7bb2135 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -894,7 +894,8 @@ func (m *manager) createAvalancheChain( Blocked: blockBlocker, VM: vmWrappingProposerVM, } - snowmanBootstrapper, err := smbootstrap.New( + var snowmanBootstrapper common.BootstrapableEngine + snowmanBootstrapper, err = smbootstrap.New( bootstrapCfg, snowmanEngine.Start, ) @@ -1243,7 +1244,8 @@ func (m *manager) createSnowmanChain( VM: vm, Bootstrapped: bootstrapFunc, } - bootstrapper, err := smbootstrap.New( + var bootstrapper common.BootstrapableEngine + bootstrapper, err = smbootstrap.New( bootstrapCfg, engine.Start, ) diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index c0644fc5170a..224cded68311 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -29,7 +29,7 @@ import ( const bootstrappingDelay = 10 * time.Second var ( - _ common.BootstrapableEngine = (*bootstrapper)(nil) + _ common.BootstrapableEngine = (*Bootstrapper)(nil) errUnexpectedTimeout = errors.New("unexpected timeout fired") ) @@ -50,7 +50,7 @@ var ( // // Invariant: The VM is not guaranteed to be initialized until Start has been // called, so it must be guaranteed the VM is not used until after Start. -type bootstrapper struct { +type Bootstrapper struct { Config // list of NoOpsHandler for messages dropped by bootstrapper @@ -97,13 +97,13 @@ type bootstrapper struct { bootstrappedOnce sync.Once } -func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) error) (common.BootstrapableEngine, error) { +func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) error) (*Bootstrapper, error) { metrics, err := newMetrics("bs", config.Ctx.Registerer) if err != nil { return nil, err } - b := &bootstrapper{ + b := &Bootstrapper{ Config: config, metrics: metrics, StateSummaryFrontierHandler: common.NewNoOpStateSummaryFrontierHandler(config.Ctx.Log), @@ -125,11 +125,11 @@ func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) e return b, nil } -func (b *bootstrapper) Context() *snow.ConsensusContext { +func (b *Bootstrapper) Context() *snow.ConsensusContext { return b.Ctx } -func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { +func (b *Bootstrapper) Start(ctx context.Context, startReqID uint32) error { b.Ctx.Log.Info("starting bootstrapper") b.Ctx.State.Set(snow.EngineState{ @@ -166,7 +166,7 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { return b.tryStartBootstrapping(ctx) } -func (b *bootstrapper) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { +func (b *Bootstrapper) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { if err := b.VM.Connected(ctx, nodeID, nodeVersion); err != nil { return err } @@ -182,7 +182,7 @@ func (b *bootstrapper) Connected(ctx context.Context, nodeID ids.NodeID, nodeVer return b.tryStartBootstrapping(ctx) } -func (b *bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) error { +func (b *Bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) error { if err := b.VM.Disconnected(ctx, nodeID); err != nil { return err } @@ -197,7 +197,7 @@ func (b *bootstrapper) Disconnected(ctx context.Context, nodeID ids.NodeID) erro // tryStartBootstrapping will start bootstrapping the first time it is called // while the startupTracker is reporting that the protocol should start. -func (b *bootstrapper) tryStartBootstrapping(ctx context.Context) error { +func (b *Bootstrapper) tryStartBootstrapping(ctx context.Context) error { if b.started || !b.StartupTracker.ShouldStart() { return nil } @@ -208,7 +208,7 @@ func (b *bootstrapper) tryStartBootstrapping(ctx context.Context) error { // Ancestors handles the receipt of multiple containers. Should be received in // response to a GetAncestors message to [nodeID] with request ID [requestID] -func (b *bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, blks [][]byte) error { +func (b *Bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, blks [][]byte) error { // Make sure this is in response to a request we made wantedBlkID, ok := b.OutstandingRequests.Remove(nodeID, requestID) if !ok { // this message isn't in response to a request we made @@ -278,7 +278,7 @@ func (b *bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, request return b.process(ctx, requestedBlock, blockSet) } -func (b *bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { +func (b *Bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { blkID, ok := b.OutstandingRequests.Remove(nodeID, requestID) if !ok { b.Ctx.Log.Debug("unexpectedly called GetAncestorsFailed", @@ -295,7 +295,7 @@ func (b *bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID return b.fetch(ctx, blkID) } -func (b *bootstrapper) Timeout(ctx context.Context) error { +func (b *Bootstrapper) Timeout(ctx context.Context) error { if !b.awaitingTimeout { return errUnexpectedTimeout } @@ -308,11 +308,11 @@ func (b *bootstrapper) Timeout(ctx context.Context) error { return b.OnFinished(ctx, b.Config.SharedCfg.RequestID) } -func (*bootstrapper) Gossip(context.Context) error { +func (*Bootstrapper) Gossip(context.Context) error { return nil } -func (b *bootstrapper) Shutdown(ctx context.Context) error { +func (b *Bootstrapper) Shutdown(ctx context.Context) error { b.Ctx.Log.Info("shutting down bootstrapper") b.Ctx.Lock.Lock() @@ -321,7 +321,7 @@ func (b *bootstrapper) Shutdown(ctx context.Context) error { return b.VM.Shutdown(ctx) } -func (b *bootstrapper) Notify(_ context.Context, msg common.Message) error { +func (b *Bootstrapper) Notify(_ context.Context, msg common.Message) error { if msg != common.StateSyncDone { b.Ctx.Log.Warn("received an unexpected message from the VM", zap.Stringer("msg", msg), @@ -333,7 +333,7 @@ func (b *bootstrapper) Notify(_ context.Context, msg common.Message) error { return nil } -func (b *bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { +func (b *Bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { b.Ctx.Lock.Lock() defer b.Ctx.Lock.Unlock() @@ -345,11 +345,11 @@ func (b *bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { return intf, vmErr } -func (b *bootstrapper) GetVM() common.VM { +func (b *Bootstrapper) GetVM() common.VM { return b.VM } -func (b *bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs []ids.ID) error { +func (b *Bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs []ids.ID) error { pendingContainerIDs := b.Blocked.MissingIDs() // Initialize the fetch from set to the currently preferred peers @@ -392,7 +392,7 @@ func (b *bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs [ } // Get block [blkID] and its ancestors from a validator -func (b *bootstrapper) fetch(ctx context.Context, blkID ids.ID) error { +func (b *Bootstrapper) fetch(ctx context.Context, blkID ids.ID) error { // Make sure we haven't already requested this block if b.OutstandingRequests.Contains(blkID) { return nil @@ -421,7 +421,7 @@ func (b *bootstrapper) fetch(ctx context.Context, blkID ids.ID) error { // markUnavailable removes [nodeID] from the set of peers used to fetch // ancestors. If the set becomes empty, it is reset to the currently preferred // peers so bootstrapping can continue. -func (b *bootstrapper) markUnavailable(nodeID ids.NodeID) { +func (b *Bootstrapper) markUnavailable(nodeID ids.NodeID) { b.fetchFrom.Remove(nodeID) // if [fetchFrom] has become empty, reset it to the currently preferred @@ -431,7 +431,7 @@ func (b *bootstrapper) markUnavailable(nodeID ids.NodeID) { } } -func (b *bootstrapper) Clear(context.Context) error { +func (b *Bootstrapper) Clear(context.Context) error { b.Ctx.Lock.Lock() defer b.Ctx.Lock.Unlock() @@ -451,7 +451,7 @@ func (b *bootstrapper) Clear(context.Context) error { // // If [blk]'s height is <= the last accepted height, then it will be removed // from the missingIDs set. -func (b *bootstrapper) process(ctx context.Context, blk snowman.Block, processingBlocks map[ids.ID]snowman.Block) error { +func (b *Bootstrapper) process(ctx context.Context, blk snowman.Block, processingBlocks map[ids.ID]snowman.Block) error { for { blkID := blk.ID() if b.Halted() { @@ -570,7 +570,7 @@ func (b *bootstrapper) process(ctx context.Context, blk snowman.Block, processin // checkFinish repeatedly executes pending transactions and requests new frontier vertices until there aren't any new ones // after which it finishes the bootstrap process -func (b *bootstrapper) checkFinish(ctx context.Context) error { +func (b *Bootstrapper) checkFinish(ctx context.Context) error { if numPending := b.Blocked.NumMissingIDs(); numPending != 0 { return nil } diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index 8bafa18fe5e1..c883de181323 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -696,10 +696,10 @@ func TestBootstrapperEmptyResponse(t *testing.T) { // add another two validators to the fetch set to test behavior on empty response newPeerID := ids.GenerateTestNodeID() - bs.(*bootstrapper).fetchFrom.Add(newPeerID) + bs.fetchFrom.Add(newPeerID) newPeerID = ids.GenerateTestNodeID() - bs.(*bootstrapper).fetchFrom.Add(newPeerID) + bs.fetchFrom.Add(newPeerID) require.NoError(bs.Ancestors(context.Background(), peerID, requestID, [][]byte{blkBytes2})) require.Equal(blkID1, requestedBlock) @@ -719,7 +719,7 @@ func TestBootstrapperEmptyResponse(t *testing.T) { require.Equal(choices.Accepted, blk2.Status()) // check peerToBlacklist was removed from the fetch set - require.NotContains(bs.(*bootstrapper).fetchFrom, peerToBlacklist) + require.NotContains(bs.fetchFrom, peerToBlacklist) } // There are multiple needed blocks and Ancestors returns all at once @@ -1111,7 +1111,7 @@ func TestRestartBootstrapping(t *testing.T) { return nil, errUnknownBlock } - bsIntf, err := New( + bs, err := New( config, func(context.Context, uint32) error { config.Ctx.State.Set(snow.EngineState{ @@ -1122,8 +1122,6 @@ func TestRestartBootstrapping(t *testing.T) { }, ) require.NoError(err) - require.IsType(&bootstrapper{}, bsIntf) - bs := bsIntf.(*bootstrapper) vm.CantSetState = false require.NoError(bs.Start(context.Background(), 0)) @@ -1220,7 +1218,7 @@ func TestBootstrapOldBlockAfterStateSync(t *testing.T) { return nil, errUnknownBlock } - bsIntf, err := New( + bs, err := New( config, func(context.Context, uint32) error { config.Ctx.State.Set(snow.EngineState{ @@ -1231,8 +1229,6 @@ func TestBootstrapOldBlockAfterStateSync(t *testing.T) { }, ) require.NoError(err) - require.IsType(&bootstrapper{}, bsIntf) - bs := bsIntf.(*bootstrapper) vm.CantSetState = false require.NoError(bs.Start(context.Background(), 0)) @@ -1291,7 +1287,7 @@ func TestBootstrapContinueAfterHalt(t *testing.T) { return blk0.ID(), nil } - bsIntf, err := New( + bs, err := New( config, func(context.Context, uint32) error { config.Ctx.State.Set(snow.EngineState{ @@ -1302,8 +1298,6 @@ func TestBootstrapContinueAfterHalt(t *testing.T) { }, ) require.NoError(err) - require.IsType(&bootstrapper{}, bsIntf) - bs := bsIntf.(*bootstrapper) vm.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { From a803f38d471b097cdcc79ba08b8d32fbca8741fc Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 17 Nov 2023 15:14:36 -0500 Subject: [PATCH 055/267] Remove common.Config from syncer.Config (#2330) --- chains/manager.go | 36 ++- snow/engine/snowman/syncer/config.go | 47 +-- .../snowman/syncer/state_syncer_test.go | 306 ++++++------------ snow/engine/snowman/syncer/utils_test.go | 32 +- 4 files changed, 171 insertions(+), 250 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index aeb4e7bb2135..794c0e65700d 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -1223,22 +1223,21 @@ func (m *manager) createSnowmanChain( engine = smeng.TraceEngine(engine, m.Tracer) } - commonCfg := common.Config{ - Ctx: ctx, - Beacons: beacons, - SampleK: sampleK, - StartupTracker: startupTracker, - Alpha: bootstrapWeight/2 + 1, // must be > 50% - Sender: messageSender, - BootstrapTracker: sb, - Timer: h, - AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, - SharedCfg: &common.SharedConfig{}, - } - // create bootstrap gear + alpha := bootstrapWeight/2 + 1 // must be > 50% bootstrapCfg := smbootstrap.Config{ - Config: commonCfg, + Config: common.Config{ + Ctx: ctx, + Beacons: beacons, + SampleK: sampleK, + StartupTracker: startupTracker, + Alpha: alpha, + Sender: messageSender, + BootstrapTracker: sb, + Timer: h, + AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, + SharedCfg: &common.SharedConfig{}, + }, AllGetsServer: snowGetHandler, Blocked: blocked, VM: vm, @@ -1259,9 +1258,14 @@ func (m *manager) createSnowmanChain( // create state sync gear stateSyncCfg, err := syncer.NewConfig( - commonCfg, - m.StateSyncBeacons, snowGetHandler, + ctx, + startupTracker, + messageSender, + beacons, + sampleK, + alpha, + m.StateSyncBeacons, vm, ) if err != nil { diff --git a/snow/engine/snowman/syncer/config.go b/snow/engine/snowman/syncer/config.go index 4e10d412f38a..9f7acf7a4910 100644 --- a/snow/engine/snowman/syncer/config.go +++ b/snow/engine/snowman/syncer/config.go @@ -7,15 +7,22 @@ import ( "fmt" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/math" ) type Config struct { - common.Config common.AllGetsServer + Ctx *snow.ConsensusContext + + StartupTracker tracker.Startup + Sender common.Sender + // SampleK determines the number of nodes to attempt to fetch the latest // state sync summary from. In order for a round of voting to succeed, there // must be at least one correct node sampled. @@ -33,18 +40,18 @@ type Config struct { } func NewConfig( - commonCfg common.Config, - stateSyncerIDs []ids.NodeID, snowGetHandler common.AllGetsServer, + ctx *snow.ConsensusContext, + startupTracker tracker.Startup, + sender common.Sender, + beacons validators.Manager, + sampleK int, + alpha uint64, + stateSyncerIDs []ids.NodeID, vm block.ChainVM, ) (Config, error) { - // Initialize the default values that will be used if stateSyncerIDs is - // empty. - var ( - stateSyncBeacons = commonCfg.Beacons - syncAlpha = commonCfg.Alpha - syncSampleK = commonCfg.SampleK - ) + // Initialize the beacons that will be used if stateSyncerIDs is empty. + stateSyncBeacons := beacons // If the user has manually provided state syncer IDs, then override the // state sync beacons to them. @@ -52,24 +59,24 @@ func NewConfig( stateSyncBeacons = validators.NewManager() for _, peerID := range stateSyncerIDs { // Invariant: We never use the TxID or BLS keys populated here. - if err := stateSyncBeacons.AddStaker(commonCfg.Ctx.SubnetID, peerID, nil, ids.Empty, 1); err != nil { + if err := stateSyncBeacons.AddStaker(ctx.SubnetID, peerID, nil, ids.Empty, 1); err != nil { return Config{}, err } } - stateSyncingWeight, err := stateSyncBeacons.TotalWeight(commonCfg.Ctx.SubnetID) + stateSyncingWeight, err := stateSyncBeacons.TotalWeight(ctx.SubnetID) if err != nil { - return Config{}, fmt.Errorf("failed to calculate total weight of state sync beacons for subnet %s: %w", commonCfg.Ctx.SubnetID, err) - } - if uint64(syncSampleK) > stateSyncingWeight { - syncSampleK = int(stateSyncingWeight) + return Config{}, fmt.Errorf("failed to calculate total weight of state sync beacons for subnet %s: %w", ctx.SubnetID, err) } - syncAlpha = stateSyncingWeight/2 + 1 // must be > 50% + sampleK = int(math.Min(uint64(sampleK), stateSyncingWeight)) + alpha = stateSyncingWeight/2 + 1 // must be > 50% } return Config{ - Config: commonCfg, AllGetsServer: snowGetHandler, - SampleK: syncSampleK, - Alpha: syncAlpha, + Ctx: ctx, + StartupTracker: startupTracker, + Sender: sender, + SampleK: sampleK, + Alpha: alpha, StateSyncBeacons: stateSyncBeacons, VM: vm, }, nil diff --git a/snow/engine/snowman/syncer/state_syncer_test.go b/snow/engine/snowman/syncer/state_syncer_test.go index 84a1ce01a0a2..95b4d6382ec3 100644 --- a/snow/engine/snowman/syncer/state_syncer_test.go +++ b/snow/engine/snowman/syncer/state_syncer_test.go @@ -39,11 +39,8 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { require := require.New(t) // Build state syncer + ctx := snow.DefaultConsensusContextTest() sender := &common.SenderTest{T: t} - commonCfg := &common.Config{ - Ctx: snow.DefaultConsensusContextTest(), - Sender: sender, - } // Non state syncableVM case nonStateSyncableVM := &block.TestVM{ @@ -59,7 +56,7 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { ) require.NoError(err) - cfg, err := NewConfig(*commonCfg, nil, dummyGetter, nonStateSyncableVM) + cfg, err := NewConfig(dummyGetter, ctx, nil, sender, nil, 0, 0, nil, nonStateSyncableVM) require.NoError(err) syncer := New(cfg, func(context.Context, uint32) error { return nil @@ -87,7 +84,7 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { prometheus.NewRegistry()) require.NoError(err) - cfg, err = NewConfig(*commonCfg, nil, dummyGetter, fullVM) + cfg, err = NewConfig(dummyGetter, ctx, nil, sender, nil, 0, 0, nil, fullVM) require.NoError(err) syncer = New(cfg, func(context.Context, uint32) error { return nil @@ -113,48 +110,41 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { func TestStateSyncingStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - alpha, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + alpha, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := alpha peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: alpha, - StartupTracker: startup, - } - syncer, _, sender := buildTestsObjects(t, &commonCfg) + syncer, _, sender := buildTestsObjects(t, ctx, startup, beacons, alpha) sender.CantSendGetStateSummaryFrontier = true sender.SendGetStateSummaryFrontierF = func(context.Context, set.Set[ids.NodeID], uint32) {} startReqID := uint32(0) // attempt starting bootstrapper with no stake connected. Bootstrapper should stall. - require.False(commonCfg.StartupTracker.ShouldStart()) + require.False(startup.ShouldStart()) require.NoError(syncer.Start(context.Background(), startReqID)) require.False(syncer.started) // attempt starting bootstrapper with not enough stake connected. Bootstrapper should stall. vdr0 := ids.GenerateTestNodeID() - require.NoError(vdrs.AddStaker(ctx.SubnetID, vdr0, nil, ids.Empty, startupAlpha/2)) + require.NoError(beacons.AddStaker(ctx.SubnetID, vdr0, nil, ids.Empty, startupAlpha/2)) require.NoError(syncer.Connected(context.Background(), vdr0, version.CurrentApp)) - require.False(commonCfg.StartupTracker.ShouldStart()) + require.False(startup.ShouldStart()) require.NoError(syncer.Start(context.Background(), startReqID)) require.False(syncer.started) // finally attempt starting bootstrapper with enough stake connected. Frontiers should be requested. vdr := ids.GenerateTestNodeID() - require.NoError(vdrs.AddStaker(ctx.SubnetID, vdr, nil, ids.Empty, startupAlpha)) + require.NoError(beacons.AddStaker(ctx.SubnetID, vdr, nil, ids.Empty, startupAlpha)) require.NoError(syncer.Connected(context.Background(), vdr, version.CurrentApp)) - require.True(commonCfg.StartupTracker.ShouldStart()) + require.True(startup.ShouldStart()) require.NoError(syncer.Start(context.Background(), startReqID)) require.True(syncer.started) } @@ -162,23 +152,16 @@ func TestStateSyncingStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { func TestStateSyncLocalSummaryIsIncludedAmongFrontiersIfAvailable(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, _ := buildTestsObjects(t, &commonCfg) + syncer, fullVM, _ := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // mock VM to simulate a valid summary is returned localSummary := &block.TestStateSummary{ @@ -192,7 +175,7 @@ func TestStateSyncLocalSummaryIsIncludedAmongFrontiersIfAvailable(t *testing.T) } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } @@ -206,23 +189,16 @@ func TestStateSyncLocalSummaryIsIncludedAmongFrontiersIfAvailable(t *testing.T) func TestStateSyncNotFoundOngoingSummaryIsNotIncludedAmongFrontiers(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, _ := buildTestsObjects(t, &commonCfg) + syncer, fullVM, _ := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // mock VM to simulate a no summary returned fullVM.CantStateSyncGetOngoingSummary = true @@ -231,7 +207,7 @@ func TestStateSyncNotFoundOngoingSummaryIsNotIncludedAmongFrontiers(t *testing.T } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } @@ -243,23 +219,16 @@ func TestBeaconsAreReachedForFrontiersUponStartup(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, _, sender := buildTestsObjects(t, &commonCfg) + syncer, _, sender := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // set sender to track nodes reached out contactedFrontiersProviders := set.NewSet[ids.NodeID](3) @@ -269,12 +238,12 @@ func TestBeaconsAreReachedForFrontiersUponStartup(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } // check that vdrs are reached out for frontiers - require.Len(contactedFrontiersProviders, safemath.Min(vdrs.Count(ctx.SubnetID), common.MaxOutstandingBroadcastRequests)) + require.Len(contactedFrontiersProviders, safemath.Min(beacons.Count(ctx.SubnetID), common.MaxOutstandingBroadcastRequests)) for beaconID := range contactedFrontiersProviders { // check that beacon is duly marked as reached out require.Contains(syncer.pendingSeeders, beaconID) @@ -288,23 +257,16 @@ func TestUnRequestedStateSummaryFrontiersAreDropped(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -316,7 +278,7 @@ func TestUnRequestedStateSummaryFrontiersAreDropped(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } @@ -377,30 +339,23 @@ func TestUnRequestedStateSummaryFrontiersAreDropped(t *testing.T) { // other listed vdrs are reached for data require.True( len(contactedFrontiersProviders) > initiallyReachedOutBeaconsSize || - len(contactedFrontiersProviders) == vdrs.Count(ctx.SubnetID)) + len(contactedFrontiersProviders) == beacons.Count(ctx.SubnetID)) } func TestMalformedStateSummaryFrontiersAreDropped(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -412,7 +367,7 @@ func TestMalformedStateSummaryFrontiersAreDropped(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } @@ -452,30 +407,23 @@ func TestMalformedStateSummaryFrontiersAreDropped(t *testing.T) { // are reached for data require.True( len(contactedFrontiersProviders) > initiallyReachedOutBeaconsSize || - len(contactedFrontiersProviders) == vdrs.Count(ctx.SubnetID)) + len(contactedFrontiersProviders) == beacons.Count(ctx.SubnetID)) } func TestLateResponsesFromUnresponsiveFrontiersAreNotRecorded(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -487,7 +435,7 @@ func TestLateResponsesFromUnresponsiveFrontiersAreNotRecorded(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } @@ -520,7 +468,7 @@ func TestLateResponsesFromUnresponsiveFrontiersAreNotRecorded(t *testing.T) { // are reached for data require.True( len(contactedFrontiersProviders) > initiallyReachedOutBeaconsSize || - len(contactedFrontiersProviders) == vdrs.Count(ctx.SubnetID)) + len(contactedFrontiersProviders) == beacons.Count(ctx.SubnetID)) // mock VM to simulate a valid but late summary is returned fullVM.CantParseStateSummary = true @@ -548,23 +496,16 @@ func TestStateSyncIsRestartedIfTooManyFrontierSeedersTimeout(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: snow.DefaultConsensusContextTest(), - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -601,7 +542,7 @@ func TestStateSyncIsRestartedIfTooManyFrontierSeedersTimeout(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } require.NotEmpty(syncer.pendingSeeders) @@ -643,23 +584,16 @@ func TestVoteRequestsAreSentAsAllFrontierBeaconsResponded(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -690,7 +624,7 @@ func TestVoteRequestsAreSentAsAllFrontierBeaconsResponded(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } require.NotEmpty(syncer.pendingSeeders) @@ -720,23 +654,16 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -766,7 +693,7 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } require.NotEmpty(syncer.pendingSeeders) @@ -830,36 +757,29 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { // responsiveBeacon not pending anymore require.NotContains(syncer.pendingSeeders, responsiveVoterID) - voterWeight := vdrs.GetWeight(ctx.SubnetID, responsiveVoterID) + voterWeight := beacons.GetWeight(ctx.SubnetID, responsiveVoterID) require.Equal(voterWeight, syncer.weightedSummaries[summaryID].weight) // other listed voters are reached out require.True( len(contactedVoters) > initiallyContactedVotersSize || - len(contactedVoters) == vdrs.Count(ctx.SubnetID)) + len(contactedVoters) == beacons.Count(ctx.SubnetID)) } func TestVotesForUnknownSummariesAreDropped(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -889,7 +809,7 @@ func TestVotesForUnknownSummariesAreDropped(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } require.NotEmpty(syncer.pendingSeeders) @@ -945,30 +865,24 @@ func TestVotesForUnknownSummariesAreDropped(t *testing.T) { // on unknown summary require.True( len(contactedVoters) > initiallyContactedVotersSize || - len(contactedVoters) == vdrs.Count(ctx.SubnetID)) + len(contactedVoters) == beacons.Count(ctx.SubnetID)) } func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 + alpha := (totalWeight + 1) / 2 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, alpha) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -1014,7 +928,7 @@ func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } require.NotEmpty(syncer.pendingSeeders) @@ -1066,23 +980,23 @@ func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { reqID := contactedVoters[voterID] switch { - case cumulatedWeight < commonCfg.Alpha/2: + case cumulatedWeight < alpha/2: require.NoError(syncer.AcceptedStateSummary( context.Background(), voterID, reqID, set.Of(summaryID, minoritySummaryID), )) - cumulatedWeight += vdrs.GetWeight(ctx.SubnetID, voterID) + cumulatedWeight += beacons.GetWeight(ctx.SubnetID, voterID) - case cumulatedWeight < commonCfg.Alpha: + case cumulatedWeight < alpha: require.NoError(syncer.AcceptedStateSummary( context.Background(), voterID, reqID, set.Of(summaryID), )) - cumulatedWeight += vdrs.GetWeight(ctx.SubnetID, voterID) + cumulatedWeight += beacons.GetWeight(ctx.SubnetID, voterID) default: require.NoError(syncer.GetAcceptedStateSummaryFailed( @@ -1102,23 +1016,17 @@ func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 + alpha := (totalWeight + 1) / 2 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: snow.DefaultConsensusContextTest(), - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, alpha) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -1150,7 +1058,7 @@ func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } require.NotEmpty(syncer.pendingSeeders) @@ -1184,13 +1092,13 @@ func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { reqID := contactedVoters[voterID] // vdr carries the largest weight by far. Make sure it fails - if timedOutWeight <= commonCfg.Alpha { + if timedOutWeight <= alpha { require.NoError(syncer.GetAcceptedStateSummaryFailed( context.Background(), voterID, reqID, )) - timedOutWeight += vdrs.GetWeight(ctx.SubnetID, voterID) + timedOutWeight += beacons.GetWeight(ctx.SubnetID, voterID) } else { require.NoError(syncer.AcceptedStateSummary( context.Background(), @@ -1213,23 +1121,17 @@ func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing. require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 + alpha := (totalWeight + 1) / 2 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, sender := buildTestsObjects(t, &commonCfg) + syncer, fullVM, sender := buildTestsObjects(t, ctx, startup, beacons, alpha) // set sender to track nodes reached out contactedFrontiersProviders := make(map[ids.NodeID]uint32) // nodeID -> reqID map @@ -1275,7 +1177,7 @@ func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing. } // Connect enough stake to start syncer - for _, nodeID := range vdrs.GetValidatorIDs(ctx.SubnetID) { + for _, nodeID := range beacons.GetValidatorIDs(ctx.SubnetID) { require.NoError(syncer.Connected(context.Background(), nodeID, version.CurrentApp)) } require.NotEmpty(syncer.pendingSeeders) @@ -1334,14 +1236,14 @@ func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing. reqID := contactedVoters[voterID] switch { - case votingWeightStake < commonCfg.Alpha/2: + case votingWeightStake < alpha/2: require.NoError(syncer.AcceptedStateSummary( context.Background(), voterID, reqID, set.Of(minoritySummary1.ID(), minoritySummary2.ID()), )) - votingWeightStake += vdrs.GetWeight(ctx.SubnetID, voterID) + votingWeightStake += beacons.GetWeight(ctx.SubnetID, voterID) default: require.NoError(syncer.AcceptedStateSummary( @@ -1350,7 +1252,7 @@ func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing. reqID, set.Of(ids.ID{'u', 'n', 'k', 'n', 'o', 'w', 'n', 'I', 'D'}), )) - votingWeightStake += vdrs.GetWeight(ctx.SubnetID, voterID) + votingWeightStake += beacons.GetWeight(ctx.SubnetID, voterID) } } @@ -1364,24 +1266,16 @@ func TestStateSyncIsDoneOnceVMNotifies(t *testing.T) { require := require.New(t) ctx := snow.DefaultConsensusContextTest() - vdrs := buildTestPeers(t, ctx.SubnetID) - totalWeight, err := vdrs.TotalWeight(ctx.SubnetID) + beacons := buildTestPeers(t, ctx.SubnetID) + totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) startupAlpha := (3*totalWeight + 3) / 4 peers := tracker.NewPeers() startup := tracker.NewStartup(peers, startupAlpha) - vdrs.RegisterCallbackListener(ctx.SubnetID, startup) + beacons.RegisterCallbackListener(ctx.SubnetID, startup) - commonCfg := common.Config{ - Ctx: snow.DefaultConsensusContextTest(), - Beacons: vdrs, - SampleK: vdrs.Count(ctx.SubnetID), - Alpha: (totalWeight + 1) / 2, - StartupTracker: startup, - } - syncer, fullVM, _ := buildTestsObjects(t, &commonCfg) - _ = fullVM + syncer, _, _ := buildTestsObjects(t, ctx, startup, beacons, (totalWeight+1)/2) stateSyncFullyDone := false syncer.onDoneStateSyncing = func(context.Context, uint32) error { diff --git a/snow/engine/snowman/syncer/utils_test.go b/snow/engine/snowman/syncer/utils_test.go index b9a31fbc18bc..fee7c4f847e6 100644 --- a/snow/engine/snowman/syncer/utils_test.go +++ b/snow/engine/snowman/syncer/utils_test.go @@ -12,7 +12,9 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/getter" "github.com/ava-labs/avalanchego/snow/validators" @@ -66,16 +68,19 @@ func buildTestPeers(t *testing.T, subnetID ids.ID) validators.Manager { return vdrs } -func buildTestsObjects(t *testing.T, commonCfg *common.Config) ( +func buildTestsObjects( + t *testing.T, + ctx *snow.ConsensusContext, + startupTracker tracker.Startup, + beacons validators.Manager, + alpha uint64, +) ( *stateSyncer, *fullVM, *common.SenderTest, ) { require := require.New(t) - sender := &common.SenderTest{T: t} - commonCfg.Sender = sender - fullVM := &fullVM{ TestVM: &block.TestVM{ TestVM: common.TestVM{T: t}, @@ -84,17 +89,28 @@ func buildTestsObjects(t *testing.T, commonCfg *common.Config) ( T: t, }, } + sender := &common.SenderTest{T: t} dummyGetter, err := getter.New( fullVM, - commonCfg.Sender, - commonCfg.Ctx.Log, + sender, + ctx.Log, time.Second, 2000, - commonCfg.Ctx.Registerer, + ctx.Registerer, ) require.NoError(err) - cfg, err := NewConfig(*commonCfg, nil, dummyGetter, fullVM) + cfg, err := NewConfig( + dummyGetter, + ctx, + startupTracker, + sender, + beacons, + beacons.Count(ctx.SubnetID), + alpha, + nil, + fullVM, + ) require.NoError(err) commonSyncer := New(cfg, func(context.Context, uint32) error { return nil From 40934bb50220c5cec73e95f038b8a3bdce2253f5 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 17 Nov 2023 15:26:22 -0500 Subject: [PATCH 056/267] `platformvm.VM` -- replace `Config` field with `validators.Manager` (#2319) --- vms/platformvm/block/builder/helpers_test.go | 6 +-- vms/platformvm/block/executor/helpers_test.go | 6 +-- vms/platformvm/state/state.go | 44 +++++++++---------- vms/platformvm/state/state_test.go | 4 +- vms/platformvm/txs/executor/helpers_test.go | 6 +-- .../validators/manager_benchmark_test.go | 4 +- vms/platformvm/vm.go | 2 +- vms/platformvm/vm_regression_test.go | 4 +- 8 files changed, 36 insertions(+), 40 deletions(-) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index f419c38c4ac0..84778add2864 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -135,7 +135,7 @@ func newEnvironment(t *testing.T) *environment { res.fx = defaultFx(t, res.clk, res.ctx.Log, res.isBootstrapped.Get()) rewardsCalc := reward.NewCalculator(res.config.RewardConfig) - res.state = defaultState(t, res.config, res.ctx, res.baseDB, rewardsCalc) + res.state = defaultState(t, res.config.Validators, res.ctx, res.baseDB, rewardsCalc) res.atomicUTXOs = avax.NewAtomicUTXOManager(res.ctx.SharedMemory, txs.Codec) res.uptimes = uptime.NewManager(res.state, res.clk) @@ -237,7 +237,7 @@ func addSubnet(t *testing.T, env *environment) { func defaultState( t *testing.T, - cfg *config.Config, + validators validators.Manager, ctx *snow.Context, db database.Database, rewards reward.Calculator, @@ -250,7 +250,7 @@ func defaultState( db, genesisBytes, prometheus.NewRegistry(), - cfg, + validators, execCfg, ctx, metrics.Noop, diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 9c9135fe6f9f..ff0aa13a2ea1 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -151,7 +151,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller) *environment { res.atomicUTXOs = avax.NewAtomicUTXOManager(res.ctx.SharedMemory, txs.Codec) if ctrl == nil { - res.state = defaultState(res.config, res.ctx, res.baseDB, rewardsCalc) + res.state = defaultState(res.config.Validators, res.ctx, res.baseDB, rewardsCalc) res.uptimes = uptime.NewManager(res.state, res.clk) res.utxosHandler = utxo.NewHandler(res.ctx, res.clk, res.fx) res.txBuilder = p_tx_builder.New( @@ -269,7 +269,7 @@ func addSubnet(env *environment) { } func defaultState( - cfg *config.Config, + validators validators.Manager, ctx *snow.Context, db database.Database, rewards reward.Calculator, @@ -280,7 +280,7 @@ func defaultState( db, genesisBytes, prometheus.NewRegistry(), - cfg, + validators, execCfg, ctx, metrics.Noop, diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index fd842f684eae..199b245008f7 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -286,10 +286,10 @@ type stateBlk struct { type state struct { validatorState - cfg *config.Config - ctx *snow.Context - metrics metrics.Metrics - rewards reward.Calculator + validators validators.Manager + ctx *snow.Context + metrics metrics.Metrics + rewards reward.Calculator baseDB *versiondb.Database @@ -451,7 +451,7 @@ func New( db database.Database, genesisBytes []byte, metricsReg prometheus.Registerer, - cfg *config.Config, + validators validators.Manager, execCfg *config.ExecutionConfig, ctx *snow.Context, metrics metrics.Metrics, @@ -460,7 +460,7 @@ func New( s, err := newState( db, metrics, - cfg, + validators, execCfg, ctx, metricsReg, @@ -504,7 +504,7 @@ func New( func newState( db database.Database, metrics metrics.Metrics, - cfg *config.Config, + validators validators.Manager, execCfg *config.ExecutionConfig, ctx *snow.Context, metricsReg prometheus.Registerer, @@ -627,11 +627,11 @@ func newState( return &state{ validatorState: newValidatorState(), - cfg: cfg, - ctx: ctx, - metrics: metrics, - rewards: rewards, - baseDB: baseDB, + validators: validators, + ctx: ctx, + metrics: metrics, + rewards: rewards, + baseDB: baseDB, addedBlockIDs: make(map[uint64]ids.ID), blockIDCache: blockIDCache, @@ -1661,21 +1661,21 @@ func (s *state) loadPendingValidators() error { // been called. func (s *state) initValidatorSets() error { for subnetID, validators := range s.currentStakers.validators { - if s.cfg.Validators.Count(subnetID) != 0 { + if s.validators.Count(subnetID) != 0 { // Enforce the invariant that the validator set is empty here. return fmt.Errorf("%w: %s", errValidatorSetAlreadyPopulated, subnetID) } for nodeID, validator := range validators { validatorStaker := validator.validator - if err := s.cfg.Validators.AddStaker(subnetID, nodeID, validatorStaker.PublicKey, validatorStaker.TxID, validatorStaker.Weight); err != nil { + if err := s.validators.AddStaker(subnetID, nodeID, validatorStaker.PublicKey, validatorStaker.TxID, validatorStaker.Weight); err != nil { return err } delegatorIterator := NewTreeIterator(validator.delegators) for delegatorIterator.Next() { delegatorStaker := delegatorIterator.Value() - if err := s.cfg.Validators.AddWeight(subnetID, nodeID, delegatorStaker.Weight); err != nil { + if err := s.validators.AddWeight(subnetID, nodeID, delegatorStaker.Weight); err != nil { delegatorIterator.Release() return err } @@ -1684,8 +1684,8 @@ func (s *state) initValidatorSets() error { } } - s.metrics.SetLocalStake(s.cfg.Validators.GetWeight(constants.PrimaryNetworkID, s.ctx.NodeID)) - totalWeight, err := s.cfg.Validators.TotalWeight(constants.PrimaryNetworkID) + s.metrics.SetLocalStake(s.validators.GetWeight(constants.PrimaryNetworkID, s.ctx.NodeID)) + totalWeight, err := s.validators.TotalWeight(constants.PrimaryNetworkID) if err != nil { return fmt.Errorf("failed to get total weight of primary network validators: %w", err) } @@ -2079,11 +2079,11 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error } if weightDiff.Decrease { - err = s.cfg.Validators.RemoveWeight(subnetID, nodeID, weightDiff.Amount) + err = s.validators.RemoveWeight(subnetID, nodeID, weightDiff.Amount) } else { if validatorDiff.validatorStatus == added { staker := validatorDiff.validator - err = s.cfg.Validators.AddStaker( + err = s.validators.AddStaker( subnetID, nodeID, staker.PublicKey, @@ -2091,7 +2091,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error weightDiff.Amount, ) } else { - err = s.cfg.Validators.AddWeight(subnetID, nodeID, weightDiff.Amount) + err = s.validators.AddWeight(subnetID, nodeID, weightDiff.Amount) } } if err != nil { @@ -2107,12 +2107,12 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error return nil } - totalWeight, err := s.cfg.Validators.TotalWeight(constants.PrimaryNetworkID) + totalWeight, err := s.validators.TotalWeight(constants.PrimaryNetworkID) if err != nil { return fmt.Errorf("failed to get total weight of primary network: %w", err) } - s.metrics.SetLocalStake(s.cfg.Validators.GetWeight(constants.PrimaryNetworkID, s.ctx.NodeID)) + s.metrics.SetLocalStake(s.validators.GetWeight(constants.PrimaryNetworkID, s.ctx.NodeID)) s.metrics.SetTotalStake(totalWeight) return nil } diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index ae79415f4bbf..3c36310c0576 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -165,9 +165,7 @@ func newStateFromDB(require *require.Assertions, db database.Database) State { state, err := newState( db, metrics.Noop, - &config.Config{ - Validators: validators.NewManager(), - }, + validators.NewManager(), execCfg, &snow.Context{}, prometheus.NewRegistry(), diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index c26a865bdc6f..df3150e04bdd 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -132,7 +132,7 @@ func newEnvironment(t *testing.T, postBanff, postCortina bool) *environment { fx := defaultFx(clk, ctx.Log, isBootstrapped.Get()) rewards := reward.NewCalculator(config.RewardConfig) - baseState := defaultState(&config, ctx, baseDB, rewards) + baseState := defaultState(config.Validators, ctx, baseDB, rewards) atomicUTXOs := avax.NewAtomicUTXOManager(ctx.SharedMemory, txs.Codec) uptimes := uptime.NewManager(baseState, clk) @@ -218,7 +218,7 @@ func addSubnet( } func defaultState( - cfg *config.Config, + validators validators.Manager, ctx *snow.Context, db database.Database, rewards reward.Calculator, @@ -229,7 +229,7 @@ func defaultState( db, genesisBytes, prometheus.NewRegistry(), - cfg, + validators, execCfg, ctx, metrics.Noop, diff --git a/vms/platformvm/validators/manager_benchmark_test.go b/vms/platformvm/validators/manager_benchmark_test.go index 0664c085c942..155811d988ad 100644 --- a/vms/platformvm/validators/manager_benchmark_test.go +++ b/vms/platformvm/validators/manager_benchmark_test.go @@ -112,9 +112,7 @@ func BenchmarkGetValidatorSet(b *testing.B) { db, genesisBytes, prometheus.NewRegistry(), - &config.Config{ - Validators: vdrs, - }, + vdrs, execConfig, &snow.Context{ NetworkID: constants.UnitTestID, diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 7f7568deb813..c312e4044e8b 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -139,7 +139,7 @@ func (vm *VM) Initialize( vm.db, genesisBytes, registerer, - &vm.Config, + vm.Config.Validators, execConfig, vm.ctx, vm.metrics, diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 5b50c9895622..80b38a06c234 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -648,7 +648,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { vm.db, nil, prometheus.NewRegistry(), - &vm.Config, + vm.Config.Validators, execCfg, vm.ctx, metrics.Noop, @@ -955,7 +955,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { vm.db, nil, prometheus.NewRegistry(), - &vm.Config, + vm.Config.Validators, execCfg, vm.ctx, metrics.Noop, From b573889510d8182efc7d2740ebe20cd3a842cca0 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 20 Nov 2023 16:01:54 -0500 Subject: [PATCH 057/267] Improve height monitoring (#2347) --- snow/consensus/metrics/height.go | 29 +++++++++++++++++++++++---- snow/consensus/snowman/topological.go | 27 +++++++++++++++++++------ 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/snow/consensus/metrics/height.go b/snow/consensus/metrics/height.go index d491f316d70b..1ff505b5226e 100644 --- a/snow/consensus/metrics/height.go +++ b/snow/consensus/metrics/height.go @@ -3,29 +3,50 @@ package metrics -import "github.com/prometheus/client_golang/prometheus" +import ( + "github.com/prometheus/client_golang/prometheus" + + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/math" +) var _ Height = (*height)(nil) -// Height reports the last accepted height type Height interface { + Verified(height uint64) Accepted(height uint64) } type height struct { - // lastAcceptedHeight keeps track of the last accepted height + currentMaxVerifiedHeight uint64 + maxVerifiedHeight prometheus.Gauge + lastAcceptedHeight prometheus.Gauge } func NewHeight(namespace string, reg prometheus.Registerer) (Height, error) { h := &height{ + maxVerifiedHeight: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "max_verified_height", + Help: "Highest verified height", + }), lastAcceptedHeight: prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "last_accepted_height", Help: "Last height accepted", }), } - return h, reg.Register(h.lastAcceptedHeight) + err := utils.Err( + reg.Register(h.lastAcceptedHeight), + reg.Register(h.maxVerifiedHeight), + ) + return h, err +} + +func (h *height) Verified(height uint64) { + h.currentMaxVerifiedHeight = math.Max(h.currentMaxVerifiedHeight, height) + h.maxVerifiedHeight.Set(float64(h.currentMaxVerifiedHeight)) } func (h *height) Accepted(height uint64) { diff --git a/snow/consensus/snowman/topological.go b/snow/consensus/snowman/topological.go index 7cf6cde8139e..a27a695b2d24 100644 --- a/snow/consensus/snowman/topological.go +++ b/snow/consensus/snowman/topological.go @@ -153,6 +153,7 @@ func (ts *Topological) Initialize( ts.tail = rootID // Initially set the metrics for the last accepted block. + ts.Height.Verified(ts.height) ts.Height.Accepted(ts.height) ts.Timestamp.Accepted(rootTime) @@ -165,8 +166,10 @@ func (ts *Topological) NumProcessing() int { func (ts *Topological) Add(ctx context.Context, blk Block) error { blkID := blk.ID() + height := blk.Height() ts.ctx.Log.Verbo("adding block", zap.Stringer("blkID", blkID), + zap.Uint64("height", height), ) // Make sure a block is not inserted twice. This enforces the invariant that @@ -178,6 +181,7 @@ func (ts *Topological) Add(ctx context.Context, blk Block) error { return errDuplicateAdd } + ts.Height.Verified(height) ts.Latency.Issued(blkID, ts.pollNumber) parentID := blk.Parent() @@ -185,6 +189,7 @@ func (ts *Topological) Add(ctx context.Context, blk Block) error { if !ok { ts.ctx.Log.Verbo("block ancestor is missing, being rejected", zap.Stringer("blkID", blkID), + zap.Uint64("height", height), zap.Stringer("parentID", parentID), ) @@ -209,11 +214,12 @@ func (ts *Topological) Add(ctx context.Context, blk Block) error { if ts.tail == parentID { ts.tail = blkID ts.preferredIDs.Add(blkID) - ts.preferredHeights[blk.Height()] = blkID + ts.preferredHeights[height] = blkID } ts.ctx.Log.Verbo("added block", zap.Stringer("blkID", blkID), + zap.Uint64("height", height), zap.Stringer("parentID", parentID), ) return nil @@ -634,8 +640,10 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock return err } + height := child.Height() ts.ctx.Log.Trace("accepting block", zap.Stringer("blkID", pref), + zap.Uint64("height", height), ) if err := child.Accept(ctx); err != nil { return err @@ -643,14 +651,14 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock // Because this is the newest accepted block, this is the new head. ts.head = pref - ts.height = child.Height() + ts.height = height // Remove the decided block from the set of processing IDs, as its status // now implies its preferredness. ts.preferredIDs.Remove(pref) - delete(ts.preferredHeights, ts.height) + delete(ts.preferredHeights, height) ts.Latency.Accepted(pref, ts.pollNumber, len(bytes)) - ts.Height.Accepted(ts.height) + ts.Height.Accepted(height) ts.Timestamp.Accepted(child.Timestamp()) // Because ts.blocks contains the last accepted block, we don't delete the @@ -665,8 +673,9 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock ts.ctx.Log.Trace("rejecting block", zap.String("reason", "conflict with accepted block"), - zap.Stringer("rejectedID", childID), - zap.Stringer("conflictedID", pref), + zap.Stringer("blkID", childID), + zap.Uint64("height", child.Height()), + zap.Stringer("conflictID", pref), ) if err := child.Reject(ctx); err != nil { return err @@ -696,6 +705,12 @@ func (ts *Topological) rejectTransitively(ctx context.Context, rejected []ids.ID delete(ts.blocks, rejectedID) for childID, child := range rejectedNode.children { + ts.ctx.Log.Trace("rejecting block", + zap.String("reason", "rejected ancestor"), + zap.Stringer("blkID", childID), + zap.Uint64("height", child.Height()), + zap.Stringer("parentID", rejectedID), + ) if err := child.Reject(ctx); err != nil { return err } From 2b737d5bde54ce659f41b9b63aa3cb530315d296 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 21 Nov 2023 13:26:55 -0500 Subject: [PATCH 058/267] Cleanup snowman consensus metrics (#2349) --- snow/consensus/metrics/height.go | 54 ------ snow/consensus/metrics/latency.go | 215 --------------------- snow/consensus/metrics/polls.go | 54 ------ snow/consensus/metrics/timestamp.go | 38 ---- snow/consensus/snowman/metrics.go | 261 ++++++++++++++++++++++++++ snow/consensus/snowman/topological.go | 158 +++++++--------- 6 files changed, 330 insertions(+), 450 deletions(-) delete mode 100644 snow/consensus/metrics/height.go delete mode 100644 snow/consensus/metrics/latency.go delete mode 100644 snow/consensus/metrics/polls.go delete mode 100644 snow/consensus/metrics/timestamp.go create mode 100644 snow/consensus/snowman/metrics.go diff --git a/snow/consensus/metrics/height.go b/snow/consensus/metrics/height.go deleted file mode 100644 index 1ff505b5226e..000000000000 --- a/snow/consensus/metrics/height.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package metrics - -import ( - "github.com/prometheus/client_golang/prometheus" - - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/math" -) - -var _ Height = (*height)(nil) - -type Height interface { - Verified(height uint64) - Accepted(height uint64) -} - -type height struct { - currentMaxVerifiedHeight uint64 - maxVerifiedHeight prometheus.Gauge - - lastAcceptedHeight prometheus.Gauge -} - -func NewHeight(namespace string, reg prometheus.Registerer) (Height, error) { - h := &height{ - maxVerifiedHeight: prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "max_verified_height", - Help: "Highest verified height", - }), - lastAcceptedHeight: prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "last_accepted_height", - Help: "Last height accepted", - }), - } - err := utils.Err( - reg.Register(h.lastAcceptedHeight), - reg.Register(h.maxVerifiedHeight), - ) - return h, err -} - -func (h *height) Verified(height uint64) { - h.currentMaxVerifiedHeight = math.Max(h.currentMaxVerifiedHeight, height) - h.maxVerifiedHeight.Set(float64(h.currentMaxVerifiedHeight)) -} - -func (h *height) Accepted(height uint64) { - h.lastAcceptedHeight.Set(float64(height)) -} diff --git a/snow/consensus/metrics/latency.go b/snow/consensus/metrics/latency.go deleted file mode 100644 index 4f5d413a6542..000000000000 --- a/snow/consensus/metrics/latency.go +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package metrics - -import ( - "fmt" - "time" - - "github.com/prometheus/client_golang/prometheus" - - "go.uber.org/zap" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/choices" - "github.com/ava-labs/avalanchego/utils/linkedhashmap" - "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/utils/metric" - "github.com/ava-labs/avalanchego/utils/wrappers" -) - -var _ Latency = (*latency)(nil) - -type Latency interface { - // Issued marks the item as having been issued. - Issued(id ids.ID, pollNumber uint64) - - // Accepted marks the item as having been accepted. - // Pass the container size in bytes for metrics tracking. - Accepted(id ids.ID, pollNumber uint64, containerSize int) - - // Rejected marks the item as having been rejected. - // Pass the container size in bytes for metrics tracking. - Rejected(id ids.ID, pollNumber uint64, containerSize int) - - // MeasureAndGetOldestDuration returns the amount of time the oldest item - // has been processing. - MeasureAndGetOldestDuration() time.Duration - - // NumProcessing returns the number of currently processing items. - NumProcessing() int -} - -type opStart struct { - time time.Time - pollNumber uint64 -} - -// Latency reports commonly used consensus latency metrics. -type latency struct { - // ProcessingEntries keeps track of the [opStart] that each item was issued - // into the consensus instance. This is used to calculate the amount of time - // to accept or reject the item. - processingEntries linkedhashmap.LinkedHashmap[ids.ID, opStart] - - // log reports anomalous events. - log logging.Logger - - // numProcessing keeps track of the number of items processing - numProcessing prometheus.Gauge - - // pollsAccepted tracks the number of polls that an item was in processing - // for before being accepted - pollsAccepted metric.Averager - - // pollsRejected tracks the number of polls that an item was in processing - // for before being rejected - pollsRejected metric.Averager - - // latAccepted tracks the number of nanoseconds that an item was processing - // before being accepted - latAccepted metric.Averager - containerSizeAcceptedSum prometheus.Gauge - - // rejected tracks the number of nanoseconds that an item was processing - // before being rejected - latRejected metric.Averager - containerSizeRejectedSum prometheus.Gauge -} - -// Initialize the metrics with the provided names. -func NewLatency(metricName, descriptionName string, log logging.Logger, namespace string, reg prometheus.Registerer) (Latency, error) { - errs := wrappers.Errs{} - l := &latency{ - processingEntries: linkedhashmap.New[ids.ID, opStart](), - log: log, - - // e.g., - // "avalanche_7y7zwo7XatqnX4dtTakLo32o7jkMX4XuDa26WaxbCXoCT1qKK_blks_processing" to count how blocks are currently processing - numProcessing: prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: fmt.Sprintf("%s_processing", metricName), - Help: fmt.Sprintf("Number of currently processing %s", metricName), - }), - - pollsAccepted: metric.NewAveragerWithErrs( - namespace, - fmt.Sprintf("%s_polls_accepted", metricName), - fmt.Sprintf("number of polls from issuance of a %s to its acceptance", descriptionName), - reg, - &errs, - ), - pollsRejected: metric.NewAveragerWithErrs( - namespace, - fmt.Sprintf("%s_polls_rejected", metricName), - fmt.Sprintf("number of polls from issuance of a %s to its rejection", descriptionName), - reg, - &errs, - ), - - // e.g., - // "avalanche_C_blks_accepted_count" to count how many "Observe" gets called -- count all "Accept" - // "avalanche_C_blks_accepted_sum" to count how many ns have elapsed since its issuance on acceptance - // "avalanche_C_blks_accepted_sum / avalanche_C_blks_accepted_count" is the average block acceptance latency in ns - // "avalanche_C_blks_accepted_container_size_sum" to track cumulative sum of all accepted blocks' sizes - // "avalanche_C_blks_accepted_container_size_sum / avalanche_C_blks_accepted_count" is the average block size - latAccepted: metric.NewAveragerWithErrs( - namespace, - fmt.Sprintf("%s_accepted", metricName), - fmt.Sprintf("time (in ns) from issuance of a %s to its acceptance", descriptionName), - reg, - &errs, - ), - containerSizeAcceptedSum: prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: fmt.Sprintf("%s_accepted_container_size_sum", metricName), - Help: fmt.Sprintf("Cumulative sum of container size of all accepted %s", metricName), - }), - - // e.g., - // "avalanche_P_blks_rejected_count" to count how many "Observe" gets called -- count all "Reject" - // "avalanche_P_blks_rejected_sum" to count how many ns have elapsed since its issuance on rejection - // "avalanche_P_blks_accepted_sum / avalanche_P_blks_accepted_count" is the average block acceptance latency in ns - // "avalanche_P_blks_accepted_container_size_sum" to track cumulative sum of all accepted blocks' sizes - // "avalanche_P_blks_accepted_container_size_sum / avalanche_P_blks_accepted_count" is the average block size - latRejected: metric.NewAveragerWithErrs( - namespace, - fmt.Sprintf("%s_rejected", metricName), - fmt.Sprintf("time (in ns) from issuance of a %s to its rejection", descriptionName), - reg, - &errs, - ), - containerSizeRejectedSum: prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: fmt.Sprintf("%s_rejected_container_size_sum", metricName), - Help: fmt.Sprintf("Cumulative sum of container size of all rejected %s", metricName), - }), - } - errs.Add( - reg.Register(l.numProcessing), - reg.Register(l.containerSizeAcceptedSum), - reg.Register(l.containerSizeRejectedSum), - ) - return l, errs.Err -} - -func (l *latency) Issued(id ids.ID, pollNumber uint64) { - l.processingEntries.Put(id, opStart{ - time: time.Now(), - pollNumber: pollNumber, - }) - l.numProcessing.Inc() -} - -func (l *latency) Accepted(id ids.ID, pollNumber uint64, containerSize int) { - start, ok := l.processingEntries.Get(id) - if !ok { - l.log.Debug("unable to measure tx latency", - zap.Stringer("status", choices.Accepted), - zap.Stringer("txID", id), - ) - return - } - l.processingEntries.Delete(id) - - l.pollsAccepted.Observe(float64(pollNumber - start.pollNumber)) - - duration := time.Since(start.time) - l.latAccepted.Observe(float64(duration)) - l.numProcessing.Dec() - - l.containerSizeAcceptedSum.Add(float64(containerSize)) -} - -func (l *latency) Rejected(id ids.ID, pollNumber uint64, containerSize int) { - start, ok := l.processingEntries.Get(id) - if !ok { - l.log.Debug("unable to measure tx latency", - zap.Stringer("status", choices.Rejected), - zap.Stringer("txID", id), - ) - return - } - l.processingEntries.Delete(id) - - l.pollsRejected.Observe(float64(pollNumber - start.pollNumber)) - - duration := time.Since(start.time) - l.latRejected.Observe(float64(duration)) - l.numProcessing.Dec() - - l.containerSizeRejectedSum.Add(float64(containerSize)) -} - -func (l *latency) MeasureAndGetOldestDuration() time.Duration { - _, oldestOp, exists := l.processingEntries.Oldest() - if !exists { - return 0 - } - return time.Since(oldestOp.time) -} - -func (l *latency) NumProcessing() int { - return l.processingEntries.Len() -} diff --git a/snow/consensus/metrics/polls.go b/snow/consensus/metrics/polls.go deleted file mode 100644 index 589833954f6b..000000000000 --- a/snow/consensus/metrics/polls.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package metrics - -import ( - "github.com/prometheus/client_golang/prometheus" - - "github.com/ava-labs/avalanchego/utils" -) - -var _ Polls = (*polls)(nil) - -// Polls reports commonly used consensus poll metrics. -type Polls interface { - Successful() - Failed() -} - -type polls struct { - // numFailedPolls keeps track of the number of polls that failed - numFailedPolls prometheus.Counter - - // numSuccessfulPolls keeps track of the number of polls that succeeded - numSuccessfulPolls prometheus.Counter -} - -func NewPolls(namespace string, reg prometheus.Registerer) (Polls, error) { - p := &polls{ - numSuccessfulPolls: prometheus.NewCounter(prometheus.CounterOpts{ - Namespace: namespace, - Name: "polls_successful", - Help: "Number of successful polls", - }), - numFailedPolls: prometheus.NewCounter(prometheus.CounterOpts{ - Namespace: namespace, - Name: "polls_failed", - Help: "Number of failed polls", - }), - } - err := utils.Err( - reg.Register(p.numFailedPolls), - reg.Register(p.numSuccessfulPolls), - ) - return p, err -} - -func (p *polls) Failed() { - p.numFailedPolls.Inc() -} - -func (p *polls) Successful() { - p.numSuccessfulPolls.Inc() -} diff --git a/snow/consensus/metrics/timestamp.go b/snow/consensus/metrics/timestamp.go deleted file mode 100644 index 0e784fa53454..000000000000 --- a/snow/consensus/metrics/timestamp.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package metrics - -import ( - "time" - - "github.com/prometheus/client_golang/prometheus" -) - -var _ Timestamp = (*timestamp)(nil) - -// Timestamp reports the last accepted block time, -// to track it in unix seconds. -type Timestamp interface { - Accepted(ts time.Time) -} - -type timestamp struct { - // lastAcceptedTimestamp keeps track of the last accepted timestamp - lastAcceptedTimestamp prometheus.Gauge -} - -func NewTimestamp(namespace string, reg prometheus.Registerer) (Timestamp, error) { - t := ×tamp{ - lastAcceptedTimestamp: prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "last_accepted_timestamp", - Help: "Last accepted block timestamp in unix seconds", - }), - } - return t, reg.Register(t.lastAcceptedTimestamp) -} - -func (t *timestamp) Accepted(ts time.Time) { - t.lastAcceptedTimestamp.Set(float64(ts.Unix())) -} diff --git a/snow/consensus/snowman/metrics.go b/snow/consensus/snowman/metrics.go new file mode 100644 index 000000000000..9dfac39880ab --- /dev/null +++ b/snow/consensus/snowman/metrics.go @@ -0,0 +1,261 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package snowman + +import ( + "time" + + "github.com/prometheus/client_golang/prometheus" + + "go.uber.org/zap" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/choices" + "github.com/ava-labs/avalanchego/utils/linkedhashmap" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/metric" + "github.com/ava-labs/avalanchego/utils/wrappers" +) + +type processingStart struct { + time time.Time + pollNumber uint64 +} + +type metrics struct { + log logging.Logger + + currentMaxVerifiedHeight uint64 + maxVerifiedHeight prometheus.Gauge + + lastAcceptedHeight prometheus.Gauge + lastAcceptedTimestamp prometheus.Gauge + + // processingBlocks keeps track of the [processingStart] that each block was + // issued into the consensus instance. This is used to calculate the amount + // of time to accept or reject the block. + processingBlocks linkedhashmap.LinkedHashmap[ids.ID, processingStart] + + // numProcessing keeps track of the number of processing blocks + numProcessing prometheus.Gauge + + // pollsAccepted tracks the number of polls that a block was in processing + // for before being accepted + pollsAccepted metric.Averager + // latAccepted tracks the number of nanoseconds that a block was processing + // before being accepted + latAccepted metric.Averager + blockSizeAcceptedSum prometheus.Gauge + + // pollsRejected tracks the number of polls that a block was in processing + // for before being rejected + pollsRejected metric.Averager + // latRejected tracks the number of nanoseconds that a block was processing + // before being rejected + latRejected metric.Averager + blockSizeRejectedSum prometheus.Gauge + + // numFailedPolls keeps track of the number of polls that failed + numFailedPolls prometheus.Counter + + // numSuccessfulPolls keeps track of the number of polls that succeeded + numSuccessfulPolls prometheus.Counter +} + +func newMetrics( + log logging.Logger, + namespace string, + reg prometheus.Registerer, + lastAcceptedHeight uint64, + lastAcceptedTime time.Time, +) (*metrics, error) { + errs := wrappers.Errs{} + m := &metrics{ + log: log, + currentMaxVerifiedHeight: lastAcceptedHeight, + maxVerifiedHeight: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "max_verified_height", + Help: "highest verified height", + }), + lastAcceptedHeight: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "last_accepted_height", + Help: "last height accepted", + }), + lastAcceptedTimestamp: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "last_accepted_timestamp", + Help: "timestamp of the last accepted block in unix seconds", + }), + + processingBlocks: linkedhashmap.New[ids.ID, processingStart](), + + // e.g., + // "avalanche_X_blks_processing" reports how many blocks are currently processing + numProcessing: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "blks_processing", + Help: "number of currently processing blocks", + }), + + pollsAccepted: metric.NewAveragerWithErrs( + namespace, + "blks_polls_accepted", + "number of polls from the issuance of a block to its acceptance", + reg, + &errs, + ), + // e.g., + // "avalanche_C_blks_accepted_count" reports how many times "Observe" has been called which is the total number of blocks accepted + // "avalanche_C_blks_accepted_sum" reports the cumulative sum of all block acceptance latencies in nanoseconds + // "avalanche_C_blks_accepted_sum / avalanche_C_blks_accepted_count" is the average block acceptance latency in nanoseconds + // "avalanche_C_blks_accepted_container_size_sum" reports the cumulative sum of all accepted blocks' sizes in bytes + // "avalanche_C_blks_accepted_container_size_sum / avalanche_C_blks_accepted_count" is the average accepted block size in bytes + latAccepted: metric.NewAveragerWithErrs( + namespace, + "blks_accepted", + "time (in ns) from the issuance of a block to its acceptance", + reg, + &errs, + ), + blockSizeAcceptedSum: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "blks_accepted_container_size_sum", + Help: "cumulative size of all accepted blocks", + }), + + pollsRejected: metric.NewAveragerWithErrs( + namespace, + "blks_polls_rejected", + "number of polls from the issuance of a block to its rejection", + reg, + &errs, + ), + // e.g., + // "avalanche_P_blks_rejected_count" reports how many times "Observe" has been called which is the total number of blocks rejected + // "avalanche_P_blks_rejected_sum" reports the cumulative sum of all block rejection latencies in nanoseconds + // "avalanche_P_blks_rejected_sum / avalanche_P_blks_rejected_count" is the average block rejection latency in nanoseconds + // "avalanche_P_blks_rejected_container_size_sum" reports the cumulative sum of all rejected blocks' sizes in bytes + // "avalanche_P_blks_rejected_container_size_sum / avalanche_P_blks_rejected_count" is the average rejected block size in bytes + latRejected: metric.NewAveragerWithErrs( + namespace, + "blks_rejected", + "time (in ns) from the issuance of a block to its rejection", + reg, + &errs, + ), + blockSizeRejectedSum: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "blks_rejected_container_size_sum", + Help: "cumulative size of all rejected blocks", + }), + + numSuccessfulPolls: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Name: "polls_successful", + Help: "number of successful polls", + }), + numFailedPolls: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Name: "polls_failed", + Help: "number of failed polls", + }), + } + + // Initially set the metrics for the last accepted block. + m.maxVerifiedHeight.Set(float64(lastAcceptedHeight)) + m.lastAcceptedHeight.Set(float64(lastAcceptedHeight)) + m.lastAcceptedTimestamp.Set(float64(lastAcceptedTime.Unix())) + + errs.Add( + reg.Register(m.maxVerifiedHeight), + reg.Register(m.lastAcceptedHeight), + reg.Register(m.lastAcceptedTimestamp), + reg.Register(m.numProcessing), + reg.Register(m.blockSizeAcceptedSum), + reg.Register(m.blockSizeRejectedSum), + reg.Register(m.numSuccessfulPolls), + reg.Register(m.numFailedPolls), + ) + return m, errs.Err +} + +func (m *metrics) Issued(blkID ids.ID, pollNumber uint64) { + m.processingBlocks.Put(blkID, processingStart{ + time: time.Now(), + pollNumber: pollNumber, + }) + m.numProcessing.Inc() +} + +func (m *metrics) Verified(height uint64) { + m.currentMaxVerifiedHeight = math.Max(m.currentMaxVerifiedHeight, height) + m.maxVerifiedHeight.Set(float64(m.currentMaxVerifiedHeight)) +} + +func (m *metrics) Accepted( + blkID ids.ID, + height uint64, + timestamp time.Time, + pollNumber uint64, + blockSize int, +) { + start, ok := m.processingBlocks.Get(blkID) + if !ok { + m.log.Error("unable to measure latency", + zap.Stringer("blkID", blkID), + zap.Stringer("status", choices.Accepted), + ) + return + } + m.lastAcceptedHeight.Set(float64(height)) + m.lastAcceptedTimestamp.Set(float64(timestamp.Unix())) + m.processingBlocks.Delete(blkID) + m.numProcessing.Dec() + + m.pollsAccepted.Observe(float64(pollNumber - start.pollNumber)) + + duration := time.Since(start.time) + m.latAccepted.Observe(float64(duration)) + + m.blockSizeAcceptedSum.Add(float64(blockSize)) +} + +func (m *metrics) Rejected(blkID ids.ID, pollNumber uint64, blockSize int) { + start, ok := m.processingBlocks.Get(blkID) + if !ok { + m.log.Error("unable to measure latency", + zap.Stringer("blkID", blkID), + zap.Stringer("status", choices.Rejected), + ) + return + } + m.processingBlocks.Delete(blkID) + m.numProcessing.Dec() + + m.pollsRejected.Observe(float64(pollNumber - start.pollNumber)) + + duration := time.Since(start.time) + m.latRejected.Observe(float64(duration)) + + m.blockSizeRejectedSum.Add(float64(blockSize)) +} + +func (m *metrics) MeasureAndGetOldestDuration() time.Duration { + _, oldestOp, exists := m.processingBlocks.Oldest() + if !exists { + return 0 + } + return time.Since(oldestOp.time) +} + +func (m *metrics) SuccessfulPoll() { + m.numSuccessfulPolls.Inc() +} + +func (m *metrics) FailedPoll() { + m.numFailedPolls.Inc() +} diff --git a/snow/consensus/snowman/topological.go b/snow/consensus/snowman/topological.go index a27a695b2d24..265724d75896 100644 --- a/snow/consensus/snowman/topological.go +++ b/snow/consensus/snowman/topological.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" - "github.com/ava-labs/avalanchego/snow/consensus/metrics" "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/utils/bag" "github.com/ava-labs/avalanchego/utils/set" @@ -41,10 +40,7 @@ func (TopologicalFactory) New() Consensus { // strongly preferred branch. This tree structure amortizes network polls to // vote on more than just the next block. type Topological struct { - metrics.Latency - metrics.Polls - metrics.Height - metrics.Timestamp + metrics *metrics // pollNumber is the number of times RecordPolls has been called pollNumber uint64 @@ -56,11 +52,8 @@ type Topological struct { // instances params snowball.Parameters - // head is the last accepted block - head ids.ID - - // height is the height of the last accepted block - height uint64 + lastAcceptedID ids.ID + lastAcceptedHeight uint64 // blocks stores the last accepted block and all the pending blocks blocks map[ids.ID]*snowmanBlock // blockID -> snowmanBlock @@ -72,8 +65,8 @@ type Topological struct { // that height. preferredHeights map[uint64]ids.ID // height -> blockID - // tail is the preferred block with no children - tail ids.ID + // preference is the preferred block with highest height + preference ids.ID // Used in [calculateInDegree] and. // Should only be accessed in that method. @@ -108,55 +101,37 @@ type votes struct { func (ts *Topological) Initialize( ctx *snow.ConsensusContext, params snowball.Parameters, - rootID ids.ID, - rootHeight uint64, - rootTime time.Time, + lastAcceptedID ids.ID, + lastAcceptedHeight uint64, + lastAcceptedTime time.Time, ) error { - if err := params.Verify(); err != nil { - return err - } - - latencyMetrics, err := metrics.NewLatency("blks", "block(s)", ctx.Log, "", ctx.Registerer) - if err != nil { - return err - } - ts.Latency = latencyMetrics - - pollsMetrics, err := metrics.NewPolls("", ctx.Registerer) + err := params.Verify() if err != nil { return err } - ts.Polls = pollsMetrics - heightMetrics, err := metrics.NewHeight("", ctx.Registerer) - if err != nil { - return err - } - ts.Height = heightMetrics - - timestampMetrics, err := metrics.NewTimestamp("", ctx.Registerer) + ts.metrics, err = newMetrics( + ctx.Log, + "", + ctx.Registerer, + lastAcceptedHeight, + lastAcceptedTime, + ) if err != nil { return err } - ts.Timestamp = timestampMetrics ts.leaves = set.Set[ids.ID]{} ts.kahnNodes = make(map[ids.ID]kahnNode) ts.ctx = ctx ts.params = params - ts.head = rootID - ts.height = rootHeight + ts.lastAcceptedID = lastAcceptedID + ts.lastAcceptedHeight = lastAcceptedHeight ts.blocks = map[ids.ID]*snowmanBlock{ - rootID: {params: ts.params}, + lastAcceptedID: {params: ts.params}, } ts.preferredHeights = make(map[uint64]ids.ID) - ts.tail = rootID - - // Initially set the metrics for the last accepted block. - ts.Height.Verified(ts.height) - ts.Height.Accepted(ts.height) - ts.Timestamp.Accepted(rootTime) - + ts.preference = lastAcceptedID return nil } @@ -181,8 +156,8 @@ func (ts *Topological) Add(ctx context.Context, blk Block) error { return errDuplicateAdd } - ts.Height.Verified(height) - ts.Latency.Issued(blkID, ts.pollNumber) + ts.metrics.Verified(height) + ts.metrics.Issued(blkID, ts.pollNumber) parentID := blk.Parent() parentNode, ok := ts.blocks[parentID] @@ -199,7 +174,7 @@ func (ts *Topological) Add(ctx context.Context, blk Block) error { if err := blk.Reject(ctx); err != nil { return err } - ts.Latency.Rejected(blkID, ts.pollNumber, len(blk.Bytes())) + ts.metrics.Rejected(blkID, ts.pollNumber, len(blk.Bytes())) return nil } @@ -210,9 +185,9 @@ func (ts *Topological) Add(ctx context.Context, blk Block) error { blk: blk, } - // If we are extending the tail, this is the new tail - if ts.tail == parentID { - ts.tail = blkID + // If we are extending the preference, this is the new preference + if ts.preference == parentID { + ts.preference = blkID ts.preferredIDs.Add(blkID) ts.preferredHeights[height] = blkID } @@ -232,17 +207,17 @@ func (ts *Topological) Decided(blk Block) bool { } // If the block is marked as fetched, we can check if it has been // transitively rejected. - return blk.Status() == choices.Processing && blk.Height() <= ts.height + return blk.Status() == choices.Processing && blk.Height() <= ts.lastAcceptedHeight } func (ts *Topological) Processing(blkID ids.ID) bool { // The last accepted block is in the blocks map, so we first must ensure the // requested block isn't the last accepted block. - if blkID == ts.head { + if blkID == ts.lastAcceptedID { return false } - // If the block is in the map of current blocks and not the head, then the - // block is currently processing. + // If the block is in the map of current blocks and not the last accepted + // block, then it is currently processing. _, ok := ts.blocks[blkID] return ok } @@ -256,16 +231,16 @@ func (ts *Topological) IsPreferred(blk Block) bool { } func (ts *Topological) LastAccepted() (ids.ID, uint64) { - return ts.head, ts.height + return ts.lastAcceptedID, ts.lastAcceptedHeight } func (ts *Topological) Preference() ids.ID { - return ts.tail + return ts.preference } func (ts *Topological) PreferenceAtHeight(height uint64) (ids.ID, bool) { - if height == ts.height { - return ts.head, true + if height == ts.lastAcceptedHeight { + return ts.lastAcceptedID, true } blkID, ok := ts.preferredHeights[height] return blkID, ok @@ -279,8 +254,8 @@ func (ts *Topological) PreferenceAtHeight(height uint64) (ids.ID, bool) { // Every other block will have an unsuccessful poll registered. // // After collecting which blocks should be voted on, the polls are registered -// and blocks are accepted/rejected as needed. The tail is then updated to equal -// the leaf on the preferred branch. +// and blocks are accepted/rejected as needed. The preference is then updated to +// equal the leaf on the preferred branch. // // To optimize the theoretical complexity of the vote propagation, a topological // sort is done over the blocks that are reachable from the provided votes. @@ -318,11 +293,11 @@ func (ts *Topological) RecordPoll(ctx context.Context, voteBag bag.Bag[ids.ID]) } // If the set of preferred IDs already contains the preference, then the - // tail is guaranteed to already be set correctly. This is because the value - // returned from vote reports the next preferred block after the last + // preference is guaranteed to already be set correctly. This is because the + // value returned from vote reports the next preferred block after the last // preferred block that was voted for. If this block was previously // preferred, then we know that following the preferences down the chain - // will return the current tail. + // will return the current preference. if ts.preferredIDs.Contains(preferred) { return nil } @@ -331,8 +306,8 @@ func (ts *Topological) RecordPoll(ctx context.Context, voteBag bag.Bag[ids.ID]) ts.preferredIDs.Clear() maps.Clear(ts.preferredHeights) - ts.tail = preferred - startBlock := ts.blocks[ts.tail] + ts.preference = preferred + startBlock := ts.blocks[ts.preference] // Runtime = |live set| ; Space = Constant // Traverse from the preferred ID to the last accepted ancestor. @@ -345,20 +320,20 @@ func (ts *Topological) RecordPoll(ctx context.Context, voteBag bag.Bag[ids.ID]) // Traverse from the preferred ID to the preferred child until there are no // children. for block := startBlock; block.sb != nil; { - ts.tail = block.sb.Preference() - ts.preferredIDs.Add(ts.tail) - block = ts.blocks[ts.tail] + ts.preference = block.sb.Preference() + ts.preferredIDs.Add(ts.preference) + block = ts.blocks[ts.preference] // Invariant: Because the prior block had an initialized snowball // instance, it must have a processing child. This guarantees that // block.blk is non-nil here. - ts.preferredHeights[block.blk.Height()] = ts.tail + ts.preferredHeights[block.blk.Height()] = ts.preference } return nil } // HealthCheck returns information about the consensus health. func (ts *Topological) HealthCheck(context.Context) (interface{}, error) { - numOutstandingBlks := ts.Latency.NumProcessing() + numOutstandingBlks := ts.NumProcessing() isOutstandingBlks := numOutstandingBlks <= ts.params.MaxOutstandingItems healthy := isOutstandingBlks details := map[string]interface{}{ @@ -366,7 +341,7 @@ func (ts *Topological) HealthCheck(context.Context) (interface{}, error) { } // check for long running blocks - timeReqRunning := ts.Latency.MeasureAndGetOldestDuration() + timeReqRunning := ts.metrics.MeasureAndGetOldestDuration() isProcessingTime := timeReqRunning <= ts.params.MaxItemProcessingTime healthy = healthy && isProcessingTime details["longestRunningBlock"] = timeReqRunning.String() @@ -501,20 +476,20 @@ func (ts *Topological) vote(ctx context.Context, voteStack []votes) (ids.ID, err // If the voteStack is empty, then the full tree should falter. This won't // change the preferred branch. if len(voteStack) == 0 { - headBlock := ts.blocks[ts.head] - headBlock.shouldFalter = true + lastAcceptedBlock := ts.blocks[ts.lastAcceptedID] + lastAcceptedBlock.shouldFalter = true if numProcessing := len(ts.blocks) - 1; numProcessing > 0 { ts.ctx.Log.Verbo("no progress was made after processing pending blocks", zap.Int("numProcessing", numProcessing), ) - ts.Polls.Failed() + ts.metrics.FailedPoll() } - return ts.tail, nil + return ts.preference, nil } // keep track of the new preferred block - newPreferred := ts.head + newPreferred := ts.lastAcceptedID onPreferredBranch := true pollSuccessful := false for len(voteStack) > 0 { @@ -550,8 +525,9 @@ func (ts *Topological) vote(ctx context.Context, voteStack []votes) (ids.ID, err // apply the votes for this snowball instance pollSuccessful = parentBlock.sb.RecordPoll(vote.votes) || pollSuccessful - // Only accept when you are finalized and the head. - if parentBlock.sb.Finalized() && ts.head == vote.parentID { + // Only accept when you are finalized and a child of the last accepted + // block. + if parentBlock.sb.Finalized() && ts.lastAcceptedID == vote.parentID { if err := ts.acceptPreferredChild(ctx, parentBlock); err != nil { return ids.ID{}, err } @@ -613,9 +589,9 @@ func (ts *Topological) vote(ctx context.Context, voteStack []votes) (ids.ID, err } if pollSuccessful { - ts.Polls.Successful() + ts.metrics.SuccessfulPoll() } else { - ts.Polls.Failed() + ts.metrics.FailedPoll() } return newPreferred, nil } @@ -649,17 +625,21 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock return err } - // Because this is the newest accepted block, this is the new head. - ts.head = pref - ts.height = height + // Update the last accepted values to the newly accepted block. + ts.lastAcceptedID = pref + ts.lastAcceptedHeight = height // Remove the decided block from the set of processing IDs, as its status // now implies its preferredness. ts.preferredIDs.Remove(pref) delete(ts.preferredHeights, height) - ts.Latency.Accepted(pref, ts.pollNumber, len(bytes)) - ts.Height.Accepted(height) - ts.Timestamp.Accepted(child.Timestamp()) + ts.metrics.Accepted( + pref, + height, + child.Timestamp(), + ts.pollNumber, + len(bytes), + ) // Because ts.blocks contains the last accepted block, we don't delete the // block from the blocks map here. @@ -680,7 +660,7 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock if err := child.Reject(ctx); err != nil { return err } - ts.Latency.Rejected(childID, ts.pollNumber, len(child.Bytes())) + ts.metrics.Rejected(childID, ts.pollNumber, len(child.Bytes())) // Track which blocks have been directly rejected rejects = append(rejects, childID) @@ -714,7 +694,7 @@ func (ts *Topological) rejectTransitively(ctx context.Context, rejected []ids.ID if err := child.Reject(ctx); err != nil { return err } - ts.Latency.Rejected(childID, ts.pollNumber, len(child.Bytes())) + ts.metrics.Rejected(childID, ts.pollNumber, len(child.Bytes())) // add the newly rejected block to the end of the stack rejected = append(rejected, childID) From f7cc69b480a25ac92c41920df007374bb584c8b7 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 21 Nov 2023 17:13:17 -0500 Subject: [PATCH 059/267] Expand consensus health check (#2354) --- snow/consensus/snowman/topological.go | 51 +++++++++++++++------------ 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/snow/consensus/snowman/topological.go b/snow/consensus/snowman/topological.go index 265724d75896..bc68762c894e 100644 --- a/snow/consensus/snowman/topological.go +++ b/snow/consensus/snowman/topological.go @@ -7,7 +7,6 @@ import ( "context" "errors" "fmt" - "strings" "time" "go.uber.org/zap" @@ -23,7 +22,9 @@ import ( ) var ( - errDuplicateAdd = errors.New("duplicate block add") + errDuplicateAdd = errors.New("duplicate block add") + errTooManyProcessingBlocks = errors.New("too many processing blocks") + errBlockProcessingTooLong = errors.New("block processing too long") _ Factory = (*TopologicalFactory)(nil) _ Consensus = (*Topological)(nil) @@ -333,30 +334,34 @@ func (ts *Topological) RecordPoll(ctx context.Context, voteBag bag.Bag[ids.ID]) // HealthCheck returns information about the consensus health. func (ts *Topological) HealthCheck(context.Context) (interface{}, error) { - numOutstandingBlks := ts.NumProcessing() - isOutstandingBlks := numOutstandingBlks <= ts.params.MaxOutstandingItems - healthy := isOutstandingBlks - details := map[string]interface{}{ - "outstandingBlocks": numOutstandingBlks, + var errs []error + + numProcessingBlks := ts.NumProcessing() + if numProcessingBlks > ts.params.MaxOutstandingItems { + err := fmt.Errorf("%w: %d > %d", + errTooManyProcessingBlocks, + numProcessingBlks, + ts.params.MaxOutstandingItems, + ) + errs = append(errs, err) } - // check for long running blocks - timeReqRunning := ts.metrics.MeasureAndGetOldestDuration() - isProcessingTime := timeReqRunning <= ts.params.MaxItemProcessingTime - healthy = healthy && isProcessingTime - details["longestRunningBlock"] = timeReqRunning.String() - - if !healthy { - var errorReasons []string - if !isOutstandingBlks { - errorReasons = append(errorReasons, fmt.Sprintf("number of outstanding blocks %d > %d", numOutstandingBlks, ts.params.MaxOutstandingItems)) - } - if !isProcessingTime { - errorReasons = append(errorReasons, fmt.Sprintf("block processing time %s > %s", timeReqRunning, ts.params.MaxItemProcessingTime)) - } - return details, fmt.Errorf("snowman consensus is not healthy reason: %s", strings.Join(errorReasons, ", ")) + maxTimeProcessing := ts.metrics.MeasureAndGetOldestDuration() + if maxTimeProcessing > ts.params.MaxItemProcessingTime { + err := fmt.Errorf("%w: %s > %s", + errBlockProcessingTooLong, + maxTimeProcessing, + ts.params.MaxItemProcessingTime, + ) + errs = append(errs, err) } - return details, nil + + return map[string]interface{}{ + "processingBlocks": numProcessingBlks, + "longestProcessingBlock": maxTimeProcessing.String(), // .String() is needed here to ensure a human readable format + "lastAcceptedID": ts.lastAcceptedID, + "lastAcceptedHeight": ts.lastAcceptedHeight, + }, errors.Join(errs...) } // takes in a list of votes and sets up the topological ordering. Returns the From 459f8ba7095cc7a3e8b95a27456fafbe84bf72cd Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 21 Nov 2023 19:24:02 -0500 Subject: [PATCH 060/267] Reduce the size of the OracleBlock interface (#2355) --- snow/consensus/snowman/oracle_block.go | 2 -- vms/platformvm/vm_test.go | 9 ++++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/snow/consensus/snowman/oracle_block.go b/snow/consensus/snowman/oracle_block.go index 0d8bd2be94dc..0ead79d03d22 100644 --- a/snow/consensus/snowman/oracle_block.go +++ b/snow/consensus/snowman/oracle_block.go @@ -16,8 +16,6 @@ var ErrNotOracle = errors.New("block isn't an oracle") // This ordering does not need to be deterministically created from the chain // state. type OracleBlock interface { - Block - // Options returns the possible children of this block in the order this // validator prefers the blocks. // Options is guaranteed to only be called on a verified block. diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 454aff29fe6d..9f286415c6e5 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -729,8 +729,7 @@ func TestRewardValidatorAccept(t *testing.T) { require.NoError(blk.Verify(context.Background())) // Assert preferences are correct - oracleBlk := blk.(smcon.OracleBlock) - options, err := oracleBlk.Options(context.Background()) + options, err := blk.(smcon.OracleBlock).Options(context.Background()) require.NoError(err) commit := options[0].(*blockexecutor.Block) @@ -739,13 +738,13 @@ func TestRewardValidatorAccept(t *testing.T) { require.IsType(&block.BanffAbortBlock{}, abort.Block) // Assert block tries to reward a genesis validator - rewardTx := oracleBlk.(block.Block).Txs()[0].Unsigned + rewardTx := blk.(block.Block).Txs()[0].Unsigned require.IsType(&txs.RewardValidatorTx{}, rewardTx) // Verify options and accept commmit block require.NoError(commit.Verify(context.Background())) require.NoError(abort.Verify(context.Background())) - txID := oracleBlk.(block.Block).Txs()[0].ID() + txID := blk.(block.Block).Txs()[0].ID() { onAbort, ok := vm.manager.GetState(abort.ID()) require.True(ok) @@ -755,7 +754,7 @@ func TestRewardValidatorAccept(t *testing.T) { require.Equal(status.Aborted, txStatus) } - require.NoError(oracleBlk.Accept(context.Background())) + require.NoError(blk.Accept(context.Background())) require.NoError(commit.Accept(context.Background())) // Verify that chain's timestamp has advanced From f2f6d0a7fbe28b46b53f01360c04f8836c8ab141 Mon Sep 17 00:00:00 2001 From: Patrick O'Grady Date: Tue, 21 Nov 2023 22:07:24 -0600 Subject: [PATCH 061/267] [vms/proposervm] Update Build Heuristic (#2348) Co-authored-by: Alberto Benegiamo --- vms/proposervm/batched_vm_test.go | 20 +- vms/proposervm/block.go | 10 +- vms/proposervm/block_test.go | 266 ++++++++++++++++++++++- vms/proposervm/post_fork_block_test.go | 28 +-- vms/proposervm/post_fork_option_test.go | 2 +- vms/proposervm/pre_fork_block_test.go | 4 +- vms/proposervm/proposer/mock_windower.go | 16 +- vms/proposervm/proposer/windower.go | 20 +- vms/proposervm/proposer/windower_test.go | 24 +- vms/proposervm/vm.go | 6 +- vms/proposervm/vm_byzantine_test.go | 8 +- vms/proposervm/vm_test.go | 16 +- 12 files changed, 345 insertions(+), 75 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 326272275dac..684d91ceb3df 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -225,7 +225,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk1.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk1.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxDelay)) + proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) coreBlk2 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -235,7 +235,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { BytesV: []byte{2}, ParentV: coreBlk1.ID(), HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreBlk1.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -246,7 +246,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk2.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk2.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxDelay)) + proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) coreBlk3 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -431,7 +431,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { BytesV: []byte{3}, ParentV: coreBlk2.ID(), HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime.Add(proposer.MaxDelay), + TimestampV: postForkTime.Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -443,7 +443,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { // prepare build of next block require.NoError(builtBlk3.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk3.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxDelay)) + proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) coreBlk4 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -704,7 +704,7 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk1.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk1.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxDelay)) + proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) coreBlk2 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -714,7 +714,7 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { BytesV: []byte{2}, ParentV: coreBlk1.ID(), HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreBlk1.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -725,7 +725,7 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk2.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk2.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxDelay)) + proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) coreBlk3 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -867,7 +867,7 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { BytesV: []byte{3}, ParentV: coreBlk2.ID(), HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime.Add(proposer.MaxDelay), + TimestampV: postForkTime.Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -879,7 +879,7 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { // prepare build of next block require.NoError(builtBlk3.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk3.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxDelay)) + proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) coreBlk4 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index f07362708611..489d325f8f70 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -144,7 +144,7 @@ func (p *postForkCommonComponents) Verify( childHeight := child.Height() proposerID := child.Proposer() - minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID) + minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) if err != nil { return err } @@ -155,7 +155,7 @@ func (p *postForkCommonComponents) Verify( } // Verify the signature of the node - shouldHaveProposer := delay < proposer.MaxDelay + shouldHaveProposer := delay < proposer.MaxVerifyDelay if err := child.SignedBlock.Verify(shouldHaveProposer, p.vm.ctx.ChainID); err != nil { return err } @@ -203,10 +203,10 @@ func (p *postForkCommonComponents) buildChild( } delay := newTimestamp.Sub(parentTimestamp) - if delay < proposer.MaxDelay { + if delay < proposer.MaxBuildDelay { parentHeight := p.innerBlk.Height() proposerID := p.vm.ctx.NodeID - minDelay, err := p.vm.Windower.Delay(ctx, parentHeight+1, parentPChainHeight, proposerID) + minDelay, err := p.vm.Windower.Delay(ctx, parentHeight+1, parentPChainHeight, proposerID, proposer.MaxBuildWindows) if err != nil { p.vm.ctx.Log.Error("unexpected build block failure", zap.String("reason", "failed to calculate required timestamp delay"), @@ -249,7 +249,7 @@ func (p *postForkCommonComponents) buildChild( // Build the child var statelessChild block.SignedBlock - if delay >= proposer.MaxDelay { + if delay >= proposer.MaxVerifyDelay { statelessChild, err = block.BuildUnsigned( parentID, newTimestamp, diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 90c99a22dd21..04ac66ecf34e 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -4,6 +4,7 @@ package proposervm import ( + "bytes" "context" "crypto/ecdsa" "crypto/elliptic" @@ -17,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" @@ -53,7 +55,7 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { vdrState := validators.NewMockState(ctrl) vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() windower := proposer.NewMockWindower(ctrl) - windower.EXPECT().Delay(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(time.Duration(0), nil).AnyTimes() + windower.EXPECT().Delay(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(time.Duration(0), nil).AnyTimes() pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) @@ -84,3 +86,265 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require.NoError(err) require.Equal(builtBlk, gotChild.(*postForkBlock).innerBlk) } + +func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { + require := require.New(t) + ctx := context.Background() + + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + defer func() { + require.NoError(proVM.Shutdown(ctx)) + }() + + // Build a post fork block. It'll be the parent block in our test cases + parentTime := time.Now().Truncate(time.Second) + proVM.Set(parentTime) + + coreParentBlk := &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: ids.GenerateTestID(), + StatusV: choices.Processing, + }, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + } + coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { + return coreParentBlk, nil + } + coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { + switch { + case blkID == coreParentBlk.ID(): + return coreParentBlk, nil + case blkID == coreGenBlk.ID(): + return coreGenBlk, nil + default: + return nil, errUnknownBlock + } + } + coreVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { // needed when setting preference + switch { + case bytes.Equal(b, coreParentBlk.Bytes()): + return coreParentBlk, nil + case bytes.Equal(b, coreGenBlk.Bytes()): + return coreGenBlk, nil + default: + return nil, errUnknownBlock + } + } + + parentBlk, err := proVM.BuildBlock(ctx) + require.NoError(err) + require.NoError(parentBlk.Verify(ctx)) + require.NoError(parentBlk.Accept(ctx)) + + // Make sure preference is duly set + require.NoError(proVM.SetPreference(ctx, parentBlk.ID())) + require.Equal(proVM.preferred, parentBlk.ID()) + _, err = proVM.getPostForkBlock(ctx, parentBlk.ID()) + require.NoError(err) + + // Force this node to be the only validator, so to guarantee + // it'd be picked if block build time was before MaxVerifyDelay + valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + // a validator with a weight large enough to fully fill the proposers list + weight := uint64(proposer.MaxBuildWindows * 2) + + return map[ids.NodeID]*validators.GetValidatorOutput{ + proVM.ctx.NodeID: { + NodeID: proVM.ctx.NodeID, + Weight: weight, + }, + }, nil + } + + coreChildBlk := &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: ids.GenerateTestID(), + StatusV: choices.Processing, + }, + BytesV: []byte{2}, + ParentV: coreParentBlk.ID(), + HeightV: coreParentBlk.Height() + 1, + } + coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { + return coreChildBlk, nil + } + + { + // Set local clock before MaxVerifyDelay from parent timestamp. + // Check that child block is signed. + localTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay - time.Second) + proVM.Set(localTime) + + childBlk, err := proVM.BuildBlock(ctx) + require.NoError(err) + require.IsType(&postForkBlock{}, childBlk) + require.Equal(proVM.ctx.NodeID, childBlk.(*postForkBlock).Proposer()) // signed block + } + + { + // Set local clock exactly MaxVerifyDelay from parent timestamp. + // Check that child block is unsigned. + localTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) + proVM.Set(localTime) + + childBlk, err := proVM.BuildBlock(ctx) + require.NoError(err) + require.IsType(&postForkBlock{}, childBlk) + require.Equal(ids.EmptyNodeID, childBlk.(*postForkBlock).Proposer()) // signed block + } + + { + // Set local clock among MaxVerifyDelay and MaxBuildDelay from parent timestamp + // Check that child block is unsigned + localTime := parentBlk.Timestamp().Add((proposer.MaxVerifyDelay + proposer.MaxBuildDelay) / 2) + proVM.Set(localTime) + + childBlk, err := proVM.BuildBlock(ctx) + require.NoError(err) + require.IsType(&postForkBlock{}, childBlk) + require.Equal(ids.EmptyNodeID, childBlk.(*postForkBlock).Proposer()) // unsigned so no proposer + } + + { + // Set local clock after MaxBuildDelay from parent timestamp + // Check that child block is unsigned + localTime := parentBlk.Timestamp().Add(proposer.MaxBuildDelay) + proVM.Set(localTime) + + childBlk, err := proVM.BuildBlock(ctx) + require.NoError(err) + require.IsType(&postForkBlock{}, childBlk) + require.Equal(ids.EmptyNodeID, childBlk.(*postForkBlock).Proposer()) // unsigned so no proposer + } +} + +func TestNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { + require := require.New(t) + ctx := context.Background() + + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + defer func() { + require.NoError(proVM.Shutdown(ctx)) + }() + + // Build a post fork block. It'll be the parent block in our test cases + parentTime := time.Now().Truncate(time.Second) + proVM.Set(parentTime) + + coreParentBlk := &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: ids.GenerateTestID(), + StatusV: choices.Processing, + }, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + } + coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { + return coreParentBlk, nil + } + coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { + switch { + case blkID == coreParentBlk.ID(): + return coreParentBlk, nil + case blkID == coreGenBlk.ID(): + return coreGenBlk, nil + default: + return nil, errUnknownBlock + } + } + coreVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { // needed when setting preference + switch { + case bytes.Equal(b, coreParentBlk.Bytes()): + return coreParentBlk, nil + case bytes.Equal(b, coreGenBlk.Bytes()): + return coreGenBlk, nil + default: + return nil, errUnknownBlock + } + } + + parentBlk, err := proVM.BuildBlock(ctx) + require.NoError(err) + require.NoError(parentBlk.Verify(ctx)) + require.NoError(parentBlk.Accept(ctx)) + + // Make sure preference is duly set + require.NoError(proVM.SetPreference(ctx, parentBlk.ID())) + require.Equal(proVM.preferred, parentBlk.ID()) + _, err = proVM.getPostForkBlock(ctx, parentBlk.ID()) + require.NoError(err) + + // Mark node as non validator + valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + var ( + aValidator = ids.GenerateTestNodeID() + + // a validator with a weight large enough to fully fill the proposers list + weight = uint64(proposer.MaxBuildWindows * 2) + ) + return map[ids.NodeID]*validators.GetValidatorOutput{ + aValidator: { + NodeID: aValidator, + Weight: weight, + }, + }, nil + } + + coreChildBlk := &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: ids.GenerateTestID(), + StatusV: choices.Processing, + }, + BytesV: []byte{2}, + ParentV: coreParentBlk.ID(), + HeightV: coreParentBlk.Height() + 1, + } + coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { + return coreChildBlk, nil + } + + { + // Set local clock before MaxVerifyDelay from parent timestamp. + // Check that child block is not built. + localTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay - time.Second) + proVM.Set(localTime) + + _, err := proVM.BuildBlock(ctx) + require.ErrorIs(errProposerWindowNotStarted, err) + } + + { + // Set local clock exactly MaxVerifyDelay from parent timestamp. + // Check that child block is not built. + localTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) + proVM.Set(localTime) + + _, err := proVM.BuildBlock(ctx) + require.ErrorIs(errProposerWindowNotStarted, err) + } + + { + // Set local clock among MaxVerifyDelay and MaxBuildDelay from parent timestamp + // Check that child block is not built. + localTime := parentBlk.Timestamp().Add((proposer.MaxVerifyDelay + proposer.MaxBuildDelay) / 2) + proVM.Set(localTime) + + _, err := proVM.BuildBlock(ctx) + require.ErrorIs(errProposerWindowNotStarted, err) + } + + { + // Set local clock after MaxBuildDelay from parent timestamp + // Check that child block is built and it is unsigned + localTime := parentBlk.Timestamp().Add(proposer.MaxBuildDelay) + proVM.Set(localTime) + + childBlk, err := proVM.BuildBlock(ctx) + require.NoError(err) + require.IsType(&postForkBlock{}, childBlk) + require.Equal(ids.EmptyNodeID, childBlk.(*postForkBlock).Proposer()) // unsigned so no proposer + } +} diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index b2b36073335d..659bdd1e5fd3 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -138,7 +138,7 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { } } - proVM.Set(proVM.Time().Add(proposer.MaxDelay)) + proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) prntProBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -177,7 +177,7 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { // child block referring known parent does verify childSlb, err = block.BuildUnsigned( prntProBlk.ID(), // refer known parent - prntProBlk.Timestamp().Add(proposer.MaxDelay), + prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay), pChainHeight, childCoreBlk.Bytes(), ) @@ -185,7 +185,7 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { childProBlk.SignedBlock = childSlb require.NoError(err) - proVM.Set(proVM.Time().Add(proposer.MaxDelay)) + proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) require.NoError(childProBlk.Verify(context.Background())) } @@ -210,7 +210,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { }, BytesV: []byte{1}, ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return prntCoreBlk, nil @@ -279,7 +279,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require.ErrorIs(err, errTimeNotMonotonic) // block cannot arrive before its creator window starts - blkWinDelay, err := proVM.Delay(context.Background(), childCoreBlk.Height(), pChainHeight, proVM.ctx.NodeID) + blkWinDelay, err := proVM.Delay(context.Background(), childCoreBlk.Height(), pChainHeight, proVM.ctx.NodeID, proposer.MaxVerifyWindows) require.NoError(err) beforeWinStart := prntTimestamp.Add(blkWinDelay).Add(-1 * time.Second) proVM.Clock.Set(beforeWinStart) @@ -332,7 +332,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require.NoError(childProBlk.Verify(context.Background())) // block can arrive within submission window - atSubWindowEnd := proVM.Time().Add(proposer.MaxDelay) + atSubWindowEnd := proVM.Time().Add(proposer.MaxVerifyDelay) proVM.Clock.Set(atSubWindowEnd) childSlb, err = block.BuildUnsigned( prntProBlk.ID(), @@ -382,7 +382,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { }, BytesV: []byte{1}, ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return prntCoreBlk, nil @@ -423,7 +423,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { }, ParentV: prntCoreBlk.ID(), BytesV: []byte{2}, - TimestampV: prntProBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay), } // child P-Chain height must not precede parent P-Chain height @@ -522,7 +522,7 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) }, BytesV: []byte{1}, ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -603,7 +603,7 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) }, ParentV: oracleCoreBlk.opts[0].ID(), BytesV: []byte{2}, - TimestampV: parentBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: parentBlk.Timestamp().Add(proposer.MaxVerifyDelay), } // child P-Chain height must not precede parent P-Chain height @@ -701,7 +701,7 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { }, BytesV: []byte{1}, ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -764,7 +764,7 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { }, BytesV: []byte{1}, ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -829,7 +829,7 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t BytesV: []byte{1}, ParentV: coreGenBlk.ID(), HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -871,7 +871,7 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { BytesV: []byte{1}, ParentV: coreGenBlk.ID(), HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 09fe29730b6f..8e93e2aad05f 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -135,7 +135,7 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { }, ParentV: oracleCoreBlk.opts[0].ID(), BytesV: []byte{4}, - TimestampV: oracleCoreBlk.opts[0].Timestamp().Add(proposer.MaxDelay), + TimestampV: oracleCoreBlk.opts[0].Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return childCoreBlk, nil diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 3a28a9568b5c..1366482a0d9b 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -275,7 +275,7 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { } } - proVM.Set(proVM.Time().Add(proposer.MaxDelay)) + proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) prntProBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -286,7 +286,7 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { StatusV: choices.Processing, }, BytesV: []byte{2}, - TimestampV: prntCoreBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: prntCoreBlk.Timestamp().Add(proposer.MaxVerifyDelay), } childProBlk := preForkBlock{ Block: childCoreBlk, diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index bfa83998995c..3e7375326429 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -40,31 +40,31 @@ func (m *MockWindower) EXPECT() *MockWindowerMockRecorder { } // Delay mocks base method. -func (m *MockWindower) Delay(arg0 context.Context, arg1, arg2 uint64, arg3 ids.NodeID) (time.Duration, error) { +func (m *MockWindower) Delay(arg0 context.Context, arg1, arg2 uint64, arg3 ids.NodeID, arg4 int) (time.Duration, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delay", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "Delay", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(time.Duration) ret1, _ := ret[1].(error) return ret0, ret1 } // Delay indicates an expected call of Delay. -func (mr *MockWindowerMockRecorder) Delay(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockWindowerMockRecorder) Delay(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delay", reflect.TypeOf((*MockWindower)(nil).Delay), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delay", reflect.TypeOf((*MockWindower)(nil).Delay), arg0, arg1, arg2, arg3, arg4) } // Proposers mocks base method. -func (m *MockWindower) Proposers(arg0 context.Context, arg1, arg2 uint64) ([]ids.NodeID, error) { +func (m *MockWindower) Proposers(arg0 context.Context, arg1, arg2 uint64, arg3 int) ([]ids.NodeID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Proposers", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "Proposers", arg0, arg1, arg2, arg3) ret0, _ := ret[0].([]ids.NodeID) ret1, _ := ret[1].(error) return ret0, ret1 } // Proposers indicates an expected call of Proposers. -func (mr *MockWindowerMockRecorder) Proposers(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockWindowerMockRecorder) Proposers(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Proposers", reflect.TypeOf((*MockWindower)(nil).Proposers), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Proposers", reflect.TypeOf((*MockWindower)(nil).Proposers), arg0, arg1, arg2, arg3) } diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 4f67b27903ea..8cb7bc43b24d 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -17,9 +17,13 @@ import ( // Proposer list constants const ( - MaxWindows = 6 WindowDuration = 5 * time.Second - MaxDelay = MaxWindows * WindowDuration + + MaxVerifyWindows = 6 + MaxVerifyDelay = MaxVerifyWindows * WindowDuration // 30 seconds + + MaxBuildWindows = 60 + MaxBuildDelay = MaxBuildWindows * WindowDuration // 5 minutes ) var _ Windower = (*windower)(nil) @@ -33,6 +37,7 @@ type Windower interface { ctx context.Context, chainHeight, pChainHeight uint64, + maxWindows int, ) ([]ids.NodeID, error) // Delay returns the amount of time that [validatorID] must wait before // building a block at [chainHeight] when the validator set is defined at @@ -42,6 +47,7 @@ type Windower interface { chainHeight, pChainHeight uint64, validatorID ids.NodeID, + maxWindows int, ) (time.Duration, error) } @@ -64,7 +70,7 @@ func New(state validators.State, subnetID, chainID ids.ID) Windower { } } -func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint64) ([]ids.NodeID, error) { +func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { // get the validator set by the p-chain height validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) if err != nil { @@ -101,7 +107,7 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint return nil, err } - numToSample := MaxWindows + numToSample := maxWindows if weight < uint64(numToSample) { numToSample = int(weight) } @@ -121,12 +127,12 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint return nodeIDs, nil } -func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, validatorID ids.NodeID) (time.Duration, error) { +func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int) (time.Duration, error) { if validatorID == ids.EmptyNodeID { - return MaxDelay, nil + return time.Duration(maxWindows) * WindowDuration, nil } - proposers, err := w.Proposers(ctx, chainHeight, pChainHeight) + proposers, err := w.Proposers(ctx, chainHeight, pChainHeight, maxWindows) if err != nil { return 0, err } diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 961398c78867..2a141a361ea2 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -30,7 +30,7 @@ func TestWindowerNoValidators(t *testing.T) { w := New(vdrState, subnetID, chainID) - delay, err := w.Delay(context.Background(), 1, 0, nodeID) + delay, err := w.Delay(context.Background(), 1, 0, nodeID, MaxVerifyWindows) require.NoError(err) require.Zero(delay) } @@ -56,13 +56,13 @@ func TestWindowerRepeatedValidator(t *testing.T) { w := New(vdrState, subnetID, chainID) - validatorDelay, err := w.Delay(context.Background(), 1, 0, validatorID) + validatorDelay, err := w.Delay(context.Background(), 1, 0, validatorID, MaxVerifyWindows) require.NoError(err) require.Zero(validatorDelay) - nonValidatorDelay, err := w.Delay(context.Background(), 1, 0, nonValidatorID) + nonValidatorDelay, err := w.Delay(context.Background(), 1, 0, nonValidatorID, MaxVerifyWindows) require.NoError(err) - require.Equal(MaxDelay, nonValidatorDelay) + require.Equal(MaxVerifyDelay, nonValidatorDelay) } func TestWindowerChangeByHeight(t *testing.T) { @@ -70,14 +70,14 @@ func TestWindowerChangeByHeight(t *testing.T) { subnetID := ids.ID{0, 1} chainID := ids.ID{0, 2} - validatorIDs := make([]ids.NodeID, MaxWindows) + validatorIDs := make([]ids.NodeID, MaxVerifyWindows) for i := range validatorIDs { validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) } vdrState := &validators.TestState{ T: t, GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxWindows) + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) for _, id := range validatorIDs { vdrs[id] = &validators.GetValidatorOutput{ NodeID: id, @@ -100,7 +100,7 @@ func TestWindowerChangeByHeight(t *testing.T) { } for i, expectedDelay := range expectedDelays1 { vdrID := validatorIDs[i] - validatorDelay, err := w.Delay(context.Background(), 1, 0, vdrID) + validatorDelay, err := w.Delay(context.Background(), 1, 0, vdrID, MaxVerifyWindows) require.NoError(err) require.Equal(expectedDelay, validatorDelay) } @@ -115,7 +115,7 @@ func TestWindowerChangeByHeight(t *testing.T) { } for i, expectedDelay := range expectedDelays2 { vdrID := validatorIDs[i] - validatorDelay, err := w.Delay(context.Background(), 2, 0, vdrID) + validatorDelay, err := w.Delay(context.Background(), 2, 0, vdrID, MaxVerifyWindows) require.NoError(err) require.Equal(expectedDelay, validatorDelay) } @@ -132,14 +132,14 @@ func TestWindowerChangeByChain(t *testing.T) { chainID1 := ids.ID{} _, _ = rand.Read(chainID1[:]) // #nosec G404 - validatorIDs := make([]ids.NodeID, MaxWindows) + validatorIDs := make([]ids.NodeID, MaxVerifyWindows) for i := range validatorIDs { validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) } vdrState := &validators.TestState{ T: t, GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxWindows) + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) for _, id := range validatorIDs { vdrs[id] = &validators.GetValidatorOutput{ NodeID: id, @@ -163,7 +163,7 @@ func TestWindowerChangeByChain(t *testing.T) { } for i, expectedDelay := range expectedDelays0 { vdrID := validatorIDs[i] - validatorDelay, err := w0.Delay(context.Background(), 1, 0, vdrID) + validatorDelay, err := w0.Delay(context.Background(), 1, 0, vdrID, MaxVerifyWindows) require.NoError(err) require.Equal(expectedDelay, validatorDelay) } @@ -178,7 +178,7 @@ func TestWindowerChangeByChain(t *testing.T) { } for i, expectedDelay := range expectedDelays1 { vdrID := validatorIDs[i] - validatorDelay, err := w1.Delay(context.Background(), 1, 0, vdrID) + validatorDelay, err := w1.Delay(context.Background(), 1, 0, vdrID, MaxVerifyWindows) require.NoError(err) require.Equal(expectedDelay, validatorDelay) } diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index ae9691ab380e..a7bb897932d3 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -200,10 +200,10 @@ func (vm *VM) Initialize( vm.State = baseState vm.Windower = proposer.New(chainCtx.ValidatorState, chainCtx.SubnetID, chainCtx.ChainID) vm.Tree = tree.New() - innerBlkCache, err := metercacher.New[ids.ID, snowman.Block]( + innerBlkCache, err := metercacher.New( "inner_block_cache", registerer, - cache.NewSizedLRU[ids.ID, snowman.Block]( + cache.NewSizedLRU( innerBlkCacheSize, cachedBlockSize, ), @@ -355,7 +355,7 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { } // reset scheduler - minDelay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID) + minDelay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) if err != nil { vm.ctx.Log.Debug("failed to fetch the expected delay", zap.Error(err), diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index c53830077bca..dcfebf847cf3 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -47,7 +47,7 @@ func TestInvalidByzantineProposerParent(t *testing.T) { BytesV: []byte{1}, ParentV: gBlock.ID(), HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp().Add(proposer.MaxDelay), + TimestampV: gBlock.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return xBlock, nil @@ -70,7 +70,7 @@ func TestInvalidByzantineProposerParent(t *testing.T) { BytesV: yBlockBytes, ParentV: xBlock.ID(), HeightV: xBlock.Height() + 1, - TimestampV: xBlock.Timestamp().Add(proposer.MaxDelay), + TimestampV: xBlock.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.ParseBlockF = func(_ context.Context, blockBytes []byte) (snowman.Block, error) { @@ -225,7 +225,7 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { BytesV: []byte{1}, ParentV: gBlock.ID(), HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp().Add(proposer.MaxDelay), + TimestampV: gBlock.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return xBlock, nil @@ -240,7 +240,7 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { BytesV: yBlockBytes, ParentV: xBlock.ID(), HeightV: xBlock.Height() + 1, - TimestampV: xBlock.Timestamp().Add(proposer.MaxDelay), + TimestampV: xBlock.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index b75493f26ac6..fb8672d8b2f4 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -233,7 +233,7 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { BytesV: []byte{1}, ParentV: coreGenBlk.ID(), HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -263,7 +263,7 @@ func TestBuildBlockIsIdempotent(t *testing.T) { BytesV: []byte{1}, ParentV: coreGenBlk.ID(), HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -298,7 +298,7 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { BytesV: []byte{1}, ParentV: coreGenBlk.ID(), HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -403,7 +403,7 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { return coreBlk3, nil } - proVM.Set(proVM.Time().Add(proposer.MaxDelay)) + proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) builtBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -498,7 +498,7 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { return coreBlk3, nil } - proVM.Set(proVM.Time().Add(proposer.MaxDelay)) + proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) blk, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -720,7 +720,7 @@ func TestPreFork_BuildBlock(t *testing.T) { BytesV: []byte{3}, ParentV: coreGenBlk.ID(), HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxDelay), + TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -1021,7 +1021,7 @@ func TestExpiredBuildBlock(t *testing.T) { _, err = proVM.BuildBlock(context.Background()) require.ErrorIs(err, errProposerWindowNotStarted) - proVM.Set(statelessBlock.Timestamp().Add(proposer.MaxDelay)) + proVM.Set(statelessBlock.Timestamp().Add(proposer.MaxVerifyDelay)) proVM.Scheduler.SetBuildBlockTime(time.Now()) // The engine should have been notified to attempt to build a block now that @@ -1604,7 +1604,7 @@ func TestTooFarAdvanced(t *testing.T) { ySlb, err = statelessblock.BuildUnsigned( aBlock.ID(), - aBlock.Timestamp().Add(proposer.MaxDelay), + aBlock.Timestamp().Add(proposer.MaxVerifyDelay), defaultPChainHeight, yBlock.Bytes(), ) From 4ce0d67703b5e62fdff9f9a95ab6e5fd5dfd7a45 Mon Sep 17 00:00:00 2001 From: Gyuho Lee <6799218+gyuho@users.noreply.github.com> Date: Thu, 23 Nov 2023 01:39:53 +0800 Subject: [PATCH 062/267] Use linkedhashmap for P-Chain mempool (#1536) Co-authored-by: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- vms/platformvm/block/builder/builder.go | 2 +- vms/platformvm/block/builder/builder_test.go | 10 +- vms/platformvm/txs/mempool/issuer.go | 95 --------- vms/platformvm/txs/mempool/mempool.go | 190 +++++++----------- vms/platformvm/txs/mempool/mempool_test.go | 73 ++++--- vms/platformvm/txs/mempool/mock_mempool.go | 43 ++-- vms/platformvm/txs/mempool/remover.go | 88 -------- vms/platformvm/txs/txheap/by_age.go | 17 -- vms/platformvm/txs/txheap/by_end_time.go | 6 + vms/platformvm/txs/txheap/by_start_time.go | 40 ---- .../txs/txheap/by_start_time_test.go | 66 ------ 11 files changed, 148 insertions(+), 482 deletions(-) delete mode 100644 vms/platformvm/txs/mempool/issuer.go delete mode 100644 vms/platformvm/txs/mempool/remover.go delete mode 100644 vms/platformvm/txs/txheap/by_age.go delete mode 100644 vms/platformvm/txs/txheap/by_start_time.go delete mode 100644 vms/platformvm/txs/txheap/by_start_time_test.go diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 13a1c7902b6d..8923857d579e 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -270,7 +270,7 @@ func buildBlock( } // Clean out the mempool's transactions with invalid timestamps. - droppedStakerTxIDs := mempool.DropExpiredStakerTxs(builder.Mempool, timestamp.Add(txexecutor.SyncBound)) + droppedStakerTxIDs := builder.Mempool.DropExpiredStakerTxs(timestamp.Add(txexecutor.SyncBound)) for _, txID := range droppedStakerTxIDs { builder.txExecutorBackend.Ctx.Log.Debug("dropping tx", zap.Stringer("txID", txID), diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 2bf97a8c8ef2..04abf5d65b71 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -401,7 +401,7 @@ func TestBuildBlock(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) // There are txs. - mempool.EXPECT().HasStakerTx().Return(false) + mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) mempool.EXPECT().HasTxs().Return(true) mempool.EXPECT().PeekTxs(targetBlockSize).Return(transactions) return &builder{ @@ -448,7 +448,7 @@ func TestBuildBlock(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) // There are no txs. - mempool.EXPECT().HasStakerTx().Return(false) + mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) mempool.EXPECT().HasTxs().Return(false) clk := &mockable.Clock{} @@ -496,7 +496,7 @@ func TestBuildBlock(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) // There are no txs. - mempool.EXPECT().HasStakerTx().Return(false) + mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) mempool.EXPECT().HasTxs().Return(false) mempool.EXPECT().PeekTxs(targetBlockSize).Return(nil) @@ -551,7 +551,7 @@ func TestBuildBlock(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) // There is a tx. - mempool.EXPECT().HasStakerTx().Return(false) + mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) mempool.EXPECT().HasTxs().Return(true) mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{transactions[0]}) @@ -605,7 +605,7 @@ func TestBuildBlock(t *testing.T) { // There are no decision txs // There is a staker tx. - mempool.EXPECT().HasStakerTx().Return(false) + mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) mempool.EXPECT().HasTxs().Return(true) mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{transactions[0]}) diff --git a/vms/platformvm/txs/mempool/issuer.go b/vms/platformvm/txs/mempool/issuer.go deleted file mode 100644 index b56c10190cf8..000000000000 --- a/vms/platformvm/txs/mempool/issuer.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package mempool - -import ( - "errors" - - "github.com/ava-labs/avalanchego/vms/platformvm/txs" -) - -var ( - _ txs.Visitor = (*issuer)(nil) - - errCantIssueAdvanceTimeTx = errors.New("can not issue an advance time tx") - errCantIssueRewardValidatorTx = errors.New("can not issue a reward validator tx") -) - -type issuer struct { - m *mempool - tx *txs.Tx -} - -func (*issuer) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - return errCantIssueAdvanceTimeTx -} - -func (*issuer) RewardValidatorTx(*txs.RewardValidatorTx) error { - return errCantIssueRewardValidatorTx -} - -func (i *issuer) AddValidatorTx(*txs.AddValidatorTx) error { - i.m.addStakerTx(i.tx) - return nil -} - -func (i *issuer) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { - i.m.addStakerTx(i.tx) - return nil -} - -func (i *issuer) AddDelegatorTx(*txs.AddDelegatorTx) error { - i.m.addStakerTx(i.tx) - return nil -} - -func (i *issuer) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) CreateChainTx(*txs.CreateChainTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) CreateSubnetTx(*txs.CreateSubnetTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) ImportTx(*txs.ImportTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) ExportTx(*txs.ExportTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) TransformSubnetTx(*txs.TransformSubnetTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) BaseTx(*txs.BaseTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) AddPermissionlessValidatorTx(*txs.AddPermissionlessValidatorTx) error { - i.m.addStakerTx(i.tx) - return nil -} - -func (i *issuer) AddPermissionlessDelegatorTx(*txs.AddPermissionlessDelegatorTx) error { - i.m.addStakerTx(i.tx) - return nil -} diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 91b547cf5414..e7a2018b7e71 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -12,10 +12,10 @@ import ( "github.com/ava-labs/avalanchego/cache" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/linkedhashmap" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/txheap" ) const ( @@ -35,10 +35,12 @@ const ( var ( _ Mempool = (*mempool)(nil) - errDuplicateTx = errors.New("duplicate tx") - errTxTooLarge = errors.New("tx too large") - errMempoolFull = errors.New("mempool is full") - errConflictsWithOtherTx = errors.New("tx conflicts with other tx") + errDuplicateTx = errors.New("duplicate tx") + errTxTooLarge = errors.New("tx too large") + errMempoolFull = errors.New("mempool is full") + errConflictsWithOtherTx = errors.New("tx conflicts with other tx") + errCantIssueAdvanceTimeTx = errors.New("can not issue an advance time tx") + errCantIssueRewardValidatorTx = errors.New("can not issue a reward validator tx") ) type BlockTimer interface { @@ -67,11 +69,11 @@ type Mempool interface { // up to maxTxsBytes without removing them from the mempool. PeekTxs(maxTxsBytes int) []*txs.Tx - HasStakerTx() bool - // PeekStakerTx returns the next stakerTx without removing it from mempool. - // It returns nil if !HasStakerTx(). - // It's guaranteed that the returned tx, if not nil, is a StakerTx. - PeekStakerTx() *txs.Tx + // Drops all [txs.Staker] transactions whose [StartTime] is before + // [minStartTime] from [mempool]. The dropped tx ids are returned. + // + // TODO: Remove once [StartTime] field is ignored in staker txs + DropExpiredStakerTxs(minStartTime time.Time) []ids.ID // Note: dropped txs are added to droppedTxIDs but are not evicted from // unissued decision/staker txs. This allows previously dropped txs to be @@ -89,8 +91,8 @@ type mempool struct { bytesAvailableMetric prometheus.Gauge bytesAvailable int - unissuedDecisionTxs txheap.Heap - unissuedStakerTxs txheap.Heap + unissuedTxs linkedhashmap.LinkedHashmap[ids.ID, *txs.Tx] + numTxs prometheus.Gauge // Key: Tx ID // Value: Verification error @@ -115,21 +117,12 @@ func New( return nil, err } - unissuedDecisionTxs, err := txheap.NewWithMetrics( - txheap.NewByAge(), - fmt.Sprintf("%s_decision_txs", namespace), - registerer, - ) - if err != nil { - return nil, err - } - - unissuedStakerTxs, err := txheap.NewWithMetrics( - txheap.NewByStartTime(), - fmt.Sprintf("%s_staker_txs", namespace), - registerer, - ) - if err != nil { + numTxs := prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "txs", + Help: "Number of decision/staker transactions in the mempool", + }) + if err := registerer.Register(numTxs); err != nil { return nil, err } @@ -137,12 +130,14 @@ func New( return &mempool{ bytesAvailableMetric: bytesAvailableMetric, bytesAvailable: maxMempoolSize, - unissuedDecisionTxs: unissuedDecisionTxs, - unissuedStakerTxs: unissuedStakerTxs, - droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, - consumedUTXOs: set.NewSet[ids.ID](initialConsumedUTXOsSize), - dropIncoming: false, // enable tx adding by default - blkTimer: blkTimer, + + unissuedTxs: linkedhashmap.New[ids.ID, *txs.Tx](), + numTxs: numTxs, + + droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, + consumedUTXOs: set.NewSet[ids.ID](initialConsumedUTXOsSize), + dropIncoming: false, // enable tx adding by default + blkTimer: blkTimer, }, nil } @@ -159,6 +154,14 @@ func (m *mempool) Add(tx *txs.Tx) error { return fmt.Errorf("tx %s not added because mempool is closed", tx.ID()) } + switch tx.Unsigned.(type) { + case *txs.AdvanceTimeTx: + return errCantIssueAdvanceTimeTx + case *txs.RewardValidatorTx: + return errCantIssueRewardValidatorTx + default: + } + // Note: a previously dropped tx can be re-added txID := tx.ID() if m.Has(txID) { @@ -188,12 +191,9 @@ func (m *mempool) Add(tx *txs.Tx) error { return fmt.Errorf("%w: %s", errConflictsWithOtherTx, txID) } - if err := tx.Unsigned.Visit(&issuer{ - m: m, - tx: tx, - }); err != nil { - return err - } + m.unissuedTxs.Put(tx.ID(), tx) + m.bytesAvailable -= txSize + m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) // Mark these UTXOs as consumed in the mempool m.consumedUTXOs.Union(inputs) @@ -210,79 +210,46 @@ func (m *mempool) Has(txID ids.ID) bool { } func (m *mempool) Get(txID ids.ID) *txs.Tx { - if tx := m.unissuedDecisionTxs.Get(txID); tx != nil { - return tx - } - return m.unissuedStakerTxs.Get(txID) + tx, _ := m.unissuedTxs.Get(txID) + return tx } func (m *mempool) Remove(txsToRemove []*txs.Tx) { - remover := &remover{ - m: m, - } - for _, tx := range txsToRemove { - remover.tx = tx - _ = tx.Unsigned.Visit(remover) + txID := tx.ID() + if !m.unissuedTxs.Delete(txID) { + continue + } + + m.bytesAvailable += len(tx.Bytes()) + m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) + + m.numTxs.Dec() + + inputs := tx.Unsigned.InputIDs() + m.consumedUTXOs.Difference(inputs) } } func (m *mempool) HasTxs() bool { - return m.unissuedDecisionTxs.Len() > 0 || m.unissuedStakerTxs.Len() > 0 + return m.unissuedTxs.Len() > 0 } func (m *mempool) PeekTxs(maxTxsBytes int) []*txs.Tx { - txs := m.unissuedDecisionTxs.List() - txs = append(txs, m.unissuedStakerTxs.List()...) - + var txs []*txs.Tx + txIter := m.unissuedTxs.NewIterator() size := 0 - for i, tx := range txs { + for txIter.Next() { + tx := txIter.Value() size += len(tx.Bytes()) if size > maxTxsBytes { - return txs[:i] + return txs } + txs = append(txs, tx) } return txs } -func (m *mempool) addDecisionTx(tx *txs.Tx) { - m.unissuedDecisionTxs.Add(tx) - m.register(tx) -} - -func (m *mempool) addStakerTx(tx *txs.Tx) { - m.unissuedStakerTxs.Add(tx) - m.register(tx) -} - -func (m *mempool) HasStakerTx() bool { - return m.unissuedStakerTxs.Len() > 0 -} - -func (m *mempool) removeDecisionTxs(txs []*txs.Tx) { - for _, tx := range txs { - txID := tx.ID() - if m.unissuedDecisionTxs.Remove(txID) != nil { - m.deregister(tx) - } - } -} - -func (m *mempool) removeStakerTx(tx *txs.Tx) { - txID := tx.ID() - if m.unissuedStakerTxs.Remove(txID) != nil { - m.deregister(tx) - } -} - -func (m *mempool) PeekStakerTx() *txs.Tx { - if m.unissuedStakerTxs.Len() == 0 { - return nil - } - - return m.unissuedStakerTxs.Peek() -} - func (m *mempool) MarkDropped(txID ids.ID, reason error) { m.droppedTxIDs.Put(txID, reason) } @@ -292,35 +259,24 @@ func (m *mempool) GetDropReason(txID ids.ID) error { return err } -func (m *mempool) register(tx *txs.Tx) { - txBytes := tx.Bytes() - m.bytesAvailable -= len(txBytes) - m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) -} - -func (m *mempool) deregister(tx *txs.Tx) { - txBytes := tx.Bytes() - m.bytesAvailable += len(txBytes) - m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) - - inputs := tx.Unsigned.InputIDs() - m.consumedUTXOs.Difference(inputs) -} - // Drops all [txs.Staker] transactions whose [StartTime] is before // [minStartTime] from [mempool]. The dropped tx ids are returned. // // TODO: Remove once [StartTime] field is ignored in staker txs -func DropExpiredStakerTxs(mempool Mempool, minStartTime time.Time) []ids.ID { +func (m *mempool) DropExpiredStakerTxs(minStartTime time.Time) []ids.ID { var droppedTxIDs []ids.ID - for mempool.HasStakerTx() { - tx := mempool.PeekStakerTx() - startTime := tx.Unsigned.(txs.Staker).StartTime() + txIter := m.unissuedTxs.NewIterator() + for txIter.Next() { + tx := txIter.Value() + stakerTx, ok := tx.Unsigned.(txs.Staker) + if !ok { + continue + } + + startTime := stakerTx.StartTime() if !startTime.Before(minStartTime) { - // The next proposal tx in the mempool starts sufficiently far in - // the future. - break + continue } txID := tx.ID() @@ -330,8 +286,8 @@ func DropExpiredStakerTxs(mempool Mempool, minStartTime time.Time) []ids.ID { startTime, ) - mempool.Remove([]*txs.Tx{tx}) - mempool.MarkDropped(txID, err) // cache tx as dropped + m.Remove([]*txs.Tx{tx}) + m.MarkDropped(txID, err) // cache tx as dropped droppedTxIDs = append(droppedTxIDs, txID) } diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index dbfe895f9d9b..a56ae4702155 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -20,14 +20,16 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -var _ BlockTimer = (*noopBlkTimer)(nil) +var ( + _ BlockTimer = (*noopBlkTimer)(nil) + + preFundedKeys = secp256k1.TestKeys() +) type noopBlkTimer struct{} func (*noopBlkTimer) ResetBlockTimer() {} -var preFundedKeys = secp256k1.TestKeys() - // shows that valid tx is not added to mempool if this would exceed its maximum // size func TestBlockBuilderMaxMempoolSizeHandling(t *testing.T) { @@ -119,9 +121,6 @@ func TestProposalTxsInMempool(t *testing.T) { proposalTxs, err := createTestProposalTxs(2) require.NoError(err) - // txs should not be already there - require.False(mpool.HasStakerTx()) - for i, tx := range proposalTxs { require.False(mpool.Has(tx.ID())) @@ -129,20 +128,12 @@ func TestProposalTxsInMempool(t *testing.T) { require.NoError(mpool.Add(tx)) // we can get it - require.True(mpool.HasStakerTx()) require.True(mpool.Has(tx.ID())) retrieved := mpool.Get(tx.ID()) require.NotNil(retrieved) require.Equal(tx, retrieved) - { - // we can peek it - peeked := mpool.PeekStakerTx() - require.NotNil(peeked) - require.Equal(tx, peeked) - } - { // we can peek it peeked := mpool.PeekTxs(math.MaxInt) @@ -222,17 +213,10 @@ func createTestProposalTxs(count int) ([]*txs.Tx, error) { now := time.Now() proposalTxs := make([]*txs.Tx, 0, count) for i := 0; i < count; i++ { - utx := &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{}, - Validator: txs.Validator{ - Start: uint64(now.Add(time.Duration(count-i) * time.Second).Unix()), - }, - StakeOuts: nil, - RewardsOwner: &secp256k1fx.OutputOwners{}, - DelegationShares: 100, - } - - tx, err := txs.NewSigned(utx, txs.Codec, nil) + tx, err := generateAddValidatorTx( + uint64(now.Add(time.Duration(count-i)*time.Second).Unix()), // startTime + 0, // endTime + ) if err != nil { return nil, err } @@ -240,3 +224,42 @@ func createTestProposalTxs(count int) ([]*txs.Tx, error) { } return proposalTxs, nil } + +func generateAddValidatorTx(startTime uint64, endTime uint64) (*txs.Tx, error) { + utx := &txs.AddValidatorTx{ + BaseTx: txs.BaseTx{}, + Validator: txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: startTime, + End: endTime, + }, + StakeOuts: nil, + RewardsOwner: &secp256k1fx.OutputOwners{}, + DelegationShares: 100, + } + + return txs.NewSigned(utx, txs.Codec, nil) +} + +func TestDropExpiredStakerTxs(t *testing.T) { + require := require.New(t) + + registerer := prometheus.NewRegistry() + mempool, err := New("mempool", registerer, &noopBlkTimer{}) + require.NoError(err) + + tx1, err := generateAddValidatorTx(10, 20) + require.NoError(err) + require.NoError(mempool.Add(tx1)) + + tx2, err := generateAddValidatorTx(8, 20) + require.NoError(err) + require.NoError(mempool.Add(tx2)) + + tx3, err := generateAddValidatorTx(15, 20) + require.NoError(err) + require.NoError(mempool.Add(tx3)) + + minStartTime := time.Unix(9, 0) + require.Len(mempool.DropExpiredStakerTxs(minStartTime), 1) +} diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index a4baccd405e9..8f8c90eb2d07 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -9,6 +9,7 @@ package mempool import ( reflect "reflect" + time "time" ids "github.com/ava-labs/avalanchego/ids" txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -64,6 +65,20 @@ func (mr *MockMempoolMockRecorder) DisableAdding() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableAdding", reflect.TypeOf((*MockMempool)(nil).DisableAdding)) } +// DropExpiredStakerTxs mocks base method. +func (m *MockMempool) DropExpiredStakerTxs(arg0 time.Time) []ids.ID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DropExpiredStakerTxs", arg0) + ret0, _ := ret[0].([]ids.ID) + return ret0 +} + +// DropExpiredStakerTxs indicates an expected call of DropExpiredStakerTxs. +func (mr *MockMempoolMockRecorder) DropExpiredStakerTxs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropExpiredStakerTxs", reflect.TypeOf((*MockMempool)(nil).DropExpiredStakerTxs), arg0) +} + // EnableAdding mocks base method. func (m *MockMempool) EnableAdding() { m.ctrl.T.Helper() @@ -118,20 +133,6 @@ func (mr *MockMempoolMockRecorder) Has(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMempool)(nil).Has), arg0) } -// HasStakerTx mocks base method. -func (m *MockMempool) HasStakerTx() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HasStakerTx") - ret0, _ := ret[0].(bool) - return ret0 -} - -// HasStakerTx indicates an expected call of HasStakerTx. -func (mr *MockMempoolMockRecorder) HasStakerTx() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasStakerTx", reflect.TypeOf((*MockMempool)(nil).HasStakerTx)) -} - // HasTxs mocks base method. func (m *MockMempool) HasTxs() bool { m.ctrl.T.Helper() @@ -158,20 +159,6 @@ func (mr *MockMempoolMockRecorder) MarkDropped(arg0, arg1 interface{}) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkDropped", reflect.TypeOf((*MockMempool)(nil).MarkDropped), arg0, arg1) } -// PeekStakerTx mocks base method. -func (m *MockMempool) PeekStakerTx() *txs.Tx { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PeekStakerTx") - ret0, _ := ret[0].(*txs.Tx) - return ret0 -} - -// PeekStakerTx indicates an expected call of PeekStakerTx. -func (mr *MockMempoolMockRecorder) PeekStakerTx() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeekStakerTx", reflect.TypeOf((*MockMempool)(nil).PeekStakerTx)) -} - // PeekTxs mocks base method. func (m *MockMempool) PeekTxs(arg0 int) []*txs.Tx { m.ctrl.T.Helper() diff --git a/vms/platformvm/txs/mempool/remover.go b/vms/platformvm/txs/mempool/remover.go deleted file mode 100644 index b21071b16465..000000000000 --- a/vms/platformvm/txs/mempool/remover.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package mempool - -import "github.com/ava-labs/avalanchego/vms/platformvm/txs" - -var _ txs.Visitor = (*remover)(nil) - -type remover struct { - m *mempool - tx *txs.Tx -} - -func (r *remover) AddValidatorTx(*txs.AddValidatorTx) error { - r.m.removeStakerTx(r.tx) - return nil -} - -func (r *remover) AddSubnetValidatorTx(*txs.AddSubnetValidatorTx) error { - r.m.removeStakerTx(r.tx) - return nil -} - -func (r *remover) AddDelegatorTx(*txs.AddDelegatorTx) error { - r.m.removeStakerTx(r.tx) - return nil -} - -func (r *remover) RemoveSubnetValidatorTx(*txs.RemoveSubnetValidatorTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) CreateChainTx(*txs.CreateChainTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) CreateSubnetTx(*txs.CreateSubnetTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) ImportTx(*txs.ImportTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) ExportTx(*txs.ExportTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) TransformSubnetTx(*txs.TransformSubnetTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) TransferSubnetOwnershipTx(*txs.TransferSubnetOwnershipTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) BaseTx(*txs.BaseTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) AddPermissionlessValidatorTx(*txs.AddPermissionlessValidatorTx) error { - r.m.removeStakerTx(r.tx) - return nil -} - -func (r *remover) AddPermissionlessDelegatorTx(*txs.AddPermissionlessDelegatorTx) error { - r.m.removeStakerTx(r.tx) - return nil -} - -func (*remover) AdvanceTimeTx(*txs.AdvanceTimeTx) error { - // this tx is never in mempool - return nil -} - -func (*remover) RewardValidatorTx(*txs.RewardValidatorTx) error { - // this tx is never in mempool - return nil -} diff --git a/vms/platformvm/txs/txheap/by_age.go b/vms/platformvm/txs/txheap/by_age.go deleted file mode 100644 index be888c437a0f..000000000000 --- a/vms/platformvm/txs/txheap/by_age.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package txheap - -import ( - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/heap" -) - -func NewByAge() Heap { - return &txHeap{ - heap: heap.NewMap[ids.ID, heapTx](func(a, b heapTx) bool { - return a.age < b.age - }), - } -} diff --git a/vms/platformvm/txs/txheap/by_end_time.go b/vms/platformvm/txs/txheap/by_end_time.go index ba144448919d..2499ce971bc9 100644 --- a/vms/platformvm/txs/txheap/by_end_time.go +++ b/vms/platformvm/txs/txheap/by_end_time.go @@ -13,6 +13,12 @@ import ( var _ TimedHeap = (*byEndTime)(nil) +type TimedHeap interface { + Heap + + Timestamp() time.Time +} + type byEndTime struct { txHeap } diff --git a/vms/platformvm/txs/txheap/by_start_time.go b/vms/platformvm/txs/txheap/by_start_time.go deleted file mode 100644 index f19c28d76436..000000000000 --- a/vms/platformvm/txs/txheap/by_start_time.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package txheap - -import ( - "time" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/heap" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" -) - -var _ TimedHeap = (*byStartTime)(nil) - -type TimedHeap interface { - Heap - - Timestamp() time.Time -} - -type byStartTime struct { - txHeap -} - -func NewByStartTime() TimedHeap { - return &byStartTime{ - txHeap: txHeap{ - heap: heap.NewMap[ids.ID, heapTx](func(a, b heapTx) bool { - aTime := a.tx.Unsigned.(txs.Staker).StartTime() - bTime := b.tx.Unsigned.(txs.Staker).StartTime() - return aTime.Before(bTime) - }), - }, - } -} - -func (h *byStartTime) Timestamp() time.Time { - return h.Peek().Unsigned.(txs.Staker).StartTime() -} diff --git a/vms/platformvm/txs/txheap/by_start_time_test.go b/vms/platformvm/txs/txheap/by_start_time_test.go deleted file mode 100644 index e00d42076015..000000000000 --- a/vms/platformvm/txs/txheap/by_start_time_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package txheap - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -func TestByStartTime(t *testing.T) { - require := require.New(t) - - txHeap := NewByStartTime() - - baseTime := time.Now() - - utx0 := &txs.AddValidatorTx{ - Validator: txs.Validator{ - NodeID: ids.BuildTestNodeID([]byte{0}), - Start: uint64(baseTime.Unix()) + 1, - End: uint64(baseTime.Unix()) + 1, - }, - RewardsOwner: &secp256k1fx.OutputOwners{}, - } - tx0 := &txs.Tx{Unsigned: utx0} - require.NoError(tx0.Initialize(txs.Codec)) - - utx1 := &txs.AddValidatorTx{ - Validator: txs.Validator{ - NodeID: ids.BuildTestNodeID([]byte{1}), - Start: uint64(baseTime.Unix()) + 2, - End: uint64(baseTime.Unix()) + 2, - }, - RewardsOwner: &secp256k1fx.OutputOwners{}, - } - tx1 := &txs.Tx{Unsigned: utx1} - require.NoError(tx1.Initialize(txs.Codec)) - - utx2 := &txs.AddValidatorTx{ - Validator: txs.Validator{ - NodeID: ids.BuildTestNodeID([]byte{1}), - Start: uint64(baseTime.Unix()) + 3, - End: uint64(baseTime.Unix()) + 3, - }, - RewardsOwner: &secp256k1fx.OutputOwners{}, - } - tx2 := &txs.Tx{Unsigned: utx2} - require.NoError(tx2.Initialize(txs.Codec)) - - txHeap.Add(tx2) - require.Equal(utx2.EndTime(), txHeap.Timestamp()) - - txHeap.Add(tx1) - require.Equal(utx1.EndTime(), txHeap.Timestamp()) - - txHeap.Add(tx0) - require.Equal(utx0.EndTime(), txHeap.Timestamp()) - require.Equal(tx0, txHeap.Peek()) -} From 48c541c8efabaabb8899c3d337a58547cc9a5783 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 22 Nov 2023 17:46:14 -0500 Subject: [PATCH 063/267] Fix P-chain mempool tx count metric (#2361) --- vms/platformvm/txs/mempool/mempool.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index e7a2018b7e71..675ec3c5c763 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -192,6 +192,7 @@ func (m *mempool) Add(tx *txs.Tx) error { } m.unissuedTxs.Put(tx.ID(), tx) + m.numTxs.Inc() m.bytesAvailable -= txSize m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) @@ -220,12 +221,11 @@ func (m *mempool) Remove(txsToRemove []*txs.Tx) { if !m.unissuedTxs.Delete(txID) { continue } + m.numTxs.Dec() m.bytesAvailable += len(tx.Bytes()) m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) - m.numTxs.Dec() - inputs := tx.Unsigned.InputIDs() m.consumedUTXOs.Difference(inputs) } From 62df19c3c90b67a27618c339a3e29cc182d34863 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 22 Nov 2023 19:47:37 -0500 Subject: [PATCH 064/267] Update versions for v1.10.16 (#2353) --- RELEASES.md | 98 ++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- version/compatibility.json | 3 +- version/constants.go | 2 +- 5 files changed, 104 insertions(+), 5 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 0f8d57aea220..073214ac4424 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,103 @@ # Release Notes +## [v1.10.16](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.16) + +This version is backwards compatible to [v1.10.0](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0). It is optional, but encouraged. + +The plugin version is unchanged at `30` and compatible with version `v1.10.15`. + +### APIs + +- Added log level information to the result of `admin.setLoggerLevel` +- Updated `info.peers` to return chain aliases for `benched` chains +- Added support to sample validators of non-tracked subnets with `platform.sampleValidators` +- Added `avalanche_{chainID}_max_verified_height` metric to track the highest verified block + +### Configs + +- Added `--db-read-only` to run the node without writing to disk. + - This flag is only expected to be used during testing as it will cause memory use to increase over time +- Removed `--bootstrap-retry-enabled` +- Removed `--bootstrap-retry-warn-frequency` + +### Fixes + +- Fixed packing of large block requests during C-chain state sync +- Fixed order of updating acceptor tip and sending chain events to C-chain event subscribers + +### What's Changed + +- Return log levels from admin.SetLoggerLevel by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2250 +- feat(api) : Peers function to return the PrimaryAlias of the chainID by @DoTheBestToGetTheBest in https://github.com/ava-labs/avalanchego/pull/2251 +- Switch to using require.TestingT interface in SenderTest struct by @marun in https://github.com/ava-labs/avalanchego/pull/2258 +- Cleanup `ipcs` `Socket` test by @danlaine in https://github.com/ava-labs/avalanchego/pull/2257 +- Require poll metrics to be registered by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2260 +- Track all subnet validator sets in the validator manager by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2253 +- e2e: Make NewWallet and NewEthclient regular functions by @marun in https://github.com/ava-labs/avalanchego/pull/2262 +- Fix typos in docs by @vuittont60 in https://github.com/ava-labs/avalanchego/pull/2261 +- Remove Token constants information from keys by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2197 +- Remove unused `UnsortedEquals` function by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2264 +- Document p2p package by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2254 +- Use extended public key to derive ledger addresses by @felipemadero in https://github.com/ava-labs/avalanchego/pull/2246 +- `merkledb` -- rename nit by @danlaine in https://github.com/ava-labs/avalanchego/pull/2267 +- `merkledb` -- fix nil check in test by @danlaine in https://github.com/ava-labs/avalanchego/pull/2268 +- Add read-only database flag (`--db-read-only`) by @danlaine in https://github.com/ava-labs/avalanchego/pull/2266 +- `merkledb` -- remove unneeded var declarations by @danlaine in https://github.com/ava-labs/avalanchego/pull/2269 +- Add fuzz test for `NewIteratorWithStartAndPrefix` by @danlaine in https://github.com/ava-labs/avalanchego/pull/1992 +- Return if element was deleted from `Hashmap` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2271 +- `mempool.NewMempool` -> `mempool.New` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2276 +- e2e: Refactor suite setup and helpers to tests/fixture/e2e for reuse by coreth by @marun in https://github.com/ava-labs/avalanchego/pull/2265 +- Cleanup platformvm mempool errs by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2278 +- MerkleDB:Naming and comments cleanup by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2274 +- Move `DropExpiredStakerTxs` to platformvm mempool by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2279 +- Cleanup `ids.NodeID` usage by @abi87 in https://github.com/ava-labs/avalanchego/pull/2280 +- Genesis validators cleanup by @abi87 in https://github.com/ava-labs/avalanchego/pull/2282 +- Remove Lazy Initialize on Node by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/1384 +- Remove sentinel node from MerkleDB proofs by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2106 +- Embed `noop` handler for all unhandled messages by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2288 +- `merkledb` -- Add `Clearer` interface by @danlaine in https://github.com/ava-labs/avalanchego/pull/2277 +- Simplify get server creation by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2285 +- Move management of platformvm preferred block to `executor.Manager` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2292 +- Add `recentTxsLock` to platform `network` struct by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2294 +- e2e: More fixture refinement in support of coreth integration testing by @marun in https://github.com/ava-labs/avalanchego/pull/2275 +- Add `VerifyTx` to `executor.Manager` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2293 +- Simplify avalanche bootstrapping by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2286 +- Replace unique slices with sets in the engine interface by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2317 +- Use zap.Stringer rather than zap.Any by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2320 +- Move `AddUnverifiedTx` logic to `network.IssueTx` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2310 +- Remove `AddUnverifiedTx` from `Builder` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2311 +- Remove error from SDK AppGossip handler by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2252 +- Rename AppRequestFailed to AppError by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2321 +- Remove `Network` interface from `Builder` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2312 +- Update `error_code` to be sint32 instead of uint32. by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2322 +- Refactor bootstrapper implementation into consensus by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2300 +- Pchain - Cleanup NodeID generation in UTs by @abi87 in https://github.com/ava-labs/avalanchego/pull/2291 +- nit: loop --> variadic by @danlaine in https://github.com/ava-labs/avalanchego/pull/2316 +- Update zap dependency to v1.26.0 by @danlaine in https://github.com/ava-labs/avalanchego/pull/2325 +- Remove useless anon functions by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2326 +- Move `network` implementation to separate package by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2296 +- Unexport avalanche constant from common package by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2327 +- Remove `common.Config` functions by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2328 +- Move engine startup into helper function by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2329 +- Remove bootstrapping retry config by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2301 +- Export snowman bootstrapper by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2331 +- Remove common.Config from syncer.Config by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2330 +- `platformvm.VM` -- replace `Config` field with `validators.Manager` by @danlaine in https://github.com/ava-labs/avalanchego/pull/2319 +- Improve height monitoring by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2347 +- Cleanup snowman consensus metrics by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2349 +- Expand consensus health check by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2354 +- Reduce the size of the OracleBlock interface by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2355 +- [vms/proposervm] Update Build Heuristic by @patrick-ogrady in https://github.com/ava-labs/avalanchego/pull/2348 +- Use linkedhashmap for P-Chain mempool by @gyuho in https://github.com/ava-labs/avalanchego/pull/1536 +- Increase txs in pool metric when adding tx by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2361 + +### New Contributors + +- @DoTheBestToGetTheBest made their first contribution in https://github.com/ava-labs/avalanchego/pull/2251 +- @vuittont60 made their first contribution in https://github.com/ava-labs/avalanchego/pull/2261 + +**Full Changelog**: https://github.com/ava-labs/avalanchego/compare/v1.10.15...v1.10.16 + ## [v1.10.15](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.15) This version is backwards compatible to [v1.10.0](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0). It is optional, but encouraged. diff --git a/go.mod b/go.mod index bf06bbc74e83..f5dfa499d1d5 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.0 + github.com/ava-labs/coreth v0.12.9-rc.5 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 573d618f19cb..35141a6c1638 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.0 h1:Xvk/iJTY2MSBkkiOs9Eo92nxd67VXzRjaC/WmQXRIb0= -github.com/ava-labs/coreth v0.12.9-rc.0/go.mod h1:rECKQfGFDeodrwGPlJSvFUJDbVr30jSMIVjQLi6pNX4= +github.com/ava-labs/coreth v0.12.9-rc.5 h1:xYBgNm1uOPfUdUNm8+fS8ellHnEd4qfFNb6uZHo9tqI= +github.com/ava-labs/coreth v0.12.9-rc.5/go.mod h1:rECKQfGFDeodrwGPlJSvFUJDbVr30jSMIVjQLi6pNX4= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/version/compatibility.json b/version/compatibility.json index 9a63fba3eafc..c3b35ed515ec 100644 --- a/version/compatibility.json +++ b/version/compatibility.json @@ -1,6 +1,7 @@ { "30": [ - "v1.10.15" + "v1.10.15", + "v1.10.16" ], "29": [ "v1.10.13", diff --git a/version/constants.go b/version/constants.go index 25cedb5b73c1..5d57933e424b 100644 --- a/version/constants.go +++ b/version/constants.go @@ -22,7 +22,7 @@ var ( Current = &Semantic{ Major: 1, Minor: 10, - Patch: 15, + Patch: 16, } CurrentApp = &Application{ Major: Current.Major, From 6ad31d6ffdba7fac4bdf4645f1d95586cd699d97 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 22 Nov 2023 17:40:43 -0800 Subject: [PATCH 065/267] Remove Banff check from mempool verifier (#2360) --- vms/platformvm/txs/executor/tx_mempool_verifier.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/vms/platformvm/txs/executor/tx_mempool_verifier.go b/vms/platformvm/txs/executor/tx_mempool_verifier.go index 6704ccbd0489..f6eff499c2ec 100644 --- a/vms/platformvm/txs/executor/tx_mempool_verifier.go +++ b/vms/platformvm/txs/executor/tx_mempool_verifier.go @@ -102,9 +102,6 @@ func (v *MempoolTxVerifier) standardTx(tx txs.UnsignedTx) error { return err } -// Upon Banff activation, txs are not verified against current chain time -// but against the block timestamp. [baseTime] calculates -// the right timestamp to be used to mempool tx verification func (v *MempoolTxVerifier) standardBaseState() (state.Diff, error) { state, err := state.NewDiff(v.ParentID, v.StateVersions) if err != nil { @@ -116,14 +113,6 @@ func (v *MempoolTxVerifier) standardBaseState() (state.Diff, error) { return nil, err } - if !v.Backend.Config.IsBanffActivated(nextBlkTime) { - // next tx would be included into an Apricot block - // so we verify it against current chain state - return state, nil - } - - // next tx would be included into a Banff block - // so we verify it against duly updated chain state changes, err := AdvanceTimeTo(v.Backend, state, nextBlkTime) if err != nil { return nil, err From 9353569fd9a0a78ae0414cfc735ea42222b107d3 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 24 Nov 2023 11:23:36 -0500 Subject: [PATCH 066/267] Document storage growth in readme (#2364) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0eb539f9f0d5..7842615f35be 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ The minimum recommended hardware specification for nodes connected to Mainnet is - CPU: Equivalent of 8 AWS vCPU - RAM: 16 GiB - Storage: 1 TiB + - Nodes running for very long periods of time or nodes with custom configurations may observe higher storage requirements. - OS: Ubuntu 20.04/22.04 or macOS >= 12 - Network: Reliable IPv4 or IPv6 network connection, with an open public port. From 8d9b93c14387c8b566051cf96a3feed174930ec5 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 24 Nov 2023 12:45:51 -0500 Subject: [PATCH 067/267] Add metric for duration between block timestamp and block acceptance time (#2366) --- snow/consensus/snowman/metrics.go | 43 ++++++++++++++-------- snow/consensus/snowman/topological.go | 4 +- snow/engine/snowman/bootstrap/block_job.go | 3 +- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/snow/consensus/snowman/metrics.go b/snow/consensus/snowman/metrics.go index 9dfac39880ab..6e5159d6c1a5 100644 --- a/snow/consensus/snowman/metrics.go +++ b/snow/consensus/snowman/metrics.go @@ -41,21 +41,22 @@ type metrics struct { // numProcessing keeps track of the number of processing blocks numProcessing prometheus.Gauge + blockSizeAcceptedSum prometheus.Gauge // pollsAccepted tracks the number of polls that a block was in processing // for before being accepted pollsAccepted metric.Averager // latAccepted tracks the number of nanoseconds that a block was processing // before being accepted latAccepted metric.Averager - blockSizeAcceptedSum prometheus.Gauge + buildLatencyAccepted prometheus.Gauge + blockSizeRejectedSum prometheus.Gauge // pollsRejected tracks the number of polls that a block was in processing // for before being rejected pollsRejected metric.Averager // latRejected tracks the number of nanoseconds that a block was processing // before being rejected - latRejected metric.Averager - blockSizeRejectedSum prometheus.Gauge + latRejected metric.Averager // numFailedPolls keeps track of the number of polls that failed numFailedPolls prometheus.Counter @@ -101,6 +102,11 @@ func newMetrics( Help: "number of currently processing blocks", }), + blockSizeAcceptedSum: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "blks_accepted_container_size_sum", + Help: "cumulative size of all accepted blocks", + }), pollsAccepted: metric.NewAveragerWithErrs( namespace, "blks_polls_accepted", @@ -121,12 +127,17 @@ func newMetrics( reg, &errs, ), - blockSizeAcceptedSum: prometheus.NewGauge(prometheus.GaugeOpts{ + buildLatencyAccepted: prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, - Name: "blks_accepted_container_size_sum", - Help: "cumulative size of all accepted blocks", + Name: "blks_build_accept_latency", + Help: "time (in ns) from the timestamp of a block to the time it was accepted", }), + blockSizeRejectedSum: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "blks_rejected_container_size_sum", + Help: "cumulative size of all rejected blocks", + }), pollsRejected: metric.NewAveragerWithErrs( namespace, "blks_polls_rejected", @@ -147,11 +158,6 @@ func newMetrics( reg, &errs, ), - blockSizeRejectedSum: prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "blks_rejected_container_size_sum", - Help: "cumulative size of all rejected blocks", - }), numSuccessfulPolls: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: namespace, @@ -176,6 +182,7 @@ func newMetrics( reg.Register(m.lastAcceptedTimestamp), reg.Register(m.numProcessing), reg.Register(m.blockSizeAcceptedSum), + reg.Register(m.buildLatencyAccepted), reg.Register(m.blockSizeRejectedSum), reg.Register(m.numSuccessfulPolls), reg.Register(m.numFailedPolls), @@ -216,12 +223,16 @@ func (m *metrics) Accepted( m.processingBlocks.Delete(blkID) m.numProcessing.Dec() + m.blockSizeAcceptedSum.Add(float64(blockSize)) + m.pollsAccepted.Observe(float64(pollNumber - start.pollNumber)) - duration := time.Since(start.time) - m.latAccepted.Observe(float64(duration)) + now := time.Now() + processingDuration := now.Sub(start.time) + m.latAccepted.Observe(float64(processingDuration)) - m.blockSizeAcceptedSum.Add(float64(blockSize)) + builtDuration := now.Sub(timestamp) + m.buildLatencyAccepted.Add(float64(builtDuration)) } func (m *metrics) Rejected(blkID ids.ID, pollNumber uint64, blockSize int) { @@ -236,12 +247,12 @@ func (m *metrics) Rejected(blkID ids.ID, pollNumber uint64, blockSize int) { m.processingBlocks.Delete(blkID) m.numProcessing.Dec() + m.blockSizeRejectedSum.Add(float64(blockSize)) + m.pollsRejected.Observe(float64(pollNumber - start.pollNumber)) duration := time.Since(start.time) m.latRejected.Observe(float64(duration)) - - m.blockSizeRejectedSum.Add(float64(blockSize)) } func (m *metrics) MeasureAndGetOldestDuration() time.Duration { diff --git a/snow/consensus/snowman/topological.go b/snow/consensus/snowman/topological.go index bc68762c894e..f3fc838a8f8b 100644 --- a/snow/consensus/snowman/topological.go +++ b/snow/consensus/snowman/topological.go @@ -622,9 +622,11 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock } height := child.Height() + timestamp := child.Timestamp() ts.ctx.Log.Trace("accepting block", zap.Stringer("blkID", pref), zap.Uint64("height", height), + zap.Time("timestamp", timestamp), ) if err := child.Accept(ctx); err != nil { return err @@ -641,7 +643,7 @@ func (ts *Topological) acceptPreferredChild(ctx context.Context, n *snowmanBlock ts.metrics.Accepted( pref, height, - child.Timestamp(), + timestamp, ts.pollNumber, len(bytes), ) diff --git a/snow/engine/snowman/bootstrap/block_job.go b/snow/engine/snowman/bootstrap/block_job.go index 83d86af27d1a..06ae8fbcb84f 100644 --- a/snow/engine/snowman/bootstrap/block_job.go +++ b/snow/engine/snowman/bootstrap/block_job.go @@ -98,7 +98,8 @@ func (b *blockJob) Execute(ctx context.Context) error { b.numAccepted.Inc() b.log.Trace("accepting block in bootstrapping", zap.Stringer("blkID", blkID), - zap.Uint64("blkHeight", b.blk.Height()), + zap.Uint64("height", b.blk.Height()), + zap.Time("timestamp", b.blk.Timestamp()), ) if err := b.blk.Accept(ctx); err != nil { b.log.Debug("failed to accept block during bootstrapping", From b1b051a89f9af6d8240a4e3f95bfaeec623fc192 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Sat, 25 Nov 2023 16:32:05 -0800 Subject: [PATCH 068/267] `vms/platformvm`: Remove unused `withMetrics` txheap (#2373) --- vms/platformvm/txs/txheap/with_metrics.go | 52 ----------------------- 1 file changed, 52 deletions(-) delete mode 100644 vms/platformvm/txs/txheap/with_metrics.go diff --git a/vms/platformvm/txs/txheap/with_metrics.go b/vms/platformvm/txs/txheap/with_metrics.go deleted file mode 100644 index 60ab4f93244d..000000000000 --- a/vms/platformvm/txs/txheap/with_metrics.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package txheap - -import ( - "github.com/prometheus/client_golang/prometheus" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" -) - -var _ Heap = (*withMetrics)(nil) - -type withMetrics struct { - Heap - - numTxs prometheus.Gauge -} - -func NewWithMetrics( - txHeap Heap, - namespace string, - registerer prometheus.Registerer, -) (Heap, error) { - h := &withMetrics{ - Heap: txHeap, - numTxs: prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "count", - Help: "Number of transactions in the heap", - }), - } - return h, registerer.Register(h.numTxs) -} - -func (h *withMetrics) Add(tx *txs.Tx) { - h.Heap.Add(tx) - h.numTxs.Set(float64(h.Heap.Len())) -} - -func (h *withMetrics) Remove(txID ids.ID) *txs.Tx { - tx := h.Heap.Remove(txID) - h.numTxs.Set(float64(h.Heap.Len())) - return tx -} - -func (h *withMetrics) RemoveTop() *txs.Tx { - tx := h.Heap.RemoveTop() - h.numTxs.Set(float64(h.Heap.Len())) - return tx -} From e04dad8576ad69f1d6c5aa13e005180ac46aadf6 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Sun, 26 Nov 2023 13:13:56 -0500 Subject: [PATCH 069/267] Move peerTracker from x/sync to network/p2p (#2356) --- {x/sync => network/p2p}/peer_tracker.go | 25 ++++--- network/p2p/peer_tracker_test.go | 99 +++++++++++++++++++++++++ x/sync/network_client.go | 5 +- 3 files changed, 115 insertions(+), 14 deletions(-) rename {x/sync => network/p2p}/peer_tracker.go (94%) create mode 100644 network/p2p/peer_tracker_test.go diff --git a/x/sync/peer_tracker.go b/network/p2p/peer_tracker.go similarity index 94% rename from x/sync/peer_tracker.go rename to network/p2p/peer_tracker.go index a1f8a66ae711..338d890bed22 100644 --- a/x/sync/peer_tracker.go +++ b/network/p2p/peer_tracker.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package sync +package p2p import ( "math" @@ -45,7 +45,7 @@ type peerInfo struct { // Tracks the bandwidth of responses coming from peers, // preferring to contact peers with known good bandwidth, connecting // to new peers with an exponentially decaying probability. -type peerTracker struct { +type PeerTracker struct { // Lock to protect concurrent access to the peer tracker lock sync.Mutex // All peers we are connected to @@ -64,12 +64,12 @@ type peerTracker struct { averageBandwidthMetric prometheus.Gauge } -func newPeerTracker( +func NewPeerTracker( log logging.Logger, metricsNamespace string, registerer prometheus.Registerer, -) (*peerTracker, error) { - t := &peerTracker{ +) (*PeerTracker, error) { + t := &PeerTracker{ peers: make(map[ids.NodeID]*peerInfo), trackedPeers: make(set.Set[ids.NodeID]), responsivePeers: make(set.Set[ids.NodeID]), @@ -112,7 +112,7 @@ func newPeerTracker( // Returns true if we're not connected to enough peers. // Otherwise returns true probabilistically based on the number of tracked peers. // Assumes p.lock is held. -func (p *peerTracker) shouldTrackNewPeer() bool { +func (p *PeerTracker) shouldTrackNewPeer() bool { numResponsivePeers := p.responsivePeers.Len() if numResponsivePeers < desiredMinResponsivePeers { return true @@ -137,11 +137,12 @@ func (p *peerTracker) shouldTrackNewPeer() bool { return rand.Float64() < newPeerProbability // #nosec G404 } +// TODO get rid of minVersion // Returns a peer that we're connected to. // If we should track more peers, returns a random peer with version >= [minVersion], if any exist. // Otherwise, with probability [randomPeerProbability] returns a random peer from [p.responsivePeers]. // With probability [1-randomPeerProbability] returns the peer in [p.bandwidthHeap] with the highest bandwidth. -func (p *peerTracker) GetAnyPeer(minVersion *version.Application) (ids.NodeID, bool) { +func (p *PeerTracker) GetAnyPeer(minVersion *version.Application) (ids.NodeID, bool) { p.lock.Lock() defer p.lock.Unlock() @@ -187,7 +188,7 @@ func (p *peerTracker) GetAnyPeer(minVersion *version.Application) (ids.NodeID, b } // Record that we sent a request to [nodeID]. -func (p *peerTracker) TrackPeer(nodeID ids.NodeID) { +func (p *PeerTracker) TrackPeer(nodeID ids.NodeID) { p.lock.Lock() defer p.lock.Unlock() @@ -197,7 +198,7 @@ func (p *peerTracker) TrackPeer(nodeID ids.NodeID) { // Record that we observed that [nodeID]'s bandwidth is [bandwidth]. // Adds the peer's bandwidth averager to the bandwidth heap. -func (p *peerTracker) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) { +func (p *PeerTracker) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) { p.lock.Lock() defer p.lock.Unlock() @@ -229,7 +230,7 @@ func (p *peerTracker) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) { } // Connected should be called when [nodeID] connects to this node -func (p *peerTracker) Connected(nodeID ids.NodeID, nodeVersion *version.Application) { +func (p *PeerTracker) Connected(nodeID ids.NodeID, nodeVersion *version.Application) { p.lock.Lock() defer p.lock.Unlock() @@ -264,7 +265,7 @@ func (p *peerTracker) Connected(nodeID ids.NodeID, nodeVersion *version.Applicat } // Disconnected should be called when [nodeID] disconnects from this node -func (p *peerTracker) Disconnected(nodeID ids.NodeID) { +func (p *PeerTracker) Disconnected(nodeID ids.NodeID) { p.lock.Lock() defer p.lock.Unlock() @@ -277,7 +278,7 @@ func (p *peerTracker) Disconnected(nodeID ids.NodeID) { } // Returns the number of peers the node is connected to. -func (p *peerTracker) Size() int { +func (p *PeerTracker) Size() int { p.lock.Lock() defer p.lock.Unlock() diff --git a/network/p2p/peer_tracker_test.go b/network/p2p/peer_tracker_test.go new file mode 100644 index 000000000000..d7c38b828e9d --- /dev/null +++ b/network/p2p/peer_tracker_test.go @@ -0,0 +1,99 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package p2p + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/version" +) + +func TestPeerTracker(t *testing.T) { + require := require.New(t) + p, err := NewPeerTracker(logging.NoLog{}, "", prometheus.NewRegistry()) + require.NoError(err) + + // Connect some peers + numExtraPeers := 10 + numPeers := desiredMinResponsivePeers + numExtraPeers + peerIDs := make([]ids.NodeID, numPeers) + peerVersion := &version.Application{ + Major: 1, + Minor: 2, + Patch: 3, + } + + for i := range peerIDs { + peerIDs[i] = ids.GenerateTestNodeID() + p.Connected(peerIDs[i], peerVersion) + } + + responsivePeers := make(map[ids.NodeID]bool) + + // Expect requests to go to new peers until we have desiredMinResponsivePeers responsive peers. + for i := 0; i < desiredMinResponsivePeers+numExtraPeers/2; i++ { + peer, ok := p.GetAnyPeer(nil) + require.True(ok) + require.NotNil(peer) + + _, exists := responsivePeers[peer] + require.Falsef(exists, "expected connecting to a new peer, but got the same peer twice: peer %s iteration %d", peer, i) + responsivePeers[peer] = true + + p.TrackPeer(peer) // mark the peer as having a message sent to it + } + + // Mark some peers as responsive and others as not responsive + i := 0 + for peer := range responsivePeers { + if i < desiredMinResponsivePeers { + p.TrackBandwidth(peer, 10) + } else { + responsivePeers[peer] = false // remember which peers were not responsive + p.TrackBandwidth(peer, 0) + } + i++ + } + + // Expect requests to go to responsive or new peers, so long as they are available + numRequests := 50 + for i := 0; i < numRequests; i++ { + peer, ok := p.GetAnyPeer(nil) + require.True(ok) + require.NotNil(peer) + + responsive, ok := responsivePeers[peer] + if ok { + require.Truef(responsive, "expected connecting to a responsive peer, but got a peer that was not responsive: peer %s iteration %d", peer, i) + p.TrackBandwidth(peer, 10) + } else { + responsivePeers[peer] = false // remember that we connected to this peer + p.TrackPeer(peer) // mark the peer as having a message sent to it + p.TrackBandwidth(peer, 0) // mark the peer as non-responsive + } + } + + // Disconnect from peers that were previously responsive and ones we didn't connect to yet. + for _, peer := range peerIDs { + responsive, ok := responsivePeers[peer] + if ok && responsive || !ok { + p.Disconnected(peer) + } + } + + // Requests should fall back on non-responsive peers when no other choice is left + peer, ok := p.GetAnyPeer(nil) + require.True(ok) + require.NotNil(peer) + + responsive, ok := responsivePeers[peer] + require.True(ok) + require.Falsef(responsive, "expected connecting to a non-responsive peer, but got a peer that was responsive: peer %s", peer) +} diff --git a/x/sync/network_client.go b/x/sync/network_client.go index 65f939019d7f..efc3c6ef089e 100644 --- a/x/sync/network_client.go +++ b/x/sync/network_client.go @@ -17,6 +17,7 @@ import ( "golang.org/x/sync/semaphore" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" @@ -87,7 +88,7 @@ type networkClient struct { // controls maximum number of active outbound requests activeRequests *semaphore.Weighted // tracking of peers & bandwidth usage - peers *peerTracker + peers *p2p.PeerTracker // For sending messages to peers appSender common.AppSender } @@ -100,7 +101,7 @@ func NewNetworkClient( metricsNamespace string, registerer prometheus.Registerer, ) (NetworkClient, error) { - peerTracker, err := newPeerTracker(log, metricsNamespace, registerer) + peerTracker, err := p2p.NewPeerTracker(log, metricsNamespace, registerer) if err != nil { return nil, fmt.Errorf("failed to create peer tracker: %w", err) } From 79e572d17d029b216fcc09fc84c8b41682571f61 Mon Sep 17 00:00:00 2001 From: felipemadero Date: Mon, 27 Nov 2023 13:43:32 -0300 Subject: [PATCH 070/267] Avoid closing stdout and stderr during log close (#2372) --- utils/logging/log.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/logging/log.go b/utils/logging/log.go index 006c487d608f..a5e6c9d79a05 100644 --- a/utils/logging/log.go +++ b/utils/logging/log.go @@ -5,6 +5,7 @@ package logging import ( "io" + "os" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -67,7 +68,9 @@ func (l *log) Write(p []byte) (int, error) { // TODO: return errors here func (l *log) Stop() { for _, wc := range l.wrappedCores { - _ = wc.Writer.Close() + if wc.Writer != os.Stdout && wc.Writer != os.Stderr { + _ = wc.Writer.Close() + } } } From 42161aaf62aeea4dcf822e4449591ad191045ed1 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 27 Nov 2023 09:07:48 -0800 Subject: [PATCH 071/267] `vms/platformvm`: Adjust `Diff.Apply` signature (#2368) --- vms/platformvm/state/diff.go | 4 +- vms/platformvm/state/diff_test.go | 108 ++++++++++++++++++++++++++++++ vms/platformvm/state/mock_diff.go | 2 +- 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/vms/platformvm/state/diff.go b/vms/platformvm/state/diff.go index 91a5f040a2b4..1aafcf079969 100644 --- a/vms/platformvm/state/diff.go +++ b/vms/platformvm/state/diff.go @@ -25,7 +25,7 @@ var ( type Diff interface { Chain - Apply(State) error + Apply(Chain) error } type diff struct { @@ -479,7 +479,7 @@ func (d *diff) DeleteUTXO(utxoID ids.ID) { } } -func (d *diff) Apply(baseState State) error { +func (d *diff) Apply(baseState Chain) error { baseState.SetTimestamp(d.timestamp) for subnetID, supply := range d.currentSupply { baseState.SetCurrentSupply(subnetID, supply) diff --git a/vms/platformvm/state/diff_test.go b/vms/platformvm/state/diff_test.go index c35fb925594b..9b833f8482a8 100644 --- a/vms/platformvm/state/diff_test.go +++ b/vms/platformvm/state/diff_test.go @@ -578,3 +578,111 @@ func TestDiffSubnetOwner(t *testing.T) { require.NoError(err) require.Equal(owner2, owner) } + +func TestDiffStacking(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + state, _ := newInitializedState(require) + + states := NewMockVersions(ctrl) + lastAcceptedID := ids.GenerateTestID() + states.EXPECT().GetState(lastAcceptedID).Return(state, true).AnyTimes() + + var ( + owner1 = fx.NewMockOwner(ctrl) + owner2 = fx.NewMockOwner(ctrl) + owner3 = fx.NewMockOwner(ctrl) + + createSubnetTx = &txs.Tx{ + Unsigned: &txs.CreateSubnetTx{ + BaseTx: txs.BaseTx{}, + Owner: owner1, + }, + } + + subnetID = createSubnetTx.ID() + ) + + // Create subnet on base state + owner, err := state.GetSubnetOwner(subnetID) + require.ErrorIs(err, database.ErrNotFound) + require.Nil(owner) + + state.AddSubnet(createSubnetTx) + state.SetSubnetOwner(subnetID, owner1) + + owner, err = state.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner1, owner) + + // Create first diff and verify that subnet owner returns correctly + statesDiff, err := NewDiff(lastAcceptedID, states) + require.NoError(err) + + owner, err = statesDiff.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner1, owner) + + // Transferring subnet ownership on first diff should be reflected on first diff not state + statesDiff.SetSubnetOwner(subnetID, owner2) + owner, err = statesDiff.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner2, owner) + + owner, err = state.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner1, owner) + + // Create a second diff on first diff and verify that subnet owner returns correctly + stackedDiff, err := wrapState(statesDiff) + require.NoError(err) + owner, err = stackedDiff.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner2, owner) + + // Transfer ownership on stacked diff and verify it is only reflected on stacked diff + stackedDiff.SetSubnetOwner(subnetID, owner3) + owner, err = stackedDiff.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner3, owner) + + owner, err = statesDiff.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner2, owner) + + owner, err = state.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner1, owner) + + // Applying both diffs successively should work as expected. + require.NoError(stackedDiff.Apply(statesDiff)) + + owner, err = statesDiff.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner3, owner) + + owner, err = state.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner1, owner) + + require.NoError(statesDiff.Apply(state)) + + owner, err = state.GetSubnetOwner(subnetID) + require.NoError(err) + require.Equal(owner3, owner) +} + +type stateGetter struct { + state Chain +} + +func (s stateGetter) GetState(ids.ID) (Chain, bool) { + return s.state, true +} + +func wrapState(parentState Chain) (Diff, error) { + return NewDiff(ids.Empty, stateGetter{ + state: parentState, + }) +} diff --git a/vms/platformvm/state/mock_diff.go b/vms/platformvm/state/mock_diff.go index 49bab7897009..abb380ca6e5f 100644 --- a/vms/platformvm/state/mock_diff.go +++ b/vms/platformvm/state/mock_diff.go @@ -115,7 +115,7 @@ func (mr *MockDiffMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { } // Apply mocks base method. -func (m *MockDiff) Apply(arg0 State) error { +func (m *MockDiff) Apply(arg0 Chain) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Apply", arg0) ret0, _ := ret[0].(error) From b9ab41a0a0719b18e619822e07e3c3349d5ee2dc Mon Sep 17 00:00:00 2001 From: felipemadero Date: Mon, 27 Nov 2023 14:44:54 -0300 Subject: [PATCH 072/267] Add option to provide BLS keys to validators in the genesis (#2371) --- genesis/config.go | 9 ++++-- genesis/genesis.go | 1 + genesis/unparsed_config.go | 9 ++++-- vms/platformvm/api/static_service.go | 45 ++++++++++++++++++++-------- vms/platformvm/state/state.go | 10 +++---- 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/genesis/config.go b/genesis/config.go index 2a7063f87940..a951e9e078fc 100644 --- a/genesis/config.go +++ b/genesis/config.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) var ( @@ -58,9 +59,10 @@ func (a Allocation) Less(other Allocation) bool { } type Staker struct { - NodeID ids.NodeID `json:"nodeID"` - RewardAddress ids.ShortID `json:"rewardAddress"` - DelegationFee uint32 `json:"delegationFee"` + NodeID ids.NodeID `json:"nodeID"` + RewardAddress ids.ShortID `json:"rewardAddress"` + DelegationFee uint32 `json:"delegationFee"` + Signer *signer.ProofOfPossession `json:"signer,omitempty"` } func (s Staker) Unparse(networkID uint32) (UnparsedStaker, error) { @@ -73,6 +75,7 @@ func (s Staker) Unparse(networkID uint32) (UnparsedStaker, error) { NodeID: s.NodeID, RewardAddress: avaxAddr, DelegationFee: s.DelegationFee, + Signer: s.Signer, }, err } diff --git a/genesis/genesis.go b/genesis/genesis.go index e59b8c6fbbbc..533795b56973 100644 --- a/genesis/genesis.go +++ b/genesis/genesis.go @@ -430,6 +430,7 @@ func FromConfig(config *Config) ([]byte, ids.ID, error) { }, Staked: utxos, ExactDelegationFee: &delegationFee, + Signer: staker.Signer, }, ) } diff --git a/genesis/unparsed_config.go b/genesis/unparsed_config.go index 9831d835add9..647443bae482 100644 --- a/genesis/unparsed_config.go +++ b/genesis/unparsed_config.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/formatting/address" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) var errInvalidETHAddress = errors.New("invalid eth address") @@ -54,15 +55,17 @@ func (ua UnparsedAllocation) Parse() (Allocation, error) { } type UnparsedStaker struct { - NodeID ids.NodeID `json:"nodeID"` - RewardAddress string `json:"rewardAddress"` - DelegationFee uint32 `json:"delegationFee"` + NodeID ids.NodeID `json:"nodeID"` + RewardAddress string `json:"rewardAddress"` + DelegationFee uint32 `json:"delegationFee"` + Signer *signer.ProofOfPossession `json:"signer,omitempty"` } func (us UnparsedStaker) Parse() (Staker, error) { s := Staker{ NodeID: us.NodeID, DelegationFee: us.DelegationFee, + Signer: us.Signer, } _, _, avaxAddrBytes, err := address.Parse(us.RewardAddress) diff --git a/vms/platformvm/api/static_service.go b/vms/platformvm/api/static_service.go index 1cf2fbe29096..ea1cfcb2d63f 100644 --- a/vms/platformvm/api/static_service.go +++ b/vms/platformvm/api/static_service.go @@ -138,10 +138,11 @@ type PermissionlessValidator struct { // GenesisPermissionlessValidator should to be used for genesis validators only. type GenesisPermissionlessValidator struct { GenesisValidator - RewardOwner *Owner `json:"rewardOwner,omitempty"` - DelegationFee json.Float32 `json:"delegationFee"` - ExactDelegationFee *json.Uint32 `json:"exactDelegationFee,omitempty"` - Staked []UTXO `json:"staked,omitempty"` + RewardOwner *Owner `json:"rewardOwner,omitempty"` + DelegationFee json.Float32 `json:"delegationFee"` + ExactDelegationFee *json.Uint32 `json:"exactDelegationFee,omitempty"` + Staked []UTXO `json:"staked,omitempty"` + Signer *signer.ProofOfPossession `json:"signer,omitempty"` } // PermissionedValidator is the repr. of a permissioned validator sent over APIs. @@ -315,21 +316,39 @@ func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, repl delegationFee = uint32(*vdr.ExactDelegationFee) } - tx := &txs.Tx{Unsigned: &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + var ( + baseTx = txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: uint32(args.NetworkID), BlockchainID: ids.Empty, - }}, - Validator: txs.Validator{ + }} + validator = txs.Validator{ NodeID: vdr.NodeID, Start: uint64(args.Time), End: uint64(vdr.EndTime), Wght: weight, - }, - StakeOuts: stake, - RewardsOwner: owner, - DelegationShares: delegationFee, - }} + } + tx *txs.Tx + ) + if vdr.Signer == nil { + tx = &txs.Tx{Unsigned: &txs.AddValidatorTx{ + BaseTx: baseTx, + Validator: validator, + StakeOuts: stake, + RewardsOwner: owner, + DelegationShares: delegationFee, + }} + } else { + tx = &txs.Tx{Unsigned: &txs.AddPermissionlessValidatorTx{ + BaseTx: baseTx, + Validator: validator, + Signer: vdr.Signer, + StakeOuts: stake, + ValidatorRewardsOwner: owner, + DelegatorRewardsOwner: owner, + DelegationShares: delegationFee, + }} + } + if err := tx.Initialize(txs.GenesisCodec); err != nil { return err } diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 199b245008f7..4b2b59cf2f70 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1319,13 +1319,13 @@ func (s *state) syncGenesis(genesisBlk block.Block, genesis *genesis.Genesis) er // Persist primary network validator set at genesis for _, vdrTx := range genesis.Validators { - tx, ok := vdrTx.Unsigned.(*txs.AddValidatorTx) + validatorTx, ok := vdrTx.Unsigned.(txs.ValidatorTx) if !ok { - return fmt.Errorf("expected tx type *txs.AddValidatorTx but got %T", vdrTx.Unsigned) + return fmt.Errorf("expected tx type txs.ValidatorTx but got %T", vdrTx.Unsigned) } - stakeAmount := tx.Validator.Wght - stakeDuration := tx.Validator.Duration() + stakeAmount := validatorTx.Weight() + stakeDuration := validatorTx.EndTime().Sub(validatorTx.StartTime()) currentSupply, err := s.GetCurrentSupply(constants.PrimaryNetworkID) if err != nil { return err @@ -1341,7 +1341,7 @@ func (s *state) syncGenesis(genesisBlk block.Block, genesis *genesis.Genesis) er return err } - staker, err := NewCurrentStaker(vdrTx.ID(), tx, potentialReward) + staker, err := NewCurrentStaker(vdrTx.ID(), validatorTx, potentialReward) if err != nil { return err } From 3a424d000fde0916da4fd935650cca4f20e6c6e7 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 27 Nov 2023 13:36:03 -0500 Subject: [PATCH 073/267] Remove `engine.GetVM` (#2374) --- snow/engine/avalanche/bootstrap/bootstrapper.go | 4 ---- snow/engine/avalanche/engine.go | 4 ---- snow/engine/common/engine.go | 3 --- snow/engine/common/test_engine.go | 13 ------------- snow/engine/common/traced_engine.go | 4 ---- snow/engine/snowman/bootstrap/bootstrapper.go | 4 ---- snow/engine/snowman/syncer/state_syncer.go | 4 ---- snow/engine/snowman/transitive.go | 4 ---- 8 files changed, 40 deletions(-) diff --git a/snow/engine/avalanche/bootstrap/bootstrapper.go b/snow/engine/avalanche/bootstrap/bootstrapper.go index c6ef6513b668..6a4cc974e648 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper.go @@ -379,10 +379,6 @@ func (b *bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { return intf, vmErr } -func (b *bootstrapper) GetVM() common.VM { - return b.VM -} - // Add the vertices in [vtxIDs] to the set of vertices that we need to fetch, // and then fetch vertices (and their ancestors) until either there are no more // to fetch or we are at the maximum number of outstanding requests. diff --git a/snow/engine/avalanche/engine.go b/snow/engine/avalanche/engine.go index 9b828ac05946..375666c99598 100644 --- a/snow/engine/avalanche/engine.go +++ b/snow/engine/avalanche/engine.go @@ -66,10 +66,6 @@ func (e *engine) Context() *snow.ConsensusContext { return e.ctx } -func (e *engine) GetVM() common.VM { - return e.vm -} - func (*engine) HealthCheck(context.Context) (interface{}, error) { return nil, nil } diff --git a/snow/engine/common/engine.go b/snow/engine/common/engine.go index d92911ff1f7f..e50d94327a30 100644 --- a/snow/engine/common/engine.go +++ b/snow/engine/common/engine.go @@ -32,9 +32,6 @@ type Engine interface { // Returns nil if the engine is healthy. // Periodically called and reported through the health API health.Checker - - // GetVM returns this engine's VM - GetVM() VM } type Handler interface { diff --git a/snow/engine/common/test_engine.go b/snow/engine/common/test_engine.go index 3eb376de8e32..0081d63b5753 100644 --- a/snow/engine/common/test_engine.go +++ b/snow/engine/common/test_engine.go @@ -691,16 +691,3 @@ func (e *EngineTest) HealthCheck(ctx context.Context) (interface{}, error) { } return nil, errHealthCheck } - -func (e *EngineTest) GetVM() VM { - if e.GetVMF != nil { - return e.GetVMF() - } - if !e.CantGetVM { - return nil - } - if e.T != nil { - require.FailNow(e.T, "Unexpectedly called GetVM") - } - return nil -} diff --git a/snow/engine/common/traced_engine.go b/snow/engine/common/traced_engine.go index 9050f29cd1e1..28be03d6df7c 100644 --- a/snow/engine/common/traced_engine.go +++ b/snow/engine/common/traced_engine.go @@ -418,7 +418,3 @@ func (e *tracedEngine) HealthCheck(ctx context.Context) (interface{}, error) { return e.engine.HealthCheck(ctx) } - -func (e *tracedEngine) GetVM() VM { - return e.engine.GetVM() -} diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index 224cded68311..728e38af59cf 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -345,10 +345,6 @@ func (b *Bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { return intf, vmErr } -func (b *Bootstrapper) GetVM() common.VM { - return b.VM -} - func (b *Bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs []ids.ID) error { pendingContainerIDs := b.Blocked.MissingIDs() diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index 89c839a25dcd..8b7431558be6 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -618,10 +618,6 @@ func (ss *stateSyncer) HealthCheck(ctx context.Context) (interface{}, error) { return intf, vmErr } -func (ss *stateSyncer) GetVM() common.VM { - return ss.VM -} - func (ss *stateSyncer) IsEnabled(ctx context.Context) (bool, error) { if ss.stateSyncVM == nil { // state sync is not implemented diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index b4c5e3e54b51..8e2b98dc5a38 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -480,10 +480,6 @@ func (t *Transitive) HealthCheck(ctx context.Context) (interface{}, error) { return intf, fmt.Errorf("vm: %w ; consensus: %w", vmErr, consensusErr) } -func (t *Transitive) GetVM() common.VM { - return t.VM -} - func (t *Transitive) GetBlock(ctx context.Context, blkID ids.ID) (snowman.Block, error) { if blk, ok := t.pending[blkID]; ok { return blk, nil From 9ad213c3166e73b185281f37d64d39be8d865c5b Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 27 Nov 2023 11:45:03 -0800 Subject: [PATCH 074/267] `vms/platformvm`: Consolidate `state` pkg mocks (#2370) --- scripts/mocks.mockgen.txt | 5 +- vms/platformvm/state/mock_chain.go | 513 ------------ vms/platformvm/state/mock_diff.go | 527 ------------- vms/platformvm/state/mock_state.go | 1040 ++++++++++++++++++++++++- vms/platformvm/state/mock_versions.go | 53 -- 5 files changed, 1040 insertions(+), 1098 deletions(-) delete mode 100644 vms/platformvm/state/mock_chain.go delete mode 100644 vms/platformvm/state/mock_diff.go delete mode 100644 vms/platformvm/state/mock_versions.go diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 4b7afa01849f..ba55a16a4b71 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -33,11 +33,8 @@ github.com/ava-labs/avalanchego/vms/components/avax=TransferableIn=vms/component github.com/ava-labs/avalanchego/vms/components/verify=Verifiable=vms/components/verify/mock_verifiable.go github.com/ava-labs/avalanchego/vms/platformvm/block/executor=Manager=vms/platformvm/block/executor/mock_manager.go github.com/ava-labs/avalanchego/vms/platformvm/block=Block=vms/platformvm/block/mock_block.go -github.com/ava-labs/avalanchego/vms/platformvm/state=Chain=vms/platformvm/state/mock_chain.go -github.com/ava-labs/avalanchego/vms/platformvm/state=Diff=vms/platformvm/state/mock_diff.go +github.com/ava-labs/avalanchego/vms/platformvm/state=Chain,Diff,State,Versions=vms/platformvm/state/mock_state.go github.com/ava-labs/avalanchego/vms/platformvm/state=StakerIterator=vms/platformvm/state/mock_staker_iterator.go -github.com/ava-labs/avalanchego/vms/platformvm/state=State=vms/platformvm/state/mock_state.go -github.com/ava-labs/avalanchego/vms/platformvm/state=Versions=vms/platformvm/state/mock_versions.go github.com/ava-labs/avalanchego/vms/platformvm/txs/builder=Builder=vms/platformvm/txs/builder/mock_builder.go github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool=Mempool=vms/platformvm/txs/mempool/mock_mempool.go github.com/ava-labs/avalanchego/vms/platformvm/utxo=Verifier=vms/platformvm/utxo/mock_verifier.go diff --git a/vms/platformvm/state/mock_chain.go b/vms/platformvm/state/mock_chain.go deleted file mode 100644 index c82ceb3af831..000000000000 --- a/vms/platformvm/state/mock_chain.go +++ /dev/null @@ -1,513 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Chain) - -// Package state is a generated GoMock package. -package state - -import ( - reflect "reflect" - time "time" - - ids "github.com/ava-labs/avalanchego/ids" - avax "github.com/ava-labs/avalanchego/vms/components/avax" - fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" - status "github.com/ava-labs/avalanchego/vms/platformvm/status" - txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" - gomock "go.uber.org/mock/gomock" -) - -// MockChain is a mock of Chain interface. -type MockChain struct { - ctrl *gomock.Controller - recorder *MockChainMockRecorder -} - -// MockChainMockRecorder is the mock recorder for MockChain. -type MockChainMockRecorder struct { - mock *MockChain -} - -// NewMockChain creates a new mock instance. -func NewMockChain(ctrl *gomock.Controller) *MockChain { - mock := &MockChain{ctrl: ctrl} - mock.recorder = &MockChainMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockChain) EXPECT() *MockChainMockRecorder { - return m.recorder -} - -// AddChain mocks base method. -func (m *MockChain) AddChain(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0) -} - -// AddChain indicates an expected call of AddChain. -func (mr *MockChainMockRecorder) AddChain(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockChain)(nil).AddChain), arg0) -} - -// AddRewardUTXO mocks base method. -func (m *MockChain) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) -} - -// AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockChainMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockChain)(nil).AddRewardUTXO), arg0, arg1) -} - -// AddSubnet mocks base method. -func (m *MockChain) AddSubnet(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnet", arg0) -} - -// AddSubnet indicates an expected call of AddSubnet. -func (mr *MockChainMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockChain)(nil).AddSubnet), arg0) -} - -// AddSubnetTransformation mocks base method. -func (m *MockChain) AddSubnetTransformation(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnetTransformation", arg0) -} - -// AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockChainMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockChain)(nil).AddSubnetTransformation), arg0) -} - -// AddTx mocks base method. -func (m *MockChain) AddTx(arg0 *txs.Tx, arg1 status.Status) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddTx", arg0, arg1) -} - -// AddTx indicates an expected call of AddTx. -func (mr *MockChainMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockChain)(nil).AddTx), arg0, arg1) -} - -// AddUTXO mocks base method. -func (m *MockChain) AddUTXO(arg0 *avax.UTXO) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddUTXO", arg0) -} - -// AddUTXO indicates an expected call of AddUTXO. -func (mr *MockChainMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockChain)(nil).AddUTXO), arg0) -} - -// DeleteCurrentDelegator mocks base method. -func (m *MockChain) DeleteCurrentDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) -} - -// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockChainMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentDelegator), arg0) -} - -// DeleteCurrentValidator mocks base method. -func (m *MockChain) DeleteCurrentValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentValidator", arg0) -} - -// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockChainMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentValidator), arg0) -} - -// DeletePendingDelegator mocks base method. -func (m *MockChain) DeletePendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingDelegator", arg0) -} - -// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockChainMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockChain)(nil).DeletePendingDelegator), arg0) -} - -// DeletePendingValidator mocks base method. -func (m *MockChain) DeletePendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingValidator", arg0) -} - -// DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockChainMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockChain)(nil).DeletePendingValidator), arg0) -} - -// DeleteUTXO mocks base method. -func (m *MockChain) DeleteUTXO(arg0 ids.ID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteUTXO", arg0) -} - -// DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockChainMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), arg0) -} - -// GetChains mocks base method. -func (m *MockChain) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChains", arg0) - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChains indicates an expected call of GetChains. -func (mr *MockChainMockRecorder) GetChains(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockChain)(nil).GetChains), arg0) -} - -// GetCurrentDelegatorIterator mocks base method. -func (m *MockChain) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), arg0, arg1) -} - -// GetCurrentStakerIterator mocks base method. -func (m *MockChain) GetCurrentStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. -func (mr *MockChainMockRecorder) GetCurrentStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentStakerIterator)) -} - -// GetCurrentSupply mocks base method. -func (m *MockChain) GetCurrentSupply(arg0 ids.ID) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockChainMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockChain)(nil).GetCurrentSupply), arg0) -} - -// GetCurrentValidator mocks base method. -func (m *MockChain) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockChainMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockChain)(nil).GetCurrentValidator), arg0, arg1) -} - -// GetDelegateeReward mocks base method. -func (m *MockChain) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockChainMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockChain)(nil).GetDelegateeReward), arg0, arg1) -} - -// GetPendingDelegatorIterator mocks base method. -func (m *MockChain) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetPendingDelegatorIterator), arg0, arg1) -} - -// GetPendingStakerIterator mocks base method. -func (m *MockChain) GetPendingStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. -func (mr *MockChainMockRecorder) GetPendingStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockChain)(nil).GetPendingStakerIterator)) -} - -// GetPendingValidator mocks base method. -func (m *MockChain) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), arg0, arg1) -} - -// GetRewardUTXOs mocks base method. -func (m *MockChain) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. -func (mr *MockChainMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockChain)(nil).GetRewardUTXOs), arg0) -} - -// GetSubnetOwner mocks base method. -func (m *MockChain) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockChainMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockChain)(nil).GetSubnetOwner), arg0) -} - -// GetSubnetTransformation mocks base method. -func (m *MockChain) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), arg0) -} - -// GetSubnets mocks base method. -func (m *MockChain) GetSubnets() ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnets") - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnets indicates an expected call of GetSubnets. -func (mr *MockChainMockRecorder) GetSubnets() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockChain)(nil).GetSubnets)) -} - -// GetTimestamp mocks base method. -func (m *MockChain) GetTimestamp() time.Time { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTimestamp") - ret0, _ := ret[0].(time.Time) - return ret0 -} - -// GetTimestamp indicates an expected call of GetTimestamp. -func (mr *MockChainMockRecorder) GetTimestamp() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockChain)(nil).GetTimestamp)) -} - -// GetTx mocks base method. -func (m *MockChain) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(status.Status) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetTx indicates an expected call of GetTx. -func (mr *MockChainMockRecorder) GetTx(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), arg0) -} - -// GetUTXO mocks base method. -func (m *MockChain) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0) - ret0, _ := ret[0].(*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetUTXO indicates an expected call of GetUTXO. -func (mr *MockChainMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), arg0) -} - -// PutCurrentDelegator mocks base method. -func (m *MockChain) PutCurrentDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentDelegator", arg0) -} - -// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockChainMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockChain)(nil).PutCurrentDelegator), arg0) -} - -// PutCurrentValidator mocks base method. -func (m *MockChain) PutCurrentValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentValidator", arg0) -} - -// PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockChainMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockChain)(nil).PutCurrentValidator), arg0) -} - -// PutPendingDelegator mocks base method. -func (m *MockChain) PutPendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingDelegator", arg0) -} - -// PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockChainMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockChain)(nil).PutPendingDelegator), arg0) -} - -// PutPendingValidator mocks base method. -func (m *MockChain) PutPendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingValidator", arg0) -} - -// PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockChainMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), arg0) -} - -// SetCurrentSupply mocks base method. -func (m *MockChain) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) -} - -// SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockChainMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockChain)(nil).SetCurrentSupply), arg0, arg1) -} - -// SetDelegateeReward mocks base method. -func (m *MockChain) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockChainMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockChain)(nil).SetDelegateeReward), arg0, arg1, arg2) -} - -// SetSubnetOwner mocks base method. -func (m *MockChain) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) -} - -// SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockChainMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockChain)(nil).SetSubnetOwner), arg0, arg1) -} - -// SetTimestamp mocks base method. -func (m *MockChain) SetTimestamp(arg0 time.Time) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetTimestamp", arg0) -} - -// SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockChainMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), arg0) -} diff --git a/vms/platformvm/state/mock_diff.go b/vms/platformvm/state/mock_diff.go deleted file mode 100644 index abb380ca6e5f..000000000000 --- a/vms/platformvm/state/mock_diff.go +++ /dev/null @@ -1,527 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Diff) - -// Package state is a generated GoMock package. -package state - -import ( - reflect "reflect" - time "time" - - ids "github.com/ava-labs/avalanchego/ids" - avax "github.com/ava-labs/avalanchego/vms/components/avax" - fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" - status "github.com/ava-labs/avalanchego/vms/platformvm/status" - txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" - gomock "go.uber.org/mock/gomock" -) - -// MockDiff is a mock of Diff interface. -type MockDiff struct { - ctrl *gomock.Controller - recorder *MockDiffMockRecorder -} - -// MockDiffMockRecorder is the mock recorder for MockDiff. -type MockDiffMockRecorder struct { - mock *MockDiff -} - -// NewMockDiff creates a new mock instance. -func NewMockDiff(ctrl *gomock.Controller) *MockDiff { - mock := &MockDiff{ctrl: ctrl} - mock.recorder = &MockDiffMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockDiff) EXPECT() *MockDiffMockRecorder { - return m.recorder -} - -// AddChain mocks base method. -func (m *MockDiff) AddChain(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0) -} - -// AddChain indicates an expected call of AddChain. -func (mr *MockDiffMockRecorder) AddChain(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockDiff)(nil).AddChain), arg0) -} - -// AddRewardUTXO mocks base method. -func (m *MockDiff) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) -} - -// AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockDiffMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockDiff)(nil).AddRewardUTXO), arg0, arg1) -} - -// AddSubnet mocks base method. -func (m *MockDiff) AddSubnet(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnet", arg0) -} - -// AddSubnet indicates an expected call of AddSubnet. -func (mr *MockDiffMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockDiff)(nil).AddSubnet), arg0) -} - -// AddSubnetTransformation mocks base method. -func (m *MockDiff) AddSubnetTransformation(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnetTransformation", arg0) -} - -// AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockDiffMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).AddSubnetTransformation), arg0) -} - -// AddTx mocks base method. -func (m *MockDiff) AddTx(arg0 *txs.Tx, arg1 status.Status) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddTx", arg0, arg1) -} - -// AddTx indicates an expected call of AddTx. -func (mr *MockDiffMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), arg0, arg1) -} - -// AddUTXO mocks base method. -func (m *MockDiff) AddUTXO(arg0 *avax.UTXO) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddUTXO", arg0) -} - -// AddUTXO indicates an expected call of AddUTXO. -func (mr *MockDiffMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), arg0) -} - -// Apply mocks base method. -func (m *MockDiff) Apply(arg0 Chain) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Apply", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Apply indicates an expected call of Apply. -func (mr *MockDiffMockRecorder) Apply(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) -} - -// DeleteCurrentDelegator mocks base method. -func (m *MockDiff) DeleteCurrentDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) -} - -// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentDelegator), arg0) -} - -// DeleteCurrentValidator mocks base method. -func (m *MockDiff) DeleteCurrentValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentValidator", arg0) -} - -// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockDiffMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentValidator), arg0) -} - -// DeletePendingDelegator mocks base method. -func (m *MockDiff) DeletePendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingDelegator", arg0) -} - -// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockDiffMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockDiff)(nil).DeletePendingDelegator), arg0) -} - -// DeletePendingValidator mocks base method. -func (m *MockDiff) DeletePendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingValidator", arg0) -} - -// DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockDiffMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockDiff)(nil).DeletePendingValidator), arg0) -} - -// DeleteUTXO mocks base method. -func (m *MockDiff) DeleteUTXO(arg0 ids.ID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteUTXO", arg0) -} - -// DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) -} - -// GetChains mocks base method. -func (m *MockDiff) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChains", arg0) - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChains indicates an expected call of GetChains. -func (mr *MockDiffMockRecorder) GetChains(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockDiff)(nil).GetChains), arg0) -} - -// GetCurrentDelegatorIterator mocks base method. -func (m *MockDiff) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentDelegatorIterator), arg0, arg1) -} - -// GetCurrentStakerIterator mocks base method. -func (m *MockDiff) GetCurrentStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. -func (mr *MockDiffMockRecorder) GetCurrentStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentStakerIterator)) -} - -// GetCurrentSupply mocks base method. -func (m *MockDiff) GetCurrentSupply(arg0 ids.ID) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockDiffMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).GetCurrentSupply), arg0) -} - -// GetCurrentValidator mocks base method. -func (m *MockDiff) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockDiffMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockDiff)(nil).GetCurrentValidator), arg0, arg1) -} - -// GetDelegateeReward mocks base method. -func (m *MockDiff) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockDiffMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).GetDelegateeReward), arg0, arg1) -} - -// GetPendingDelegatorIterator mocks base method. -func (m *MockDiff) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockDiffMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingDelegatorIterator), arg0, arg1) -} - -// GetPendingStakerIterator mocks base method. -func (m *MockDiff) GetPendingStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. -func (mr *MockDiffMockRecorder) GetPendingStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingStakerIterator)) -} - -// GetPendingValidator mocks base method. -func (m *MockDiff) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockDiffMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockDiff)(nil).GetPendingValidator), arg0, arg1) -} - -// GetRewardUTXOs mocks base method. -func (m *MockDiff) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. -func (mr *MockDiffMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockDiff)(nil).GetRewardUTXOs), arg0) -} - -// GetSubnetOwner mocks base method. -func (m *MockDiff) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockDiffMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).GetSubnetOwner), arg0) -} - -// GetSubnetTransformation mocks base method. -func (m *MockDiff) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockDiffMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).GetSubnetTransformation), arg0) -} - -// GetSubnets mocks base method. -func (m *MockDiff) GetSubnets() ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnets") - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnets indicates an expected call of GetSubnets. -func (mr *MockDiffMockRecorder) GetSubnets() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockDiff)(nil).GetSubnets)) -} - -// GetTimestamp mocks base method. -func (m *MockDiff) GetTimestamp() time.Time { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTimestamp") - ret0, _ := ret[0].(time.Time) - return ret0 -} - -// GetTimestamp indicates an expected call of GetTimestamp. -func (mr *MockDiffMockRecorder) GetTimestamp() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockDiff)(nil).GetTimestamp)) -} - -// GetTx mocks base method. -func (m *MockDiff) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(status.Status) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetTx indicates an expected call of GetTx. -func (mr *MockDiffMockRecorder) GetTx(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockDiff)(nil).GetTx), arg0) -} - -// GetUTXO mocks base method. -func (m *MockDiff) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0) - ret0, _ := ret[0].(*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetUTXO indicates an expected call of GetUTXO. -func (mr *MockDiffMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockDiff)(nil).GetUTXO), arg0) -} - -// PutCurrentDelegator mocks base method. -func (m *MockDiff) PutCurrentDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentDelegator", arg0) -} - -// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockDiffMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).PutCurrentDelegator), arg0) -} - -// PutCurrentValidator mocks base method. -func (m *MockDiff) PutCurrentValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentValidator", arg0) -} - -// PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockDiffMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockDiff)(nil).PutCurrentValidator), arg0) -} - -// PutPendingDelegator mocks base method. -func (m *MockDiff) PutPendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingDelegator", arg0) -} - -// PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockDiffMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockDiff)(nil).PutPendingDelegator), arg0) -} - -// PutPendingValidator mocks base method. -func (m *MockDiff) PutPendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingValidator", arg0) -} - -// PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockDiffMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockDiff)(nil).PutPendingValidator), arg0) -} - -// SetCurrentSupply mocks base method. -func (m *MockDiff) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) -} - -// SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockDiffMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).SetCurrentSupply), arg0, arg1) -} - -// SetDelegateeReward mocks base method. -func (m *MockDiff) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockDiffMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).SetDelegateeReward), arg0, arg1, arg2) -} - -// SetSubnetOwner mocks base method. -func (m *MockDiff) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) -} - -// SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockDiffMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).SetSubnetOwner), arg0, arg1) -} - -// SetTimestamp mocks base method. -func (m *MockDiff) SetTimestamp(arg0 time.Time) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetTimestamp", arg0) -} - -// SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockDiffMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockDiff)(nil).SetTimestamp), arg0) -} diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index 41ce946a12e0..465b3fda2bac 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -2,7 +2,7 @@ // See the file LICENSE for licensing terms. // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: State) +// Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Chain,Diff,State,Versions) // Package state is a generated GoMock package. package state @@ -25,6 +25,1006 @@ import ( gomock "go.uber.org/mock/gomock" ) +// MockChain is a mock of Chain interface. +type MockChain struct { + ctrl *gomock.Controller + recorder *MockChainMockRecorder +} + +// MockChainMockRecorder is the mock recorder for MockChain. +type MockChainMockRecorder struct { + mock *MockChain +} + +// NewMockChain creates a new mock instance. +func NewMockChain(ctrl *gomock.Controller) *MockChain { + mock := &MockChain{ctrl: ctrl} + mock.recorder = &MockChainMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockChain) EXPECT() *MockChainMockRecorder { + return m.recorder +} + +// AddChain mocks base method. +func (m *MockChain) AddChain(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddChain", arg0) +} + +// AddChain indicates an expected call of AddChain. +func (mr *MockChainMockRecorder) AddChain(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockChain)(nil).AddChain), arg0) +} + +// AddRewardUTXO mocks base method. +func (m *MockChain) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) +} + +// AddRewardUTXO indicates an expected call of AddRewardUTXO. +func (mr *MockChainMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockChain)(nil).AddRewardUTXO), arg0, arg1) +} + +// AddSubnet mocks base method. +func (m *MockChain) AddSubnet(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddSubnet", arg0) +} + +// AddSubnet indicates an expected call of AddSubnet. +func (mr *MockChainMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockChain)(nil).AddSubnet), arg0) +} + +// AddSubnetTransformation mocks base method. +func (m *MockChain) AddSubnetTransformation(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddSubnetTransformation", arg0) +} + +// AddSubnetTransformation indicates an expected call of AddSubnetTransformation. +func (mr *MockChainMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockChain)(nil).AddSubnetTransformation), arg0) +} + +// AddTx mocks base method. +func (m *MockChain) AddTx(arg0 *txs.Tx, arg1 status.Status) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddTx", arg0, arg1) +} + +// AddTx indicates an expected call of AddTx. +func (mr *MockChainMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockChain)(nil).AddTx), arg0, arg1) +} + +// AddUTXO mocks base method. +func (m *MockChain) AddUTXO(arg0 *avax.UTXO) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddUTXO", arg0) +} + +// AddUTXO indicates an expected call of AddUTXO. +func (mr *MockChainMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockChain)(nil).AddUTXO), arg0) +} + +// DeleteCurrentDelegator mocks base method. +func (m *MockChain) DeleteCurrentDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) +} + +// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. +func (mr *MockChainMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentDelegator), arg0) +} + +// DeleteCurrentValidator mocks base method. +func (m *MockChain) DeleteCurrentValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteCurrentValidator", arg0) +} + +// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. +func (mr *MockChainMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentValidator), arg0) +} + +// DeletePendingDelegator mocks base method. +func (m *MockChain) DeletePendingDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeletePendingDelegator", arg0) +} + +// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. +func (mr *MockChainMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockChain)(nil).DeletePendingDelegator), arg0) +} + +// DeletePendingValidator mocks base method. +func (m *MockChain) DeletePendingValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeletePendingValidator", arg0) +} + +// DeletePendingValidator indicates an expected call of DeletePendingValidator. +func (mr *MockChainMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockChain)(nil).DeletePendingValidator), arg0) +} + +// DeleteUTXO mocks base method. +func (m *MockChain) DeleteUTXO(arg0 ids.ID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteUTXO", arg0) +} + +// DeleteUTXO indicates an expected call of DeleteUTXO. +func (mr *MockChainMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), arg0) +} + +// GetChains mocks base method. +func (m *MockChain) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetChains", arg0) + ret0, _ := ret[0].([]*txs.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetChains indicates an expected call of GetChains. +func (mr *MockChainMockRecorder) GetChains(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockChain)(nil).GetChains), arg0) +} + +// GetCurrentDelegatorIterator mocks base method. +func (m *MockChain) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. +func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), arg0, arg1) +} + +// GetCurrentStakerIterator mocks base method. +func (m *MockChain) GetCurrentStakerIterator() (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. +func (mr *MockChainMockRecorder) GetCurrentStakerIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentStakerIterator)) +} + +// GetCurrentSupply mocks base method. +func (m *MockChain) GetCurrentSupply(arg0 ids.ID) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentSupply indicates an expected call of GetCurrentSupply. +func (mr *MockChainMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockChain)(nil).GetCurrentSupply), arg0) +} + +// GetCurrentValidator mocks base method. +func (m *MockChain) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentValidator indicates an expected call of GetCurrentValidator. +func (mr *MockChainMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockChain)(nil).GetCurrentValidator), arg0, arg1) +} + +// GetDelegateeReward mocks base method. +func (m *MockChain) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDelegateeReward indicates an expected call of GetDelegateeReward. +func (mr *MockChainMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockChain)(nil).GetDelegateeReward), arg0, arg1) +} + +// GetPendingDelegatorIterator mocks base method. +func (m *MockChain) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. +func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetPendingDelegatorIterator), arg0, arg1) +} + +// GetPendingStakerIterator mocks base method. +func (m *MockChain) GetPendingStakerIterator() (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. +func (mr *MockChainMockRecorder) GetPendingStakerIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockChain)(nil).GetPendingStakerIterator)) +} + +// GetPendingValidator mocks base method. +func (m *MockChain) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingValidator indicates an expected call of GetPendingValidator. +func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), arg0, arg1) +} + +// GetRewardUTXOs mocks base method. +func (m *MockChain) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) + ret0, _ := ret[0].([]*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. +func (mr *MockChainMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockChain)(nil).GetRewardUTXOs), arg0) +} + +// GetSubnetOwner mocks base method. +func (m *MockChain) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) + ret0, _ := ret[0].(fx.Owner) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnetOwner indicates an expected call of GetSubnetOwner. +func (mr *MockChainMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockChain)(nil).GetSubnetOwner), arg0) +} + +// GetSubnetTransformation mocks base method. +func (m *MockChain) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. +func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), arg0) +} + +// GetSubnets mocks base method. +func (m *MockChain) GetSubnets() ([]*txs.Tx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnets") + ret0, _ := ret[0].([]*txs.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnets indicates an expected call of GetSubnets. +func (mr *MockChainMockRecorder) GetSubnets() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockChain)(nil).GetSubnets)) +} + +// GetTimestamp mocks base method. +func (m *MockChain) GetTimestamp() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTimestamp") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// GetTimestamp indicates an expected call of GetTimestamp. +func (mr *MockChainMockRecorder) GetTimestamp() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockChain)(nil).GetTimestamp)) +} + +// GetTx mocks base method. +func (m *MockChain) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTx", arg0) + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(status.Status) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetTx indicates an expected call of GetTx. +func (mr *MockChainMockRecorder) GetTx(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), arg0) +} + +// GetUTXO mocks base method. +func (m *MockChain) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUTXO", arg0) + ret0, _ := ret[0].(*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUTXO indicates an expected call of GetUTXO. +func (mr *MockChainMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), arg0) +} + +// PutCurrentDelegator mocks base method. +func (m *MockChain) PutCurrentDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutCurrentDelegator", arg0) +} + +// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. +func (mr *MockChainMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockChain)(nil).PutCurrentDelegator), arg0) +} + +// PutCurrentValidator mocks base method. +func (m *MockChain) PutCurrentValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutCurrentValidator", arg0) +} + +// PutCurrentValidator indicates an expected call of PutCurrentValidator. +func (mr *MockChainMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockChain)(nil).PutCurrentValidator), arg0) +} + +// PutPendingDelegator mocks base method. +func (m *MockChain) PutPendingDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutPendingDelegator", arg0) +} + +// PutPendingDelegator indicates an expected call of PutPendingDelegator. +func (mr *MockChainMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockChain)(nil).PutPendingDelegator), arg0) +} + +// PutPendingValidator mocks base method. +func (m *MockChain) PutPendingValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutPendingValidator", arg0) +} + +// PutPendingValidator indicates an expected call of PutPendingValidator. +func (mr *MockChainMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), arg0) +} + +// SetCurrentSupply mocks base method. +func (m *MockChain) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) +} + +// SetCurrentSupply indicates an expected call of SetCurrentSupply. +func (mr *MockChainMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockChain)(nil).SetCurrentSupply), arg0, arg1) +} + +// SetDelegateeReward mocks base method. +func (m *MockChain) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetDelegateeReward indicates an expected call of SetDelegateeReward. +func (mr *MockChainMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockChain)(nil).SetDelegateeReward), arg0, arg1, arg2) +} + +// SetSubnetOwner mocks base method. +func (m *MockChain) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) +} + +// SetSubnetOwner indicates an expected call of SetSubnetOwner. +func (mr *MockChainMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockChain)(nil).SetSubnetOwner), arg0, arg1) +} + +// SetTimestamp mocks base method. +func (m *MockChain) SetTimestamp(arg0 time.Time) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetTimestamp", arg0) +} + +// SetTimestamp indicates an expected call of SetTimestamp. +func (mr *MockChainMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), arg0) +} + +// MockDiff is a mock of Diff interface. +type MockDiff struct { + ctrl *gomock.Controller + recorder *MockDiffMockRecorder +} + +// MockDiffMockRecorder is the mock recorder for MockDiff. +type MockDiffMockRecorder struct { + mock *MockDiff +} + +// NewMockDiff creates a new mock instance. +func NewMockDiff(ctrl *gomock.Controller) *MockDiff { + mock := &MockDiff{ctrl: ctrl} + mock.recorder = &MockDiffMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDiff) EXPECT() *MockDiffMockRecorder { + return m.recorder +} + +// AddChain mocks base method. +func (m *MockDiff) AddChain(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddChain", arg0) +} + +// AddChain indicates an expected call of AddChain. +func (mr *MockDiffMockRecorder) AddChain(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockDiff)(nil).AddChain), arg0) +} + +// AddRewardUTXO mocks base method. +func (m *MockDiff) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) +} + +// AddRewardUTXO indicates an expected call of AddRewardUTXO. +func (mr *MockDiffMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockDiff)(nil).AddRewardUTXO), arg0, arg1) +} + +// AddSubnet mocks base method. +func (m *MockDiff) AddSubnet(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddSubnet", arg0) +} + +// AddSubnet indicates an expected call of AddSubnet. +func (mr *MockDiffMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockDiff)(nil).AddSubnet), arg0) +} + +// AddSubnetTransformation mocks base method. +func (m *MockDiff) AddSubnetTransformation(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddSubnetTransformation", arg0) +} + +// AddSubnetTransformation indicates an expected call of AddSubnetTransformation. +func (mr *MockDiffMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).AddSubnetTransformation), arg0) +} + +// AddTx mocks base method. +func (m *MockDiff) AddTx(arg0 *txs.Tx, arg1 status.Status) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddTx", arg0, arg1) +} + +// AddTx indicates an expected call of AddTx. +func (mr *MockDiffMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), arg0, arg1) +} + +// AddUTXO mocks base method. +func (m *MockDiff) AddUTXO(arg0 *avax.UTXO) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddUTXO", arg0) +} + +// AddUTXO indicates an expected call of AddUTXO. +func (mr *MockDiffMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), arg0) +} + +// Apply mocks base method. +func (m *MockDiff) Apply(arg0 Chain) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Apply", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Apply indicates an expected call of Apply. +func (mr *MockDiffMockRecorder) Apply(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) +} + +// DeleteCurrentDelegator mocks base method. +func (m *MockDiff) DeleteCurrentDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) +} + +// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. +func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentDelegator), arg0) +} + +// DeleteCurrentValidator mocks base method. +func (m *MockDiff) DeleteCurrentValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteCurrentValidator", arg0) +} + +// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. +func (mr *MockDiffMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentValidator), arg0) +} + +// DeletePendingDelegator mocks base method. +func (m *MockDiff) DeletePendingDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeletePendingDelegator", arg0) +} + +// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. +func (mr *MockDiffMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockDiff)(nil).DeletePendingDelegator), arg0) +} + +// DeletePendingValidator mocks base method. +func (m *MockDiff) DeletePendingValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeletePendingValidator", arg0) +} + +// DeletePendingValidator indicates an expected call of DeletePendingValidator. +func (mr *MockDiffMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockDiff)(nil).DeletePendingValidator), arg0) +} + +// DeleteUTXO mocks base method. +func (m *MockDiff) DeleteUTXO(arg0 ids.ID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteUTXO", arg0) +} + +// DeleteUTXO indicates an expected call of DeleteUTXO. +func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) +} + +// GetChains mocks base method. +func (m *MockDiff) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetChains", arg0) + ret0, _ := ret[0].([]*txs.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetChains indicates an expected call of GetChains. +func (mr *MockDiffMockRecorder) GetChains(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockDiff)(nil).GetChains), arg0) +} + +// GetCurrentDelegatorIterator mocks base method. +func (m *MockDiff) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. +func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentDelegatorIterator), arg0, arg1) +} + +// GetCurrentStakerIterator mocks base method. +func (m *MockDiff) GetCurrentStakerIterator() (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. +func (mr *MockDiffMockRecorder) GetCurrentStakerIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentStakerIterator)) +} + +// GetCurrentSupply mocks base method. +func (m *MockDiff) GetCurrentSupply(arg0 ids.ID) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentSupply indicates an expected call of GetCurrentSupply. +func (mr *MockDiffMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).GetCurrentSupply), arg0) +} + +// GetCurrentValidator mocks base method. +func (m *MockDiff) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentValidator indicates an expected call of GetCurrentValidator. +func (mr *MockDiffMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockDiff)(nil).GetCurrentValidator), arg0, arg1) +} + +// GetDelegateeReward mocks base method. +func (m *MockDiff) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDelegateeReward indicates an expected call of GetDelegateeReward. +func (mr *MockDiffMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).GetDelegateeReward), arg0, arg1) +} + +// GetPendingDelegatorIterator mocks base method. +func (m *MockDiff) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. +func (mr *MockDiffMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingDelegatorIterator), arg0, arg1) +} + +// GetPendingStakerIterator mocks base method. +func (m *MockDiff) GetPendingStakerIterator() (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. +func (mr *MockDiffMockRecorder) GetPendingStakerIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingStakerIterator)) +} + +// GetPendingValidator mocks base method. +func (m *MockDiff) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingValidator indicates an expected call of GetPendingValidator. +func (mr *MockDiffMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockDiff)(nil).GetPendingValidator), arg0, arg1) +} + +// GetRewardUTXOs mocks base method. +func (m *MockDiff) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) + ret0, _ := ret[0].([]*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. +func (mr *MockDiffMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockDiff)(nil).GetRewardUTXOs), arg0) +} + +// GetSubnetOwner mocks base method. +func (m *MockDiff) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) + ret0, _ := ret[0].(fx.Owner) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnetOwner indicates an expected call of GetSubnetOwner. +func (mr *MockDiffMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).GetSubnetOwner), arg0) +} + +// GetSubnetTransformation mocks base method. +func (m *MockDiff) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. +func (mr *MockDiffMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).GetSubnetTransformation), arg0) +} + +// GetSubnets mocks base method. +func (m *MockDiff) GetSubnets() ([]*txs.Tx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnets") + ret0, _ := ret[0].([]*txs.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnets indicates an expected call of GetSubnets. +func (mr *MockDiffMockRecorder) GetSubnets() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockDiff)(nil).GetSubnets)) +} + +// GetTimestamp mocks base method. +func (m *MockDiff) GetTimestamp() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTimestamp") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// GetTimestamp indicates an expected call of GetTimestamp. +func (mr *MockDiffMockRecorder) GetTimestamp() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockDiff)(nil).GetTimestamp)) +} + +// GetTx mocks base method. +func (m *MockDiff) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTx", arg0) + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(status.Status) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetTx indicates an expected call of GetTx. +func (mr *MockDiffMockRecorder) GetTx(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockDiff)(nil).GetTx), arg0) +} + +// GetUTXO mocks base method. +func (m *MockDiff) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUTXO", arg0) + ret0, _ := ret[0].(*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUTXO indicates an expected call of GetUTXO. +func (mr *MockDiffMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockDiff)(nil).GetUTXO), arg0) +} + +// PutCurrentDelegator mocks base method. +func (m *MockDiff) PutCurrentDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutCurrentDelegator", arg0) +} + +// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. +func (mr *MockDiffMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).PutCurrentDelegator), arg0) +} + +// PutCurrentValidator mocks base method. +func (m *MockDiff) PutCurrentValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutCurrentValidator", arg0) +} + +// PutCurrentValidator indicates an expected call of PutCurrentValidator. +func (mr *MockDiffMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockDiff)(nil).PutCurrentValidator), arg0) +} + +// PutPendingDelegator mocks base method. +func (m *MockDiff) PutPendingDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutPendingDelegator", arg0) +} + +// PutPendingDelegator indicates an expected call of PutPendingDelegator. +func (mr *MockDiffMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockDiff)(nil).PutPendingDelegator), arg0) +} + +// PutPendingValidator mocks base method. +func (m *MockDiff) PutPendingValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutPendingValidator", arg0) +} + +// PutPendingValidator indicates an expected call of PutPendingValidator. +func (mr *MockDiffMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockDiff)(nil).PutPendingValidator), arg0) +} + +// SetCurrentSupply mocks base method. +func (m *MockDiff) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) +} + +// SetCurrentSupply indicates an expected call of SetCurrentSupply. +func (mr *MockDiffMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).SetCurrentSupply), arg0, arg1) +} + +// SetDelegateeReward mocks base method. +func (m *MockDiff) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetDelegateeReward indicates an expected call of SetDelegateeReward. +func (mr *MockDiffMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).SetDelegateeReward), arg0, arg1, arg2) +} + +// SetSubnetOwner mocks base method. +func (m *MockDiff) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) +} + +// SetSubnetOwner indicates an expected call of SetSubnetOwner. +func (mr *MockDiffMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).SetSubnetOwner), arg0, arg1) +} + +// SetTimestamp mocks base method. +func (m *MockDiff) SetTimestamp(arg0 time.Time) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetTimestamp", arg0) +} + +// SetTimestamp indicates an expected call of SetTimestamp. +func (mr *MockDiffMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockDiff)(nil).SetTimestamp), arg0) +} + // MockState is a mock of State interface. type MockState struct { ctrl *gomock.Controller @@ -783,3 +1783,41 @@ func (mr *MockStateMockRecorder) UTXOIDs(arg0, arg1, arg2 interface{}) *gomock.C mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UTXOIDs", reflect.TypeOf((*MockState)(nil).UTXOIDs), arg0, arg1, arg2) } + +// MockVersions is a mock of Versions interface. +type MockVersions struct { + ctrl *gomock.Controller + recorder *MockVersionsMockRecorder +} + +// MockVersionsMockRecorder is the mock recorder for MockVersions. +type MockVersionsMockRecorder struct { + mock *MockVersions +} + +// NewMockVersions creates a new mock instance. +func NewMockVersions(ctrl *gomock.Controller) *MockVersions { + mock := &MockVersions{ctrl: ctrl} + mock.recorder = &MockVersionsMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockVersions) EXPECT() *MockVersionsMockRecorder { + return m.recorder +} + +// GetState mocks base method. +func (m *MockVersions) GetState(arg0 ids.ID) (Chain, bool) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetState", arg0) + ret0, _ := ret[0].(Chain) + ret1, _ := ret[1].(bool) + return ret0, ret1 +} + +// GetState indicates an expected call of GetState. +func (mr *MockVersionsMockRecorder) GetState(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockVersions)(nil).GetState), arg0) +} diff --git a/vms/platformvm/state/mock_versions.go b/vms/platformvm/state/mock_versions.go deleted file mode 100644 index 3f8a20550b22..000000000000 --- a/vms/platformvm/state/mock_versions.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Versions) - -// Package state is a generated GoMock package. -package state - -import ( - reflect "reflect" - - ids "github.com/ava-labs/avalanchego/ids" - gomock "go.uber.org/mock/gomock" -) - -// MockVersions is a mock of Versions interface. -type MockVersions struct { - ctrl *gomock.Controller - recorder *MockVersionsMockRecorder -} - -// MockVersionsMockRecorder is the mock recorder for MockVersions. -type MockVersionsMockRecorder struct { - mock *MockVersions -} - -// NewMockVersions creates a new mock instance. -func NewMockVersions(ctrl *gomock.Controller) *MockVersions { - mock := &MockVersions{ctrl: ctrl} - mock.recorder = &MockVersionsMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockVersions) EXPECT() *MockVersionsMockRecorder { - return m.recorder -} - -// GetState mocks base method. -func (m *MockVersions) GetState(arg0 ids.ID) (Chain, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetState", arg0) - ret0, _ := ret[0].(Chain) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// GetState indicates an expected call of GetState. -func (mr *MockVersionsMockRecorder) GetState(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockVersions)(nil).GetState), arg0) -} From 590ad124bcf48686f72e259506885440401e0c8f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 27 Nov 2023 16:57:15 -0500 Subject: [PATCH 075/267] Remove common bootstrapper (#2297) --- chains/manager.go | 57 +-- .../avalanche/bootstrap/bootstrapper.go | 16 +- snow/engine/common/bootstrapable.go | 14 +- snow/engine/common/bootstrapper.go | 208 -------- snow/engine/common/config.go | 40 -- snow/engine/common/test_bootstrapable.go | 56 --- snow/engine/common/test_bootstrapper.go | 31 +- snow/engine/common/test_config.go | 43 -- .../common/traced_bootstrapable_engine.go | 14 - snow/engine/snowman/bootstrap/bootstrapper.go | 473 ++++++++++++------ .../snowman/bootstrap/bootstrapper_test.go | 106 ++-- snow/engine/snowman/bootstrap/config.go | 17 +- snow/engine/snowman/config_test.go | 10 +- snow/engine/snowman/syncer/state_syncer.go | 8 +- .../snowman/syncer/state_syncer_test.go | 14 +- snow/engine/snowman/syncer/utils_test.go | 6 +- snow/engine/snowman/transitive_test.go | 30 +- snow/networking/handler/handler_test.go | 18 - snow/networking/handler/health_test.go | 3 - snow/networking/router/chain_router_test.go | 18 - snow/networking/sender/sender_test.go | 9 - vms/platformvm/vm_test.go | 14 +- 22 files changed, 482 insertions(+), 723 deletions(-) delete mode 100644 snow/engine/common/bootstrapper.go delete mode 100644 snow/engine/common/config.go delete mode 100644 snow/engine/common/test_bootstrapable.go delete mode 100644 snow/engine/common/test_config.go diff --git a/chains/manager.go b/chains/manager.go index 794c0e65700d..b4f28b1290be 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -878,21 +878,17 @@ func (m *manager) createAvalancheChain( // create bootstrap gear bootstrapCfg := smbootstrap.Config{ - Config: common.Config{ - Ctx: ctx, - Beacons: vdrs, - SampleK: sampleK, - Alpha: bootstrapWeight/2 + 1, // must be > 50% - StartupTracker: startupTracker, - Sender: snowmanMessageSender, - BootstrapTracker: sb, - Timer: h, - AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, - SharedCfg: &common.SharedConfig{}, - }, - AllGetsServer: snowGetHandler, - Blocked: blockBlocker, - VM: vmWrappingProposerVM, + AllGetsServer: snowGetHandler, + Ctx: ctx, + Beacons: vdrs, + SampleK: sampleK, + StartupTracker: startupTracker, + Sender: snowmanMessageSender, + BootstrapTracker: sb, + Timer: h, + AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, + Blocked: blockBlocker, + VM: vmWrappingProposerVM, } var snowmanBootstrapper common.BootstrapableEngine snowmanBootstrapper, err = smbootstrap.New( @@ -1224,24 +1220,19 @@ func (m *manager) createSnowmanChain( } // create bootstrap gear - alpha := bootstrapWeight/2 + 1 // must be > 50% bootstrapCfg := smbootstrap.Config{ - Config: common.Config{ - Ctx: ctx, - Beacons: beacons, - SampleK: sampleK, - StartupTracker: startupTracker, - Alpha: alpha, - Sender: messageSender, - BootstrapTracker: sb, - Timer: h, - AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, - SharedCfg: &common.SharedConfig{}, - }, - AllGetsServer: snowGetHandler, - Blocked: blocked, - VM: vm, - Bootstrapped: bootstrapFunc, + AllGetsServer: snowGetHandler, + Ctx: ctx, + Beacons: beacons, + SampleK: sampleK, + StartupTracker: startupTracker, + Sender: messageSender, + BootstrapTracker: sb, + Timer: h, + AncestorsMaxContainersReceived: m.BootstrapAncestorsMaxContainersReceived, + Blocked: blocked, + VM: vm, + Bootstrapped: bootstrapFunc, } var bootstrapper common.BootstrapableEngine bootstrapper, err = smbootstrap.New( @@ -1264,7 +1255,7 @@ func (m *manager) createSnowmanChain( messageSender, beacons, sampleK, - alpha, + bootstrapWeight/2+1, // must be > 50% m.StateSyncBeacons, vm, ) diff --git a/snow/engine/avalanche/bootstrap/bootstrapper.go b/snow/engine/avalanche/bootstrap/bootstrapper.go index 6a4cc974e648..59f421158fa2 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper.go @@ -30,6 +30,10 @@ const ( stripeWidth = 5 cacheSize = 100000 + // statusUpdateFrequency is how many containers should be processed between + // logs + statusUpdateFrequency = 5000 + // maxOutstandingGetAncestorsRequests is the maximum number of GetAncestors // sent but not yet responded to/failed maxOutstandingGetAncestorsRequests = 10 @@ -333,7 +337,7 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { return fmt.Errorf("failed to get linearization status: %w", err) } if linearized { - return b.ForceAccepted(ctx, nil) + return b.startSyncing(ctx, nil) } // If a stop vertex is well known, accept that. @@ -342,7 +346,7 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { zap.Stringer("vtxID", b.Config.StopVertexID), ) - return b.ForceAccepted(ctx, []ids.ID{b.Config.StopVertexID}) + return b.startSyncing(ctx, []ids.ID{b.Config.StopVertexID}) } // If a stop vertex isn't well known, treat the current state as the final @@ -364,7 +368,7 @@ func (b *bootstrapper) Start(ctx context.Context, startReqID uint32) error { zap.Stringer("vtxID", stopVertexID), ) - return b.ForceAccepted(ctx, nil) + return b.startSyncing(ctx, nil) } func (b *bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { @@ -490,7 +494,7 @@ func (b *bootstrapper) process(ctx context.Context, vtxs ...avalanche.Vertex) er b.numFetchedVts.Inc() verticesFetchedSoFar := b.VtxBlocked.Jobs.PendingJobs() - if verticesFetchedSoFar%common.StatusUpdateFrequency == 0 { // Periodically print progress + if verticesFetchedSoFar%statusUpdateFrequency == 0 { // Periodically print progress b.Ctx.Log.Info("fetched vertices", zap.Uint64("numVerticesFetched", verticesFetchedSoFar), ) @@ -536,8 +540,8 @@ func (b *bootstrapper) process(ctx context.Context, vtxs ...avalanche.Vertex) er return b.fetch(ctx) } -// ForceAccepted starts bootstrapping. Process the vertices in [accepterContainerIDs]. -func (b *bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs []ids.ID) error { +// startSyncing starts bootstrapping. Process the vertices in [accepterContainerIDs]. +func (b *bootstrapper) startSyncing(ctx context.Context, acceptedContainerIDs []ids.ID) error { pendingContainerIDs := b.VtxBlocked.MissingIDs() // Append the list of accepted container IDs to pendingContainerIDs to ensure // we iterate over every container that must be traversed. diff --git a/snow/engine/common/bootstrapable.go b/snow/engine/common/bootstrapable.go index a4abcc59a880..256acb6d468e 100644 --- a/snow/engine/common/bootstrapable.go +++ b/snow/engine/common/bootstrapable.go @@ -3,22 +3,10 @@ package common -import ( - "context" - - "github.com/ava-labs/avalanchego/ids" -) +import "context" type BootstrapableEngine interface { - Bootstrapable Engine -} - -// Bootstrapable defines the functionality required to support bootstrapping -type Bootstrapable interface { - // Force the provided containers to be accepted. Only returns fatal errors - // if they occur. - ForceAccepted(ctx context.Context, acceptedContainerIDs []ids.ID) error // Clear removes all containers to be processed upon bootstrapping Clear(ctx context.Context) error diff --git a/snow/engine/common/bootstrapper.go b/snow/engine/common/bootstrapper.go deleted file mode 100644 index d4c8f041a8d2..000000000000 --- a/snow/engine/common/bootstrapper.go +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package common - -import ( - "context" - - "go.uber.org/zap" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/set" - - smbootstrapper "github.com/ava-labs/avalanchego/snow/consensus/snowman/bootstrapper" -) - -const ( - // StatusUpdateFrequency is how many containers should be processed between - // logs - StatusUpdateFrequency = 5000 - - // MaxOutstandingBroadcastRequests is the maximum number of requests to have - // outstanding when broadcasting. - MaxOutstandingBroadcastRequests = 50 -) - -var _ Bootstrapper = (*bootstrapper)(nil) - -type Bootstrapper interface { - AcceptedFrontierHandler - AcceptedHandler - Haltable - Startup(context.Context) error - Restart(ctx context.Context) error -} - -// It collects mechanisms common to both snowman and avalanche bootstrappers -type bootstrapper struct { - Config - Halter - - minority smbootstrapper.Poll - majority smbootstrapper.Poll -} - -func NewCommonBootstrapper(config Config) Bootstrapper { - return &bootstrapper{ - Config: config, - minority: smbootstrapper.Noop, - majority: smbootstrapper.Noop, - } -} - -func (b *bootstrapper) AcceptedFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error { - if requestID != b.Config.SharedCfg.RequestID { - b.Ctx.Log.Debug("received out-of-sync AcceptedFrontier message", - zap.Stringer("nodeID", nodeID), - zap.Uint32("expectedRequestID", b.Config.SharedCfg.RequestID), - zap.Uint32("requestID", requestID), - ) - return nil - } - - if err := b.minority.RecordOpinion(ctx, nodeID, set.Of(containerID)); err != nil { - return err - } - return b.sendMessagesOrFinish(ctx) -} - -func (b *bootstrapper) GetAcceptedFrontierFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - if requestID != b.Config.SharedCfg.RequestID { - b.Ctx.Log.Debug("received out-of-sync GetAcceptedFrontierFailed message", - zap.Stringer("nodeID", nodeID), - zap.Uint32("expectedRequestID", b.Config.SharedCfg.RequestID), - zap.Uint32("requestID", requestID), - ) - return nil - } - - if err := b.minority.RecordOpinion(ctx, nodeID, nil); err != nil { - return err - } - return b.sendMessagesOrFinish(ctx) -} - -func (b *bootstrapper) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { - if requestID != b.Config.SharedCfg.RequestID { - b.Ctx.Log.Debug("received out-of-sync Accepted message", - zap.Stringer("nodeID", nodeID), - zap.Uint32("expectedRequestID", b.Config.SharedCfg.RequestID), - zap.Uint32("requestID", requestID), - ) - return nil - } - - if err := b.majority.RecordOpinion(ctx, nodeID, containerIDs); err != nil { - return err - } - return b.sendMessagesOrFinish(ctx) -} - -func (b *bootstrapper) GetAcceptedFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - if requestID != b.Config.SharedCfg.RequestID { - b.Ctx.Log.Debug("received out-of-sync GetAcceptedFailed message", - zap.Stringer("nodeID", nodeID), - zap.Uint32("expectedRequestID", b.Config.SharedCfg.RequestID), - zap.Uint32("requestID", requestID), - ) - return nil - } - - if err := b.majority.RecordOpinion(ctx, nodeID, nil); err != nil { - return err - } - return b.sendMessagesOrFinish(ctx) -} - -func (b *bootstrapper) Startup(ctx context.Context) error { - currentBeacons := b.Beacons.GetMap(b.Ctx.SubnetID) - nodeWeights := make(map[ids.NodeID]uint64, len(currentBeacons)) - for nodeID, beacon := range currentBeacons { - nodeWeights[nodeID] = beacon.Weight - } - - frontierNodes, err := smbootstrapper.Sample(nodeWeights, b.SampleK) - if err != nil { - return err - } - - b.Ctx.Log.Debug("sampled nodes to seed bootstrapping frontier", - zap.Reflect("sampledNodes", frontierNodes), - zap.Int("numNodes", len(nodeWeights)), - ) - - b.minority = smbootstrapper.NewMinority( - b.Ctx.Log, - frontierNodes, - MaxOutstandingBroadcastRequests, - ) - b.majority = smbootstrapper.NewMajority( - b.Ctx.Log, - nodeWeights, - MaxOutstandingBroadcastRequests, - ) - - if accepted, finalized := b.majority.Result(ctx); finalized { - b.Ctx.Log.Info("bootstrapping skipped", - zap.String("reason", "no provided bootstraps"), - ) - return b.Bootstrapable.ForceAccepted(ctx, accepted) - } - - b.Config.SharedCfg.RequestID++ - return b.sendMessagesOrFinish(ctx) -} - -func (b *bootstrapper) Restart(ctx context.Context) error { - b.Ctx.Log.Debug("Checking for new frontiers") - b.Config.SharedCfg.Restarted = true - return b.Startup(ctx) -} - -func (b *bootstrapper) sendMessagesOrFinish(ctx context.Context) error { - if peers := b.minority.GetPeers(ctx); peers.Len() > 0 { - b.Sender.SendGetAcceptedFrontier(ctx, peers, b.Config.SharedCfg.RequestID) - return nil - } - - potentialAccepted, finalized := b.minority.Result(ctx) - if !finalized { - // We haven't finalized the accepted frontier, so we should wait for the - // outstanding requests. - return nil - } - - if peers := b.majority.GetPeers(ctx); peers.Len() > 0 { - b.Sender.SendGetAccepted(ctx, peers, b.Config.SharedCfg.RequestID, potentialAccepted) - return nil - } - - accepted, finalized := b.majority.Result(ctx) - if !finalized { - // We haven't finalized the accepted set, so we should wait for the - // outstanding requests. - return nil - } - - numAccepted := len(accepted) - if numAccepted == 0 { - b.Ctx.Log.Debug("restarting bootstrap", - zap.String("reason", "no blocks accepted"), - zap.Int("numBeacons", b.Beacons.Count(b.Ctx.SubnetID)), - ) - return b.Startup(ctx) - } - - if !b.Config.SharedCfg.Restarted { - b.Ctx.Log.Info("bootstrapping started syncing", - zap.Int("numAccepted", numAccepted), - ) - } else { - b.Ctx.Log.Debug("bootstrapping started syncing", - zap.Int("numAccepted", numAccepted), - ) - } - - return b.Bootstrapable.ForceAccepted(ctx, accepted) -} diff --git a/snow/engine/common/config.go b/snow/engine/common/config.go deleted file mode 100644 index 5ac9052f0593..000000000000 --- a/snow/engine/common/config.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package common - -import ( - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/snow/engine/common/tracker" - "github.com/ava-labs/avalanchego/snow/validators" -) - -// Config wraps the common configurations that are needed by a Snow consensus -// engine -type Config struct { - Ctx *snow.ConsensusContext - Beacons validators.Manager - - SampleK int - Alpha uint64 - StartupTracker tracker.Startup - Sender Sender - Bootstrapable Bootstrapable - BootstrapTracker BootstrapTracker - Timer Timer - - // This node will only consider the first [AncestorsMaxContainersReceived] - // containers in an ancestors message it receives. - AncestorsMaxContainersReceived int - - SharedCfg *SharedConfig -} - -// Shared among common.bootstrapper and snowman/avalanche bootstrapper -type SharedConfig struct { - // Tracks the last requestID that was used in a request - RequestID uint32 - - // True if RestartBootstrap has been called at least once - Restarted bool -} diff --git a/snow/engine/common/test_bootstrapable.go b/snow/engine/common/test_bootstrapable.go deleted file mode 100644 index 625070616377..000000000000 --- a/snow/engine/common/test_bootstrapable.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package common - -import ( - "context" - "errors" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" -) - -var ( - _ Bootstrapable = (*BootstrapableTest)(nil) - - errForceAccepted = errors.New("unexpectedly called ForceAccepted") - errClear = errors.New("unexpectedly called Clear") -) - -// BootstrapableTest is a test engine that supports bootstrapping -type BootstrapableTest struct { - T *testing.T - - CantForceAccepted, CantClear bool - - ClearF func(ctx context.Context) error - ForceAcceptedF func(ctx context.Context, acceptedContainerIDs []ids.ID) error -} - -// Default sets the default on call handling -func (b *BootstrapableTest) Default(cant bool) { - b.CantForceAccepted = cant -} - -func (b *BootstrapableTest) Clear(ctx context.Context) error { - if b.ClearF != nil { - return b.ClearF(ctx) - } - if b.CantClear && b.T != nil { - require.FailNow(b.T, errClear.Error()) - } - return errClear -} - -func (b *BootstrapableTest) ForceAccepted(ctx context.Context, containerIDs []ids.ID) error { - if b.ForceAcceptedF != nil { - return b.ForceAcceptedF(ctx, containerIDs) - } - if b.CantForceAccepted && b.T != nil { - require.FailNow(b.T, errForceAccepted.Error()) - } - return errForceAccepted -} diff --git a/snow/engine/common/test_bootstrapper.go b/snow/engine/common/test_bootstrapper.go index 1f8fd59bf3d3..6ee9e223dc18 100644 --- a/snow/engine/common/test_bootstrapper.go +++ b/snow/engine/common/test_bootstrapper.go @@ -3,18 +3,39 @@ package common +import ( + "context" + "errors" + + "github.com/stretchr/testify/require" +) + var ( - _ Engine = (*BootstrapperTest)(nil) - _ Bootstrapable = (*BootstrapperTest)(nil) + _ BootstrapableEngine = (*BootstrapperTest)(nil) + + errClear = errors.New("unexpectedly called Clear") ) -// EngineTest is a test engine type BootstrapperTest struct { - BootstrapableTest EngineTest + + CantClear bool + + ClearF func(ctx context.Context) error } func (b *BootstrapperTest) Default(cant bool) { - b.BootstrapableTest.Default(cant) b.EngineTest.Default(cant) + + b.CantClear = cant +} + +func (b *BootstrapperTest) Clear(ctx context.Context) error { + if b.ClearF != nil { + return b.ClearF(ctx) + } + if b.CantClear && b.T != nil { + require.FailNow(b.T, errClear.Error()) + } + return errClear } diff --git a/snow/engine/common/test_config.go b/snow/engine/common/test_config.go deleted file mode 100644 index c8cfa7fc76fd..000000000000 --- a/snow/engine/common/test_config.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package common - -import ( - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/snow/engine/common/tracker" - "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/constants" -) - -// DefaultConfigTest returns a test configuration -func DefaultConfigTest() Config { - isBootstrapped := false - bootstrapTracker := &BootstrapTrackerTest{ - IsBootstrappedF: func() bool { - return isBootstrapped - }, - BootstrappedF: func(ids.ID) { - isBootstrapped = true - }, - } - - beacons := validators.NewManager() - - connectedPeers := tracker.NewPeers() - startupTracker := tracker.NewStartup(connectedPeers, 0) - beacons.RegisterCallbackListener(constants.PrimaryNetworkID, startupTracker) - - return Config{ - Ctx: snow.DefaultConsensusContextTest(), - Beacons: beacons, - StartupTracker: startupTracker, - Sender: &SenderTest{}, - Bootstrapable: &BootstrapableTest{}, - BootstrapTracker: bootstrapTracker, - Timer: &TimerTest{}, - AncestorsMaxContainersReceived: 2000, - SharedCfg: &SharedConfig{}, - } -} diff --git a/snow/engine/common/traced_bootstrapable_engine.go b/snow/engine/common/traced_bootstrapable_engine.go index ba7a0d89228d..d387df04ac34 100644 --- a/snow/engine/common/traced_bootstrapable_engine.go +++ b/snow/engine/common/traced_bootstrapable_engine.go @@ -6,11 +6,6 @@ package common import ( "context" - "go.opentelemetry.io/otel/attribute" - - oteltrace "go.opentelemetry.io/otel/trace" - - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/trace" ) @@ -29,15 +24,6 @@ func TraceBootstrapableEngine(bootstrapableEngine BootstrapableEngine, tracer tr } } -func (e *tracedBootstrapableEngine) ForceAccepted(ctx context.Context, acceptedContainerIDs []ids.ID) error { - ctx, span := e.tracer.Start(ctx, "tracedBootstrapableEngine.ForceAccepted", oteltrace.WithAttributes( - attribute.Int("numAcceptedContainerIDs", len(acceptedContainerIDs)), - )) - defer span.End() - - return e.bootstrapableEngine.ForceAccepted(ctx, acceptedContainerIDs) -} - func (e *tracedBootstrapableEngine) Clear(ctx context.Context) error { ctx, span := e.tracer.Start(ctx, "tracedBootstrapableEngine.Clear") defer span.End() diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index 728e38af59cf..b575229954fb 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" + "github.com/ava-labs/avalanchego/snow/consensus/snowman/bootstrapper" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/utils/set" @@ -25,8 +26,18 @@ import ( "github.com/ava-labs/avalanchego/version" ) -// Parameters for delaying bootstrapping to avoid potential CPU burns -const bootstrappingDelay = 10 * time.Second +const ( + // Delay bootstrapping to avoid potential CPU burns + bootstrappingDelay = 10 * time.Second + + // statusUpdateFrequency is how many containers should be processed between + // logs + statusUpdateFrequency = 5000 + + // maxOutstandingBroadcastRequests is the maximum number of requests to have + // outstanding when broadcasting. + maxOutstandingBroadcastRequests = 50 +) var ( _ common.BootstrapableEngine = (*Bootstrapper)(nil) @@ -52,6 +63,8 @@ var ( // called, so it must be guaranteed the VM is not used until after Start. type Bootstrapper struct { Config + common.Halter + *metrics // list of NoOpsHandler for messages dropped by bootstrapper common.StateSummaryFrontierHandler @@ -61,21 +74,25 @@ type Bootstrapper struct { common.ChitsHandler common.AppHandler - common.Bootstrapper - common.Fetcher - *metrics + requestID uint32 // Tracks the last requestID that was used in a request + + started bool + restarted bool - started bool + minority bootstrapper.Poll + majority bootstrapper.Poll - // Greatest height of the blocks passed in ForceAccepted + // Greatest height of the blocks passed in startSyncing tipHeight uint64 // Height of the last accepted block when bootstrapping starts startingHeight uint64 - // Number of blocks that were fetched on ForceAccepted + // Number of blocks that were fetched on startSyncing initiallyFetched uint64 - // Time that ForceAccepted was last called + // Time that startSyncing was last called startTime time.Time + common.Fetcher + // number of state transitions executed executedStateTransitions int @@ -99,11 +116,7 @@ type Bootstrapper struct { func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) error) (*Bootstrapper, error) { metrics, err := newMetrics("bs", config.Ctx.Registerer) - if err != nil { - return nil, err - } - - b := &Bootstrapper{ + return &Bootstrapper{ Config: config, metrics: metrics, StateSummaryFrontierHandler: common.NewNoOpStateSummaryFrontierHandler(config.Ctx.Log), @@ -113,22 +126,30 @@ func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) e ChitsHandler: common.NewNoOpChitsHandler(config.Ctx.Log), AppHandler: config.VM, + minority: bootstrapper.Noop, + majority: bootstrapper.Noop, + Fetcher: common.Fetcher{ OnFinished: onFinished, }, - executedStateTransitions: math.MaxInt32, - } - - config.Bootstrapable = b - b.Bootstrapper = common.NewCommonBootstrapper(config.Config) - - return b, nil + executedStateTransitions: math.MaxInt, + }, err } func (b *Bootstrapper) Context() *snow.ConsensusContext { return b.Ctx } +func (b *Bootstrapper) Clear(context.Context) error { + b.Ctx.Lock.Lock() + defer b.Ctx.Lock.Unlock() + + if err := b.Config.Blocked.Clear(); err != nil { + return err + } + return b.Config.Blocked.Commit() +} + func (b *Bootstrapper) Start(ctx context.Context, startReqID uint32) error { b.Ctx.Log.Info("starting bootstrapper") @@ -161,7 +182,7 @@ func (b *Bootstrapper) Start(ctx context.Context, startReqID uint32) error { return fmt.Errorf("couldn't get last accepted block: %w", err) } b.startingHeight = lastAccepted.Height() - b.Config.SharedCfg.RequestID = startReqID + b.requestID = startReqID return b.tryStartBootstrapping(ctx) } @@ -203,162 +224,176 @@ func (b *Bootstrapper) tryStartBootstrapping(ctx context.Context) error { } b.started = true - return b.Startup(ctx) + return b.startBootstrapping(ctx) } -// Ancestors handles the receipt of multiple containers. Should be received in -// response to a GetAncestors message to [nodeID] with request ID [requestID] -func (b *Bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, blks [][]byte) error { - // Make sure this is in response to a request we made - wantedBlkID, ok := b.OutstandingRequests.Remove(nodeID, requestID) - if !ok { // this message isn't in response to a request we made - b.Ctx.Log.Debug("received unexpected Ancestors", - zap.Stringer("nodeID", nodeID), - zap.Uint32("requestID", requestID), - ) - return nil +func (b *Bootstrapper) startBootstrapping(ctx context.Context) error { + currentBeacons := b.Beacons.GetMap(b.Ctx.SubnetID) + nodeWeights := make(map[ids.NodeID]uint64, len(currentBeacons)) + for nodeID, beacon := range currentBeacons { + nodeWeights[nodeID] = beacon.Weight } - lenBlks := len(blks) - if lenBlks == 0 { - b.Ctx.Log.Debug("received Ancestors with no block", - zap.Stringer("nodeID", nodeID), - zap.Uint32("requestID", requestID), + frontierNodes, err := bootstrapper.Sample(nodeWeights, b.SampleK) + if err != nil { + return err + } + + b.Ctx.Log.Debug("sampled nodes to seed bootstrapping frontier", + zap.Reflect("sampledNodes", frontierNodes), + zap.Int("numNodes", len(nodeWeights)), + ) + + b.minority = bootstrapper.NewMinority( + b.Ctx.Log, + frontierNodes, + maxOutstandingBroadcastRequests, + ) + b.majority = bootstrapper.NewMajority( + b.Ctx.Log, + nodeWeights, + maxOutstandingBroadcastRequests, + ) + + if accepted, finalized := b.majority.Result(ctx); finalized { + b.Ctx.Log.Info("bootstrapping skipped", + zap.String("reason", "no provided bootstraps"), ) + return b.startSyncing(ctx, accepted) + } - b.markUnavailable(nodeID) + b.requestID++ + return b.sendBootstrappingMessagesOrFinish(ctx) +} - // Send another request for this - return b.fetch(ctx, wantedBlkID) +func (b *Bootstrapper) sendBootstrappingMessagesOrFinish(ctx context.Context) error { + if peers := b.minority.GetPeers(ctx); peers.Len() > 0 { + b.Sender.SendGetAcceptedFrontier(ctx, peers, b.requestID) + return nil } - // This node has responded - so add it back into the set - b.fetchFrom.Add(nodeID) + potentialAccepted, finalized := b.minority.Result(ctx) + if !finalized { + // We haven't finalized the accepted frontier, so we should wait for the + // outstanding requests. + return nil + } - if lenBlks > b.Config.AncestorsMaxContainersReceived { - blks = blks[:b.Config.AncestorsMaxContainersReceived] - b.Ctx.Log.Debug("ignoring containers in Ancestors", - zap.Int("numContainers", lenBlks-b.Config.AncestorsMaxContainersReceived), - zap.Stringer("nodeID", nodeID), - zap.Uint32("requestID", requestID), - ) + if peers := b.majority.GetPeers(ctx); peers.Len() > 0 { + b.Sender.SendGetAccepted(ctx, peers, b.requestID, potentialAccepted) + return nil } - blocks, err := block.BatchedParseBlock(ctx, b.VM, blks) - if err != nil { // the provided blocks couldn't be parsed - b.Ctx.Log.Debug("failed to parse blocks in Ancestors", - zap.Stringer("nodeID", nodeID), - zap.Uint32("requestID", requestID), - zap.Error(err), - ) - return b.fetch(ctx, wantedBlkID) + accepted, finalized := b.majority.Result(ctx) + if !finalized { + // We haven't finalized the accepted set, so we should wait for the + // outstanding requests. + return nil } - if len(blocks) == 0 { - b.Ctx.Log.Debug("parsing blocks returned an empty set of blocks", - zap.Stringer("nodeID", nodeID), - zap.Uint32("requestID", requestID), + numAccepted := len(accepted) + if numAccepted == 0 { + b.Ctx.Log.Debug("restarting bootstrap", + zap.String("reason", "no blocks accepted"), + zap.Int("numBeacons", b.Beacons.Count(b.Ctx.SubnetID)), ) - return b.fetch(ctx, wantedBlkID) + // Invariant: These functions are mutualy recursive. However, when + // [startBootstrapping] calls [sendMessagesOrFinish], it is guaranteed + // to exit when sending GetAcceptedFrontier requests. + return b.startBootstrapping(ctx) } - requestedBlock := blocks[0] - if actualID := requestedBlock.ID(); actualID != wantedBlkID { - b.Ctx.Log.Debug("first block is not the requested block", - zap.Stringer("expectedBlkID", wantedBlkID), - zap.Stringer("blkID", actualID), + if !b.restarted { + b.Ctx.Log.Info("bootstrapping started syncing", + zap.Int("numAccepted", numAccepted), + ) + } else { + b.Ctx.Log.Debug("bootstrapping started syncing", + zap.Int("numAccepted", numAccepted), ) - return b.fetch(ctx, wantedBlkID) } - blockSet := make(map[ids.ID]snowman.Block, len(blocks)) - for _, block := range blocks[1:] { - blockSet[block.ID()] = block - } - return b.process(ctx, requestedBlock, blockSet) + return b.startSyncing(ctx, accepted) } -func (b *Bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - blkID, ok := b.OutstandingRequests.Remove(nodeID, requestID) - if !ok { - b.Ctx.Log.Debug("unexpectedly called GetAncestorsFailed", +func (b *Bootstrapper) AcceptedFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error { + if requestID != b.requestID { + b.Ctx.Log.Debug("received out-of-sync AcceptedFrontier message", zap.Stringer("nodeID", nodeID), + zap.Uint32("expectedRequestID", b.requestID), zap.Uint32("requestID", requestID), ) return nil } - // This node timed out their request, so we can add them back to [fetchFrom] - b.fetchFrom.Add(nodeID) - - // Send another request for this - return b.fetch(ctx, blkID) + if err := b.minority.RecordOpinion(ctx, nodeID, set.Of(containerID)); err != nil { + return err + } + return b.sendBootstrappingMessagesOrFinish(ctx) } -func (b *Bootstrapper) Timeout(ctx context.Context) error { - if !b.awaitingTimeout { - return errUnexpectedTimeout +func (b *Bootstrapper) GetAcceptedFrontierFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + if requestID != b.requestID { + b.Ctx.Log.Debug("received out-of-sync GetAcceptedFrontierFailed message", + zap.Stringer("nodeID", nodeID), + zap.Uint32("expectedRequestID", b.requestID), + zap.Uint32("requestID", requestID), + ) + return nil } - b.awaitingTimeout = false - if !b.Config.BootstrapTracker.IsBootstrapped() { - return b.Restart(ctx) + if err := b.minority.RecordOpinion(ctx, nodeID, nil); err != nil { + return err } - b.fetchETA.Set(0) - return b.OnFinished(ctx, b.Config.SharedCfg.RequestID) -} - -func (*Bootstrapper) Gossip(context.Context) error { - return nil + return b.sendBootstrappingMessagesOrFinish(ctx) } -func (b *Bootstrapper) Shutdown(ctx context.Context) error { - b.Ctx.Log.Info("shutting down bootstrapper") - - b.Ctx.Lock.Lock() - defer b.Ctx.Lock.Unlock() - - return b.VM.Shutdown(ctx) -} - -func (b *Bootstrapper) Notify(_ context.Context, msg common.Message) error { - if msg != common.StateSyncDone { - b.Ctx.Log.Warn("received an unexpected message from the VM", - zap.Stringer("msg", msg), +func (b *Bootstrapper) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { + if requestID != b.requestID { + b.Ctx.Log.Debug("received out-of-sync Accepted message", + zap.Stringer("nodeID", nodeID), + zap.Uint32("expectedRequestID", b.requestID), + zap.Uint32("requestID", requestID), ) return nil } - b.Ctx.StateSyncing.Set(false) - return nil + if err := b.majority.RecordOpinion(ctx, nodeID, containerIDs); err != nil { + return err + } + return b.sendBootstrappingMessagesOrFinish(ctx) } -func (b *Bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { - b.Ctx.Lock.Lock() - defer b.Ctx.Lock.Unlock() +func (b *Bootstrapper) GetAcceptedFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + if requestID != b.requestID { + b.Ctx.Log.Debug("received out-of-sync GetAcceptedFailed message", + zap.Stringer("nodeID", nodeID), + zap.Uint32("expectedRequestID", b.requestID), + zap.Uint32("requestID", requestID), + ) + return nil + } - vmIntf, vmErr := b.VM.HealthCheck(ctx) - intf := map[string]interface{}{ - "consensus": struct{}{}, - "vm": vmIntf, + if err := b.majority.RecordOpinion(ctx, nodeID, nil); err != nil { + return err } - return intf, vmErr + return b.sendBootstrappingMessagesOrFinish(ctx) } -func (b *Bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs []ids.ID) error { - pendingContainerIDs := b.Blocked.MissingIDs() - +func (b *Bootstrapper) startSyncing(ctx context.Context, acceptedContainerIDs []ids.ID) error { // Initialize the fetch from set to the currently preferred peers b.fetchFrom = b.StartupTracker.PreferredPeers() + pendingContainerIDs := b.Blocked.MissingIDs() // Append the list of accepted container IDs to pendingContainerIDs to ensure // we iterate over every container that must be traversed. pendingContainerIDs = append(pendingContainerIDs, acceptedContainerIDs...) - toProcess := make([]snowman.Block, 0, len(pendingContainerIDs)) b.Ctx.Log.Debug("starting bootstrapping", zap.Int("numPendingBlocks", len(pendingContainerIDs)), zap.Int("numAcceptedBlocks", len(acceptedContainerIDs)), ) + + toProcess := make([]snowman.Block, 0, len(pendingContainerIDs)) for _, blkID := range pendingContainerIDs { b.Blocked.AddMissingID(blkID) @@ -384,7 +419,7 @@ func (b *Bootstrapper) ForceAccepted(ctx context.Context, acceptedContainerIDs [ } } - return b.checkFinish(ctx) + return b.tryStartExecuting(ctx) } // Get block [blkID] and its ancestors from a validator @@ -396,7 +431,7 @@ func (b *Bootstrapper) fetch(ctx context.Context, blkID ids.ID) error { // Make sure we don't already have this block if _, err := b.VM.GetBlock(ctx, blkID); err == nil { - return b.checkFinish(ctx) + return b.tryStartExecuting(ctx) } validatorID, ok := b.fetchFrom.Peek() @@ -407,13 +442,102 @@ func (b *Bootstrapper) fetch(ctx context.Context, blkID ids.ID) error { // We only allow one outbound request at a time from a node b.markUnavailable(validatorID) - b.Config.SharedCfg.RequestID++ + b.requestID++ - b.OutstandingRequests.Add(validatorID, b.Config.SharedCfg.RequestID, blkID) - b.Config.Sender.SendGetAncestors(ctx, validatorID, b.Config.SharedCfg.RequestID, blkID) // request block and ancestors + b.OutstandingRequests.Add(validatorID, b.requestID, blkID) + b.Config.Sender.SendGetAncestors(ctx, validatorID, b.requestID, blkID) // request block and ancestors return nil } +// Ancestors handles the receipt of multiple containers. Should be received in +// response to a GetAncestors message to [nodeID] with request ID [requestID] +func (b *Bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, blks [][]byte) error { + // Make sure this is in response to a request we made + wantedBlkID, ok := b.OutstandingRequests.Remove(nodeID, requestID) + if !ok { // this message isn't in response to a request we made + b.Ctx.Log.Debug("received unexpected Ancestors", + zap.Stringer("nodeID", nodeID), + zap.Uint32("requestID", requestID), + ) + return nil + } + + lenBlks := len(blks) + if lenBlks == 0 { + b.Ctx.Log.Debug("received Ancestors with no block", + zap.Stringer("nodeID", nodeID), + zap.Uint32("requestID", requestID), + ) + + b.markUnavailable(nodeID) + + // Send another request for this + return b.fetch(ctx, wantedBlkID) + } + + // This node has responded - so add it back into the set + b.fetchFrom.Add(nodeID) + + if lenBlks > b.Config.AncestorsMaxContainersReceived { + blks = blks[:b.Config.AncestorsMaxContainersReceived] + b.Ctx.Log.Debug("ignoring containers in Ancestors", + zap.Int("numContainers", lenBlks-b.Config.AncestorsMaxContainersReceived), + zap.Stringer("nodeID", nodeID), + zap.Uint32("requestID", requestID), + ) + } + + blocks, err := block.BatchedParseBlock(ctx, b.VM, blks) + if err != nil { // the provided blocks couldn't be parsed + b.Ctx.Log.Debug("failed to parse blocks in Ancestors", + zap.Stringer("nodeID", nodeID), + zap.Uint32("requestID", requestID), + zap.Error(err), + ) + return b.fetch(ctx, wantedBlkID) + } + + if len(blocks) == 0 { + b.Ctx.Log.Debug("parsing blocks returned an empty set of blocks", + zap.Stringer("nodeID", nodeID), + zap.Uint32("requestID", requestID), + ) + return b.fetch(ctx, wantedBlkID) + } + + requestedBlock := blocks[0] + if actualID := requestedBlock.ID(); actualID != wantedBlkID { + b.Ctx.Log.Debug("first block is not the requested block", + zap.Stringer("expectedBlkID", wantedBlkID), + zap.Stringer("blkID", actualID), + ) + return b.fetch(ctx, wantedBlkID) + } + + blockSet := make(map[ids.ID]snowman.Block, len(blocks)) + for _, block := range blocks[1:] { + blockSet[block.ID()] = block + } + return b.process(ctx, requestedBlock, blockSet) +} + +func (b *Bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + blkID, ok := b.OutstandingRequests.Remove(nodeID, requestID) + if !ok { + b.Ctx.Log.Debug("unexpectedly called GetAncestorsFailed", + zap.Stringer("nodeID", nodeID), + zap.Uint32("requestID", requestID), + ) + return nil + } + + // This node timed out their request, so we can add them back to [fetchFrom] + b.fetchFrom.Add(nodeID) + + // Send another request for this + return b.fetch(ctx, blkID) +} + // markUnavailable removes [nodeID] from the set of peers used to fetch // ancestors. If the set becomes empty, it is reset to the currently preferred // peers so bootstrapping can continue. @@ -427,16 +551,6 @@ func (b *Bootstrapper) markUnavailable(nodeID ids.NodeID) { } } -func (b *Bootstrapper) Clear(context.Context) error { - b.Ctx.Lock.Lock() - defer b.Ctx.Lock.Unlock() - - if err := b.Config.Blocked.Clear(); err != nil { - return err - } - return b.Config.Blocked.Commit() -} - // process a series of consecutive blocks starting at [blk]. // // - blk is a block that is assumed to have been marked as acceptable by the @@ -473,7 +587,7 @@ func (b *Bootstrapper) process(ctx context.Context, blk snowman.Block, processin if err := b.Blocked.Commit(); err != nil { return err } - return b.checkFinish(ctx) + return b.tryStartExecuting(ctx) } // If this block is going to be accepted, make sure to update the @@ -499,7 +613,7 @@ func (b *Bootstrapper) process(ctx context.Context, blk snowman.Block, processin if err := b.Blocked.Commit(); err != nil { return err } - return b.checkFinish(ctx) + return b.tryStartExecuting(ctx) } // We added a new block to the queue, so track that it was fetched @@ -507,7 +621,7 @@ func (b *Bootstrapper) process(ctx context.Context, blk snowman.Block, processin // Periodically log progress blocksFetchedSoFar := b.Blocked.Jobs.PendingJobs() - if blocksFetchedSoFar%common.StatusUpdateFrequency == 0 { + if blocksFetchedSoFar%statusUpdateFrequency == 0 { totalBlocksToFetch := b.tipHeight - b.startingHeight eta := timer.EstimateETA( b.startTime, @@ -516,7 +630,7 @@ func (b *Bootstrapper) process(ctx context.Context, blk snowman.Block, processin ) b.fetchETA.Set(float64(eta)) - if !b.Config.SharedCfg.Restarted { + if !b.restarted { b.Ctx.Log.Info("fetching blocks", zap.Uint64("numFetchedBlocks", blocksFetchedSoFar), zap.Uint64("numTotalBlocks", totalBlocksToFetch), @@ -560,13 +674,14 @@ func (b *Bootstrapper) process(ctx context.Context, blk snowman.Block, processin if err := b.Blocked.Commit(); err != nil { return err } - return b.checkFinish(ctx) + return b.tryStartExecuting(ctx) } } -// checkFinish repeatedly executes pending transactions and requests new frontier vertices until there aren't any new ones -// after which it finishes the bootstrap process -func (b *Bootstrapper) checkFinish(ctx context.Context) error { +// tryStartExecuting executes all pending blocks if there are no more blocks +// being fetched. After executing all pending blocks it will either restart +// bootstrapping, or transition into normal operations. +func (b *Bootstrapper) tryStartExecuting(ctx context.Context) error { if numPending := b.Blocked.NumMissingIDs(); numPending != 0 { return nil } @@ -575,7 +690,7 @@ func (b *Bootstrapper) checkFinish(ctx context.Context) error { return nil } - if !b.Config.SharedCfg.Restarted { + if !b.restarted { b.Ctx.Log.Info("executing blocks", zap.Uint64("numPendingJobs", b.Blocked.PendingJobs()), ) @@ -589,7 +704,7 @@ func (b *Bootstrapper) checkFinish(ctx context.Context) error { ctx, b.Config.Ctx, b, - b.Config.SharedCfg.Restarted, + b.restarted, b.Ctx.BlockAcceptor, ) if err != nil || b.Halted() { @@ -603,7 +718,7 @@ func (b *Bootstrapper) checkFinish(ctx context.Context) error { // so that the bootstrapping process will terminate even as new blocks are // being issued. if executedBlocks > 0 && executedBlocks < previouslyExecuted/2 { - return b.Restart(ctx) + return b.restartBootstrapping(ctx) } // If there is an additional callback, notify them that this chain has been @@ -618,7 +733,7 @@ func (b *Bootstrapper) checkFinish(ctx context.Context) error { // If the subnet hasn't finished bootstrapping, this chain should remain // syncing. if !b.Config.BootstrapTracker.IsBootstrapped() { - if !b.Config.SharedCfg.Restarted { + if !b.restarted { b.Ctx.Log.Info("waiting for the remaining chains in this subnet to finish syncing") } else { b.Ctx.Log.Debug("waiting for the remaining chains in this subnet to finish syncing") @@ -630,5 +745,61 @@ func (b *Bootstrapper) checkFinish(ctx context.Context) error { return nil } b.fetchETA.Set(0) - return b.OnFinished(ctx, b.Config.SharedCfg.RequestID) + return b.OnFinished(ctx, b.requestID) +} + +func (b *Bootstrapper) Timeout(ctx context.Context) error { + if !b.awaitingTimeout { + return errUnexpectedTimeout + } + b.awaitingTimeout = false + + if !b.Config.BootstrapTracker.IsBootstrapped() { + return b.restartBootstrapping(ctx) + } + b.fetchETA.Set(0) + return b.OnFinished(ctx, b.requestID) +} + +func (b *Bootstrapper) restartBootstrapping(ctx context.Context) error { + b.Ctx.Log.Debug("Checking for new frontiers") + b.restarted = true + return b.startBootstrapping(ctx) +} + +func (b *Bootstrapper) Notify(_ context.Context, msg common.Message) error { + if msg != common.StateSyncDone { + b.Ctx.Log.Warn("received an unexpected message from the VM", + zap.Stringer("msg", msg), + ) + return nil + } + + b.Ctx.StateSyncing.Set(false) + return nil +} + +func (b *Bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { + b.Ctx.Lock.Lock() + defer b.Ctx.Lock.Unlock() + + vmIntf, vmErr := b.VM.HealthCheck(ctx) + intf := map[string]interface{}{ + "consensus": struct{}{}, + "vm": vmIntf, + } + return intf, vmErr +} + +func (b *Bootstrapper) Shutdown(ctx context.Context) error { + b.Ctx.Log.Info("shutting down bootstrapper") + + b.Ctx.Lock.Lock() + defer b.Ctx.Lock.Unlock() + + return b.VM.Shutdown(ctx) +} + +func (*Bootstrapper) Gossip(context.Context) error { + return nil } diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index c883de181323..6cf69d797ff5 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -75,28 +75,22 @@ func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *block.Tes require.NoError(startupTracker.Connected(context.Background(), peer, version.CurrentApp)) - commonConfig := common.Config{ + snowGetHandler, err := getter.New(vm, sender, ctx.Log, time.Second, 2000, ctx.Registerer) + require.NoError(err) + + blocker, _ := queue.NewWithMissing(memdb.New(), "", prometheus.NewRegistry()) + return Config{ + AllGetsServer: snowGetHandler, Ctx: ctx, Beacons: vdrs, SampleK: vdrs.Count(ctx.SubnetID), - Alpha: totalWeight/2 + 1, StartupTracker: startupTracker, Sender: sender, BootstrapTracker: bootstrapTracker, Timer: &common.TimerTest{}, AncestorsMaxContainersReceived: 2000, - SharedCfg: &common.SharedConfig{}, - } - - snowGetHandler, err := getter.New(vm, sender, ctx.Log, time.Second, 2000, ctx.Registerer) - require.NoError(err) - - blocker, _ := queue.NewWithMissing(memdb.New(), "", prometheus.NewRegistry()) - return Config{ - Config: commonConfig, - AllGetsServer: snowGetHandler, - Blocked: blocker, - VM: vm, + Blocked: blocker, + VM: vm, }, peer, sender, vm } @@ -121,27 +115,21 @@ func TestBootstrapperStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { startupTracker := tracker.NewStartup(peerTracker, startupAlpha) peers.RegisterCallbackListener(ctx.SubnetID, startupTracker) - commonCfg := common.Config{ + blocker, _ := queue.NewWithMissing(memdb.New(), "", prometheus.NewRegistry()) + snowGetHandler, err := getter.New(vm, sender, ctx.Log, time.Second, 2000, ctx.Registerer) + require.NoError(err) + cfg := Config{ + AllGetsServer: snowGetHandler, Ctx: ctx, Beacons: peers, SampleK: sampleK, - Alpha: alpha, StartupTracker: startupTracker, Sender: sender, BootstrapTracker: &common.BootstrapTrackerTest{}, Timer: &common.TimerTest{}, AncestorsMaxContainersReceived: 2000, - SharedCfg: &common.SharedConfig{}, - } - - blocker, _ := queue.NewWithMissing(memdb.New(), "", prometheus.NewRegistry()) - snowGetHandler, err := getter.New(vm, sender, ctx.Log, time.Second, 2000, ctx.Registerer) - require.NoError(err) - cfg := Config{ - Config: commonCfg, - AllGetsServer: snowGetHandler, - Blocked: blocker, - VM: vm, + Blocked: blocker, + VM: vm, } blkID0 := ids.Empty.Prefix(0) @@ -192,7 +180,7 @@ func TestBootstrapperStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { // attempt starting bootstrapper with not enough stake connected. Bootstrapper should stall. vdr0 := ids.GenerateTestNodeID() - require.NoError(peers.AddStaker(commonCfg.Ctx.SubnetID, vdr0, nil, ids.Empty, startupAlpha/2)) + require.NoError(peers.AddStaker(ctx.SubnetID, vdr0, nil, ids.Empty, startupAlpha/2)) require.NoError(bs.Connected(context.Background(), vdr0, version.CurrentApp)) require.NoError(bs.Start(context.Background(), 0)) @@ -200,7 +188,7 @@ func TestBootstrapperStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { // finally attempt starting bootstrapper with enough stake connected. Frontiers should be requested. vdr := ids.GenerateTestNodeID() - require.NoError(peers.AddStaker(commonCfg.Ctx.SubnetID, vdr, nil, ids.Empty, startupAlpha)) + require.NoError(peers.AddStaker(ctx.SubnetID, vdr, nil, ids.Empty, startupAlpha)) require.NoError(bs.Connected(context.Background(), vdr, version.CurrentApp)) require.True(frontierRequested) } @@ -283,7 +271,7 @@ func TestBootstrapperSingleFrontier(t *testing.T) { return nil, errUnknownBlock } - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) + require.NoError(bs.startSyncing(context.Background(), acceptedIDs)) require.Equal(snow.NormalOp, config.Ctx.State.Get().State) require.Equal(choices.Accepted, blk1.Status()) } @@ -396,7 +384,7 @@ func TestBootstrapperUnknownByzantineResponse(t *testing.T) { } vm.CantSetState = false - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID2})) // should request blk1 + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID2})) // should request blk1 oldReqID := requestID require.NoError(bs.Ancestors(context.Background(), peerID, requestID, [][]byte{blkBytes0})) // respond with wrong block @@ -409,7 +397,7 @@ func TestBootstrapperUnknownByzantineResponse(t *testing.T) { require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID2})) + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID2})) require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } @@ -542,7 +530,7 @@ func TestBootstrapperPartialFetch(t *testing.T) { requested = blkID } - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) // should request blk2 + require.NoError(bs.startSyncing(context.Background(), acceptedIDs)) // should request blk2 require.NoError(bs.Ancestors(context.Background(), peerID, *requestID, [][]byte{blkBytes2})) // respond with blk2 require.Equal(blkID1, requested) @@ -555,7 +543,7 @@ func TestBootstrapperPartialFetch(t *testing.T) { require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) + require.NoError(bs.startSyncing(context.Background(), acceptedIDs)) require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } @@ -690,7 +678,7 @@ func TestBootstrapperEmptyResponse(t *testing.T) { } // should request blk2 - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) + require.NoError(bs.startSyncing(context.Background(), acceptedIDs)) require.Equal(peerID, requestedVdr) require.Equal(blkID2, requestedBlock) @@ -851,7 +839,7 @@ func TestBootstrapperAncestors(t *testing.T) { requested = blkID } - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) // should request blk2 + require.NoError(bs.startSyncing(context.Background(), acceptedIDs)) // should request blk2 require.NoError(bs.Ancestors(context.Background(), peerID, *requestID, [][]byte{blkBytes2, blkBytes1})) // respond with blk2 and blk1 require.Equal(blkID2, requested) @@ -860,7 +848,7 @@ func TestBootstrapperAncestors(t *testing.T) { require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) - require.NoError(bs.ForceAccepted(context.Background(), acceptedIDs)) + require.NoError(bs.startSyncing(context.Background(), acceptedIDs)) require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } @@ -971,7 +959,7 @@ func TestBootstrapperFinalized(t *testing.T) { requestIDs[blkID] = reqID } - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID1, blkID2})) // should request blk2 and blk1 + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID1, blkID2})) // should request blk2 and blk1 reqIDBlk2, ok := requestIDs[blkID2] require.True(ok) @@ -983,7 +971,7 @@ func TestBootstrapperFinalized(t *testing.T) { require.Equal(choices.Accepted, blk1.Status()) require.Equal(choices.Accepted, blk2.Status()) - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID2})) + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID2})) require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } @@ -1133,7 +1121,7 @@ func TestRestartBootstrapping(t *testing.T) { } // Force Accept blk3 - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID3})) // should request blk3 + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID3})) // should request blk3 reqID, ok := requestIDs[blkID3] require.True(ok) @@ -1142,11 +1130,11 @@ func TestRestartBootstrapping(t *testing.T) { require.Contains(requestIDs, blkID1) - // Remove request, so we can restart bootstrapping via ForceAccepted + // Remove request, so we can restart bootstrapping via startSyncing require.True(bs.OutstandingRequests.RemoveAny(blkID1)) requestIDs = map[ids.ID]uint32{} - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID4})) + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID4})) blk1RequestID, ok := requestIDs[blkID1] require.True(ok) @@ -1166,7 +1154,7 @@ func TestRestartBootstrapping(t *testing.T) { require.Equal(choices.Accepted, blk3.Status()) require.Equal(choices.Accepted, blk4.Status()) - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blkID4})) + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID4})) require.Equal(snow.NormalOp, config.Ctx.State.Get().State) } @@ -1240,7 +1228,7 @@ func TestBootstrapOldBlockAfterStateSync(t *testing.T) { } // Force Accept, the already transitively accepted, blk0 - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blk0.ID()})) // should request blk0 + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blk0.ID()})) // should request blk0 reqID, ok := requestIDs[blk0.ID()] require.True(ok) @@ -1317,7 +1305,7 @@ func TestBootstrapContinueAfterHalt(t *testing.T) { vm.CantSetState = false require.NoError(bs.Start(context.Background(), 0)) - require.NoError(bs.ForceAccepted(context.Background(), []ids.ID{blk2.ID()})) + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blk2.ID()})) require.Equal(1, bs.Blocked.NumMissingIDs()) } @@ -1360,19 +1348,6 @@ func TestBootstrapNoParseOnNew(t *testing.T) { peers.RegisterCallbackListener(ctx.SubnetID, startupTracker) require.NoError(startupTracker.Connected(context.Background(), peer, version.CurrentApp)) - commonConfig := common.Config{ - Ctx: ctx, - Beacons: peers, - SampleK: peers.Count(ctx.SubnetID), - Alpha: totalWeight/2 + 1, - StartupTracker: startupTracker, - Sender: sender, - BootstrapTracker: bootstrapTracker, - Timer: &common.TimerTest{}, - AncestorsMaxContainersReceived: 2000, - SharedCfg: &common.SharedConfig{}, - } - snowGetHandler, err := getter.New(vm, sender, ctx.Log, time.Second, 2000, ctx.Registerer) require.NoError(err) @@ -1422,10 +1397,17 @@ func TestBootstrapNoParseOnNew(t *testing.T) { require.NoError(err) config := Config{ - Config: commonConfig, - AllGetsServer: snowGetHandler, - Blocked: blocker, - VM: vm, + AllGetsServer: snowGetHandler, + Ctx: ctx, + Beacons: peers, + SampleK: peers.Count(ctx.SubnetID), + StartupTracker: startupTracker, + Sender: sender, + BootstrapTracker: bootstrapTracker, + Timer: &common.TimerTest{}, + AncestorsMaxContainersReceived: 2000, + Blocked: blocker, + VM: vm, } _, err = New( diff --git a/snow/engine/snowman/bootstrap/config.go b/snow/engine/snowman/bootstrap/config.go index 0c05feb7dfa5..785654cb72dc 100644 --- a/snow/engine/snowman/bootstrap/config.go +++ b/snow/engine/snowman/bootstrap/config.go @@ -4,15 +4,30 @@ package bootstrap import ( + "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/common/queue" + "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/snow/validators" ) type Config struct { - common.Config common.AllGetsServer + Ctx *snow.ConsensusContext + Beacons validators.Manager + + SampleK int + StartupTracker tracker.Startup + Sender common.Sender + BootstrapTracker common.BootstrapTracker + Timer common.Timer + + // This node will only consider the first [AncestorsMaxContainersReceived] + // containers in an ancestors message it receives. + AncestorsMaxContainersReceived int + // Blocked tracks operations that are blocked on blocks // // It should be guaranteed that `MissingIDs` should contain all IDs diff --git a/snow/engine/snowman/config_test.go b/snow/engine/snowman/config_test.go index 54d9536a4884..23fc0fc39fd4 100644 --- a/snow/engine/snowman/config_test.go +++ b/snow/engine/snowman/config_test.go @@ -4,6 +4,7 @@ package snowman import ( + "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" @@ -11,13 +12,12 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" ) -func DefaultConfigs() Config { - commonCfg := common.DefaultConfigTest() +func DefaultConfig() Config { return Config{ - Ctx: commonCfg.Ctx, - Sender: commonCfg.Sender, - Validators: validators.NewManager(), + Ctx: snow.DefaultConsensusContextTest(), VM: &block.TestVM{}, + Sender: &common.SenderTest{}, + Validators: validators.NewManager(), Params: snowball.Parameters{ K: 1, AlphaPreference: 1, diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index 8b7431558be6..42db0b264cd1 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -24,6 +24,10 @@ import ( safemath "github.com/ava-labs/avalanchego/utils/math" ) +// maxOutstandingBroadcastRequests is the maximum number of requests to have +// outstanding when broadcasting. +const maxOutstandingBroadcastRequests = 50 + var _ common.StateSyncer = (*stateSyncer)(nil) // summary content as received from network, along with accumulated weight. @@ -544,7 +548,7 @@ func (ss *stateSyncer) startup(ctx context.Context) error { // no more seeders to be reached in the pending set func (ss *stateSyncer) sendGetStateSummaryFrontiers(ctx context.Context) { vdrs := set.NewSet[ids.NodeID](1) - for ss.targetSeeders.Len() > 0 && ss.pendingSeeders.Len() < common.MaxOutstandingBroadcastRequests { + for ss.targetSeeders.Len() > 0 && ss.pendingSeeders.Len() < maxOutstandingBroadcastRequests { vdr, _ := ss.targetSeeders.Pop() vdrs.Add(vdr) ss.pendingSeeders.Add(vdr) @@ -560,7 +564,7 @@ func (ss *stateSyncer) sendGetStateSummaryFrontiers(ctx context.Context) { // no more voters to be reached in the pending set. func (ss *stateSyncer) sendGetAcceptedStateSummaries(ctx context.Context) { vdrs := set.NewSet[ids.NodeID](1) - for ss.targetVoters.Len() > 0 && ss.pendingVoters.Len() < common.MaxOutstandingBroadcastRequests { + for ss.targetVoters.Len() > 0 && ss.pendingVoters.Len() < maxOutstandingBroadcastRequests { vdr, _ := ss.targetVoters.Pop() vdrs.Add(vdr) ss.pendingVoters.Add(vdr) diff --git a/snow/engine/snowman/syncer/state_syncer_test.go b/snow/engine/snowman/syncer/state_syncer_test.go index 95b4d6382ec3..c3dd9b2f16a6 100644 --- a/snow/engine/snowman/syncer/state_syncer_test.go +++ b/snow/engine/snowman/syncer/state_syncer_test.go @@ -243,7 +243,7 @@ func TestBeaconsAreReachedForFrontiersUponStartup(t *testing.T) { } // check that vdrs are reached out for frontiers - require.Len(contactedFrontiersProviders, safemath.Min(beacons.Count(ctx.SubnetID), common.MaxOutstandingBroadcastRequests)) + require.Len(contactedFrontiersProviders, safemath.Min(beacons.Count(ctx.SubnetID), maxOutstandingBroadcastRequests)) for beaconID := range contactedFrontiersProviders { // check that beacon is duly marked as reached out require.Contains(syncer.pendingSeeders, beaconID) @@ -284,7 +284,7 @@ func TestUnRequestedStateSummaryFrontiersAreDropped(t *testing.T) { initiallyReachedOutBeaconsSize := len(contactedFrontiersProviders) require.Positive(initiallyReachedOutBeaconsSize) - require.LessOrEqual(initiallyReachedOutBeaconsSize, common.MaxOutstandingBroadcastRequests) + require.LessOrEqual(initiallyReachedOutBeaconsSize, maxOutstandingBroadcastRequests) // mock VM to simulate a valid summary is returned fullVM.CantParseStateSummary = true @@ -373,7 +373,7 @@ func TestMalformedStateSummaryFrontiersAreDropped(t *testing.T) { initiallyReachedOutBeaconsSize := len(contactedFrontiersProviders) require.Positive(initiallyReachedOutBeaconsSize) - require.LessOrEqual(initiallyReachedOutBeaconsSize, common.MaxOutstandingBroadcastRequests) + require.LessOrEqual(initiallyReachedOutBeaconsSize, maxOutstandingBroadcastRequests) // mock VM to simulate an invalid summary is returned summary := []byte{'s', 'u', 'm', 'm', 'a', 'r', 'y'} @@ -441,7 +441,7 @@ func TestLateResponsesFromUnresponsiveFrontiersAreNotRecorded(t *testing.T) { initiallyReachedOutBeaconsSize := len(contactedFrontiersProviders) require.Positive(initiallyReachedOutBeaconsSize) - require.LessOrEqual(initiallyReachedOutBeaconsSize, common.MaxOutstandingBroadcastRequests) + require.LessOrEqual(initiallyReachedOutBeaconsSize, maxOutstandingBroadcastRequests) // pick one of the vdrs that have been reached out unresponsiveBeaconID := pickRandomFrom(contactedFrontiersProviders) @@ -647,7 +647,7 @@ func TestVoteRequestsAreSentAsAllFrontierBeaconsResponded(t *testing.T) { // check that vote requests are issued initiallyContactedVotersSize := len(contactedVoters) require.Positive(initiallyContactedVotersSize) - require.LessOrEqual(initiallyContactedVotersSize, common.MaxOutstandingBroadcastRequests) + require.LessOrEqual(initiallyContactedVotersSize, maxOutstandingBroadcastRequests) } func TestUnRequestedVotesAreDropped(t *testing.T) { @@ -716,7 +716,7 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { // check that vote requests are issued initiallyContactedVotersSize := len(contactedVoters) require.Positive(initiallyContactedVotersSize) - require.LessOrEqual(initiallyContactedVotersSize, common.MaxOutstandingBroadcastRequests) + require.LessOrEqual(initiallyContactedVotersSize, maxOutstandingBroadcastRequests) _, found := syncer.weightedSummaries[summaryID] require.True(found) @@ -832,7 +832,7 @@ func TestVotesForUnknownSummariesAreDropped(t *testing.T) { // check that vote requests are issued initiallyContactedVotersSize := len(contactedVoters) require.Positive(initiallyContactedVotersSize) - require.LessOrEqual(initiallyContactedVotersSize, common.MaxOutstandingBroadcastRequests) + require.LessOrEqual(initiallyContactedVotersSize, maxOutstandingBroadcastRequests) _, found := syncer.weightedSummaries[summaryID] require.True(found) diff --git a/snow/engine/snowman/syncer/utils_test.go b/snow/engine/snowman/syncer/utils_test.go index fee7c4f847e6..149d1fe0e681 100644 --- a/snow/engine/snowman/syncer/utils_test.go +++ b/snow/engine/snowman/syncer/utils_test.go @@ -58,10 +58,10 @@ type fullVM struct { } func buildTestPeers(t *testing.T, subnetID ids.ID) validators.Manager { - // we consider more than common.MaxOutstandingBroadcastRequests peers - // so to test the effect of cap on number of requests sent out + // We consider more than maxOutstandingBroadcastRequests peers to test + // capping the number of requests sent out. vdrs := validators.NewManager() - for idx := 0; idx < 2*common.MaxOutstandingBroadcastRequests; idx++ { + for idx := 0; idx < 2*maxOutstandingBroadcastRequests; idx++ { beaconID := ids.GenerateTestNodeID() require.NoError(t, vdrs.AddStaker(subnetID, beaconID, nil, ids.Empty, 1)) } diff --git a/snow/engine/snowman/transitive_test.go b/snow/engine/snowman/transitive_test.go index 96cb2d72ba76..405f1abd3666 100644 --- a/snow/engine/snowman/transitive_test.go +++ b/snow/engine/snowman/transitive_test.go @@ -33,18 +33,17 @@ var ( Genesis = ids.GenerateTestID() ) -func setup(t *testing.T, commonCfg common.Config, engCfg Config) (ids.NodeID, validators.Manager, *common.SenderTest, *block.TestVM, *Transitive, snowman.Block) { +func setup(t *testing.T, engCfg Config) (ids.NodeID, validators.Manager, *common.SenderTest, *block.TestVM, *Transitive, snowman.Block) { require := require.New(t) vals := validators.NewManager() engCfg.Validators = vals vdr := ids.GenerateTestNodeID() - require.NoError(vals.AddStaker(commonCfg.Ctx.SubnetID, vdr, nil, ids.Empty, 1)) + require.NoError(vals.AddStaker(engCfg.Ctx.SubnetID, vdr, nil, ids.Empty, 1)) sender := &common.SenderTest{T: t} engCfg.Sender = sender - commonCfg.Sender = sender sender.Default(true) vm := &block.TestVM{} @@ -54,10 +53,10 @@ func setup(t *testing.T, commonCfg common.Config, engCfg Config) (ids.NodeID, va snowGetHandler, err := getter.New( vm, sender, - commonCfg.Ctx.Log, + engCfg.Ctx.Log, time.Second, 2000, - commonCfg.Ctx.Registerer, + engCfg.Ctx.Registerer, ) require.NoError(err) engCfg.AllGetsServer = snowGetHandler @@ -95,9 +94,8 @@ func setup(t *testing.T, commonCfg common.Config, engCfg Config) (ids.NodeID, va } func setupDefaultConfig(t *testing.T) (ids.NodeID, validators.Manager, *common.SenderTest, *block.TestVM, *Transitive, snowman.Block) { - commonCfg := common.DefaultConfigTest() - engCfg := DefaultConfigs() - return setup(t, commonCfg, engCfg) + engCfg := DefaultConfig() + return setup(t, engCfg) } func TestEngineShutdown(t *testing.T) { @@ -326,7 +324,7 @@ func TestEngineQuery(t *testing.T) { func TestEngineMultipleQuery(t *testing.T) { require := require.New(t) - engCfg := DefaultConfigs() + engCfg := DefaultConfig() engCfg.Params = snowball.Parameters{ K: 3, AlphaPreference: 2, @@ -721,7 +719,7 @@ func TestEngineRepoll(t *testing.T) { func TestVoteCanceling(t *testing.T) { require := require.New(t) - engCfg := DefaultConfigs() + engCfg := DefaultConfig() engCfg.Params = snowball.Parameters{ K: 3, AlphaPreference: 2, @@ -819,7 +817,7 @@ func TestVoteCanceling(t *testing.T) { func TestEngineNoQuery(t *testing.T) { require := require.New(t) - engCfg := DefaultConfigs() + engCfg := DefaultConfig() sender := &common.SenderTest{T: t} engCfg.Sender = sender @@ -866,7 +864,7 @@ func TestEngineNoQuery(t *testing.T) { func TestEngineNoRepollQuery(t *testing.T) { require := require.New(t) - engCfg := DefaultConfigs() + engCfg := DefaultConfig() sender := &common.SenderTest{T: t} engCfg.Sender = sender @@ -1504,7 +1502,7 @@ func TestEnginePushQueryRequestIDConflict(t *testing.T) { func TestEngineAggressivePolling(t *testing.T) { require := require.New(t) - engCfg := DefaultConfigs() + engCfg := DefaultConfig() engCfg.Params.ConcurrentRepolls = 2 vals := validators.NewManager() @@ -1592,7 +1590,7 @@ func TestEngineAggressivePolling(t *testing.T) { func TestEngineDoubleChit(t *testing.T) { require := require.New(t) - engCfg := DefaultConfigs() + engCfg := DefaultConfig() engCfg.Params = snowball.Parameters{ K: 2, AlphaPreference: 2, @@ -1696,7 +1694,7 @@ func TestEngineDoubleChit(t *testing.T) { func TestEngineBuildBlockLimit(t *testing.T) { require := require.New(t) - engCfg := DefaultConfigs() + engCfg := DefaultConfig() engCfg.Params.K = 1 engCfg.Params.AlphaPreference = 1 engCfg.Params.AlphaConfidence = 1 @@ -2718,7 +2716,7 @@ func TestEngineBuildBlockWithCachedNonVerifiedParent(t *testing.T) { func TestEngineApplyAcceptedFrontierInQueryFailed(t *testing.T) { require := require.New(t) - engCfg := DefaultConfigs() + engCfg := DefaultConfig() engCfg.Params = snowball.Parameters{ K: 1, AlphaPreference: 1, diff --git a/snow/networking/handler/handler_test.go b/snow/networking/handler/handler_test.go index 0c87ed752f8b..bb434e2017d4 100644 --- a/snow/networking/handler/handler_test.go +++ b/snow/networking/handler/handler_test.go @@ -68,9 +68,6 @@ func TestHandlerDropsTimedOutMessages(t *testing.T) { handler := handlerIntf.(*handler) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -170,9 +167,6 @@ func TestHandlerClosesOnError(t *testing.T) { }) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -260,9 +254,6 @@ func TestHandlerDropsGossipDuringBootstrapping(t *testing.T) { handler.clock.Set(time.Now()) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -338,9 +329,6 @@ func TestHandlerDispatchInternal(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -415,9 +403,6 @@ func TestHandlerSubnetConnector(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -587,9 +572,6 @@ func TestDynamicEngineTypeDispatch(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, diff --git a/snow/networking/handler/health_test.go b/snow/networking/handler/health_test.go index 9767859a4abf..63b7dbea140c 100644 --- a/snow/networking/handler/health_test.go +++ b/snow/networking/handler/health_test.go @@ -82,9 +82,6 @@ func TestHealthCheckSubnet(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, diff --git a/snow/networking/router/chain_router_test.go b/snow/networking/router/chain_router_test.go index d4f71828799f..1e37c7c1d799 100644 --- a/snow/networking/router/chain_router_test.go +++ b/snow/networking/router/chain_router_test.go @@ -105,9 +105,6 @@ func TestShutdown(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -246,9 +243,6 @@ func TestShutdownTimesOut(t *testing.T) { bootstrapFinished := make(chan struct{}, 1) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -407,9 +401,6 @@ func TestRouterTimeout(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -886,9 +877,6 @@ func TestRouterClearTimeouts(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -1182,9 +1170,6 @@ func TestValidatorOnlyMessageDrops(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -1634,9 +1619,6 @@ func TestValidatorOnlyAllowedNodeMessageDrops(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index 88c02b9a7f3f..a6da8738e1fa 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -134,9 +134,6 @@ func TestTimeout(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -392,9 +389,6 @@ func TestReliableMessages(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, @@ -540,9 +534,6 @@ func TestReliableMessagesToMyself(t *testing.T) { require.NoError(err) bootstrapper := &common.BootstrapperTest{ - BootstrapableTest: common.BootstrapableTest{ - T: t, - }, EngineTest: common.EngineTest{ T: t, }, diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 9f286415c6e5..045ccf85b6ac 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1482,23 +1482,17 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { ) require.NoError(err) - commonCfg := common.Config{ + bootstrapConfig := bootstrap.Config{ + AllGetsServer: snowGetHandler, Ctx: consensusCtx, Beacons: beacons, SampleK: beacons.Count(ctx.SubnetID), StartupTracker: startup, - Alpha: (totalWeight + 1) / 2, Sender: sender, BootstrapTracker: bootstrapTracker, AncestorsMaxContainersReceived: 2000, - SharedCfg: &common.SharedConfig{}, - } - - bootstrapConfig := bootstrap.Config{ - Config: commonCfg, - AllGetsServer: snowGetHandler, - Blocked: blocked, - VM: vm, + Blocked: blocked, + VM: vm, } // Asynchronously passes messages from the network to the consensus engine From 6e5292224a6dbd51aa3d7a68f3f9be20b25f8315 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 28 Nov 2023 07:55:27 -0800 Subject: [PATCH 076/267] `vms/platformvm`: Move `toEngine` channel to mempool (#2333) --- vms/platformvm/block/builder/builder.go | 24 ++++---------- vms/platformvm/block/builder/helpers_test.go | 3 +- vms/platformvm/block/executor/helpers_test.go | 8 +---- vms/platformvm/block/executor/rejector.go | 2 ++ .../block/executor/rejector_test.go | 2 ++ vms/platformvm/network/network.go | 2 ++ vms/platformvm/network/network_test.go | 1 + vms/platformvm/txs/mempool/mempool.go | 33 ++++++++++++------- vms/platformvm/txs/mempool/mempool_test.go | 18 +++------- vms/platformvm/txs/mempool/mock_mempool.go | 12 +++++++ vms/platformvm/vm.go | 5 +-- 11 files changed, 55 insertions(+), 55 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 8923857d579e..b8476e19b032 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -13,7 +13,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" @@ -40,7 +39,11 @@ var ( type Builder interface { mempool.Mempool - mempool.BlockTimer + + // ResetBlockTimer schedules a timer to notify the consensus engine once + // there is a block ready to be built. If a block is ready to be built when + // this function is called, the engine will be notified directly. + ResetBlockTimer() // BuildBlock is called on timer clock to attempt to create // next block @@ -58,9 +61,6 @@ type builder struct { txExecutorBackend *txexecutor.Backend blkManager blockexecutor.Manager - // channel to send messages to the consensus engine - toEngine chan<- common.Message - // This timer goes off when it is time for the next validator to add/leave // the validator set. When it goes off ResetTimer() is called, potentially // triggering creation of a new block. @@ -72,14 +72,12 @@ func New( txBuilder txbuilder.Builder, txExecutorBackend *txexecutor.Backend, blkManager blockexecutor.Manager, - toEngine chan<- common.Message, ) Builder { builder := &builder{ Mempool: mempool, txBuilder: txBuilder, txExecutorBackend: txExecutorBackend, blkManager: blkManager, - toEngine: toEngine, } builder.timer = timer.NewTimer(builder.setNextBuildBlockTime) @@ -192,7 +190,7 @@ func (b *builder) setNextBuildBlockTime() { if _, err := b.buildBlock(); err == nil { // We can build a block now - b.notifyBlockReady() + b.Mempool.RequestBuildBlock(true /*=emptyBlockPermitted*/) return } @@ -229,16 +227,6 @@ func (b *builder) setNextBuildBlockTime() { b.timer.SetTimeoutIn(waitTime) } -// notifyBlockReady tells the consensus engine that a new block is ready to be -// created -func (b *builder) notifyBlockReady() { - select { - case b.toEngine <- common.PendingTxs: - default: - b.txExecutorBackend.Ctx.Log.Debug("dropping message to consensus engine") - } -} - // [timestamp] is min(max(now, parent timestamp), next staker change time) func buildBlock( builder *builder, diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 84778add2864..de37d08ff0dd 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -169,7 +169,7 @@ func newEnvironment(t *testing.T) *environment { metrics, err := metrics.New("", registerer) require.NoError(err) - res.mempool, err = mempool.New("mempool", registerer, res) + res.mempool, err = mempool.New("mempool", registerer, nil) require.NoError(err) res.blkManager = blockexecutor.NewManager( @@ -193,7 +193,6 @@ func newEnvironment(t *testing.T) *environment { res.txBuilder, &res.backend, res.blkManager, - nil, // toEngine, ) res.blkManager.SetPreference(genesisID) diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index ff0aa13a2ea1..778d9b203181 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -63,8 +63,6 @@ const ( ) var ( - _ mempool.BlockTimer = (*environment)(nil) - defaultMinStakingDuration = 24 * time.Hour defaultMaxStakingDuration = 365 * 24 * time.Hour defaultGenesisTime = time.Date(1997, 1, 1, 0, 0, 0, 0, time.UTC) @@ -131,10 +129,6 @@ type environment struct { backend *executor.Backend } -func (*environment) ResetBlockTimer() { - // dummy call, do nothing for now -} - func newEnvironment(t *testing.T, ctrl *gomock.Controller) *environment { res := &environment{ isBootstrapped: &utils.Atomic[bool]{}, @@ -199,7 +193,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller) *environment { metrics := metrics.Noop var err error - res.mempool, err = mempool.New("mempool", registerer, res) + res.mempool, err = mempool.New("mempool", registerer, nil) if err != nil { panic(fmt.Errorf("failed to create mempool: %w", err)) } diff --git a/vms/platformvm/block/executor/rejector.go b/vms/platformvm/block/executor/rejector.go index daa6939f05cd..cfc64b050be4 100644 --- a/vms/platformvm/block/executor/rejector.go +++ b/vms/platformvm/block/executor/rejector.go @@ -82,5 +82,7 @@ func (r *rejector) rejectBlock(b block.Block, blockType string) error { } } + r.Mempool.RequestBuildBlock(false) + return nil } diff --git a/vms/platformvm/block/executor/rejector_test.go b/vms/platformvm/block/executor/rejector_test.go index 1e1e5768618d..3ccd9c0d66b1 100644 --- a/vms/platformvm/block/executor/rejector_test.go +++ b/vms/platformvm/block/executor/rejector_test.go @@ -142,6 +142,8 @@ func TestRejectBlock(t *testing.T) { mempool.EXPECT().Add(tx).Return(nil).Times(1) } + mempool.EXPECT().RequestBuildBlock(false).Times(1) + require.NoError(tt.rejectFunc(rejector, blk)) // Make sure block and its parent are removed from the state map. require.NotContains(rejector.blkIDToState, blk.ID()) diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index 0bbfc4f86eaf..5f4945093d60 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -181,6 +181,8 @@ func (n *network) issueTx(tx *txs.Tx) error { return err } + n.mempool.RequestBuildBlock(false) + return nil } diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go index 8c17bb0491b5..000cbda7e195 100644 --- a/vms/platformvm/network/network_test.go +++ b/vms/platformvm/network/network_test.go @@ -284,6 +284,7 @@ func TestNetworkIssueTx(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Has(gomock.Any()).Return(false) mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().RequestBuildBlock(false) return mempool }, managerFunc: func(ctrl *gomock.Controller) executor.Manager { diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 675ec3c5c763..ce0d6a96f071 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -12,6 +12,7 @@ import ( "github.com/ava-labs/avalanchego/cache" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/linkedhashmap" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" @@ -43,13 +44,6 @@ var ( errCantIssueRewardValidatorTx = errors.New("can not issue a reward validator tx") ) -type BlockTimer interface { - // ResetBlockTimer schedules a timer to notify the consensus engine once - // there is a block ready to be built. If a block is ready to be built when - // this function is called, the engine will be notified directly. - ResetBlockTimer() -} - type Mempool interface { // we may want to be able to stop valid transactions // from entering the mempool, e.g. during blocks creation @@ -75,6 +69,13 @@ type Mempool interface { // TODO: Remove once [StartTime] field is ignored in staker txs DropExpiredStakerTxs(minStartTime time.Time) []ids.ID + // RequestBuildBlock notifies the consensus engine that a block should be + // built. If [emptyBlockPermitted] is true, the notification will be sent + // regardless of whether there are no transactions in the mempool. If not, + // a notification will only be sent if there is at least one transaction in + // the mempool. + RequestBuildBlock(emptyBlockPermitted bool) + // Note: dropped txs are added to droppedTxIDs but are not evicted from // unissued decision/staker txs. This allows previously dropped txs to be // possibly reissued. @@ -100,13 +101,13 @@ type mempool struct { consumedUTXOs set.Set[ids.ID] - blkTimer BlockTimer + toEngine chan<- common.Message } func New( namespace string, registerer prometheus.Registerer, - blkTimer BlockTimer, + toEngine chan<- common.Message, ) (Mempool, error) { bytesAvailableMetric := prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, @@ -137,7 +138,7 @@ func New( droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, consumedUTXOs: set.NewSet[ids.ID](initialConsumedUTXOsSize), dropIncoming: false, // enable tx adding by default - blkTimer: blkTimer, + toEngine: toEngine, }, nil } @@ -202,7 +203,6 @@ func (m *mempool) Add(tx *txs.Tx) error { // An explicitly added tx must not be marked as dropped. m.droppedTxIDs.Evict(txID) - m.blkTimer.ResetBlockTimer() return nil } @@ -259,6 +259,17 @@ func (m *mempool) GetDropReason(txID ids.ID) error { return err } +func (m *mempool) RequestBuildBlock(emptyBlockPermitted bool) { + if !emptyBlockPermitted && !m.HasTxs() { + return + } + + select { + case m.toEngine <- common.PendingTxs: + default: + } +} + // Drops all [txs.Staker] transactions whose [StartTime] is before // [minStartTime] from [mempool]. The dropped tx ids are returned. // diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index a56ae4702155..1d92132ebbcd 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -20,15 +20,7 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -var ( - _ BlockTimer = (*noopBlkTimer)(nil) - - preFundedKeys = secp256k1.TestKeys() -) - -type noopBlkTimer struct{} - -func (*noopBlkTimer) ResetBlockTimer() {} +var preFundedKeys = secp256k1.TestKeys() // shows that valid tx is not added to mempool if this would exceed its maximum // size @@ -36,7 +28,7 @@ func TestBlockBuilderMaxMempoolSizeHandling(t *testing.T) { require := require.New(t) registerer := prometheus.NewRegistry() - mpool, err := New("mempool", registerer, &noopBlkTimer{}) + mpool, err := New("mempool", registerer, nil) require.NoError(err) decisionTxs, err := createTestDecisionTxs(1) @@ -60,7 +52,7 @@ func TestDecisionTxsInMempool(t *testing.T) { require := require.New(t) registerer := prometheus.NewRegistry() - mpool, err := New("mempool", registerer, &noopBlkTimer{}) + mpool, err := New("mempool", registerer, nil) require.NoError(err) decisionTxs, err := createTestDecisionTxs(2) @@ -112,7 +104,7 @@ func TestProposalTxsInMempool(t *testing.T) { require := require.New(t) registerer := prometheus.NewRegistry() - mpool, err := New("mempool", registerer, &noopBlkTimer{}) + mpool, err := New("mempool", registerer, nil) require.NoError(err) // The proposal txs are ordered by decreasing start time. This means after @@ -245,7 +237,7 @@ func TestDropExpiredStakerTxs(t *testing.T) { require := require.New(t) registerer := prometheus.NewRegistry() - mempool, err := New("mempool", registerer, &noopBlkTimer{}) + mempool, err := New("mempool", registerer, nil) require.NoError(err) tx1, err := generateAddValidatorTx(10, 20) diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index 8f8c90eb2d07..edc134a42ddf 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -184,3 +184,15 @@ func (mr *MockMempoolMockRecorder) Remove(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockMempool)(nil).Remove), arg0) } + +// RequestBuildBlock mocks base method. +func (m *MockMempool) RequestBuildBlock(arg0 bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RequestBuildBlock", arg0) +} + +// RequestBuildBlock indicates an expected call of RequestBuildBlock. +func (mr *MockMempoolMockRecorder) RequestBuildBlock(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestBuildBlock", reflect.TypeOf((*MockMempool)(nil).RequestBuildBlock), arg0) +} diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index c312e4044e8b..d9898b873137 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -177,9 +177,7 @@ func (vm *VM) Initialize( Bootstrapped: &vm.bootstrapped, } - // Note: There is a circular dependency between the mempool and block - // builder which is broken by passing in the vm. - mempool, err := mempool.New("mempool", registerer, vm) + mempool, err := mempool.New("mempool", registerer, toEngine) if err != nil { return fmt.Errorf("failed to create mempool: %w", err) } @@ -203,7 +201,6 @@ func (vm *VM) Initialize( vm.txBuilder, txExecutorBackend, vm.manager, - toEngine, ) // Create all of the chains that the database says exist From d7e7ff5cc702d108701d325c38895c2642127124 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 28 Nov 2023 10:10:49 -0800 Subject: [PATCH 077/267] `vms/avm`: Rename `states` pkg to `state` (#2381) --- scripts/mocks.mockgen.txt | 2 +- vms/avm/block/builder/builder.go | 12 +- vms/avm/block/builder/builder_test.go | 18 +-- vms/avm/block/executor/block.go | 4 +- vms/avm/block/executor/block_test.go | 42 +++---- vms/avm/block/executor/manager.go | 14 +-- vms/avm/block/executor/manager_test.go | 22 ++-- vms/avm/block/executor/mock_manager.go | 6 +- vms/avm/service_test.go | 18 +-- vms/avm/{states => state}/diff.go | 2 +- .../mock_states.go => state/mock_state.go} | 6 +- vms/avm/{states => state}/state.go | 2 +- vms/avm/{states => state}/state_test.go | 2 +- vms/avm/{states => state}/versions.go | 2 +- vms/avm/txs/executor/executor.go | 4 +- vms/avm/txs/executor/executor_test.go | 8 +- vms/avm/txs/executor/semantic_verifier.go | 4 +- .../txs/executor/semantic_verifier_test.go | 106 +++++++++--------- vms/avm/vm.go | 6 +- 19 files changed, 140 insertions(+), 140 deletions(-) rename vms/avm/{states => state}/diff.go (99%) rename vms/avm/{states/mock_states.go => state/mock_state.go} (99%) rename vms/avm/{states => state}/state.go (99%) rename vms/avm/{states => state}/state_test.go (99%) rename vms/avm/{states => state}/versions.go (95%) diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index ba55a16a4b71..76add90f3f7f 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -27,7 +27,7 @@ github.com/ava-labs/avalanchego/utils/logging=Logger=utils/logging/mock_logger.g github.com/ava-labs/avalanchego/utils/resource=User=utils/resource/mock_user.go github.com/ava-labs/avalanchego/vms/avm/block=Block=vms/avm/block/mock_block.go github.com/ava-labs/avalanchego/vms/avm/metrics=Metrics=vms/avm/metrics/mock_metrics.go -github.com/ava-labs/avalanchego/vms/avm/states=Chain,State,Diff=vms/avm/states/mock_states.go +github.com/ava-labs/avalanchego/vms/avm/state=Chain,State,Diff=vms/avm/state/mock_state.go github.com/ava-labs/avalanchego/vms/avm/txs/mempool=Mempool=vms/avm/txs/mempool/mock_mempool.go github.com/ava-labs/avalanchego/vms/components/avax=TransferableIn=vms/components/avax/mock_transferable_in.go github.com/ava-labs/avalanchego/vms/components/verify=Verifiable=vms/components/verify/mock_verifiable.go diff --git a/vms/avm/block/builder/builder.go b/vms/avm/block/builder/builder.go index 77bbf38a6a35..a3129d797808 100644 --- a/vms/avm/block/builder/builder.go +++ b/vms/avm/block/builder/builder.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/avm/block" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" @@ -82,7 +82,7 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { nextTimestamp = preferredTimestamp } - stateDiff, err := states.NewDiff(preferredID, b.manager) + stateDiff, err := state.NewDiff(preferredID, b.manager) if err != nil { return nil, err } @@ -168,15 +168,15 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { } type stateGetter struct { - state states.Chain + state state.Chain } -func (s stateGetter) GetState(ids.ID) (states.Chain, bool) { +func (s stateGetter) GetState(ids.ID) (state.Chain, bool) { return s.state, true } -func wrapState(parentState states.Chain) (states.Diff, error) { - return states.NewDiff(ids.Empty, stateGetter{ +func wrapState(parentState state.Chain) (state.Diff, error) { + return state.NewDiff(ids.Empty, stateGetter{ state: parentState, }) } diff --git a/vms/avm/block/builder/builder_test.go b/vms/avm/block/builder/builder_test.go index fdab9d6cf064..7faeddbe71e6 100644 --- a/vms/avm/block/builder/builder_test.go +++ b/vms/avm/block/builder/builder_test.go @@ -29,7 +29,7 @@ import ( "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/fxs" "github.com/ava-labs/avalanchego/vms/avm/metrics" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -108,7 +108,7 @@ func TestBuilderBuildBlock(t *testing.T) { mempool, ) }, - expectedErr: states.ErrMissingParentState, + expectedErr: state.ErrMissingParentState, }, { name: "tx fails semantic verification", @@ -120,7 +120,7 @@ func TestBuilderBuildBlock(t *testing.T) { preferredBlock.EXPECT().Height().Return(preferredHeight) preferredBlock.EXPECT().Timestamp().Return(preferredTimestamp) - preferredState := states.NewMockChain(ctrl) + preferredState := state.NewMockChain(ctrl) preferredState.EXPECT().GetLastAccepted().Return(preferredID) preferredState.EXPECT().GetTimestamp().Return(preferredTimestamp) @@ -164,7 +164,7 @@ func TestBuilderBuildBlock(t *testing.T) { preferredBlock.EXPECT().Height().Return(preferredHeight) preferredBlock.EXPECT().Timestamp().Return(preferredTimestamp) - preferredState := states.NewMockChain(ctrl) + preferredState := state.NewMockChain(ctrl) preferredState.EXPECT().GetLastAccepted().Return(preferredID) preferredState.EXPECT().GetTimestamp().Return(preferredTimestamp) @@ -209,7 +209,7 @@ func TestBuilderBuildBlock(t *testing.T) { preferredBlock.EXPECT().Height().Return(preferredHeight) preferredBlock.EXPECT().Timestamp().Return(preferredTimestamp) - preferredState := states.NewMockChain(ctrl) + preferredState := state.NewMockChain(ctrl) preferredState.EXPECT().GetLastAccepted().Return(preferredID) preferredState.EXPECT().GetTimestamp().Return(preferredTimestamp) @@ -255,7 +255,7 @@ func TestBuilderBuildBlock(t *testing.T) { preferredBlock.EXPECT().Height().Return(preferredHeight) preferredBlock.EXPECT().Timestamp().Return(preferredTimestamp) - preferredState := states.NewMockChain(ctrl) + preferredState := state.NewMockChain(ctrl) preferredState.EXPECT().GetLastAccepted().Return(preferredID) preferredState.EXPECT().GetTimestamp().Return(preferredTimestamp) @@ -353,7 +353,7 @@ func TestBuilderBuildBlock(t *testing.T) { clock := &mockable.Clock{} clock.Set(preferredTimestamp.Add(-2 * time.Second)) - preferredState := states.NewMockChain(ctrl) + preferredState := state.NewMockChain(ctrl) preferredState.EXPECT().GetLastAccepted().Return(preferredID) preferredState.EXPECT().GetTimestamp().Return(preferredTimestamp) @@ -427,7 +427,7 @@ func TestBuilderBuildBlock(t *testing.T) { clock := &mockable.Clock{} clock.Set(now) - preferredState := states.NewMockChain(ctrl) + preferredState := state.NewMockChain(ctrl) preferredState.EXPECT().GetLastAccepted().Return(preferredID) preferredState.EXPECT().GetTimestamp().Return(preferredTimestamp) @@ -526,7 +526,7 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { baseDB := versiondb.New(memdb.New()) - state, err := states.New(baseDB, parser, registerer, trackChecksums) + state, err := state.New(baseDB, parser, registerer, trackChecksums) require.NoError(err) clk := &mockable.Clock{} diff --git a/vms/avm/block/executor/block.go b/vms/avm/block/executor/block.go index 418ca0b539ca..5e643ad4ecc0 100644 --- a/vms/avm/block/executor/block.go +++ b/vms/avm/block/executor/block.go @@ -17,7 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/vms/avm/block" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs/executor" ) @@ -106,7 +106,7 @@ func (b *Block) Verify(context.Context) error { ) } - stateDiff, err := states.NewDiff(parentID, b.manager) + stateDiff, err := state.NewDiff(parentID, b.manager) if err != nil { return err } diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index 9d7f291a8f60..da965884ae58 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -24,7 +24,7 @@ import ( "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/metrics" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/executor" "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" @@ -153,7 +153,7 @@ func TestBlockVerify(t *testing.T) { parentID := ids.GenerateTestID() mockBlock.EXPECT().Parent().Return(parentID).AnyTimes() - mockState := states.NewMockState(ctrl) + mockState := state.NewMockState(ctrl) mockState.EXPECT().GetBlock(parentID).Return(nil, errTest) return &Block{ Block: mockBlock, @@ -186,7 +186,7 @@ func TestBlockVerify(t *testing.T) { parentID := ids.GenerateTestID() mockBlock.EXPECT().Parent().Return(parentID).AnyTimes() - mockState := states.NewMockState(ctrl) + mockState := state.NewMockState(ctrl) mockParentBlock := block.NewMockBlock(ctrl) mockParentBlock.EXPECT().Height().Return(blockHeight) // Should be blockHeight - 1 mockState.EXPECT().GetBlock(parentID).Return(mockParentBlock, nil) @@ -226,7 +226,7 @@ func TestBlockVerify(t *testing.T) { mockParentBlock := block.NewMockBlock(ctrl) mockParentBlock.EXPECT().Height().Return(blockHeight - 1) - mockParentState := states.NewMockDiff(ctrl) + mockParentState := state.NewMockDiff(ctrl) mockParentState.EXPECT().GetLastAccepted().Return(parentID) mockParentState.EXPECT().GetTimestamp().Return(blockTimestamp.Add(1)) @@ -271,7 +271,7 @@ func TestBlockVerify(t *testing.T) { mockParentBlock := block.NewMockBlock(ctrl) mockParentBlock.EXPECT().Height().Return(blockHeight - 1) - mockParentState := states.NewMockDiff(ctrl) + mockParentState := state.NewMockDiff(ctrl) mockParentState.EXPECT().GetLastAccepted().Return(parentID) mockParentState.EXPECT().GetTimestamp().Return(blockTimestamp) @@ -321,7 +321,7 @@ func TestBlockVerify(t *testing.T) { mockParentBlock := block.NewMockBlock(ctrl) mockParentBlock.EXPECT().Height().Return(blockHeight - 1) - mockParentState := states.NewMockDiff(ctrl) + mockParentState := state.NewMockDiff(ctrl) mockParentState.EXPECT().GetLastAccepted().Return(parentID) mockParentState.EXPECT().GetTimestamp().Return(blockTimestamp) @@ -399,7 +399,7 @@ func TestBlockVerify(t *testing.T) { mockParentBlock := block.NewMockBlock(ctrl) mockParentBlock.EXPECT().Height().Return(blockHeight - 1) - mockParentState := states.NewMockDiff(ctrl) + mockParentState := state.NewMockDiff(ctrl) mockParentState.EXPECT().GetLastAccepted().Return(parentID) mockParentState.EXPECT().GetTimestamp().Return(blockTimestamp) @@ -461,7 +461,7 @@ func TestBlockVerify(t *testing.T) { mockParentBlock := block.NewMockBlock(ctrl) mockParentBlock.EXPECT().Height().Return(blockHeight - 1) - mockParentState := states.NewMockDiff(ctrl) + mockParentState := state.NewMockDiff(ctrl) mockParentState.EXPECT().GetLastAccepted().Return(parentID) mockParentState.EXPECT().GetTimestamp().Return(blockTimestamp) @@ -509,7 +509,7 @@ func TestBlockVerify(t *testing.T) { mockParentBlock := block.NewMockBlock(ctrl) mockParentBlock.EXPECT().Height().Return(blockHeight - 1) - mockParentState := states.NewMockDiff(ctrl) + mockParentState := state.NewMockDiff(ctrl) mockParentState.EXPECT().GetLastAccepted().Return(parentID) mockParentState.EXPECT().GetTimestamp().Return(blockTimestamp) @@ -616,11 +616,11 @@ func TestBlockAccept(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Remove(gomock.Any()).AnyTimes() - mockManagerState := states.NewMockState(ctrl) + mockManagerState := state.NewMockState(ctrl) mockManagerState.EXPECT().CommitBatch().Return(nil, errTest) mockManagerState.EXPECT().Abort() - mockOnAcceptState := states.NewMockDiff(ctrl) + mockOnAcceptState := state.NewMockDiff(ctrl) mockOnAcceptState.EXPECT().Apply(mockManagerState) return &Block{ @@ -654,7 +654,7 @@ func TestBlockAccept(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Remove(gomock.Any()).AnyTimes() - mockManagerState := states.NewMockState(ctrl) + mockManagerState := state.NewMockState(ctrl) // Note the returned batch is nil but not used // because we mock the call to shared memory mockManagerState.EXPECT().CommitBatch().Return(nil, nil) @@ -663,7 +663,7 @@ func TestBlockAccept(t *testing.T) { mockSharedMemory := atomic.NewMockSharedMemory(ctrl) mockSharedMemory.EXPECT().Apply(gomock.Any(), gomock.Any()).Return(errTest) - mockOnAcceptState := states.NewMockDiff(ctrl) + mockOnAcceptState := state.NewMockDiff(ctrl) mockOnAcceptState.EXPECT().Apply(mockManagerState) return &Block{ @@ -698,7 +698,7 @@ func TestBlockAccept(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Remove(gomock.Any()).AnyTimes() - mockManagerState := states.NewMockState(ctrl) + mockManagerState := state.NewMockState(ctrl) // Note the returned batch is nil but not used // because we mock the call to shared memory mockManagerState.EXPECT().CommitBatch().Return(nil, nil) @@ -707,7 +707,7 @@ func TestBlockAccept(t *testing.T) { mockSharedMemory := atomic.NewMockSharedMemory(ctrl) mockSharedMemory.EXPECT().Apply(gomock.Any(), gomock.Any()).Return(nil) - mockOnAcceptState := states.NewMockDiff(ctrl) + mockOnAcceptState := state.NewMockDiff(ctrl) mockOnAcceptState.EXPECT().Apply(mockManagerState) metrics := metrics.NewMockMetrics(ctrl) @@ -748,7 +748,7 @@ func TestBlockAccept(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Remove(gomock.Any()).AnyTimes() - mockManagerState := states.NewMockState(ctrl) + mockManagerState := state.NewMockState(ctrl) // Note the returned batch is nil but not used // because we mock the call to shared memory mockManagerState.EXPECT().CommitBatch().Return(nil, nil) @@ -758,7 +758,7 @@ func TestBlockAccept(t *testing.T) { mockSharedMemory := atomic.NewMockSharedMemory(ctrl) mockSharedMemory.EXPECT().Apply(gomock.Any(), gomock.Any()).Return(nil) - mockOnAcceptState := states.NewMockDiff(ctrl) + mockOnAcceptState := state.NewMockDiff(ctrl) mockOnAcceptState.EXPECT().Apply(mockManagerState) metrics := metrics.NewMockMetrics(ctrl) @@ -859,7 +859,7 @@ func TestBlockReject(t *testing.T) { mempool.EXPECT().Add(validTx).Return(nil) // Only add the one that passes verification preferredID := ids.GenerateTestID() - mockPreferredState := states.NewMockDiff(ctrl) + mockPreferredState := state.NewMockDiff(ctrl) mockPreferredState.EXPECT().GetLastAccepted().Return(ids.GenerateTestID()).AnyTimes() mockPreferredState.EXPECT().GetTimestamp().Return(time.Now()).AnyTimes() @@ -918,7 +918,7 @@ func TestBlockReject(t *testing.T) { mempool.EXPECT().Add(tx2).Return(nil) preferredID := ids.GenerateTestID() - mockPreferredState := states.NewMockDiff(ctrl) + mockPreferredState := state.NewMockDiff(ctrl) mockPreferredState.EXPECT().GetLastAccepted().Return(ids.GenerateTestID()).AnyTimes() mockPreferredState.EXPECT().GetTimestamp().Return(time.Now()).AnyTimes() @@ -1014,7 +1014,7 @@ func TestBlockStatus(t *testing.T) { mockBlock := block.NewMockBlock(ctrl) mockBlock.EXPECT().ID().Return(blockID).AnyTimes() - mockState := states.NewMockState(ctrl) + mockState := state.NewMockState(ctrl) mockState.EXPECT().GetBlock(blockID).Return(nil, nil) return &Block{ @@ -1034,7 +1034,7 @@ func TestBlockStatus(t *testing.T) { mockBlock := block.NewMockBlock(ctrl) mockBlock.EXPECT().ID().Return(blockID).AnyTimes() - mockState := states.NewMockState(ctrl) + mockState := state.NewMockState(ctrl) mockState.EXPECT().GetBlock(blockID).Return(nil, database.ErrNotFound) return &Block{ diff --git a/vms/avm/block/executor/manager.go b/vms/avm/block/executor/manager.go index dd9b8bfab400..48eea701bbd9 100644 --- a/vms/avm/block/executor/manager.go +++ b/vms/avm/block/executor/manager.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/metrics" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/executor" "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" @@ -27,7 +27,7 @@ var ( ) type Manager interface { - states.Versions + state.Versions // Returns the ID of the most recently accepted block. LastAccepted() ids.ID @@ -51,7 +51,7 @@ type Manager interface { func NewManager( mempool mempool.Mempool, metrics metrics.Metrics, - state states.State, + state state.State, backend *executor.Backend, clk *mockable.Clock, onAccept func(*txs.Tx) error, @@ -72,7 +72,7 @@ func NewManager( type manager struct { backend *executor.Backend - state states.State + state state.State metrics metrics.Metrics mempool mempool.Mempool clk *mockable.Clock @@ -93,12 +93,12 @@ type manager struct { type blockState struct { statelessBlock block.Block - onAcceptState states.Diff + onAcceptState state.Diff importedInputs set.Set[ids.ID] atomicRequests map[ids.ID]*atomic.Requests } -func (m *manager) GetState(blkID ids.ID) (states.Chain, bool) { +func (m *manager) GetState(blkID ids.ID) (state.Chain, bool) { // If the block is in the map, it is processing. if state, ok := m.blkIDToState[blkID]; ok { return state.onAcceptState, true @@ -155,7 +155,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - stateDiff, err := states.NewDiff(m.preferred, m) + stateDiff, err := state.NewDiff(m.preferred, m) if err != nil { return err } diff --git a/vms/avm/block/executor/manager_test.go b/vms/avm/block/executor/manager_test.go index c21201417add..904154bf7030 100644 --- a/vms/avm/block/executor/manager_test.go +++ b/vms/avm/block/executor/manager_test.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/avm/block" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/executor" ) @@ -31,7 +31,7 @@ func TestManagerGetStatelessBlock(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) m := &manager{ state: state, blkIDToState: map[ids.ID]*blockState{}, @@ -73,16 +73,16 @@ func TestManagerGetState(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state := states.NewMockState(ctrl) + s := state.NewMockState(ctrl) m := &manager{ - state: state, + state: s, blkIDToState: map[ids.ID]*blockState{}, lastAccepted: ids.GenerateTestID(), } // Case: Block is in memory { - diff := states.NewMockDiff(ctrl) + diff := state.NewMockDiff(ctrl) blkID := ids.GenerateTestID() m.blkIDToState[blkID] = &blockState{ onAcceptState: diff, @@ -97,14 +97,14 @@ func TestManagerGetState(t *testing.T) { blkID := ids.GenerateTestID() gotState, ok := m.GetState(blkID) require.False(ok) - require.Equal(state, gotState) + require.Equal(s, gotState) } // Case: Block isn't in memory; block is last accepted { gotState, ok := m.GetState(m.lastAccepted) require.True(ok) - require.Equal(state, gotState) + require.Equal(s, gotState) } } @@ -164,7 +164,7 @@ func TestManagerVerifyTx(t *testing.T) { preferred := ids.GenerateTestID() // These values don't matter for this test - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetLastAccepted().Return(preferred) state.EXPECT().GetTimestamp().Return(time.Time{}) @@ -197,7 +197,7 @@ func TestManagerVerifyTx(t *testing.T) { preferred := ids.GenerateTestID() // These values don't matter for this test - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetLastAccepted().Return(preferred) state.EXPECT().GetTimestamp().Return(time.Time{}) @@ -237,7 +237,7 @@ func TestManagerVerifyTx(t *testing.T) { preferred.EXPECT().Parent().Return(lastAcceptedID).AnyTimes() // These values don't matter for this test - diffState := states.NewMockDiff(ctrl) + diffState := state.NewMockDiff(ctrl) diffState.EXPECT().GetLastAccepted().Return(preferredID) diffState.EXPECT().GetTimestamp().Return(time.Time{}) @@ -276,7 +276,7 @@ func TestManagerVerifyTx(t *testing.T) { preferred := ids.GenerateTestID() // These values don't matter for this test - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetLastAccepted().Return(preferred) state.EXPECT().GetTimestamp().Return(time.Time{}) diff --git a/vms/avm/block/executor/mock_manager.go b/vms/avm/block/executor/mock_manager.go index b3560f2e8afa..5e27089b19fa 100644 --- a/vms/avm/block/executor/mock_manager.go +++ b/vms/avm/block/executor/mock_manager.go @@ -14,7 +14,7 @@ import ( snowman "github.com/ava-labs/avalanchego/snow/consensus/snowman" set "github.com/ava-labs/avalanchego/utils/set" block "github.com/ava-labs/avalanchego/vms/avm/block" - states "github.com/ava-labs/avalanchego/vms/avm/states" + state "github.com/ava-labs/avalanchego/vms/avm/state" txs "github.com/ava-labs/avalanchego/vms/avm/txs" gomock "go.uber.org/mock/gomock" ) @@ -58,10 +58,10 @@ func (mr *MockManagerMockRecorder) GetBlock(arg0 interface{}) *gomock.Call { } // GetState mocks base method. -func (m *MockManager) GetState(arg0 ids.ID) (states.Chain, bool) { +func (m *MockManager) GetState(arg0 ids.ID) (state.Chain, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetState", arg0) - ret0, _ := ret[0].(states.Chain) + ret0, _ := ret[0].(state.Chain) ret1, _ := ret[1].(bool) return ret0, ret1 } diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 67a92a663879..19cacb158d13 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -36,7 +36,7 @@ import ( "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/block/executor" "github.com/ava-labs/avalanchego/vms/avm/config" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/index" @@ -2266,7 +2266,7 @@ func TestServiceGetBlockByHeight(t *testing.T) { { name: "block height not found", serviceAndExpectedBlockFunc: func(_ *testing.T, ctrl *gomock.Controller) (*Service, interface{}) { - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetBlockIDAtHeight(blockHeight).Return(ids.Empty, database.ErrNotFound) manager := executor.NewMockManager(ctrl) @@ -2286,7 +2286,7 @@ func TestServiceGetBlockByHeight(t *testing.T) { { name: "block not found", serviceAndExpectedBlockFunc: func(_ *testing.T, ctrl *gomock.Controller) (*Service, interface{}) { - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetBlockIDAtHeight(blockHeight).Return(blockID, nil) manager := executor.NewMockManager(ctrl) @@ -2311,7 +2311,7 @@ func TestServiceGetBlockByHeight(t *testing.T) { block.EXPECT().InitCtx(gomock.Any()) block.EXPECT().Txs().Return(nil) - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetBlockIDAtHeight(blockHeight).Return(blockID, nil) manager := executor.NewMockManager(ctrl) @@ -2336,7 +2336,7 @@ func TestServiceGetBlockByHeight(t *testing.T) { blockBytes := []byte("hi mom") block.EXPECT().Bytes().Return(blockBytes) - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetBlockIDAtHeight(blockHeight).Return(blockID, nil) expected, err := formatting.Encode(formatting.Hex, blockBytes) @@ -2364,7 +2364,7 @@ func TestServiceGetBlockByHeight(t *testing.T) { blockBytes := []byte("hi mom") block.EXPECT().Bytes().Return(blockBytes) - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetBlockIDAtHeight(blockHeight).Return(blockID, nil) expected, err := formatting.Encode(formatting.HexC, blockBytes) @@ -2392,7 +2392,7 @@ func TestServiceGetBlockByHeight(t *testing.T) { blockBytes := []byte("hi mom") block.EXPECT().Bytes().Return(blockBytes) - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetBlockIDAtHeight(blockHeight).Return(blockID, nil) expected, err := formatting.Encode(formatting.HexNC, blockBytes) @@ -2470,7 +2470,7 @@ func TestServiceGetHeight(t *testing.T) { { name: "block not found", serviceFunc: func(ctrl *gomock.Controller) *Service { - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetLastAccepted().Return(blockID) manager := executor.NewMockManager(ctrl) @@ -2490,7 +2490,7 @@ func TestServiceGetHeight(t *testing.T) { { name: "happy path", serviceFunc: func(ctrl *gomock.Controller) *Service { - state := states.NewMockState(ctrl) + state := state.NewMockState(ctrl) state.EXPECT().GetLastAccepted().Return(blockID) block := block.NewMockBlock(ctrl) diff --git a/vms/avm/states/diff.go b/vms/avm/state/diff.go similarity index 99% rename from vms/avm/states/diff.go rename to vms/avm/state/diff.go index 2ca6d58cd5ee..1d53fa37da3e 100644 --- a/vms/avm/states/diff.go +++ b/vms/avm/state/diff.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package states +package state import ( "errors" diff --git a/vms/avm/states/mock_states.go b/vms/avm/state/mock_state.go similarity index 99% rename from vms/avm/states/mock_states.go rename to vms/avm/state/mock_state.go index 007b8622042e..3bb615283ce6 100644 --- a/vms/avm/states/mock_states.go +++ b/vms/avm/state/mock_state.go @@ -2,10 +2,10 @@ // See the file LICENSE for licensing terms. // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/avm/states (interfaces: Chain,State,Diff) +// Source: github.com/ava-labs/avalanchego/vms/avm/state (interfaces: Chain,State,Diff) -// Package states is a generated GoMock package. -package states +// Package state is a generated GoMock package. +package state import ( reflect "reflect" diff --git a/vms/avm/states/state.go b/vms/avm/state/state.go similarity index 99% rename from vms/avm/states/state.go rename to vms/avm/state/state.go index 1167cdb37dce..e290f093aa22 100644 --- a/vms/avm/states/state.go +++ b/vms/avm/state/state.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package states +package state import ( "bytes" diff --git a/vms/avm/states/state_test.go b/vms/avm/state/state_test.go similarity index 99% rename from vms/avm/states/state_test.go rename to vms/avm/state/state_test.go index b64fa3aa7933..c97836aee794 100644 --- a/vms/avm/states/state_test.go +++ b/vms/avm/state/state_test.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package states +package state import ( "testing" diff --git a/vms/avm/states/versions.go b/vms/avm/state/versions.go similarity index 95% rename from vms/avm/states/versions.go rename to vms/avm/state/versions.go index 409c47becfff..da84182bb683 100644 --- a/vms/avm/states/versions.go +++ b/vms/avm/state/versions.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package states +package state import "github.com/ava-labs/avalanchego/ids" diff --git a/vms/avm/txs/executor/executor.go b/vms/avm/txs/executor/executor.go index 040b1d9c816f..6a5991cade04 100644 --- a/vms/avm/txs/executor/executor.go +++ b/vms/avm/txs/executor/executor.go @@ -10,7 +10,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" ) @@ -19,7 +19,7 @@ var _ txs.Visitor = (*Executor)(nil) type Executor struct { Codec codec.Manager - State states.Chain // state will be modified + State state.Chain // state will be modified Tx *txs.Tx Inputs set.Set[ids.ID] // imported inputs AtomicRequests map[ids.ID]*atomic.Requests // may be nil diff --git a/vms/avm/txs/executor/executor_test.go b/vms/avm/txs/executor/executor_test.go index 042ae39a9048..81d301ad6bae 100644 --- a/vms/avm/txs/executor/executor_test.go +++ b/vms/avm/txs/executor/executor_test.go @@ -19,7 +19,7 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/fxs" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" @@ -44,7 +44,7 @@ func TestBaseTxExecutor(t *testing.T) { db := memdb.New() vdb := versiondb.New(db) registerer := prometheus.NewRegistry() - state, err := states.New(vdb, parser, registerer, trackChecksums) + state, err := state.New(vdb, parser, registerer, trackChecksums) require.NoError(err) utxoID := avax.UTXOID{ @@ -149,7 +149,7 @@ func TestCreateAssetTxExecutor(t *testing.T) { db := memdb.New() vdb := versiondb.New(db) registerer := prometheus.NewRegistry() - state, err := states.New(vdb, parser, registerer, trackChecksums) + state, err := state.New(vdb, parser, registerer, trackChecksums) require.NoError(err) utxoID := avax.UTXOID{ @@ -292,7 +292,7 @@ func TestOperationTxExecutor(t *testing.T) { db := memdb.New() vdb := versiondb.New(db) registerer := prometheus.NewRegistry() - state, err := states.New(vdb, parser, registerer, trackChecksums) + state, err := state.New(vdb, parser, registerer, trackChecksums) require.NoError(err) outputOwners := secp256k1fx.OutputOwners{ diff --git a/vms/avm/txs/executor/semantic_verifier.go b/vms/avm/txs/executor/semantic_verifier.go index 0a8d59083255..1fd94fb0e131 100644 --- a/vms/avm/txs/executor/semantic_verifier.go +++ b/vms/avm/txs/executor/semantic_verifier.go @@ -9,7 +9,7 @@ import ( "reflect" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" @@ -26,7 +26,7 @@ var ( type SemanticVerifier struct { *Backend - State states.ReadOnlyChain + State state.ReadOnlyChain Tx *txs.Tx } diff --git a/vms/avm/txs/executor/semantic_verifier_test.go b/vms/avm/txs/executor/semantic_verifier_test.go index 72638762c39b..7c659f7ec227 100644 --- a/vms/avm/txs/executor/semantic_verifier_test.go +++ b/vms/avm/txs/executor/semantic_verifier_test.go @@ -22,7 +22,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/avm/fxs" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" @@ -117,14 +117,14 @@ func TestSemanticVerifierBaseTx(t *testing.T) { tests := []struct { name string - stateFunc func(*gomock.Controller) states.Chain + stateFunc func(*gomock.Controller) state.Chain txFunc func(*require.Assertions) *txs.Tx err error }{ { name: "valid", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil) state.EXPECT().GetTx(asset.ID).Return(&createAssetTx, nil) @@ -147,8 +147,8 @@ func TestSemanticVerifierBaseTx(t *testing.T) { }, { name: "assetID mismatch", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) utxo := utxo utxo.Asset.ID = ids.GenerateTestID() @@ -173,8 +173,8 @@ func TestSemanticVerifierBaseTx(t *testing.T) { }, { name: "not allowed input feature extension", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) unsignedCreateAssetTx := unsignedCreateAssetTx unsignedCreateAssetTx.States = nil @@ -204,8 +204,8 @@ func TestSemanticVerifierBaseTx(t *testing.T) { }, { name: "invalid signature", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil) state.EXPECT().GetTx(asset.ID).Return(&createAssetTx, nil) @@ -228,8 +228,8 @@ func TestSemanticVerifierBaseTx(t *testing.T) { }, { name: "missing UTXO", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(nil, database.ErrNotFound) @@ -251,8 +251,8 @@ func TestSemanticVerifierBaseTx(t *testing.T) { }, { name: "invalid UTXO amount", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) output := output output.Amt-- @@ -281,8 +281,8 @@ func TestSemanticVerifierBaseTx(t *testing.T) { }, { name: "not allowed output feature extension", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) unsignedCreateAssetTx := unsignedCreateAssetTx unsignedCreateAssetTx.States = nil @@ -317,8 +317,8 @@ func TestSemanticVerifierBaseTx(t *testing.T) { }, { name: "unknown asset", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil) state.EXPECT().GetTx(asset.ID).Return(nil, database.ErrNotFound) @@ -341,8 +341,8 @@ func TestSemanticVerifierBaseTx(t *testing.T) { }, { name: "not an asset", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) tx := txs.Tx{ Unsigned: &baseTx, @@ -483,14 +483,14 @@ func TestSemanticVerifierExportTx(t *testing.T) { tests := []struct { name string - stateFunc func(*gomock.Controller) states.Chain + stateFunc func(*gomock.Controller) state.Chain txFunc func(*require.Assertions) *txs.Tx err error }{ { name: "valid", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil) state.EXPECT().GetTx(asset.ID).Return(&createAssetTx, nil) @@ -513,8 +513,8 @@ func TestSemanticVerifierExportTx(t *testing.T) { }, { name: "assetID mismatch", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) utxo := utxo utxo.Asset.ID = ids.GenerateTestID() @@ -539,8 +539,8 @@ func TestSemanticVerifierExportTx(t *testing.T) { }, { name: "not allowed input feature extension", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) unsignedCreateAssetTx := unsignedCreateAssetTx unsignedCreateAssetTx.States = nil @@ -570,8 +570,8 @@ func TestSemanticVerifierExportTx(t *testing.T) { }, { name: "invalid signature", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil) state.EXPECT().GetTx(asset.ID).Return(&createAssetTx, nil) @@ -594,8 +594,8 @@ func TestSemanticVerifierExportTx(t *testing.T) { }, { name: "missing UTXO", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(nil, database.ErrNotFound) @@ -617,8 +617,8 @@ func TestSemanticVerifierExportTx(t *testing.T) { }, { name: "invalid UTXO amount", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) output := output output.Amt-- @@ -647,8 +647,8 @@ func TestSemanticVerifierExportTx(t *testing.T) { }, { name: "not allowed output feature extension", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) unsignedCreateAssetTx := unsignedCreateAssetTx unsignedCreateAssetTx.States = nil @@ -683,8 +683,8 @@ func TestSemanticVerifierExportTx(t *testing.T) { }, { name: "unknown asset", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil) state.EXPECT().GetTx(asset.ID).Return(nil, database.ErrNotFound) @@ -707,8 +707,8 @@ func TestSemanticVerifierExportTx(t *testing.T) { }, { name: "not an asset", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) tx := txs.Tx{ Unsigned: &baseTx, @@ -849,7 +849,7 @@ func TestSemanticVerifierExportTxDifferentSubnet(t *testing.T) { Unsigned: &unsignedCreateAssetTx, } - state := states.NewMockChain(ctrl) + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil) state.EXPECT().GetTx(asset.ID).Return(&createAssetTx, nil) @@ -999,14 +999,14 @@ func TestSemanticVerifierImportTx(t *testing.T) { } tests := []struct { name string - stateFunc func(*gomock.Controller) states.Chain + stateFunc func(*gomock.Controller) state.Chain txFunc func(*require.Assertions) *txs.Tx expectedErr error }{ { name: "valid", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil).AnyTimes() state.EXPECT().GetTx(asset.ID).Return(&createAssetTx, nil).AnyTimes() return state @@ -1018,8 +1018,8 @@ func TestSemanticVerifierImportTx(t *testing.T) { }, { name: "not allowed input feature extension", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) unsignedCreateAssetTx := unsignedCreateAssetTx unsignedCreateAssetTx.States = nil createAssetTx := txs.Tx{ @@ -1036,8 +1036,8 @@ func TestSemanticVerifierImportTx(t *testing.T) { }, { name: "invalid signature", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil).AnyTimes() state.EXPECT().GetTx(asset.ID).Return(&createAssetTx, nil).AnyTimes() return state @@ -1058,8 +1058,8 @@ func TestSemanticVerifierImportTx(t *testing.T) { }, { name: "not allowed output feature extension", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) unsignedCreateAssetTx := unsignedCreateAssetTx unsignedCreateAssetTx.States = nil createAssetTx := txs.Tx{ @@ -1087,8 +1087,8 @@ func TestSemanticVerifierImportTx(t *testing.T) { }, { name: "unknown asset", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) state.EXPECT().GetUTXO(utxoID.InputID()).Return(&utxo, nil).AnyTimes() state.EXPECT().GetTx(asset.ID).Return(nil, database.ErrNotFound) return state @@ -1100,8 +1100,8 @@ func TestSemanticVerifierImportTx(t *testing.T) { }, { name: "not an asset", - stateFunc: func(ctrl *gomock.Controller) states.Chain { - state := states.NewMockChain(ctrl) + stateFunc: func(ctrl *gomock.Controller) state.Chain { + state := state.NewMockChain(ctrl) tx := txs.Tx{ Unsigned: &baseTx, } diff --git a/vms/avm/vm.go b/vms/avm/vm.go index cae4514ff3a6..36049befd07c 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -38,7 +38,7 @@ import ( "github.com/ava-labs/avalanchego/vms/avm/config" "github.com/ava-labs/avalanchego/vms/avm/metrics" "github.com/ava-labs/avalanchego/vms/avm/network" - "github.com/ava-labs/avalanchego/vms/avm/states" + "github.com/ava-labs/avalanchego/vms/avm/state" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" "github.com/ava-labs/avalanchego/vms/avm/utxo" @@ -91,7 +91,7 @@ type VM struct { appSender common.AppSender // State management - state states.State + state state.State // Set to true once this VM is marked as `Bootstrapped` by the engine bootstrapped bool @@ -220,7 +220,7 @@ func (vm *VM) Initialize( vm.AtomicUTXOManager = avax.NewAtomicUTXOManager(ctx.SharedMemory, codec) vm.Spender = utxo.NewSpender(&vm.clock, codec) - state, err := states.New( + state, err := state.New( vm.db, vm.parser, vm.registerer, From be422a0179bb920d20d5e4f547f07cc23671e3df Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 28 Nov 2023 13:58:45 -0500 Subject: [PATCH 078/267] Implement generic bimap (#2383) --- codec/hierarchycodec/codec.go | 26 +- codec/linearcodec/codec.go | 22 +- .../avalanche/bootstrap/bootstrapper.go | 40 ++- snow/engine/common/fetcher.go | 14 - snow/engine/common/request.go | 11 + snow/engine/common/requests.go | 110 ------ snow/engine/common/requests_test.go | 69 ---- snow/engine/snowman/bootstrap/bootstrapper.go | 37 +- .../snowman/bootstrap/bootstrapper_test.go | 3 +- snow/engine/snowman/transitive.go | 34 +- utils/bimap/bimap.go | 102 ++++++ utils/bimap/bimap_test.go | 328 ++++++++++++++++++ 12 files changed, 545 insertions(+), 251 deletions(-) delete mode 100644 snow/engine/common/fetcher.go create mode 100644 snow/engine/common/request.go delete mode 100644 snow/engine/common/requests.go delete mode 100644 snow/engine/common/requests_test.go create mode 100644 utils/bimap/bimap.go create mode 100644 utils/bimap/bimap_test.go diff --git a/codec/hierarchycodec/codec.go b/codec/hierarchycodec/codec.go index d1d03d879275..1b82380bc576 100644 --- a/codec/hierarchycodec/codec.go +++ b/codec/hierarchycodec/codec.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/reflectcodec" + "github.com/ava-labs/avalanchego/utils/bimap" "github.com/ava-labs/avalanchego/utils/wrappers" ) @@ -42,20 +43,18 @@ type typeID struct { type hierarchyCodec struct { codec.Codec - lock sync.RWMutex - currentGroupID uint16 - nextTypeID uint16 - typeIDToType map[typeID]reflect.Type - typeToTypeID map[reflect.Type]typeID + lock sync.RWMutex + currentGroupID uint16 + nextTypeID uint16 + registeredTypes *bimap.BiMap[typeID, reflect.Type] } // New returns a new, concurrency-safe codec func New(tagNames []string, maxSliceLen uint32) Codec { hCodec := &hierarchyCodec{ - currentGroupID: 0, - nextTypeID: 0, - typeIDToType: map[typeID]reflect.Type{}, - typeToTypeID: map[reflect.Type]typeID{}, + currentGroupID: 0, + nextTypeID: 0, + registeredTypes: bimap.New[typeID, reflect.Type](), } hCodec.Codec = reflectcodec.New(hCodec, tagNames, maxSliceLen) return hCodec @@ -88,7 +87,7 @@ func (c *hierarchyCodec) RegisterType(val interface{}) error { defer c.lock.Unlock() valType := reflect.TypeOf(val) - if _, exists := c.typeToTypeID[valType]; exists { + if c.registeredTypes.HasValue(valType) { return fmt.Errorf("%w: %v", codec.ErrDuplicateType, valType) } @@ -98,8 +97,7 @@ func (c *hierarchyCodec) RegisterType(val interface{}) error { } c.nextTypeID++ - c.typeIDToType[valTypeID] = valType - c.typeToTypeID[valType] = valTypeID + c.registeredTypes.Put(valTypeID, valType) return nil } @@ -112,7 +110,7 @@ func (c *hierarchyCodec) PackPrefix(p *wrappers.Packer, valueType reflect.Type) c.lock.RLock() defer c.lock.RUnlock() - typeID, ok := c.typeToTypeID[valueType] // Get the type ID of the value being marshaled + typeID, ok := c.registeredTypes.GetKey(valueType) // Get the type ID of the value being marshaled if !ok { return fmt.Errorf("can't marshal unregistered type %q", valueType) } @@ -136,7 +134,7 @@ func (c *hierarchyCodec) UnpackPrefix(p *wrappers.Packer, valueType reflect.Type typeID: typeIDShort, } // Get a type that implements the interface - implementingType, ok := c.typeIDToType[t] + implementingType, ok := c.registeredTypes.GetValue(t) if !ok { return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: unknown type ID %+v", t) } diff --git a/codec/linearcodec/codec.go b/codec/linearcodec/codec.go index 677c331b0366..07097aee79eb 100644 --- a/codec/linearcodec/codec.go +++ b/codec/linearcodec/codec.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/reflectcodec" + "github.com/ava-labs/avalanchego/utils/bimap" "github.com/ava-labs/avalanchego/utils/wrappers" ) @@ -36,19 +37,17 @@ type Codec interface { type linearCodec struct { codec.Codec - lock sync.RWMutex - nextTypeID uint32 - typeIDToType map[uint32]reflect.Type - typeToTypeID map[reflect.Type]uint32 + lock sync.RWMutex + nextTypeID uint32 + registeredTypes *bimap.BiMap[uint32, reflect.Type] } // New returns a new, concurrency-safe codec; it allow to specify // both tagNames and maxSlicelenght func New(tagNames []string, maxSliceLen uint32) Codec { hCodec := &linearCodec{ - nextTypeID: 0, - typeIDToType: map[uint32]reflect.Type{}, - typeToTypeID: map[reflect.Type]uint32{}, + nextTypeID: 0, + registeredTypes: bimap.New[uint32, reflect.Type](), } hCodec.Codec = reflectcodec.New(hCodec, tagNames, maxSliceLen) return hCodec @@ -78,12 +77,11 @@ func (c *linearCodec) RegisterType(val interface{}) error { defer c.lock.Unlock() valType := reflect.TypeOf(val) - if _, exists := c.typeToTypeID[valType]; exists { + if c.registeredTypes.HasValue(valType) { return fmt.Errorf("%w: %v", codec.ErrDuplicateType, valType) } - c.typeIDToType[c.nextTypeID] = valType - c.typeToTypeID[valType] = c.nextTypeID + c.registeredTypes.Put(c.nextTypeID, valType) c.nextTypeID++ return nil } @@ -97,7 +95,7 @@ func (c *linearCodec) PackPrefix(p *wrappers.Packer, valueType reflect.Type) err c.lock.RLock() defer c.lock.RUnlock() - typeID, ok := c.typeToTypeID[valueType] // Get the type ID of the value being marshaled + typeID, ok := c.registeredTypes.GetKey(valueType) // Get the type ID of the value being marshaled if !ok { return fmt.Errorf("can't marshal unregistered type %q", valueType) } @@ -114,7 +112,7 @@ func (c *linearCodec) UnpackPrefix(p *wrappers.Packer, valueType reflect.Type) ( return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: %w", p.Err) } // Get a type that implements the interface - implementingType, ok := c.typeIDToType[typeID] + implementingType, ok := c.registeredTypes.GetValue(typeID) if !ok { return reflect.Value{}, fmt.Errorf("couldn't unmarshal interface: unknown type ID %d", typeID) } diff --git a/snow/engine/avalanche/bootstrap/bootstrapper.go b/snow/engine/avalanche/bootstrap/bootstrapper.go index 59f421158fa2..967d65711abc 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/avalanche" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils/bimap" "github.com/ava-labs/avalanchego/utils/heap" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" @@ -57,10 +58,10 @@ func New( ChitsHandler: common.NewNoOpChitsHandler(config.Ctx.Log), AppHandler: config.VM, + outstandingRequests: bimap.New[common.Request, ids.ID](), + processedCache: &cache.LRU[ids.ID, struct{}]{Size: cacheSize}, - Fetcher: common.Fetcher{ - OnFinished: onFinished, - }, + onFinished: onFinished, } return b, b.metrics.Initialize("bs", config.Ctx.AvalancheRegisterer) } @@ -81,9 +82,11 @@ type bootstrapper struct { common.ChitsHandler common.AppHandler - common.Fetcher metrics + // tracks which validators were asked for which containers in which requests + outstandingRequests *bimap.BiMap[common.Request, ids.ID] + // IDs of vertices that we will send a GetAncestors request for once we are // not at the max number of outstanding requests needToFetch set.Set[ids.ID] @@ -93,6 +96,9 @@ type bootstrapper struct { // Tracks the last requestID that was used in a request requestID uint32 + + // Called when bootstrapping is done on a specific chain + onFinished func(ctx context.Context, lastReqID uint32) error } func (b *bootstrapper) Context() *snow.ConsensusContext { @@ -137,7 +143,10 @@ func (b *bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, request vtxs = vtxs[:b.Config.AncestorsMaxContainersReceived] } - requestedVtxID, requested := b.OutstandingRequests.Remove(nodeID, requestID) + requestedVtxID, requested := b.outstandingRequests.DeleteKey(common.Request{ + NodeID: nodeID, + RequestID: requestID, + }) vtx, err := b.Manager.ParseVtx(ctx, vtxs[0]) // first vertex should be the one we requested in GetAncestors request if err != nil { if !requested { @@ -177,7 +186,7 @@ func (b *bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, request ) return b.fetch(ctx, requestedVtxID) } - if !requested && !b.OutstandingRequests.Contains(vtxID) && !b.needToFetch.Contains(vtxID) { + if !requested && !b.outstandingRequests.HasValue(vtxID) && !b.needToFetch.Contains(vtxID) { b.Ctx.Log.Debug("received un-needed vertex", zap.Stringer("nodeID", nodeID), zap.Uint32("requestID", requestID), @@ -244,7 +253,10 @@ func (b *bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, request } func (b *bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - vtxID, ok := b.OutstandingRequests.Remove(nodeID, requestID) + vtxID, ok := b.outstandingRequests.DeleteKey(common.Request{ + NodeID: nodeID, + RequestID: requestID, + }) if !ok { b.Ctx.Log.Debug("skipping GetAncestorsFailed call", zap.String("reason", "no matching outstanding request"), @@ -388,12 +400,12 @@ func (b *bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { // to fetch or we are at the maximum number of outstanding requests. func (b *bootstrapper) fetch(ctx context.Context, vtxIDs ...ids.ID) error { b.needToFetch.Add(vtxIDs...) - for b.needToFetch.Len() > 0 && b.OutstandingRequests.Len() < maxOutstandingGetAncestorsRequests { + for b.needToFetch.Len() > 0 && b.outstandingRequests.Len() < maxOutstandingGetAncestorsRequests { vtxID := b.needToFetch.CappedList(1)[0] b.needToFetch.Remove(vtxID) // Make sure we haven't already requested this vertex - if b.OutstandingRequests.Contains(vtxID) { + if b.outstandingRequests.HasValue(vtxID) { continue } @@ -409,7 +421,13 @@ func (b *bootstrapper) fetch(ctx context.Context, vtxIDs ...ids.ID) error { validatorID := validatorIDs[0] b.requestID++ - b.OutstandingRequests.Add(validatorID, b.requestID, vtxID) + b.outstandingRequests.Put( + common.Request{ + NodeID: validatorID, + RequestID: b.requestID, + }, + vtxID, + ) b.Config.Sender.SendGetAncestors(ctx, validatorID, b.requestID, vtxID) // request vertex and ancestors } return b.checkFinish(ctx) @@ -606,7 +624,7 @@ func (b *bootstrapper) checkFinish(ctx context.Context) error { } b.processedCache.Flush() - return b.OnFinished(ctx, b.requestID) + return b.onFinished(ctx, b.requestID) } // A vertex is less than another vertex if it is unknown. Ties are broken by diff --git a/snow/engine/common/fetcher.go b/snow/engine/common/fetcher.go deleted file mode 100644 index 9e90da3d325b..000000000000 --- a/snow/engine/common/fetcher.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package common - -import "context" - -type Fetcher struct { - // tracks which validators were asked for which containers in which requests - OutstandingRequests Requests - - // Called when bootstrapping is done on a specific chain - OnFinished func(ctx context.Context, lastReqID uint32) error -} diff --git a/snow/engine/common/request.go b/snow/engine/common/request.go new file mode 100644 index 000000000000..d677a485c8f4 --- /dev/null +++ b/snow/engine/common/request.go @@ -0,0 +1,11 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package common + +import "github.com/ava-labs/avalanchego/ids" + +type Request struct { + NodeID ids.NodeID + RequestID uint32 +} diff --git a/snow/engine/common/requests.go b/snow/engine/common/requests.go deleted file mode 100644 index ce66585e590d..000000000000 --- a/snow/engine/common/requests.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package common - -import ( - "fmt" - "strings" - - "github.com/ava-labs/avalanchego/ids" -) - -const ( - minRequestsSize = 32 -) - -type req struct { - vdr ids.NodeID - id uint32 -} - -// Requests tracks pending container messages from a peer. -type Requests struct { - reqsToID map[ids.NodeID]map[uint32]ids.ID - idToReq map[ids.ID]req -} - -// Add a request. Assumes that requestIDs are unique. Assumes that containerIDs -// are only in one request at a time. -func (r *Requests) Add(vdr ids.NodeID, requestID uint32, containerID ids.ID) { - if r.reqsToID == nil { - r.reqsToID = make(map[ids.NodeID]map[uint32]ids.ID, minRequestsSize) - } - vdrReqs, ok := r.reqsToID[vdr] - if !ok { - vdrReqs = make(map[uint32]ids.ID) - r.reqsToID[vdr] = vdrReqs - } - vdrReqs[requestID] = containerID - - if r.idToReq == nil { - r.idToReq = make(map[ids.ID]req, minRequestsSize) - } - r.idToReq[containerID] = req{ - vdr: vdr, - id: requestID, - } -} - -// Get the containerID the request is expecting and if the request exists. -func (r *Requests) Get(vdr ids.NodeID, requestID uint32) (ids.ID, bool) { - containerID, ok := r.reqsToID[vdr][requestID] - return containerID, ok -} - -// Remove attempts to abandon a requestID sent to a validator. If the request is -// currently outstanding, the requested ID will be returned along with true. If -// the request isn't currently outstanding, false will be returned. -func (r *Requests) Remove(vdr ids.NodeID, requestID uint32) (ids.ID, bool) { - vdrReqs := r.reqsToID[vdr] - containerID, ok := vdrReqs[requestID] - if !ok { - return ids.ID{}, false - } - - if len(vdrReqs) == 1 { - delete(r.reqsToID, vdr) - } else { - delete(vdrReqs, requestID) - } - - delete(r.idToReq, containerID) - return containerID, true -} - -// RemoveAny outstanding requests for the container ID. True is returned if the -// container ID had an outstanding request. -func (r *Requests) RemoveAny(containerID ids.ID) bool { - req, ok := r.idToReq[containerID] - if !ok { - return false - } - - r.Remove(req.vdr, req.id) - return true -} - -// Len returns the total number of outstanding requests. -func (r *Requests) Len() int { - return len(r.idToReq) -} - -// Contains returns true if there is an outstanding request for the container -// ID. -func (r *Requests) Contains(containerID ids.ID) bool { - _, ok := r.idToReq[containerID] - return ok -} - -func (r Requests) String() string { - sb := strings.Builder{} - sb.WriteString(fmt.Sprintf("Requests: (Num Validators = %d)", len(r.reqsToID))) - for vdr, reqs := range r.reqsToID { - sb.WriteString(fmt.Sprintf("\n VDR[%s]: (Outstanding Requests %d)", vdr, len(reqs))) - for reqID, containerID := range reqs { - sb.WriteString(fmt.Sprintf("\n Request[%d]: %s", reqID, containerID)) - } - } - return sb.String() -} diff --git a/snow/engine/common/requests_test.go b/snow/engine/common/requests_test.go deleted file mode 100644 index 73a98e4ccb94..000000000000 --- a/snow/engine/common/requests_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package common - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" -) - -func TestRequests(t *testing.T) { - require := require.New(t) - - req := Requests{} - - require.Empty(req) - - _, removed := req.Remove(ids.EmptyNodeID, 0) - require.False(removed) - - require.False(req.RemoveAny(ids.Empty)) - require.False(req.Contains(ids.Empty)) - - req.Add(ids.EmptyNodeID, 0, ids.Empty) - require.Equal(1, req.Len()) - - _, removed = req.Remove(ids.EmptyNodeID, 1) - require.False(removed) - - _, removed = req.Remove(ids.BuildTestNodeID([]byte{0x01}), 0) - require.False(removed) - - require.True(req.Contains(ids.Empty)) - require.Equal(1, req.Len()) - - req.Add(ids.EmptyNodeID, 10, ids.Empty.Prefix(0)) - require.Equal(2, req.Len()) - - _, removed = req.Remove(ids.EmptyNodeID, 1) - require.False(removed) - - _, removed = req.Remove(ids.BuildTestNodeID([]byte{0x01}), 0) - require.False(removed) - - require.True(req.Contains(ids.Empty)) - require.Equal(2, req.Len()) - - removedID, removed := req.Remove(ids.EmptyNodeID, 0) - require.True(removed) - require.Equal(ids.Empty, removedID) - - removedID, removed = req.Remove(ids.EmptyNodeID, 10) - require.True(removed) - require.Equal(ids.Empty.Prefix(0), removedID) - - require.Zero(req.Len()) - - req.Add(ids.EmptyNodeID, 0, ids.Empty) - require.Equal(1, req.Len()) - - require.True(req.RemoveAny(ids.Empty)) - require.Zero(req.Len()) - - require.False(req.RemoveAny(ids.Empty)) - require.Zero(req.Len()) -} diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index b575229954fb..0e2c7e0dab16 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman/bootstrapper" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/utils/bimap" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/version" @@ -91,7 +92,8 @@ type Bootstrapper struct { // Time that startSyncing was last called startTime time.Time - common.Fetcher + // tracks which validators were asked for which containers in which requests + outstandingRequests *bimap.BiMap[common.Request, ids.ID] // number of state transitions executed executedStateTransitions int @@ -112,6 +114,9 @@ type Bootstrapper struct { // bootstrappedOnce ensures that the [Bootstrapped] callback is only invoked // once, even if bootstrapping is retried. bootstrappedOnce sync.Once + + // Called when bootstrapping is done on a specific chain + onFinished func(ctx context.Context, lastReqID uint32) error } func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) error) (*Bootstrapper, error) { @@ -129,10 +134,10 @@ func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) e minority: bootstrapper.Noop, majority: bootstrapper.Noop, - Fetcher: common.Fetcher{ - OnFinished: onFinished, - }, + outstandingRequests: bimap.New[common.Request, ids.ID](), + executedStateTransitions: math.MaxInt, + onFinished: onFinished, }, err } @@ -425,7 +430,7 @@ func (b *Bootstrapper) startSyncing(ctx context.Context, acceptedContainerIDs [] // Get block [blkID] and its ancestors from a validator func (b *Bootstrapper) fetch(ctx context.Context, blkID ids.ID) error { // Make sure we haven't already requested this block - if b.OutstandingRequests.Contains(blkID) { + if b.outstandingRequests.HasValue(blkID) { return nil } @@ -444,7 +449,13 @@ func (b *Bootstrapper) fetch(ctx context.Context, blkID ids.ID) error { b.requestID++ - b.OutstandingRequests.Add(validatorID, b.requestID, blkID) + b.outstandingRequests.Put( + common.Request{ + NodeID: validatorID, + RequestID: b.requestID, + }, + blkID, + ) b.Config.Sender.SendGetAncestors(ctx, validatorID, b.requestID, blkID) // request block and ancestors return nil } @@ -453,7 +464,10 @@ func (b *Bootstrapper) fetch(ctx context.Context, blkID ids.ID) error { // response to a GetAncestors message to [nodeID] with request ID [requestID] func (b *Bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, blks [][]byte) error { // Make sure this is in response to a request we made - wantedBlkID, ok := b.OutstandingRequests.Remove(nodeID, requestID) + wantedBlkID, ok := b.outstandingRequests.DeleteKey(common.Request{ + NodeID: nodeID, + RequestID: requestID, + }) if !ok { // this message isn't in response to a request we made b.Ctx.Log.Debug("received unexpected Ancestors", zap.Stringer("nodeID", nodeID), @@ -522,7 +536,10 @@ func (b *Bootstrapper) Ancestors(ctx context.Context, nodeID ids.NodeID, request } func (b *Bootstrapper) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - blkID, ok := b.OutstandingRequests.Remove(nodeID, requestID) + blkID, ok := b.outstandingRequests.DeleteKey(common.Request{ + NodeID: nodeID, + RequestID: requestID, + }) if !ok { b.Ctx.Log.Debug("unexpectedly called GetAncestorsFailed", zap.Stringer("nodeID", nodeID), @@ -745,7 +762,7 @@ func (b *Bootstrapper) tryStartExecuting(ctx context.Context) error { return nil } b.fetchETA.Set(0) - return b.OnFinished(ctx, b.requestID) + return b.onFinished(ctx, b.requestID) } func (b *Bootstrapper) Timeout(ctx context.Context) error { @@ -758,7 +775,7 @@ func (b *Bootstrapper) Timeout(ctx context.Context) error { return b.restartBootstrapping(ctx) } b.fetchETA.Set(0) - return b.OnFinished(ctx, b.requestID) + return b.onFinished(ctx, b.requestID) } func (b *Bootstrapper) restartBootstrapping(ctx context.Context) error { diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index 6cf69d797ff5..83cbca730ba5 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -1131,7 +1131,8 @@ func TestRestartBootstrapping(t *testing.T) { require.Contains(requestIDs, blkID1) // Remove request, so we can restart bootstrapping via startSyncing - require.True(bs.OutstandingRequests.RemoveAny(blkID1)) + _, removed := bs.outstandingRequests.DeleteValue(blkID1) + require.True(removed) requestIDs = map[ids.ID]uint32{} require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID4})) diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 8e2b98dc5a38..f0ce42ecf912 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -23,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/snow/event" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/bag" + "github.com/ava-labs/avalanchego/utils/bimap" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/math" @@ -64,7 +65,7 @@ type Transitive struct { polls poll.Set // blocks that have we have sent get requests for but haven't yet received - blkReqs common.Requests + blkReqs *bimap.BiMap[common.Request, ids.ID] // blocks that are queued to be issued to consensus once missing dependencies are fetched // Block ID --> Block @@ -140,6 +141,7 @@ func newTransitive(config Config) (*Transitive, error) { nonVerifiedCache: nonVerifiedCache, acceptedFrontiers: acceptedFrontiers, polls: polls, + blkReqs: bimap.New[common.Request, ids.ID](), } return t, t.metrics.Initialize("", config.Ctx.Registerer) @@ -169,7 +171,10 @@ func (t *Transitive) Put(ctx context.Context, nodeID ids.NodeID, requestID uint3 } actualBlkID := blk.ID() - expectedBlkID, ok := t.blkReqs.Get(nodeID, requestID) + expectedBlkID, ok := t.blkReqs.GetValue(common.Request{ + NodeID: nodeID, + RequestID: requestID, + }) // If the provided block is not the requested block, we need to explicitly // mark the request as failed to avoid having a dangling dependency. if ok && actualBlkID != expectedBlkID { @@ -202,7 +207,10 @@ func (t *Transitive) Put(ctx context.Context, nodeID ids.NodeID, requestID uint3 func (t *Transitive) GetFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { // We don't assume that this function is called after a failed Get message. // Check to see if we have an outstanding request and also get what the request was for if it exists. - blkID, ok := t.blkReqs.Remove(nodeID, requestID) + blkID, ok := t.blkReqs.DeleteKey(common.Request{ + NodeID: nodeID, + RequestID: requestID, + }) if !ok { t.Ctx.Log.Debug("unexpected GetFailed", zap.Stringer("nodeID", nodeID), @@ -658,7 +666,7 @@ func (t *Transitive) issueFrom(ctx context.Context, nodeID ids.NodeID, blk snowm } // Remove any outstanding requests for this block - t.blkReqs.RemoveAny(blkID) + t.blkReqs.DeleteValue(blkID) issued := t.Consensus.Decided(blk) || t.Consensus.Processing(blkID) if issued { @@ -702,7 +710,7 @@ func (t *Transitive) issueWithAncestors(ctx context.Context, blk snowman.Block) // There's an outstanding request for this block. // We can just wait for that request to succeed or fail. - if t.blkReqs.Contains(blkID) { + if t.blkReqs.HasValue(blkID) { return false, nil } @@ -731,7 +739,7 @@ func (t *Transitive) issue(ctx context.Context, blk snowman.Block, push bool) er t.pending[blkID] = blk // Remove any outstanding requests for this block - t.blkReqs.RemoveAny(blkID) + t.blkReqs.DeleteValue(blkID) // Will add [blk] to consensus once its ancestors have been i := &issuer{ @@ -762,12 +770,18 @@ func (t *Transitive) issue(ctx context.Context, blk snowman.Block, push bool) er // Request that [vdr] send us block [blkID] func (t *Transitive) sendRequest(ctx context.Context, nodeID ids.NodeID, blkID ids.ID) { // There is already an outstanding request for this block - if t.blkReqs.Contains(blkID) { + if t.blkReqs.HasValue(blkID) { return } t.RequestID++ - t.blkReqs.Add(nodeID, t.RequestID, blkID) + t.blkReqs.Put( + common.Request{ + NodeID: nodeID, + RequestID: t.RequestID, + }, + blkID, + ) t.Ctx.Log.Verbo("sending Get request", zap.Stringer("nodeID", nodeID), zap.Uint32("requestID", t.RequestID), @@ -917,13 +931,13 @@ func (t *Transitive) deliver(ctx context.Context, blk snowman.Block, push bool) t.removeFromPending(blk) t.blocked.Fulfill(ctx, blkID) - t.blkReqs.RemoveAny(blkID) + t.blkReqs.DeleteValue(blkID) } for _, blk := range dropped { blkID := blk.ID() t.removeFromPending(blk) t.blocked.Abandon(ctx, blkID) - t.blkReqs.RemoveAny(blkID) + t.blkReqs.DeleteValue(blkID) } // If we should issue multiple queries at the same time, we need to repoll diff --git a/utils/bimap/bimap.go b/utils/bimap/bimap.go new file mode 100644 index 000000000000..28d20750bace --- /dev/null +++ b/utils/bimap/bimap.go @@ -0,0 +1,102 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bimap + +import "github.com/ava-labs/avalanchego/utils" + +type Entry[K, V any] struct { + Key K + Value V +} + +// BiMap is a bi-directional map. +type BiMap[K, V comparable] struct { + keyToValue map[K]V + valueToKey map[V]K +} + +// New creates a new empty bimap. +func New[K, V comparable]() *BiMap[K, V] { + return &BiMap[K, V]{ + keyToValue: make(map[K]V), + valueToKey: make(map[V]K), + } +} + +// Put the key value pair into the map. If either [key] or [val] was previously +// in the map, the previous entries will be removed and returned. +// +// Note: Unlike normal maps, it's possible that Put removes 0, 1, or 2 existing +// entries to ensure that mappings are one-to-one. +func (m *BiMap[K, V]) Put(key K, val V) []Entry[K, V] { + var removed []Entry[K, V] + oldVal, oldValDeleted := m.DeleteKey(key) + if oldValDeleted { + removed = append(removed, Entry[K, V]{ + Key: key, + Value: oldVal, + }) + } + oldKey, oldKeyDeleted := m.DeleteValue(val) + if oldKeyDeleted { + removed = append(removed, Entry[K, V]{ + Key: oldKey, + Value: val, + }) + } + m.keyToValue[key] = val + m.valueToKey[val] = key + return removed +} + +// GetKey that maps to the provided value. +func (m *BiMap[K, V]) GetKey(val V) (K, bool) { + key, ok := m.valueToKey[val] + return key, ok +} + +// GetValue that is mapped to the provided key. +func (m *BiMap[K, V]) GetValue(key K) (V, bool) { + val, ok := m.keyToValue[key] + return val, ok +} + +// HasKey returns true if [key] is in the map. +func (m *BiMap[K, _]) HasKey(key K) bool { + _, ok := m.keyToValue[key] + return ok +} + +// HasValue returns true if [val] is in the map. +func (m *BiMap[_, V]) HasValue(val V) bool { + _, ok := m.valueToKey[val] + return ok +} + +// DeleteKey removes [key] from the map and returns the value it mapped to. +func (m *BiMap[K, V]) DeleteKey(key K) (V, bool) { + val, ok := m.keyToValue[key] + if !ok { + return utils.Zero[V](), false + } + delete(m.keyToValue, key) + delete(m.valueToKey, val) + return val, true +} + +// DeleteValue removes [val] from the map and returns the key that mapped to it. +func (m *BiMap[K, V]) DeleteValue(val V) (K, bool) { + key, ok := m.valueToKey[val] + if !ok { + return utils.Zero[K](), false + } + delete(m.keyToValue, key) + delete(m.valueToKey, val) + return key, true +} + +// Len return the number of entries in this map. +func (m *BiMap[K, V]) Len() int { + return len(m.keyToValue) +} diff --git a/utils/bimap/bimap_test.go b/utils/bimap/bimap_test.go new file mode 100644 index 000000000000..9914578c6070 --- /dev/null +++ b/utils/bimap/bimap_test.go @@ -0,0 +1,328 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bimap + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBiMapPut(t *testing.T) { + tests := []struct { + name string + state *BiMap[int, int] + key int + value int + expectedRemoved []Entry[int, int] + expectedState *BiMap[int, int] + }{ + { + name: "none removed", + state: New[int, int](), + key: 1, + value: 2, + expectedRemoved: nil, + expectedState: &BiMap[int, int]{ + keyToValue: map[int]int{ + 1: 2, + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + }, + { + name: "key removed", + state: &BiMap[int, int]{ + keyToValue: map[int]int{ + 1: 2, + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + key: 1, + value: 3, + expectedRemoved: []Entry[int, int]{ + { + Key: 1, + Value: 2, + }, + }, + expectedState: &BiMap[int, int]{ + keyToValue: map[int]int{ + 1: 3, + }, + valueToKey: map[int]int{ + 3: 1, + }, + }, + }, + { + name: "value removed", + state: &BiMap[int, int]{ + keyToValue: map[int]int{ + 1: 2, + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + key: 3, + value: 2, + expectedRemoved: []Entry[int, int]{ + { + Key: 1, + Value: 2, + }, + }, + expectedState: &BiMap[int, int]{ + keyToValue: map[int]int{ + 3: 2, + }, + valueToKey: map[int]int{ + 2: 3, + }, + }, + }, + { + name: "key and value removed", + state: &BiMap[int, int]{ + keyToValue: map[int]int{ + 1: 2, + 3: 4, + }, + valueToKey: map[int]int{ + 2: 1, + 4: 3, + }, + }, + key: 1, + value: 4, + expectedRemoved: []Entry[int, int]{ + { + Key: 1, + Value: 2, + }, + { + Key: 3, + Value: 4, + }, + }, + expectedState: &BiMap[int, int]{ + keyToValue: map[int]int{ + 1: 4, + }, + valueToKey: map[int]int{ + 4: 1, + }, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + removed := test.state.Put(test.key, test.value) + require.Equal(test.expectedRemoved, removed) + require.Equal(test.expectedState, test.state) + }) + } +} + +func TestBiMapHasValueAndGetKey(t *testing.T) { + m := New[int, int]() + require.Empty(t, m.Put(1, 2)) + + tests := []struct { + name string + value int + expectedKey int + expectedExists bool + }{ + { + name: "fetch unknown", + value: 3, + expectedKey: 0, + expectedExists: false, + }, + { + name: "fetch known value", + value: 2, + expectedKey: 1, + expectedExists: true, + }, + { + name: "fetch known key", + value: 1, + expectedKey: 0, + expectedExists: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + exists := m.HasValue(test.value) + require.Equal(test.expectedExists, exists) + + key, exists := m.GetKey(test.value) + require.Equal(test.expectedKey, key) + require.Equal(test.expectedExists, exists) + }) + } +} + +func TestBiMapHasKeyAndGetValue(t *testing.T) { + m := New[int, int]() + require.Empty(t, m.Put(1, 2)) + + tests := []struct { + name string + key int + expectedValue int + expectedExists bool + }{ + { + name: "fetch unknown", + key: 3, + expectedValue: 0, + expectedExists: false, + }, + { + name: "fetch known key", + key: 1, + expectedValue: 2, + expectedExists: true, + }, + { + name: "fetch known value", + key: 2, + expectedValue: 0, + expectedExists: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + exists := m.HasKey(test.key) + require.Equal(test.expectedExists, exists) + + value, exists := m.GetValue(test.key) + require.Equal(test.expectedValue, value) + require.Equal(test.expectedExists, exists) + }) + } +} + +func TestBiMapDeleteKey(t *testing.T) { + tests := []struct { + name string + state *BiMap[int, int] + key int + expectedValue int + expectedRemoved bool + expectedState *BiMap[int, int] + }{ + { + name: "none removed", + state: New[int, int](), + key: 1, + expectedValue: 0, + expectedRemoved: false, + expectedState: New[int, int](), + }, + { + name: "key removed", + state: &BiMap[int, int]{ + keyToValue: map[int]int{ + 1: 2, + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + key: 1, + expectedValue: 2, + expectedRemoved: true, + expectedState: New[int, int](), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + value, removed := test.state.DeleteKey(test.key) + require.Equal(test.expectedValue, value) + require.Equal(test.expectedRemoved, removed) + require.Equal(test.expectedState, test.state) + }) + } +} + +func TestBiMapDeleteValue(t *testing.T) { + tests := []struct { + name string + state *BiMap[int, int] + value int + expectedKey int + expectedRemoved bool + expectedState *BiMap[int, int] + }{ + { + name: "none removed", + state: New[int, int](), + value: 1, + expectedKey: 0, + expectedRemoved: false, + expectedState: New[int, int](), + }, + { + name: "key removed", + state: &BiMap[int, int]{ + keyToValue: map[int]int{ + 1: 2, + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + value: 2, + expectedKey: 1, + expectedRemoved: true, + expectedState: New[int, int](), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + key, removed := test.state.DeleteValue(test.value) + require.Equal(test.expectedKey, key) + require.Equal(test.expectedRemoved, removed) + require.Equal(test.expectedState, test.state) + }) + } +} + +func TestBiMapLen(t *testing.T) { + require := require.New(t) + + m := New[int, int]() + require.Zero(m.Len()) + + m.Put(1, 2) + require.Equal(1, m.Len()) + + m.Put(2, 3) + require.Equal(2, m.Len()) + + m.Put(1, 3) + require.Equal(1, m.Len()) + + m.DeleteKey(1) + require.Zero(m.Len()) +} From 02ae8d9b9a195a091a419a5cb8912cd3e0ebd3fb Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 28 Nov 2023 15:10:25 -0500 Subject: [PATCH 079/267] Unexport RequestID from snowman engine (#2384) --- snow/engine/snowman/transitive.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index f0ce42ecf912..76a9d218ca65 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -59,7 +59,7 @@ type Transitive struct { common.AppHandler validators.Connector - RequestID uint32 + requestID uint32 // track outstanding preference requests polls poll.Set @@ -409,7 +409,7 @@ func (t *Transitive) Context() *snow.ConsensusContext { } func (t *Transitive) Start(ctx context.Context, startReqID uint32) error { - t.RequestID = startReqID + t.requestID = startReqID lastAcceptedID, err := t.VM.LastAccepted(ctx) if err != nil { return err @@ -774,20 +774,20 @@ func (t *Transitive) sendRequest(ctx context.Context, nodeID ids.NodeID, blkID i return } - t.RequestID++ + t.requestID++ t.blkReqs.Put( common.Request{ NodeID: nodeID, - RequestID: t.RequestID, + RequestID: t.requestID, }, blkID, ) t.Ctx.Log.Verbo("sending Get request", zap.Stringer("nodeID", nodeID), - zap.Uint32("requestID", t.RequestID), + zap.Uint32("requestID", t.requestID), zap.Stringer("blkID", blkID), ) - t.Sender.SendGet(ctx, nodeID, t.RequestID, blkID) + t.Sender.SendGet(ctx, nodeID, t.requestID, blkID) // Tracks performance statistics t.metrics.numRequests.Set(float64(t.blkReqs.Len())) @@ -828,21 +828,21 @@ func (t *Transitive) sendQuery( } vdrBag := bag.Of(vdrIDs...) - t.RequestID++ - if !t.polls.Add(t.RequestID, vdrBag) { + t.requestID++ + if !t.polls.Add(t.requestID, vdrBag) { t.Ctx.Log.Error("dropped query for block", zap.String("reason", "failed to add poll"), zap.Stringer("blkID", blkID), - zap.Uint32("requestID", t.RequestID), + zap.Uint32("requestID", t.requestID), ) return } vdrSet := set.Of(vdrIDs...) if push { - t.Sender.SendPushQuery(ctx, vdrSet, t.RequestID, blkBytes, nextHeightToAccept) + t.Sender.SendPushQuery(ctx, vdrSet, t.requestID, blkBytes, nextHeightToAccept) } else { - t.Sender.SendPullQuery(ctx, vdrSet, t.RequestID, blkID, nextHeightToAccept) + t.Sender.SendPullQuery(ctx, vdrSet, t.requestID, blkID, nextHeightToAccept) } } From 21c14b111ece5cc6d4ffa618ff73c83b4fc66d8a Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 28 Nov 2023 23:59:51 -0500 Subject: [PATCH 080/267] Add metric to track the stake weight of block providers (#2376) --- snow/engine/snowman/issuer.go | 3 ++- snow/engine/snowman/metrics.go | 8 ++++++ snow/engine/snowman/transitive.go | 26 +++++++++++--------- snow/engine/snowman/transitive_test.go | 34 +++++++++++++------------- 4 files changed, 42 insertions(+), 29 deletions(-) diff --git a/snow/engine/snowman/issuer.go b/snow/engine/snowman/issuer.go index ca69064105e1..697bc302e730 100644 --- a/snow/engine/snowman/issuer.go +++ b/snow/engine/snowman/issuer.go @@ -14,6 +14,7 @@ import ( // issuer issues [blk] into to consensus after its dependencies are met. type issuer struct { t *Transitive + nodeID ids.NodeID // nodeID of the peer that provided this block blk snowman.Block abandoned bool deps set.Set[ids.ID] @@ -51,5 +52,5 @@ func (i *issuer) Update(ctx context.Context) { return } // Issue the block into consensus - i.t.errs.Add(i.t.deliver(ctx, i.blk, i.push)) + i.t.errs.Add(i.t.deliver(ctx, i.nodeID, i.blk, i.push)) } diff --git a/snow/engine/snowman/metrics.go b/snow/engine/snowman/metrics.go index ae7cc66cfbfb..a0e5e5b565fe 100644 --- a/snow/engine/snowman/metrics.go +++ b/snow/engine/snowman/metrics.go @@ -27,6 +27,7 @@ type metrics struct { numProcessingAncestorFetchesUnneeded prometheus.Counter getAncestorsBlks metric.Averager selectedVoteIndex metric.Averager + issuerStake metric.Averager } func (m *metrics) Initialize(namespace string, reg prometheus.Registerer) error { @@ -115,6 +116,13 @@ func (m *metrics) Initialize(namespace string, reg prometheus.Registerer) error reg, &errs, ) + m.issuerStake = metric.NewAveragerWithErrs( + namespace, + "issuer_stake", + "stake weight of the peer who provided a block that was issued into consensus", + reg, + &errs, + ) errs.Add( reg.Register(m.bootstrapFinished), diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 76a9d218ca65..fd2ac3a86b75 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -444,7 +444,7 @@ func (t *Transitive) Start(ctx context.Context, startReqID uint32) error { default: for _, blk := range options { // note that deliver will set the VM's preference - if err := t.deliver(ctx, blk, false); err != nil { + if err := t.deliver(ctx, t.Ctx.NodeID, blk, false); err != nil { return err } } @@ -650,7 +650,7 @@ func (t *Transitive) issueFrom(ctx context.Context, nodeID ids.NodeID, blk snowm // issue [blk] and its ancestors to consensus. blkID := blk.ID() for !t.wasIssued(blk) { - if err := t.issue(ctx, blk, false); err != nil { + if err := t.issue(ctx, nodeID, blk, false); err != nil { return false, err } @@ -690,7 +690,7 @@ func (t *Transitive) issueWithAncestors(ctx context.Context, blk snowman.Block) // issue [blk] and its ancestors into consensus status := blk.Status() for status.Fetched() && !t.wasIssued(blk) { - err := t.issue(ctx, blk, true) + err := t.issue(ctx, t.Ctx.NodeID, blk, true) if err != nil { return false, err } @@ -732,7 +732,7 @@ func (t *Transitive) wasIssued(blk snowman.Block) bool { // Issue [blk] to consensus once its ancestors have been issued. // If [push] is true, a push query will be used. Otherwise, a pull query will be // used. -func (t *Transitive) issue(ctx context.Context, blk snowman.Block, push bool) error { +func (t *Transitive) issue(ctx context.Context, nodeID ids.NodeID, blk snowman.Block, push bool) error { blkID := blk.ID() // mark that the block is queued to be added to consensus once its ancestors have been @@ -743,9 +743,10 @@ func (t *Transitive) issue(ctx context.Context, blk snowman.Block, push bool) er // Will add [blk] to consensus once its ancestors have been i := &issuer{ - t: t, - blk: blk, - push: push, + t: t, + nodeID: nodeID, + blk: blk, + push: push, } // block on the parent if needed @@ -849,7 +850,7 @@ func (t *Transitive) sendQuery( // issue [blk] to consensus // If [push] is true, a push query will be used. Otherwise, a pull query will be // used. -func (t *Transitive) deliver(ctx context.Context, blk snowman.Block, push bool) error { +func (t *Transitive) deliver(ctx context.Context, nodeID ids.NodeID, blk snowman.Block, push bool) error { blkID := blk.ID() if t.Consensus.Decided(blk) || t.Consensus.Processing(blkID) { return nil @@ -875,7 +876,7 @@ func (t *Transitive) deliver(ctx context.Context, blk snowman.Block, push bool) // By ensuring that the parent is either processing or accepted, it is // guaranteed that the parent was successfully verified. This means that // calling Verify on this block is allowed. - blkAdded, err := t.addUnverifiedBlockToConsensus(ctx, blk) + blkAdded, err := t.addUnverifiedBlockToConsensus(ctx, nodeID, blk) if err != nil { return err } @@ -899,7 +900,7 @@ func (t *Transitive) deliver(ctx context.Context, blk snowman.Block, push bool) } for _, blk := range options { - blkAdded, err := t.addUnverifiedBlockToConsensus(ctx, blk) + blkAdded, err := t.addUnverifiedBlockToConsensus(ctx, nodeID, blk) if err != nil { return err } @@ -979,12 +980,13 @@ func (t *Transitive) addToNonVerifieds(blk snowman.Block) { // addUnverifiedBlockToConsensus returns whether the block was added and an // error if one occurred while adding it to consensus. -func (t *Transitive) addUnverifiedBlockToConsensus(ctx context.Context, blk snowman.Block) (bool, error) { +func (t *Transitive) addUnverifiedBlockToConsensus(ctx context.Context, nodeID ids.NodeID, blk snowman.Block) (bool, error) { blkID := blk.ID() // make sure this block is valid if err := blk.Verify(ctx); err != nil { t.Ctx.Log.Debug("block verification failed", + zap.Stringer("nodeID", nodeID), zap.Stringer("blkID", blkID), zap.Error(err), ) @@ -997,7 +999,9 @@ func (t *Transitive) addUnverifiedBlockToConsensus(ctx context.Context, blk snow t.nonVerifieds.Remove(blkID) t.nonVerifiedCache.Evict(blkID) t.metrics.numNonVerifieds.Set(float64(t.nonVerifieds.Len())) + t.metrics.issuerStake.Observe(float64(t.Validators.GetWeight(t.Ctx.SubnetID, nodeID))) t.Ctx.Log.Verbo("adding block to consensus", + zap.Stringer("nodeID", nodeID), zap.Stringer("blkID", blkID), ) return true, t.Consensus.Add(ctx, &memoryBlock{ diff --git a/snow/engine/snowman/transitive_test.go b/snow/engine/snowman/transitive_test.go index 405f1abd3666..62662ed66077 100644 --- a/snow/engine/snowman/transitive_test.go +++ b/snow/engine/snowman/transitive_test.go @@ -412,7 +412,7 @@ func TestEngineMultipleQuery(t *testing.T) { } } - require.NoError(te.issue(context.Background(), blk0, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk0, false)) blk1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -522,10 +522,10 @@ func TestEngineBlockedIssue(t *testing.T) { } } - require.NoError(te.issue(context.Background(), blk1, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk1, false)) blk0.StatusV = choices.Processing - require.NoError(te.issue(context.Background(), blk0, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk0, false)) require.Equal(blk1.ID(), te.Consensus.Preference()) } @@ -558,7 +558,7 @@ func TestEngineAbandonResponse(t *testing.T) { return nil, errUnknownBlock } - require.NoError(te.issue(context.Background(), blk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, false)) require.NoError(te.QueryFailed(context.Background(), vdr, 1)) require.Empty(te.blocked) @@ -797,7 +797,7 @@ func TestVoteCanceling(t *testing.T) { require.Equal(uint64(1), requestedHeight) } - require.NoError(te.issue(context.Background(), blk, true)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, true)) require.Equal(1, te.polls.Len()) @@ -858,7 +858,7 @@ func TestEngineNoQuery(t *testing.T) { BytesV: []byte{1}, } - require.NoError(te.issue(context.Background(), blk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, false)) } func TestEngineNoRepollQuery(t *testing.T) { @@ -961,7 +961,7 @@ func TestEngineAbandonChit(t *testing.T) { reqID = requestID } - require.NoError(te.issue(context.Background(), blk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, false)) fakeBlkID := ids.GenerateTestID() vm.GetBlockF = func(_ context.Context, id ids.ID) (snowman.Block, error) { @@ -1016,7 +1016,7 @@ func TestEngineAbandonChitWithUnexpectedPutBlock(t *testing.T) { reqID = requestID } - require.NoError(te.issue(context.Background(), blk, true)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, true)) fakeBlkID := ids.GenerateTestID() vm.GetBlockF = func(_ context.Context, id ids.ID) (snowman.Block, error) { @@ -1099,7 +1099,7 @@ func TestEngineBlockingChitRequest(t *testing.T) { return blockingBlk, nil } - require.NoError(te.issue(context.Background(), parentBlk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, parentBlk, false)) sender.CantSendChits = false @@ -1110,7 +1110,7 @@ func TestEngineBlockingChitRequest(t *testing.T) { sender.CantSendPullQuery = false missingBlk.StatusV = choices.Processing - require.NoError(te.issue(context.Background(), missingBlk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, missingBlk, false)) require.Empty(te.blocked) } @@ -1163,7 +1163,7 @@ func TestEngineBlockingChitResponse(t *testing.T) { } } - require.NoError(te.issue(context.Background(), blockingBlk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blockingBlk, false)) queryRequestID := new(uint32) sender.SendPullQueryF = func(_ context.Context, inVdrs set.Set[ids.NodeID], requestID uint32, blkID ids.ID, requestedHeight uint64) { @@ -1174,7 +1174,7 @@ func TestEngineBlockingChitResponse(t *testing.T) { require.Equal(uint64(1), requestedHeight) } - require.NoError(te.issue(context.Background(), issuedBlk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, issuedBlk, false)) sender.SendPushQueryF = nil sender.CantSendPushQuery = false @@ -1185,7 +1185,7 @@ func TestEngineBlockingChitResponse(t *testing.T) { sender.CantSendPullQuery = false missingBlk.StatusV = choices.Processing - require.NoError(te.issue(context.Background(), missingBlk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, missingBlk, false)) } func TestEngineRetryFetch(t *testing.T) { @@ -1281,9 +1281,9 @@ func TestEngineUndeclaredDependencyDeadlock(t *testing.T) { return nil, errUnknownBlock } } - require.NoError(te.issue(context.Background(), validBlk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, validBlk, false)) sender.SendPushQueryF = nil - require.NoError(te.issue(context.Background(), invalidBlk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, invalidBlk, false)) require.NoError(te.Chits(context.Background(), vdr, *reqID, invalidBlkID, invalidBlkID, invalidBlkID)) require.Equal(choices.Accepted, validBlk.Status()) @@ -1666,7 +1666,7 @@ func TestEngineDoubleChit(t *testing.T) { require.Equal(blk.ID(), blkID) require.Equal(uint64(1), requestedHeight) } - require.NoError(te.issue(context.Background(), blk, false)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, false)) vm.GetBlockF = func(_ context.Context, id ids.ID) (snowman.Block, error) { switch id { @@ -2785,7 +2785,7 @@ func TestEngineApplyAcceptedFrontierInQueryFailed(t *testing.T) { require.Equal(uint64(1), requestedHeight) } - require.NoError(te.issue(context.Background(), blk, true)) + require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, true)) vm.GetBlockF = func(_ context.Context, id ids.ID) (snowman.Block, error) { switch id { From 6ed238cb06703813c2751dfc2afcb4e65f10b813 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 29 Nov 2023 01:05:16 -0500 Subject: [PATCH 081/267] Add block source metrics to monitor gossip (#2386) --- snow/engine/snowman/issuer.go | 17 ++- snow/engine/snowman/metrics.go | 22 +++ snow/engine/snowman/transitive.go | 191 +++++++++++++++++-------- snow/engine/snowman/transitive_test.go | 136 +++++++++++++++--- 4 files changed, 285 insertions(+), 81 deletions(-) diff --git a/snow/engine/snowman/issuer.go b/snow/engine/snowman/issuer.go index 697bc302e730..3558d47360dc 100644 --- a/snow/engine/snowman/issuer.go +++ b/snow/engine/snowman/issuer.go @@ -6,6 +6,8 @@ package snowman import ( "context" + "github.com/prometheus/client_golang/prometheus" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/utils/set" @@ -13,12 +15,13 @@ import ( // issuer issues [blk] into to consensus after its dependencies are met. type issuer struct { - t *Transitive - nodeID ids.NodeID // nodeID of the peer that provided this block - blk snowman.Block - abandoned bool - deps set.Set[ids.ID] - push bool + t *Transitive + nodeID ids.NodeID // nodeID of the peer that provided this block + blk snowman.Block + issuedMetric prometheus.Counter + abandoned bool + deps set.Set[ids.ID] + push bool } func (i *issuer) Dependencies() set.Set[ids.ID] { @@ -52,5 +55,5 @@ func (i *issuer) Update(ctx context.Context) { return } // Issue the block into consensus - i.t.errs.Add(i.t.deliver(ctx, i.nodeID, i.blk, i.push)) + i.t.errs.Add(i.t.deliver(ctx, i.nodeID, i.blk, i.push, i.issuedMetric)) } diff --git a/snow/engine/snowman/metrics.go b/snow/engine/snowman/metrics.go index a0e5e5b565fe..dfdc92c636db 100644 --- a/snow/engine/snowman/metrics.go +++ b/snow/engine/snowman/metrics.go @@ -10,6 +10,14 @@ import ( "github.com/ava-labs/avalanchego/utils/wrappers" ) +const ( + pullGossipSource = "pull_gossip" + pushGossipSource = "push_gossip" + putGossipSource = "put_gossip" + builtSource = "built" + unknownSource = "unknown" +) + type metrics struct { bootstrapFinished prometheus.Gauge numRequests prometheus.Gauge @@ -28,6 +36,7 @@ type metrics struct { getAncestorsBlks metric.Averager selectedVoteIndex metric.Averager issuerStake metric.Averager + issued *prometheus.CounterVec } func (m *metrics) Initialize(namespace string, reg prometheus.Registerer) error { @@ -123,6 +132,18 @@ func (m *metrics) Initialize(namespace string, reg prometheus.Registerer) error reg, &errs, ) + m.issued = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "blks_issued", + Help: "number of blocks that have been issued into consensus by discovery mechanism", + }, []string{"source"}) + + // Register the labels + m.issued.WithLabelValues(pullGossipSource) + m.issued.WithLabelValues(pushGossipSource) + m.issued.WithLabelValues(putGossipSource) + m.issued.WithLabelValues(builtSource) + m.issued.WithLabelValues(unknownSource) errs.Add( reg.Register(m.bootstrapFinished), @@ -139,6 +160,7 @@ func (m *metrics) Initialize(namespace string, reg prometheus.Registerer) error reg.Register(m.numProcessingAncestorFetchesDropped), reg.Register(m.numProcessingAncestorFetchesSucceeded), reg.Register(m.numProcessingAncestorFetchesUnneeded), + reg.Register(m.issued), ) return errs.Err } diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index fd2ac3a86b75..7675cff931fe 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -7,6 +7,8 @@ import ( "context" "fmt" + "github.com/prometheus/client_golang/prometheus" + "go.uber.org/zap" "github.com/ava-labs/avalanchego/cache" @@ -65,7 +67,8 @@ type Transitive struct { polls poll.Set // blocks that have we have sent get requests for but haven't yet received - blkReqs *bimap.BiMap[common.Request, ids.ID] + blkReqs *bimap.BiMap[common.Request, ids.ID] + blkReqSourceMetric map[common.Request]prometheus.Counter // blocks that are queued to be issued to consensus once missing dependencies are fetched // Block ID --> Block @@ -142,6 +145,7 @@ func newTransitive(config Config) (*Transitive, error) { acceptedFrontiers: acceptedFrontiers, polls: polls, blkReqs: bimap.New[common.Request, ids.ID](), + blkReqSourceMetric: make(map[common.Request]prometheus.Counter), } return t, t.metrics.Initialize("", config.Ctx.Registerer) @@ -170,23 +174,39 @@ func (t *Transitive) Put(ctx context.Context, nodeID ids.NodeID, requestID uint3 return t.GetFailed(ctx, nodeID, requestID) } - actualBlkID := blk.ID() - expectedBlkID, ok := t.blkReqs.GetValue(common.Request{ - NodeID: nodeID, - RequestID: requestID, - }) - // If the provided block is not the requested block, we need to explicitly - // mark the request as failed to avoid having a dangling dependency. - if ok && actualBlkID != expectedBlkID { - t.Ctx.Log.Debug("incorrect block returned in Put", - zap.Stringer("nodeID", nodeID), - zap.Uint32("requestID", requestID), - zap.Stringer("blkID", actualBlkID), - zap.Stringer("expectedBlkID", expectedBlkID), - ) - // We assume that [blk] is useless because it doesn't match what we - // expected. - return t.GetFailed(ctx, nodeID, requestID) + var ( + req = common.Request{ + NodeID: nodeID, + RequestID: requestID, + } + issuedMetric prometheus.Counter + ) + switch expectedBlkID, ok := t.blkReqs.GetValue(req); { + case ok: + actualBlkID := blk.ID() + if actualBlkID != expectedBlkID { + t.Ctx.Log.Debug("incorrect block returned in Put", + zap.Stringer("nodeID", nodeID), + zap.Uint32("requestID", requestID), + zap.Stringer("blkID", actualBlkID), + zap.Stringer("expectedBlkID", expectedBlkID), + ) + // We assume that [blk] is useless because it doesn't match what we + // expected. + return t.GetFailed(ctx, nodeID, requestID) + } + + issuedMetric = t.blkReqSourceMetric[req] + case requestID == constants.GossipMsgRequestID: + issuedMetric = t.metrics.issued.WithLabelValues(putGossipSource) + default: + // This can happen if this block was provided to this engine while a Get + // request was outstanding. For example, the block may have been locally + // built or the node may have received a PushQuery with this block. + // + // Note: It is still possible this block will be issued here, because + // the block may have previously failed verification. + issuedMetric = t.metrics.issued.WithLabelValues(unknownSource) } if t.wasIssued(blk) { @@ -198,7 +218,7 @@ func (t *Transitive) Put(ctx context.Context, nodeID ids.NodeID, requestID uint3 // receive requests to fill the ancestry. dependencies that have already // been fetched, but with missing dependencies themselves won't be requested // from the vdr. - if _, err := t.issueFrom(ctx, nodeID, blk); err != nil { + if _, err := t.issueFrom(ctx, nodeID, blk, issuedMetric); err != nil { return err } return t.buildBlocks(ctx) @@ -206,11 +226,13 @@ func (t *Transitive) Put(ctx context.Context, nodeID ids.NodeID, requestID uint3 func (t *Transitive) GetFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { // We don't assume that this function is called after a failed Get message. - // Check to see if we have an outstanding request and also get what the request was for if it exists. - blkID, ok := t.blkReqs.DeleteKey(common.Request{ + // Check to see if we have an outstanding request and also get what the + // request was for if it exists. + req := common.Request{ NodeID: nodeID, RequestID: requestID, - }) + } + blkID, ok := t.blkReqs.DeleteKey(req) if !ok { t.Ctx.Log.Debug("unexpected GetFailed", zap.Stringer("nodeID", nodeID), @@ -218,6 +240,7 @@ func (t *Transitive) GetFailed(ctx context.Context, nodeID ids.NodeID, requestID ) return nil } + delete(t.blkReqSourceMetric, req) // Because the get request was dropped, we no longer expect blkID to be issued. t.blocked.Abandon(ctx, blkID) @@ -229,9 +252,11 @@ func (t *Transitive) GetFailed(ctx context.Context, nodeID ids.NodeID, requestID func (t *Transitive) PullQuery(ctx context.Context, nodeID ids.NodeID, requestID uint32, blkID ids.ID, requestedHeight uint64) error { t.sendChits(ctx, nodeID, requestID, requestedHeight) + issuedMetric := t.metrics.issued.WithLabelValues(pushGossipSource) + // Try to issue [blkID] to consensus. // If we're missing an ancestor, request it from [vdr] - if _, err := t.issueFromByID(ctx, nodeID, blkID); err != nil { + if _, err := t.issueFromByID(ctx, nodeID, blkID, issuedMetric); err != nil { return err } @@ -265,12 +290,14 @@ func (t *Transitive) PushQuery(ctx context.Context, nodeID ids.NodeID, requestID t.metrics.numUselessPushQueryBytes.Add(float64(len(blkBytes))) } + issuedMetric := t.metrics.issued.WithLabelValues(pushGossipSource) + // issue the block into consensus. If the block has already been issued, // this will be a noop. If this block has missing dependencies, nodeID will // receive requests to fill the ancestry. dependencies that have already // been fetched, but with missing dependencies themselves won't be requested // from the vdr. - if _, err := t.issueFrom(ctx, nodeID, blk); err != nil { + if _, err := t.issueFrom(ctx, nodeID, blk, issuedMetric); err != nil { return err } @@ -288,7 +315,9 @@ func (t *Transitive) Chits(ctx context.Context, nodeID ids.NodeID, requestID uin zap.Stringer("acceptedID", acceptedID), ) - addedPreferred, err := t.issueFromByID(ctx, nodeID, preferredID) + issuedMetric := t.metrics.issued.WithLabelValues(pullGossipSource) + + addedPreferred, err := t.issueFromByID(ctx, nodeID, preferredID, issuedMetric) if err != nil { return err } @@ -302,7 +331,7 @@ func (t *Transitive) Chits(ctx context.Context, nodeID ids.NodeID, requestID uin responseOptions = []ids.ID{preferredID} ) if preferredID != preferredIDAtHeight { - addedPreferredIDAtHeight, err = t.issueFromByID(ctx, nodeID, preferredIDAtHeight) + addedPreferredIDAtHeight, err = t.issueFromByID(ctx, nodeID, preferredIDAtHeight, issuedMetric) if err != nil { return err } @@ -442,9 +471,10 @@ func (t *Transitive) Start(ctx context.Context, startReqID uint32) error { case err != nil: return err default: + issuedMetric := t.metrics.issued.WithLabelValues(builtSource) for _, blk := range options { // note that deliver will set the VM's preference - if err := t.deliver(ctx, t.Ctx.NodeID, blk, false); err != nil { + if err := t.deliver(ctx, t.Ctx.NodeID, blk, false, issuedMetric); err != nil { return err } } @@ -604,7 +634,8 @@ func (t *Transitive) buildBlocks(ctx context.Context) error { ) } - added, err := t.issueWithAncestors(ctx, blk) + issuedMetric := t.metrics.issued.WithLabelValues(builtSource) + added, err := t.issueWithAncestors(ctx, blk, issuedMetric) if err != nil { return err } @@ -634,23 +665,33 @@ func (t *Transitive) repoll(ctx context.Context) { // issueFromByID attempts to issue the branch ending with a block [blkID] into consensus. // If we do not have [blkID], request it. // Returns true if the block is processing in consensus or is decided. -func (t *Transitive) issueFromByID(ctx context.Context, nodeID ids.NodeID, blkID ids.ID) (bool, error) { +func (t *Transitive) issueFromByID( + ctx context.Context, + nodeID ids.NodeID, + blkID ids.ID, + issuedMetric prometheus.Counter, +) (bool, error) { blk, err := t.GetBlock(ctx, blkID) if err != nil { - t.sendRequest(ctx, nodeID, blkID) + t.sendRequest(ctx, nodeID, blkID, issuedMetric) return false, nil } - return t.issueFrom(ctx, nodeID, blk) + return t.issueFrom(ctx, nodeID, blk, issuedMetric) } // issueFrom attempts to issue the branch ending with block [blkID] to consensus. // Returns true if the block is processing in consensus or is decided. // If a dependency is missing, request it from [vdr]. -func (t *Transitive) issueFrom(ctx context.Context, nodeID ids.NodeID, blk snowman.Block) (bool, error) { +func (t *Transitive) issueFrom( + ctx context.Context, + nodeID ids.NodeID, + blk snowman.Block, + issuedMetric prometheus.Counter, +) (bool, error) { // issue [blk] and its ancestors to consensus. blkID := blk.ID() for !t.wasIssued(blk) { - if err := t.issue(ctx, nodeID, blk, false); err != nil { + if err := t.issue(ctx, nodeID, blk, false, issuedMetric); err != nil { return false, err } @@ -660,13 +701,15 @@ func (t *Transitive) issueFrom(ctx context.Context, nodeID ids.NodeID, blk snowm // If we don't have this ancestor, request it from [vdr] if err != nil || !blk.Status().Fetched() { - t.sendRequest(ctx, nodeID, blkID) + t.sendRequest(ctx, nodeID, blkID, issuedMetric) return false, nil } } // Remove any outstanding requests for this block - t.blkReqs.DeleteValue(blkID) + if req, ok := t.blkReqs.DeleteValue(blkID); ok { + delete(t.blkReqSourceMetric, req) + } issued := t.Consensus.Decided(blk) || t.Consensus.Processing(blkID) if issued { @@ -685,12 +728,16 @@ func (t *Transitive) issueFrom(ctx context.Context, nodeID ids.NodeID, blk snowm // issueWithAncestors attempts to issue the branch ending with [blk] to consensus. // Returns true if the block is processing in consensus or is decided. // If a dependency is missing and the dependency hasn't been requested, the issuance will be abandoned. -func (t *Transitive) issueWithAncestors(ctx context.Context, blk snowman.Block) (bool, error) { +func (t *Transitive) issueWithAncestors( + ctx context.Context, + blk snowman.Block, + issuedMetric prometheus.Counter, +) (bool, error) { blkID := blk.ID() // issue [blk] and its ancestors into consensus status := blk.Status() for status.Fetched() && !t.wasIssued(blk) { - err := t.issue(ctx, t.Ctx.NodeID, blk, true) + err := t.issue(ctx, t.Ctx.NodeID, blk, true, issuedMetric) if err != nil { return false, err } @@ -732,21 +779,30 @@ func (t *Transitive) wasIssued(blk snowman.Block) bool { // Issue [blk] to consensus once its ancestors have been issued. // If [push] is true, a push query will be used. Otherwise, a pull query will be // used. -func (t *Transitive) issue(ctx context.Context, nodeID ids.NodeID, blk snowman.Block, push bool) error { +func (t *Transitive) issue( + ctx context.Context, + nodeID ids.NodeID, + blk snowman.Block, + push bool, + issuedMetric prometheus.Counter, +) error { blkID := blk.ID() // mark that the block is queued to be added to consensus once its ancestors have been t.pending[blkID] = blk // Remove any outstanding requests for this block - t.blkReqs.DeleteValue(blkID) + if req, ok := t.blkReqs.DeleteValue(blkID); ok { + delete(t.blkReqSourceMetric, req) + } // Will add [blk] to consensus once its ancestors have been i := &issuer{ - t: t, - nodeID: nodeID, - blk: blk, - push: push, + t: t, + nodeID: nodeID, + blk: blk, + issuedMetric: issuedMetric, + push: push, } // block on the parent if needed @@ -769,20 +825,25 @@ func (t *Transitive) issue(ctx context.Context, nodeID ids.NodeID, blk snowman.B } // Request that [vdr] send us block [blkID] -func (t *Transitive) sendRequest(ctx context.Context, nodeID ids.NodeID, blkID ids.ID) { +func (t *Transitive) sendRequest( + ctx context.Context, + nodeID ids.NodeID, + blkID ids.ID, + issuedMetric prometheus.Counter, +) { // There is already an outstanding request for this block if t.blkReqs.HasValue(blkID) { return } t.requestID++ - t.blkReqs.Put( - common.Request{ - NodeID: nodeID, - RequestID: t.requestID, - }, - blkID, - ) + req := common.Request{ + NodeID: nodeID, + RequestID: t.requestID, + } + t.blkReqs.Put(req, blkID) + t.blkReqSourceMetric[req] = issuedMetric + t.Ctx.Log.Verbo("sending Get request", zap.Stringer("nodeID", nodeID), zap.Uint32("requestID", t.requestID), @@ -850,7 +911,13 @@ func (t *Transitive) sendQuery( // issue [blk] to consensus // If [push] is true, a push query will be used. Otherwise, a pull query will be // used. -func (t *Transitive) deliver(ctx context.Context, nodeID ids.NodeID, blk snowman.Block, push bool) error { +func (t *Transitive) deliver( + ctx context.Context, + nodeID ids.NodeID, + blk snowman.Block, + push bool, + issuedMetric prometheus.Counter, +) error { blkID := blk.ID() if t.Consensus.Decided(blk) || t.Consensus.Processing(blkID) { return nil @@ -876,7 +943,7 @@ func (t *Transitive) deliver(ctx context.Context, nodeID ids.NodeID, blk snowman // By ensuring that the parent is either processing or accepted, it is // guaranteed that the parent was successfully verified. This means that // calling Verify on this block is allowed. - blkAdded, err := t.addUnverifiedBlockToConsensus(ctx, nodeID, blk) + blkAdded, err := t.addUnverifiedBlockToConsensus(ctx, nodeID, blk, issuedMetric) if err != nil { return err } @@ -900,7 +967,7 @@ func (t *Transitive) deliver(ctx context.Context, nodeID ids.NodeID, blk snowman } for _, blk := range options { - blkAdded, err := t.addUnverifiedBlockToConsensus(ctx, nodeID, blk) + blkAdded, err := t.addUnverifiedBlockToConsensus(ctx, nodeID, blk, issuedMetric) if err != nil { return err } @@ -932,13 +999,17 @@ func (t *Transitive) deliver(ctx context.Context, nodeID ids.NodeID, blk snowman t.removeFromPending(blk) t.blocked.Fulfill(ctx, blkID) - t.blkReqs.DeleteValue(blkID) + if req, ok := t.blkReqs.DeleteValue(blkID); ok { + delete(t.blkReqSourceMetric, req) + } } for _, blk := range dropped { blkID := blk.ID() t.removeFromPending(blk) t.blocked.Abandon(ctx, blkID) - t.blkReqs.DeleteValue(blkID) + if req, ok := t.blkReqs.DeleteValue(blkID); ok { + delete(t.blkReqSourceMetric, req) + } } // If we should issue multiple queries at the same time, we need to repoll @@ -980,7 +1051,12 @@ func (t *Transitive) addToNonVerifieds(blk snowman.Block) { // addUnverifiedBlockToConsensus returns whether the block was added and an // error if one occurred while adding it to consensus. -func (t *Transitive) addUnverifiedBlockToConsensus(ctx context.Context, nodeID ids.NodeID, blk snowman.Block) (bool, error) { +func (t *Transitive) addUnverifiedBlockToConsensus( + ctx context.Context, + nodeID ids.NodeID, + blk snowman.Block, + issuedMetric prometheus.Counter, +) (bool, error) { blkID := blk.ID() // make sure this block is valid @@ -996,6 +1072,7 @@ func (t *Transitive) addUnverifiedBlockToConsensus(ctx context.Context, nodeID i return false, nil } + issuedMetric.Inc() t.nonVerifieds.Remove(blkID) t.nonVerifiedCache.Evict(blkID) t.metrics.numNonVerifieds.Set(float64(t.nonVerifieds.Len())) diff --git a/snow/engine/snowman/transitive_test.go b/snow/engine/snowman/transitive_test.go index 62662ed66077..69ca9611cc3f 100644 --- a/snow/engine/snowman/transitive_test.go +++ b/snow/engine/snowman/transitive_test.go @@ -412,7 +412,13 @@ func TestEngineMultipleQuery(t *testing.T) { } } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk0, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk0, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) blk1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -522,10 +528,22 @@ func TestEngineBlockedIssue(t *testing.T) { } } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk1, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk1, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) blk0.StatusV = choices.Processing - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk0, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk0, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) require.Equal(blk1.ID(), te.Consensus.Preference()) } @@ -558,7 +576,13 @@ func TestEngineAbandonResponse(t *testing.T) { return nil, errUnknownBlock } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) require.NoError(te.QueryFailed(context.Background(), vdr, 1)) require.Empty(te.blocked) @@ -797,7 +821,13 @@ func TestVoteCanceling(t *testing.T) { require.Equal(uint64(1), requestedHeight) } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, true)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk, + true, + te.metrics.issued.WithLabelValues(unknownSource), + )) require.Equal(1, te.polls.Len()) @@ -858,7 +888,13 @@ func TestEngineNoQuery(t *testing.T) { BytesV: []byte{1}, } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) } func TestEngineNoRepollQuery(t *testing.T) { @@ -961,7 +997,13 @@ func TestEngineAbandonChit(t *testing.T) { reqID = requestID } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) fakeBlkID := ids.GenerateTestID() vm.GetBlockF = func(_ context.Context, id ids.ID) (snowman.Block, error) { @@ -1016,7 +1058,13 @@ func TestEngineAbandonChitWithUnexpectedPutBlock(t *testing.T) { reqID = requestID } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, true)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk, + true, + te.metrics.issued.WithLabelValues(unknownSource), + )) fakeBlkID := ids.GenerateTestID() vm.GetBlockF = func(_ context.Context, id ids.ID) (snowman.Block, error) { @@ -1099,7 +1147,13 @@ func TestEngineBlockingChitRequest(t *testing.T) { return blockingBlk, nil } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, parentBlk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + parentBlk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) sender.CantSendChits = false @@ -1110,7 +1164,13 @@ func TestEngineBlockingChitRequest(t *testing.T) { sender.CantSendPullQuery = false missingBlk.StatusV = choices.Processing - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, missingBlk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + missingBlk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) require.Empty(te.blocked) } @@ -1163,7 +1223,13 @@ func TestEngineBlockingChitResponse(t *testing.T) { } } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blockingBlk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blockingBlk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) queryRequestID := new(uint32) sender.SendPullQueryF = func(_ context.Context, inVdrs set.Set[ids.NodeID], requestID uint32, blkID ids.ID, requestedHeight uint64) { @@ -1174,7 +1240,13 @@ func TestEngineBlockingChitResponse(t *testing.T) { require.Equal(uint64(1), requestedHeight) } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, issuedBlk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + issuedBlk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) sender.SendPushQueryF = nil sender.CantSendPushQuery = false @@ -1185,7 +1257,13 @@ func TestEngineBlockingChitResponse(t *testing.T) { sender.CantSendPullQuery = false missingBlk.StatusV = choices.Processing - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, missingBlk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + missingBlk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) } func TestEngineRetryFetch(t *testing.T) { @@ -1281,9 +1359,21 @@ func TestEngineUndeclaredDependencyDeadlock(t *testing.T) { return nil, errUnknownBlock } } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, validBlk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + validBlk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) sender.SendPushQueryF = nil - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, invalidBlk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + invalidBlk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) require.NoError(te.Chits(context.Background(), vdr, *reqID, invalidBlkID, invalidBlkID, invalidBlkID)) require.Equal(choices.Accepted, validBlk.Status()) @@ -1666,7 +1756,13 @@ func TestEngineDoubleChit(t *testing.T) { require.Equal(blk.ID(), blkID) require.Equal(uint64(1), requestedHeight) } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, false)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk, + false, + te.metrics.issued.WithLabelValues(unknownSource), + )) vm.GetBlockF = func(_ context.Context, id ids.ID) (snowman.Block, error) { switch id { @@ -2785,7 +2881,13 @@ func TestEngineApplyAcceptedFrontierInQueryFailed(t *testing.T) { require.Equal(uint64(1), requestedHeight) } - require.NoError(te.issue(context.Background(), te.Ctx.NodeID, blk, true)) + require.NoError(te.issue( + context.Background(), + te.Ctx.NodeID, + blk, + true, + te.metrics.issued.WithLabelValues(unknownSource), + )) vm.GetBlockF = func(_ context.Context, id ids.ID) (snowman.Block, error) { switch id { From 1dddf3021a0b42a7d18bc83e2b9204778b9d7380 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 29 Nov 2023 07:16:27 -0800 Subject: [PATCH 082/267] Rename `D` to `Durango` (#2389) --- node/node.go | 2 +- version/constants.go | 6 +++--- vms/platformvm/config/config.go | 9 ++++----- vms/platformvm/txs/executor/staker_tx_verification.go | 6 +++--- vms/platformvm/txs/executor/standard_tx_executor.go | 4 ++-- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/node/node.go b/node/node.go index 06544e8f9e6b..7867625fc982 100644 --- a/node/node.go +++ b/node/node.go @@ -1084,7 +1084,7 @@ func (n *Node) initVMs() error { ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), BanffTime: version.GetBanffTime(n.Config.NetworkID), CortinaTime: version.GetCortinaTime(n.Config.NetworkID), - DTime: version.GetDTime(n.Config.NetworkID), + DurangoTime: version.GetDurangoTime(n.Config.NetworkID), UseCurrentHeight: n.Config.UseCurrentHeight, }, }), diff --git a/version/constants.go b/version/constants.go index 5d57933e424b..a9bc3d2a6f91 100644 --- a/version/constants.go +++ b/version/constants.go @@ -99,7 +99,7 @@ var ( CortinaXChainStopVertexID map[uint32]ids.ID // TODO: update this before release - DTimes = map[uint32]time.Time{ + DurangoTimes = map[uint32]time.Time{ constants.MainnetID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), constants.FujiID: time.Date(10000, time.December, 1, 0, 0, 0, 0, time.UTC), } @@ -191,8 +191,8 @@ func GetCortinaTime(networkID uint32) time.Time { return DefaultUpgradeTime } -func GetDTime(networkID uint32) time.Time { - if upgradeTime, exists := DTimes[networkID]; exists { +func GetDurangoTime(networkID uint32) time.Time { + if upgradeTime, exists := DurangoTimes[networkID]; exists { return upgradeTime } return DefaultUpgradeTime diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index 05068e46a69d..f9504708f78a 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -104,8 +104,8 @@ type Config struct { // Time of the Cortina network upgrade CortinaTime time.Time - // Time of the D network upgrade - DTime time.Time + // Time of the Durango network upgrade + DurangoTime time.Time // UseCurrentHeight forces [GetMinimumHeight] to return the current height // of the P-Chain instead of the oldest block in the [recentlyAccepted] @@ -133,9 +133,8 @@ func (c *Config) IsCortinaActivated(timestamp time.Time) bool { return !timestamp.Before(c.CortinaTime) } -// TODO: Rename -func (c *Config) IsDActivated(timestamp time.Time) bool { - return !timestamp.Before(c.DTime) +func (c *Config) IsDurangoActivated(timestamp time.Time) bool { + return !timestamp.Before(c.DurangoTime) } func (c *Config) GetCreateBlockchainTxFee(timestamp time.Time) uint64 { diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 9ec4880e4a44..7fae0e78a85b 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -37,7 +37,7 @@ var ( ErrDuplicateValidator = errors.New("duplicate validator") ErrDelegateToPermissionedValidator = errors.New("delegation to permissioned validator") ErrWrongStakedAssetID = errors.New("incorrect staked assetID") - ErrDUpgradeNotActive = errors.New("attempting to use a D-upgrade feature prior to activation") + ErrDurangoUpgradeNotActive = errors.New("attempting to use a Durango-upgrade feature prior to activation") ) // verifySubnetValidatorPrimaryNetworkRequirements verifies the primary @@ -727,8 +727,8 @@ func verifyTransferSubnetOwnershipTx( sTx *txs.Tx, tx *txs.TransferSubnetOwnershipTx, ) error { - if !backend.Config.IsDActivated(chainState.GetTimestamp()) { - return ErrDUpgradeNotActive + if !backend.Config.IsDurangoActivated(chainState.GetTimestamp()) { + return ErrDurangoUpgradeNotActive } // Verify the tx is well-formed diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 22bab59afd3b..63069cb5d5d5 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -516,8 +516,8 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn } func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { - if !e.Backend.Config.IsDActivated(e.State.GetTimestamp()) { - return ErrDUpgradeNotActive + if !e.Backend.Config.IsDurangoActivated(e.State.GetTimestamp()) { + return ErrDurangoUpgradeNotActive } // Verify the tx is well-formed From 56c2ad9a86d8d55feeb2e97210bf2ddc603052d9 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 29 Nov 2023 14:35:33 -0500 Subject: [PATCH 083/267] Replace periodic push accepted gossip with pull preference gossip for block discovery (#2367) --- chains/manager.go | 8 +-- config/config.go | 17 +++-- config/flags.go | 2 +- config/keys.go | 4 +- node/config.go | 4 +- node/node.go | 2 +- node/overridden_manager.go | 4 ++ snow/engine/snowman/transitive.go | 97 ++++++++++++++++++++------ snow/engine/snowman/transitive_test.go | 12 ++-- snow/validators/manager.go | 19 +++++ snow/validators/set.go | 23 ++++++ utils/constants/networking.go | 4 +- 12 files changed, 150 insertions(+), 46 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index b4f28b1290be..a1158e67716c 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -205,8 +205,8 @@ type ManagerConfig struct { MeterVMEnabled bool // Should each VM be wrapped with a MeterVM Metrics metrics.MultiGatherer - AcceptedFrontierGossipFrequency time.Duration - ConsensusAppConcurrency int + FrontierPollFrequency time.Duration + ConsensusAppConcurrency int // Max Time to spend fetching a container and its // ancestors when responding to a GetAncestors @@ -824,7 +824,7 @@ func (m *manager) createAvalancheChain( ctx, vdrs, msgChan, - m.AcceptedFrontierGossipFrequency, + m.FrontierPollFrequency, m.ConsensusAppConcurrency, m.ResourceTracker, validators.UnhandledSubnetConnector, // avalanche chains don't use subnet connector @@ -1166,7 +1166,7 @@ func (m *manager) createSnowmanChain( ctx, vdrs, msgChan, - m.AcceptedFrontierGossipFrequency, + m.FrontierPollFrequency, m.ConsensusAppConcurrency, m.ResourceTracker, subnetConnector, diff --git a/config/config.go b/config/config.go index db080ec2514a..d894e832d889 100644 --- a/config/config.go +++ b/config/config.go @@ -60,8 +60,9 @@ const ( subnetConfigFileExt = ".json" ipResolutionTimeout = 30 * time.Second - ipcDeprecationMsg = "IPC API is deprecated" - keystoreDeprecationMsg = "keystore API is deprecated" + ipcDeprecationMsg = "IPC API is deprecated" + keystoreDeprecationMsg = "keystore API is deprecated" + acceptedFrontierGossipDeprecationMsg = "push-based accepted frontier gossip is deprecated" ) var ( @@ -72,6 +73,12 @@ var ( IpcsChainIDsKey: ipcDeprecationMsg, IpcsPathKey: ipcDeprecationMsg, KeystoreAPIEnabledKey: keystoreDeprecationMsg, + ConsensusGossipAcceptedFrontierValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, + ConsensusGossipAcceptedFrontierNonValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, + ConsensusGossipAcceptedFrontierPeerSizeKey: acceptedFrontierGossipDeprecationMsg, + ConsensusGossipOnAcceptValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, + ConsensusGossipOnAcceptNonValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, + ConsensusGossipOnAcceptPeerSizeKey: acceptedFrontierGossipDeprecationMsg, } errSybilProtectionDisabledStakerWeights = errors.New("sybil protection disabled weights must be positive") @@ -1320,9 +1327,9 @@ func GetNodeConfig(v *viper.Viper) (node.Config, error) { } // Gossiping - nodeConfig.AcceptedFrontierGossipFrequency = v.GetDuration(ConsensusAcceptedFrontierGossipFrequencyKey) - if nodeConfig.AcceptedFrontierGossipFrequency < 0 { - return node.Config{}, fmt.Errorf("%s must be >= 0", ConsensusAcceptedFrontierGossipFrequencyKey) + nodeConfig.FrontierPollFrequency = v.GetDuration(ConsensusFrontierPollFrequencyKey) + if nodeConfig.FrontierPollFrequency < 0 { + return node.Config{}, fmt.Errorf("%s must be >= 0", ConsensusFrontierPollFrequencyKey) } // App handling diff --git a/config/flags.go b/config/flags.go index 20f42381320f..6e381e1c6a85 100644 --- a/config/flags.go +++ b/config/flags.go @@ -177,9 +177,9 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.Duration(BenchlistMinFailingDurationKey, constants.DefaultBenchlistMinFailingDuration, "Minimum amount of time messages to a peer must be failing before the peer is benched") // Router - fs.Duration(ConsensusAcceptedFrontierGossipFrequencyKey, constants.DefaultAcceptedFrontierGossipFrequency, "Frequency of gossiping accepted frontiers") fs.Uint(ConsensusAppConcurrencyKey, constants.DefaultConsensusAppConcurrency, "Maximum number of goroutines to use when handling App messages on a chain") fs.Duration(ConsensusShutdownTimeoutKey, constants.DefaultConsensusShutdownTimeout, "Timeout before killing an unresponsive chain") + fs.Duration(ConsensusFrontierPollFrequencyKey, constants.DefaultFrontierPollFrequency, "Frequency of polling for new consensus frontiers") fs.Uint(ConsensusGossipAcceptedFrontierValidatorSizeKey, constants.DefaultConsensusGossipAcceptedFrontierValidatorSize, "Number of validators to gossip to when gossiping accepted frontier") fs.Uint(ConsensusGossipAcceptedFrontierNonValidatorSizeKey, constants.DefaultConsensusGossipAcceptedFrontierNonValidatorSize, "Number of non-validators to gossip to when gossiping accepted frontier") fs.Uint(ConsensusGossipAcceptedFrontierPeerSizeKey, constants.DefaultConsensusGossipAcceptedFrontierPeerSize, "Number of peers to gossip to when gossiping accepted frontier") diff --git a/config/keys.go b/config/keys.go index 1fe19cd2424a..c627abfc1b57 100644 --- a/config/keys.go +++ b/config/keys.go @@ -143,8 +143,9 @@ const ( IpcsChainIDsKey = "ipcs-chain-ids" IpcsPathKey = "ipcs-path" MeterVMsEnabledKey = "meter-vms-enabled" - ConsensusAcceptedFrontierGossipFrequencyKey = "consensus-accepted-frontier-gossip-frequency" ConsensusAppConcurrencyKey = "consensus-app-concurrency" + ConsensusShutdownTimeoutKey = "consensus-shutdown-timeout" + ConsensusFrontierPollFrequencyKey = "consensus-frontier-poll-frequency" ConsensusGossipAcceptedFrontierValidatorSizeKey = "consensus-accepted-frontier-gossip-validator-size" ConsensusGossipAcceptedFrontierNonValidatorSizeKey = "consensus-accepted-frontier-gossip-non-validator-size" ConsensusGossipAcceptedFrontierPeerSizeKey = "consensus-accepted-frontier-gossip-peer-size" @@ -154,7 +155,6 @@ const ( AppGossipValidatorSizeKey = "consensus-app-gossip-validator-size" AppGossipNonValidatorSizeKey = "consensus-app-gossip-non-validator-size" AppGossipPeerSizeKey = "consensus-app-gossip-peer-size" - ConsensusShutdownTimeoutKey = "consensus-shutdown-timeout" ProposerVMUseCurrentHeightKey = "proposervm-use-current-height" FdLimitKey = "fd-limit" IndexEnabledKey = "index-enabled" diff --git a/node/config.go b/node/config.go index 87783bd9935b..5839da75960a 100644 --- a/node/config.go +++ b/node/config.go @@ -181,8 +181,8 @@ type Config struct { ConsensusRouter router.Router `json:"-"` RouterHealthConfig router.HealthConfig `json:"routerHealthConfig"` ConsensusShutdownTimeout time.Duration `json:"consensusShutdownTimeout"` - // Gossip a container in the accepted frontier every [AcceptedFrontierGossipFrequency] - AcceptedFrontierGossipFrequency time.Duration `json:"consensusGossipFreq"` + // Poll for new frontiers every [FrontierPollFrequency] + FrontierPollFrequency time.Duration `json:"consensusGossipFreq"` // ConsensusAppConcurrency defines the maximum number of goroutines to // handle App messages per chain. ConsensusAppConcurrency int `json:"consensusAppConcurrency"` diff --git a/node/node.go b/node/node.go index 7867625fc982..40eb8dc16bef 100644 --- a/node/node.go +++ b/node/node.go @@ -1014,7 +1014,7 @@ func (n *Node) initChainManager(avaxAssetID ids.ID) error { Metrics: n.MetricsGatherer, SubnetConfigs: n.Config.SubnetConfigs, ChainConfigs: n.Config.ChainConfigs, - AcceptedFrontierGossipFrequency: n.Config.AcceptedFrontierGossipFrequency, + FrontierPollFrequency: n.Config.FrontierPollFrequency, ConsensusAppConcurrency: n.Config.ConsensusAppConcurrency, BootstrapMaxTimeGetAncestors: n.Config.BootstrapMaxTimeGetAncestors, BootstrapAncestorsMaxContainersSent: n.Config.BootstrapAncestorsMaxContainersSent, diff --git a/node/overridden_manager.go b/node/overridden_manager.go index 91d8c198a4c3..80295f8636ea 100644 --- a/node/overridden_manager.go +++ b/node/overridden_manager.go @@ -68,6 +68,10 @@ func (o *overriddenManager) Sample(_ ids.ID, size int) ([]ids.NodeID, error) { return o.manager.Sample(o.subnetID, size) } +func (o *overriddenManager) UniformSample(_ ids.ID, size int) ([]ids.NodeID, error) { + return o.manager.UniformSample(o.subnetID, size) +} + func (o *overriddenManager) GetMap(ids.ID) map[ids.NodeID]*validators.GetValidatorOutput { return o.manager.GetMap(o.subnetID) } diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 7675cff931fe..7f06698cbab0 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -34,7 +34,14 @@ import ( "github.com/ava-labs/avalanchego/utils/wrappers" ) -const nonVerifiedCacheSize = 64 * units.MiB +const ( + nonVerifiedCacheSize = 64 * units.MiB + + // putGossipPeriod specifies the number of times Gossip will be called per + // Put gossip. This is done to avoid splitting Gossip into multiple + // functions and to allow more frequent pull gossip than push gossip. + putGossipPeriod = 10 +) var _ Engine = (*Transitive)(nil) @@ -63,6 +70,8 @@ type Transitive struct { requestID uint32 + gossipCounter int + // track outstanding preference requests polls poll.Set @@ -151,6 +160,69 @@ func newTransitive(config Config) (*Transitive, error) { return t, t.metrics.Initialize("", config.Ctx.Registerer) } +func (t *Transitive) Gossip(ctx context.Context) error { + lastAcceptedID, lastAcceptedHeight := t.Consensus.LastAccepted() + if numProcessing := t.Consensus.NumProcessing(); numProcessing == 0 { + t.Ctx.Log.Verbo("sampling from validators", + zap.Stringer("validators", t.Validators), + ) + + // Uniform sampling is used here to reduce bandwidth requirements of + // nodes with a large amount of stake weight. + vdrIDs, err := t.Validators.UniformSample(t.Ctx.SubnetID, 1) + if err != nil { + t.Ctx.Log.Error("skipping block gossip", + zap.String("reason", "no validators"), + zap.Error(err), + ) + return nil + } + + nextHeightToAccept, err := math.Add64(lastAcceptedHeight, 1) + if err != nil { + t.Ctx.Log.Error("skipping block gossip", + zap.String("reason", "block height overflow"), + zap.Stringer("blkID", lastAcceptedID), + zap.Uint64("lastAcceptedHeight", lastAcceptedHeight), + zap.Error(err), + ) + return nil + } + + t.requestID++ + vdrSet := set.Of(vdrIDs...) + preferredID := t.Consensus.Preference() + t.Sender.SendPullQuery(ctx, vdrSet, t.requestID, preferredID, nextHeightToAccept) + } else { + t.Ctx.Log.Debug("skipping block gossip", + zap.String("reason", "blocks currently processing"), + zap.Int("numProcessing", numProcessing), + ) + } + + // TODO: Remove periodic push gossip after v1.11.x is activated + t.gossipCounter++ + t.gossipCounter %= putGossipPeriod + if t.gossipCounter > 0 { + return nil + } + + lastAccepted, err := t.GetBlock(ctx, lastAcceptedID) + if err != nil { + t.Ctx.Log.Warn("dropping gossip request", + zap.String("reason", "block couldn't be loaded"), + zap.Stringer("blkID", lastAcceptedID), + zap.Error(err), + ) + return nil + } + t.Ctx.Log.Verbo("gossiping accepted block to the network", + zap.Stringer("blkID", lastAcceptedID), + ) + t.Sender.SendGossip(ctx, lastAccepted.Bytes()) + return nil +} + func (t *Transitive) Put(ctx context.Context, nodeID ids.NodeID, requestID uint32, blkBytes []byte) error { blk, err := t.VM.ParseBlock(ctx, blkBytes) if err != nil { @@ -383,28 +455,6 @@ func (*Transitive) Timeout(context.Context) error { return nil } -func (t *Transitive) Gossip(ctx context.Context) error { - blkID, err := t.VM.LastAccepted(ctx) - if err != nil { - return err - } - - blk, err := t.GetBlock(ctx, blkID) - if err != nil { - t.Ctx.Log.Warn("dropping gossip request", - zap.String("reason", "block couldn't be loaded"), - zap.Stringer("blkID", blkID), - zap.Error(err), - ) - return nil - } - t.Ctx.Log.Verbo("gossiping accepted block to the network", - zap.Stringer("blkID", blkID), - ) - t.Sender.SendGossip(ctx, blk.Bytes()) - return nil -} - func (*Transitive) Halt(context.Context) {} func (t *Transitive) Shutdown(ctx context.Context) error { @@ -873,6 +923,7 @@ func (t *Transitive) sendQuery( t.Ctx.Log.Error("dropped query for block", zap.String("reason", "insufficient number of validators"), zap.Stringer("blkID", blkID), + zap.Int("size", t.Params.K), ) return } diff --git a/snow/engine/snowman/transitive_test.go b/snow/engine/snowman/transitive_test.go index 69ca9611cc3f..26f6c1127bbf 100644 --- a/snow/engine/snowman/transitive_test.go +++ b/snow/engine/snowman/transitive_test.go @@ -1382,7 +1382,7 @@ func TestEngineUndeclaredDependencyDeadlock(t *testing.T) { func TestEngineGossip(t *testing.T) { require := require.New(t) - _, _, sender, vm, te, gBlk := setupDefaultConfig(t) + nodeID, _, sender, vm, te, gBlk := setupDefaultConfig(t) vm.LastAcceptedF = func(context.Context) (ids.ID, error) { return gBlk.ID(), nil @@ -1392,15 +1392,15 @@ func TestEngineGossip(t *testing.T) { return gBlk, nil } - called := new(bool) - sender.SendGossipF = func(_ context.Context, blkBytes []byte) { - *called = true - require.Equal(gBlk.Bytes(), blkBytes) + var calledSendPullQuery bool + sender.SendPullQueryF = func(_ context.Context, nodeIDs set.Set[ids.NodeID], _ uint32, _ ids.ID, _ uint64) { + calledSendPullQuery = true + require.Equal(set.Of(nodeID), nodeIDs) } require.NoError(te.Gossip(context.Background())) - require.True(*called) + require.True(calledSendPullQuery) } func TestEngineInvalidBlockIgnoredFromUnexpectedPeer(t *testing.T) { diff --git a/snow/validators/manager.go b/snow/validators/manager.go index c42ea779d96b..8cf634f29bd7 100644 --- a/snow/validators/manager.go +++ b/snow/validators/manager.go @@ -85,6 +85,10 @@ type Manager interface { // If sampling the requested size isn't possible, an error will be returned. Sample(subnetID ids.ID, size int) ([]ids.NodeID, error) + // UniformSample returns a collection of validatorIDs in the subnet. + // If sampling the requested size isn't possible, an error will be returned. + UniformSample(subnetID ids.ID, size int) ([]ids.NodeID, error) + // Map of the validators in this subnet GetMap(subnetID ids.ID) map[ids.NodeID]*GetValidatorOutput @@ -253,6 +257,21 @@ func (m *manager) Sample(subnetID ids.ID, size int) ([]ids.NodeID, error) { return set.Sample(size) } +func (m *manager) UniformSample(subnetID ids.ID, size int) ([]ids.NodeID, error) { + if size == 0 { + return nil, nil + } + + m.lock.RLock() + set, exists := m.subnetToVdrs[subnetID] + m.lock.RUnlock() + if !exists { + return nil, ErrMissingValidators + } + + return set.UniformSample(size) +} + func (m *manager) GetMap(subnetID ids.ID) map[ids.NodeID]*GetValidatorOutput { m.lock.RLock() set, exists := m.subnetToVdrs[subnetID] diff --git a/snow/validators/set.go b/snow/validators/set.go index dfa294a70bbe..564cd107153a 100644 --- a/snow/validators/set.go +++ b/snow/validators/set.go @@ -243,6 +243,13 @@ func (s *vdrSet) Sample(size int) ([]ids.NodeID, error) { return s.sample(size) } +func (s *vdrSet) UniformSample(size int) ([]ids.NodeID, error) { + s.lock.RLock() + defer s.lock.RUnlock() + + return s.uniformSample(size) +} + func (s *vdrSet) sample(size int) ([]ids.NodeID, error) { if !s.samplerInitialized { if err := s.sampler.Initialize(s.weights); err != nil { @@ -263,6 +270,22 @@ func (s *vdrSet) sample(size int) ([]ids.NodeID, error) { return list, nil } +func (s *vdrSet) uniformSample(size int) ([]ids.NodeID, error) { + uniform := sampler.NewUniform() + uniform.Initialize(uint64(len(s.vdrSlice))) + + indices, err := uniform.Sample(size) + if err != nil { + return nil, err + } + + list := make([]ids.NodeID, size) + for i, index := range indices { + list[i] = s.vdrSlice[index].NodeID + } + return list, nil +} + func (s *vdrSet) TotalWeight() (uint64, error) { s.lock.RLock() defer s.lock.RUnlock() diff --git a/utils/constants/networking.go b/utils/constants/networking.go index d26f3db1070d..a9417eac37c9 100644 --- a/utils/constants/networking.go +++ b/utils/constants/networking.go @@ -71,12 +71,12 @@ const ( DefaultBenchlistMinFailingDuration = 2*time.Minute + 30*time.Second // Router - DefaultAcceptedFrontierGossipFrequency = 10 * time.Second DefaultConsensusAppConcurrency = 2 DefaultConsensusShutdownTimeout = time.Minute + DefaultFrontierPollFrequency = 100 * time.Millisecond DefaultConsensusGossipAcceptedFrontierValidatorSize = 0 DefaultConsensusGossipAcceptedFrontierNonValidatorSize = 0 - DefaultConsensusGossipAcceptedFrontierPeerSize = 15 + DefaultConsensusGossipAcceptedFrontierPeerSize = 1 DefaultConsensusGossipOnAcceptValidatorSize = 0 DefaultConsensusGossipOnAcceptNonValidatorSize = 0 DefaultConsensusGossipOnAcceptPeerSize = 10 From c5169a333864c4d18bfe70f7075f88059130e069 Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:34:57 -0500 Subject: [PATCH 084/267] MerkleDB Remove ID from Node to reduce size and removal channel creation. (#2324) Co-authored-by: Dan Laine --- x/merkledb/codec.go | 4 +- x/merkledb/codec_test.go | 8 ++-- x/merkledb/db.go | 59 +++++++++++------------ x/merkledb/history_test.go | 4 +- x/merkledb/node.go | 33 +++++++------ x/merkledb/proof.go | 2 +- x/merkledb/trieview.go | 98 +++++++++++++------------------------- 7 files changed, 86 insertions(+), 122 deletions(-) diff --git a/x/merkledb/codec.go b/x/merkledb/codec.go index c9837abb509f..973dd5888ab6 100644 --- a/x/merkledb/codec.go +++ b/x/merkledb/codec.go @@ -160,7 +160,7 @@ func (c *codecImpl) decodeDBNode(b []byte, n *dbNode) error { return io.ErrUnexpectedEOF } - n.children = make(map[byte]child, numChildren) + n.children = make(map[byte]*child, numChildren) var previousChild uint64 for i := uint64(0); i < numChildren; i++ { index, err := c.decodeUint(src) @@ -184,7 +184,7 @@ func (c *codecImpl) decodeDBNode(b []byte, n *dbNode) error { if err != nil { return err } - n.children[byte(index)] = child{ + n.children[byte(index)] = &child{ compressedKey: compressedKey, id: childID, hasValue: hasValue, diff --git a/x/merkledb/codec_test.go b/x/merkledb/codec_test.go index 00e5790b3171..699db9a4bd81 100644 --- a/x/merkledb/codec_test.go +++ b/x/merkledb/codec_test.go @@ -146,7 +146,7 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) { numChildren := r.Intn(int(bf)) // #nosec G404 - children := map[byte]child{} + children := map[byte]*child{} for i := 0; i < numChildren; i++ { var childID ids.ID _, _ = r.Read(childID[:]) // #nosec G404 @@ -154,7 +154,7 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) { childKeyBytes := make([]byte, r.Intn(32)) // #nosec G404 _, _ = r.Read(childKeyBytes) // #nosec G404 - children[byte(i)] = child{ + children[byte(i)] = &child{ compressedKey: ToKey(childKeyBytes), id: childID, } @@ -202,14 +202,14 @@ func FuzzEncodeHashValues(f *testing.F) { for _, bf := range validBranchFactors { // Create a random node r := rand.New(rand.NewSource(int64(randSeed))) // #nosec G404 - children := map[byte]child{} + children := map[byte]*child{} numChildren := r.Intn(int(bf)) // #nosec G404 for i := 0; i < numChildren; i++ { compressedKeyLen := r.Intn(32) // #nosec G404 compressedKeyBytes := make([]byte, compressedKeyLen) _, _ = r.Read(compressedKeyBytes) // #nosec G404 - children[byte(i)] = child{ + children[byte(i)] = &child{ compressedKey: ToKey(compressedKeyBytes), id: ids.GenerateTestID(), hasValue: r.Intn(2) == 1, // #nosec G404 diff --git a/x/merkledb/db.go b/x/merkledb/db.go index b1ee699bab97..c813a9478b1f 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -205,6 +205,7 @@ type merkleDB struct { // It is the node with a nil key and is the ancestor of all nodes in the trie. // If it has a value or has multiple children, it is also the root of the trie. sentinelNode *node + rootID ids.ID // Valid children of this trie. childViews []*trieView @@ -260,14 +261,13 @@ func newDatabase( tokenSize: BranchFactorToTokenSize[config.BranchFactor], } - root, err := trieDB.initializeRootIfNeeded() - if err != nil { + if err := trieDB.initializeRoot(); err != nil { return nil, err } // add current root to history (has no changes) trieDB.history.record(&changeSummary{ - rootID: root, + rootID: trieDB.rootID, values: map[Key]*change[maybe.Maybe[[]byte]]{}, nodes: map[Key]*change[*node]{}, }) @@ -578,13 +578,7 @@ func (db *merkleDB) GetMerkleRoot(ctx context.Context) (ids.ID, error) { // Assumes [db.lock] is read locked. func (db *merkleDB) getMerkleRoot() ids.ID { - if !isSentinelNodeTheRoot(db.sentinelNode) { - // if the sentinel node should be skipped, the trie's root is the nil key node's only child - for _, childEntry := range db.sentinelNode.children { - return childEntry.id - } - } - return db.sentinelNode.id + return db.rootID } // isSentinelNodeTheRoot returns true if the passed in sentinel node has a value and or multiple child nodes @@ -982,6 +976,7 @@ func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *trieView) e // Only modify in-memory state after the commit succeeds // so that we don't need to clean up on error. db.sentinelNode = sentinelChange.after + db.rootID = changes.rootID db.history.record(changes) return nil } @@ -1161,34 +1156,38 @@ func (db *merkleDB) invalidateChildrenExcept(exception *trieView) { } } -func (db *merkleDB) initializeRootIfNeeded() (ids.ID, error) { - // not sure if the sentinel node exists or if it had a value - // check under both prefixes +func (db *merkleDB) initializeRoot() error { + // Not sure if the sentinel node exists or if it had a value, + // so check under both prefixes var err error db.sentinelNode, err = db.intermediateNodeDB.Get(Key{}) + if errors.Is(err, database.ErrNotFound) { + // Didn't find the sentinel in the intermediateNodeDB, check the valueNodeDB db.sentinelNode, err = db.valueNodeDB.Get(Key{}) } - if err == nil { - // sentinel node already exists, so calculate the root ID of the trie - db.sentinelNode.calculateID(db.metrics) - return db.getMerkleRoot(), nil - } - if !errors.Is(err, database.ErrNotFound) { - return ids.Empty, err - } - - // sentinel node doesn't exist; make a new one. - db.sentinelNode = newNode(Key{}) - // update its ID - db.sentinelNode.calculateID(db.metrics) + if err != nil { + if !errors.Is(err, database.ErrNotFound) { + return err + } - if err := db.intermediateNodeDB.Put(Key{}, db.sentinelNode); err != nil { - return ids.Empty, err + // Sentinel node doesn't exist in either database prefix. + // Make a new one and store it in the intermediateNodeDB + db.sentinelNode = newNode(Key{}) + if err := db.intermediateNodeDB.Put(Key{}, db.sentinelNode); err != nil { + return err + } } - return db.sentinelNode.id, nil + db.rootID = db.sentinelNode.calculateID(db.metrics) + if !isSentinelNodeTheRoot(db.sentinelNode) { + // If the sentinel node is not the root, the trie's root is the sentinel node's only child + for _, childEntry := range db.sentinelNode.children { + db.rootID = childEntry.id + } + } + return nil } // Returns a view of the trie as it was when it had root [rootID] for keys within range [start, end]. @@ -1289,7 +1288,7 @@ func (db *merkleDB) Clear() error { // Clear root db.sentinelNode = newNode(Key{}) - db.sentinelNode.calculateID(db.metrics) + db.rootID = db.sentinelNode.calculateID(db.metrics) // Clear history db.history = newTrieHistory(db.history.maxHistoryLen) diff --git a/x/merkledb/history_test.go b/x/merkledb/history_test.go index 2ee1e5f4b31b..d2945c9c5018 100644 --- a/x/merkledb/history_test.go +++ b/x/merkledb/history_test.go @@ -660,8 +660,8 @@ func TestHistoryGetChangesToRoot(t *testing.T) { rootID: ids.GenerateTestID(), nodes: map[Key]*change[*node]{ ToKey([]byte{byte(i)}): { - before: &node{id: ids.GenerateTestID()}, - after: &node{id: ids.GenerateTestID()}, + before: &node{}, + after: &node{}, }, }, values: map[Key]*change[maybe.Maybe[[]byte]]{ diff --git a/x/merkledb/node.go b/x/merkledb/node.go index 3fd38021a0c8..9a63ef82c4a7 100644 --- a/x/merkledb/node.go +++ b/x/merkledb/node.go @@ -4,7 +4,6 @@ package merkledb import ( - "golang.org/x/exp/maps" "golang.org/x/exp/slices" "github.com/ava-labs/avalanchego/ids" @@ -17,7 +16,7 @@ const HashLength = 32 // Representation of a node stored in the database. type dbNode struct { value maybe.Maybe[[]byte] - children map[byte]child + children map[byte]*child } type child struct { @@ -29,7 +28,6 @@ type child struct { // node holds additional information on top of the dbNode that makes calculations easier to do type node struct { dbNode - id ids.ID key Key nodeBytes []byte valueDigest maybe.Maybe[[]byte] @@ -39,7 +37,7 @@ type node struct { func newNode(key Key) *node { return &node{ dbNode: dbNode{ - children: make(map[byte]child, 2), + children: make(map[byte]*child, 2), }, key: key, } @@ -78,19 +76,14 @@ func (n *node) bytes() []byte { // clear the cached values that will need to be recalculated whenever the node changes // for example, node ID and byte representation func (n *node) onNodeChanged() { - n.id = ids.Empty n.nodeBytes = nil } // Returns and caches the ID of this node. -func (n *node) calculateID(metrics merkleMetrics) { - if n.id != ids.Empty { - return - } - +func (n *node) calculateID(metrics merkleMetrics) ids.ID { metrics.HashCalculated() bytes := codec.encodeHashValues(n) - n.id = hashing.ComputeHash256Array(bytes) + return hashing.ComputeHash256Array(bytes) } // Set [n]'s value to [val]. @@ -114,16 +107,15 @@ func (n *node) setValueDigest() { func (n *node) addChild(childNode *node, tokenSize int) { n.setChildEntry( childNode.key.Token(n.key.length, tokenSize), - child{ + &child{ compressedKey: childNode.key.Skip(n.key.length + tokenSize), - id: childNode.id, hasValue: childNode.hasValue(), }, ) } // Adds a child to [n] without a reference to the child node. -func (n *node) setChildEntry(index byte, childEntry child) { +func (n *node) setChildEntry(index byte, childEntry *child) { n.onNodeChanged() n.children[index] = childEntry } @@ -139,16 +131,23 @@ func (n *node) removeChild(child *node, tokenSize int) { // if this ever changes, value will need to be copied as well // it is safe to clone all fields because they are only written/read while one or both of the db locks are held func (n *node) clone() *node { - return &node{ - id: n.id, + result := &node{ key: n.key, dbNode: dbNode{ value: n.value, - children: maps.Clone(n.children), + children: make(map[byte]*child, len(n.children)), }, valueDigest: n.valueDigest, nodeBytes: n.nodeBytes, } + for key, existing := range n.children { + result.children[key] = &child{ + compressedKey: existing.compressedKey, + id: existing.id, + hasValue: existing.hasValue, + } + } + return result } // Returns the ProofNode representation of this node. diff --git a/x/merkledb/proof.go b/x/merkledb/proof.go index e348a83f0f13..39ceff3d3157 100644 --- a/x/merkledb/proof.go +++ b/x/merkledb/proof.go @@ -847,7 +847,7 @@ func addPathInfo( // We only need the IDs to be correct so that the calculated hash is correct. n.setChildEntry( index, - child{ + &child{ id: childID, compressedKey: compressedKey, }) diff --git a/x/merkledb/trieview.go b/x/merkledb/trieview.go index 622bfcb11207..730d4b0187d0 100644 --- a/x/merkledb/trieview.go +++ b/x/merkledb/trieview.go @@ -251,9 +251,15 @@ func (t *trieView) calculateNodeIDs(ctx context.Context) error { } _ = t.db.calculateNodeIDsSema.Acquire(context.Background(), 1) - t.calculateNodeIDsHelper(t.sentinelNode) + t.changes.rootID = t.calculateNodeIDsHelper(t.sentinelNode) t.db.calculateNodeIDsSema.Release(1) - t.changes.rootID = t.getMerkleRoot() + + // If the sentinel node is not the root, the trie's root is the sentinel node's only child + if !isSentinelNodeTheRoot(t.sentinelNode) { + for _, childEntry := range t.sentinelNode.children { + t.changes.rootID = childEntry.id + } + } // ensure no ancestor changes occurred during execution if t.isInvalid() { @@ -266,58 +272,40 @@ func (t *trieView) calculateNodeIDs(ctx context.Context) error { // Calculates the ID of all descendants of [n] which need to be recalculated, // and then calculates the ID of [n] itself. -func (t *trieView) calculateNodeIDsHelper(n *node) { - var ( - // We use [wg] to wait until all descendants of [n] have been updated. - wg sync.WaitGroup - updatedChildren = make(chan *node, len(n.children)) - ) +func (t *trieView) calculateNodeIDsHelper(n *node) ids.ID { + // We use [wg] to wait until all descendants of [n] have been updated. + var wg sync.WaitGroup - for childIndex, child := range n.children { - childKey := n.key.Extend(ToToken(childIndex, t.tokenSize), child.compressedKey) + for childIndex := range n.children { + childEntry := n.children[childIndex] + childKey := n.key.Extend(ToToken(childIndex, t.tokenSize), childEntry.compressedKey) childNodeChange, ok := t.changes.nodes[childKey] if !ok { // This child wasn't changed. continue } - - wg.Add(1) - calculateChildID := func() { - defer wg.Done() - - t.calculateNodeIDsHelper(childNodeChange.after) - - // Note that this will never block - updatedChildren <- childNodeChange.after - } + n.onNodeChanged() + childEntry.hasValue = childNodeChange.after.hasValue() // Try updating the child and its descendants in a goroutine. if ok := t.db.calculateNodeIDsSema.TryAcquire(1); ok { + wg.Add(1) go func() { - calculateChildID() + childEntry.id = t.calculateNodeIDsHelper(childNodeChange.after) t.db.calculateNodeIDsSema.Release(1) + wg.Done() }() } else { // We're at the goroutine limit; do the work in this goroutine. - calculateChildID() + childEntry.id = t.calculateNodeIDsHelper(childNodeChange.after) } } // Wait until all descendants of [n] have been updated. wg.Wait() - close(updatedChildren) - - for updatedChild := range updatedChildren { - index := updatedChild.key.Token(n.key.length, t.tokenSize) - n.setChildEntry(index, child{ - compressedKey: n.children[index].compressedKey, - id: updatedChild.id, - hasValue: updatedChild.hasValue(), - }) - } // The IDs [n]'s descendants are up to date so we can calculate [n]'s ID. - n.calculateID(t.db.metrics) + return n.calculateID(t.db.metrics) } // GetProof returns a proof that [bytesPath] is in or not in trie [t]. @@ -381,8 +369,7 @@ func (t *trieView) getProof(ctx context.Context, key []byte) (*Proof, error) { return proof, nil } - childNode, err := t.getNodeWithID( - child.id, + childNode, err := t.getNode( closestNode.key.Extend(ToToken(nextIndex, t.tokenSize), child.compressedKey), child.hasValue, ) @@ -568,17 +555,7 @@ func (t *trieView) GetMerkleRoot(ctx context.Context) (ids.ID, error) { if err := t.calculateNodeIDs(ctx); err != nil { return ids.Empty, err } - return t.getMerkleRoot(), nil -} - -func (t *trieView) getMerkleRoot() ids.ID { - if !isSentinelNodeTheRoot(t.sentinelNode) { - for _, childEntry := range t.sentinelNode.children { - return childEntry.id - } - } - - return t.sentinelNode.id + return t.changes.rootID, nil } func (t *trieView) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []error) { @@ -650,7 +627,7 @@ func (t *trieView) remove(key Key) error { } // confirm a node exists with a value - keyNode, err := t.getNodeWithID(ids.Empty, key, true) + keyNode, err := t.getNode(key, true) if err != nil { if errors.Is(err, database.ErrNotFound) { // key didn't exist @@ -719,7 +696,7 @@ func (t *trieView) compressNodePath(parent, node *node) error { } var ( - childEntry child + childEntry *child childKey Key ) // There is only one child, but we don't know the index. @@ -733,7 +710,7 @@ func (t *trieView) compressNodePath(parent, node *node) error { // [node] is the first node with multiple children. // combine it with the [node] passed in. parent.setChildEntry(childKey.Token(parent.key.length, t.tokenSize), - child{ + &child{ compressedKey: childKey.Skip(parent.key.length + t.tokenSize), id: childEntry.id, hasValue: childEntry.hasValue, @@ -765,7 +742,7 @@ func (t *trieView) visitPathToKey(key Key, visitNode func(*node) error) error { return nil } // grab the next node along the path - currentNode, err = t.getNodeWithID(nextChildEntry.id, key.Take(currentNode.key.length+t.tokenSize+nextChildEntry.compressedKey.length), nextChildEntry.hasValue) + currentNode, err = t.getNode(key.Take(currentNode.key.length+t.tokenSize+nextChildEntry.compressedKey.length), nextChildEntry.hasValue) if err != nil { return err } @@ -784,7 +761,7 @@ func (t *trieView) getEditableNode(key Key, hadValue bool) (*node, error) { } // grab the node in question - n, err := t.getNodeWithID(ids.Empty, key, hadValue) + n, err := t.getNode(key, hadValue) if err != nil { return nil, err } @@ -880,7 +857,7 @@ func (t *trieView) insert( // add the existing child onto the branch node branchNode.setChildEntry( existingChildEntry.compressedKey.Token(commonPrefixLength, t.tokenSize), - child{ + &child{ compressedKey: existingChildEntry.compressedKey.Skip(commonPrefixLength + t.tokenSize), id: existingChildEntry.id, hasValue: existingChildEntry.hasValue, @@ -924,8 +901,7 @@ func (t *trieView) getRoot() (*node, error) { if !isSentinelNodeTheRoot(t.sentinelNode) { // sentinelNode has one child, which is the root for index, childEntry := range t.sentinelNode.children { - return t.getNodeWithID( - childEntry.id, + return t.getNode( t.sentinelNode.key.Extend(ToToken(index, t.tokenSize), childEntry.compressedKey), childEntry.hasValue) } @@ -1004,7 +980,7 @@ func (t *trieView) recordValueChange(key Key, value maybe.Maybe[[]byte]) error { // sets the node's ID to [id]. // If the node is loaded from the baseDB, [hasValue] determines which database the node is stored in. // Returns database.ErrNotFound if the node doesn't exist. -func (t *trieView) getNodeWithID(id ids.ID, key Key, hasValue bool) (*node, error) { +func (t *trieView) getNode(key Key, hasValue bool) (*node, error) { // check for the key within the changed nodes if nodeChange, isChanged := t.changes.nodes[key]; isChanged { t.db.metrics.ViewNodeCacheHit() @@ -1015,17 +991,7 @@ func (t *trieView) getNodeWithID(id ids.ID, key Key, hasValue bool) (*node, erro } // get the node from the parent trie and store a local copy - parentTrieNode, err := t.getParentTrie().getEditableNode(key, hasValue) - if err != nil { - return nil, err - } - - // only need to initialize the id if it's from the parent trie. - // nodes in the current view change list have already been initialized. - if id != ids.Empty { - parentTrieNode.id = id - } - return parentTrieNode, nil + return t.getParentTrie().getEditableNode(key, hasValue) } // Get the parent trie of the view From 0da5bccfb04f98e1e1ac5079acea84056457fcbc Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 29 Nov 2023 16:32:16 -0500 Subject: [PATCH 085/267] Remove method `CappedList` from `set.Set` (#2395) --- .../avalanche/bootstrap/bootstrapper.go | 3 +- utils/set/set.go | 21 -------------- utils/set/set_test.go | 29 ------------------- 3 files changed, 1 insertion(+), 52 deletions(-) diff --git a/snow/engine/avalanche/bootstrap/bootstrapper.go b/snow/engine/avalanche/bootstrap/bootstrapper.go index 967d65711abc..162937dc7860 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper.go @@ -401,8 +401,7 @@ func (b *bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { func (b *bootstrapper) fetch(ctx context.Context, vtxIDs ...ids.ID) error { b.needToFetch.Add(vtxIDs...) for b.needToFetch.Len() > 0 && b.outstandingRequests.Len() < maxOutstandingGetAncestorsRequests { - vtxID := b.needToFetch.CappedList(1)[0] - b.needToFetch.Remove(vtxID) + vtxID, _ := b.needToFetch.Pop() // Length checked in predicate above // Make sure we haven't already requested this vertex if b.outstandingRequests.HasValue(vtxID) { diff --git a/utils/set/set.go b/utils/set/set.go index 29eb8fe11bd4..7ab330fcc066 100644 --- a/utils/set/set.go +++ b/utils/set/set.go @@ -118,27 +118,6 @@ func (s Set[T]) List() []T { return maps.Keys(s) } -// CappedList returns a list of length at most [size]. -// Size should be >= 0. If size < 0, returns nil. -func (s Set[T]) CappedList(size int) []T { - if size < 0 { - return nil - } - if l := s.Len(); l < size { - size = l - } - i := 0 - elts := make([]T, size) - for elt := range s { - if i >= size { - break - } - elts[i] = elt - i++ - } - return elts -} - // Equals returns true if the sets contain the same elements func (s Set[T]) Equals(other Set[T]) bool { return maps.Equal(s, other) diff --git a/utils/set/set_test.go b/utils/set/set_test.go index bcba36944adf..4e0a3d1fa3ed 100644 --- a/utils/set/set_test.go +++ b/utils/set/set_test.go @@ -87,35 +87,6 @@ func TestOf(t *testing.T) { } } -func TestSetCappedList(t *testing.T) { - require := require.New(t) - s := Set[int]{} - - id := 0 - - require.Empty(s.CappedList(0)) - - s.Add(id) - - require.Empty(s.CappedList(0)) - require.Len(s.CappedList(1), 1) - require.Equal(s.CappedList(1)[0], id) - require.Len(s.CappedList(2), 1) - require.Equal(s.CappedList(2)[0], id) - - id2 := 1 - s.Add(id2) - - require.Empty(s.CappedList(0)) - require.Len(s.CappedList(1), 1) - require.Len(s.CappedList(2), 2) - require.Len(s.CappedList(3), 2) - gotList := s.CappedList(2) - require.Contains(gotList, id) - require.Contains(gotList, id2) - require.NotEqual(gotList[0], gotList[1]) -} - func TestSetClear(t *testing.T) { require := require.New(t) From 96d451d2e2986fedc45d3c60834d2aae9c404643 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 29 Nov 2023 18:15:47 -0500 Subject: [PATCH 086/267] Periodically PullGossip only from connected validators (#2399) --- chains/manager.go | 32 ++++++++++++++------------ node/overridden_manager.go | 4 ---- snow/engine/common/tracker/peers.go | 14 +++++++++++ snow/engine/snowman/config.go | 16 +++++++------ snow/engine/snowman/config_test.go | 10 ++++---- snow/engine/snowman/transitive.go | 17 ++++++++------ snow/engine/snowman/transitive_test.go | 4 ++++ snow/validators/manager.go | 19 --------------- snow/validators/set.go | 23 ------------------ utils/set/set.go | 2 +- 10 files changed, 61 insertions(+), 80 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index a1158e67716c..e764a5dfb3ce 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -859,13 +859,14 @@ func (m *manager) createAvalancheChain( // Create engine, bootstrapper and state-syncer in this order, // to make sure start callbacks are duly initialized snowmanEngineConfig := smeng.Config{ - Ctx: ctx, - AllGetsServer: snowGetHandler, - VM: vmWrappingProposerVM, - Sender: snowmanMessageSender, - Validators: vdrs, - Params: consensusParams, - Consensus: snowmanConsensus, + Ctx: ctx, + AllGetsServer: snowGetHandler, + VM: vmWrappingProposerVM, + Sender: snowmanMessageSender, + Validators: vdrs, + ConnectedValidators: connectedValidators, + Params: consensusParams, + Consensus: snowmanConsensus, } snowmanEngine, err := smeng.New(snowmanEngineConfig) if err != nil { @@ -1201,14 +1202,15 @@ func (m *manager) createSnowmanChain( // Create engine, bootstrapper and state-syncer in this order, // to make sure start callbacks are duly initialized engineConfig := smeng.Config{ - Ctx: ctx, - AllGetsServer: snowGetHandler, - VM: vm, - Sender: messageSender, - Validators: vdrs, - Params: consensusParams, - Consensus: consensus, - PartialSync: m.PartialSyncPrimaryNetwork && ctx.ChainID == constants.PlatformChainID, + Ctx: ctx, + AllGetsServer: snowGetHandler, + VM: vm, + Sender: messageSender, + Validators: vdrs, + ConnectedValidators: connectedValidators, + Params: consensusParams, + Consensus: consensus, + PartialSync: m.PartialSyncPrimaryNetwork && ctx.ChainID == constants.PlatformChainID, } engine, err := smeng.New(engineConfig) if err != nil { diff --git a/node/overridden_manager.go b/node/overridden_manager.go index 80295f8636ea..91d8c198a4c3 100644 --- a/node/overridden_manager.go +++ b/node/overridden_manager.go @@ -68,10 +68,6 @@ func (o *overriddenManager) Sample(_ ids.ID, size int) ([]ids.NodeID, error) { return o.manager.Sample(o.subnetID, size) } -func (o *overriddenManager) UniformSample(_ ids.ID, size int) ([]ids.NodeID, error) { - return o.manager.UniformSample(o.subnetID, size) -} - func (o *overriddenManager) GetMap(ids.ID) map[ids.NodeID]*validators.GetValidatorOutput { return o.manager.GetMap(o.subnetID) } diff --git a/snow/engine/common/tracker/peers.go b/snow/engine/common/tracker/peers.go index ad9592209a5a..94d653a53b1f 100644 --- a/snow/engine/common/tracker/peers.go +++ b/snow/engine/common/tracker/peers.go @@ -33,6 +33,9 @@ type Peers interface { ConnectedPercent() float64 // TotalWeight returns the total validator weight TotalWeight() uint64 + // SampleValidator returns a randomly selected connected validator. If there + // are no currently connected validators then it will return false. + SampleValidator() (ids.NodeID, bool) // PreferredPeers returns the currently connected validators. If there are // no currently connected validators then it will return the currently // connected peers. @@ -108,6 +111,13 @@ func (p *lockedPeers) TotalWeight() uint64 { return p.peers.TotalWeight() } +func (p *lockedPeers) SampleValidator() (ids.NodeID, bool) { + p.lock.RLock() + defer p.lock.RUnlock() + + return p.peers.SampleValidator() +} + func (p *lockedPeers) PreferredPeers() set.Set[ids.NodeID] { p.lock.RLock() defer p.lock.RUnlock() @@ -263,6 +273,10 @@ func (p *peerData) TotalWeight() uint64 { return p.totalWeight } +func (p *peerData) SampleValidator() (ids.NodeID, bool) { + return p.connectedValidators.Peek() +} + func (p *peerData) PreferredPeers() set.Set[ids.NodeID] { if p.connectedValidators.Len() == 0 { connectedPeers := set.NewSet[ids.NodeID](p.connectedPeers.Len()) diff --git a/snow/engine/snowman/config.go b/snow/engine/snowman/config.go index ed63af2f4936..65a24a2ea816 100644 --- a/snow/engine/snowman/config.go +++ b/snow/engine/snowman/config.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/validators" ) @@ -16,11 +17,12 @@ import ( type Config struct { common.AllGetsServer - Ctx *snow.ConsensusContext - VM block.ChainVM - Sender common.Sender - Validators validators.Manager - Params snowball.Parameters - Consensus snowman.Consensus - PartialSync bool + Ctx *snow.ConsensusContext + VM block.ChainVM + Sender common.Sender + Validators validators.Manager + ConnectedValidators tracker.Peers + Params snowball.Parameters + Consensus snowman.Consensus + PartialSync bool } diff --git a/snow/engine/snowman/config_test.go b/snow/engine/snowman/config_test.go index 23fc0fc39fd4..9611990d9d95 100644 --- a/snow/engine/snowman/config_test.go +++ b/snow/engine/snowman/config_test.go @@ -8,16 +8,18 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/validators" ) func DefaultConfig() Config { return Config{ - Ctx: snow.DefaultConsensusContextTest(), - VM: &block.TestVM{}, - Sender: &common.SenderTest{}, - Validators: validators.NewManager(), + Ctx: snow.DefaultConsensusContextTest(), + VM: &block.TestVM{}, + Sender: &common.SenderTest{}, + Validators: validators.NewManager(), + ConnectedValidators: tracker.NewPeers(), Params: snowball.Parameters{ K: 1, AlphaPreference: 1, diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 7f06698cbab0..4b43dcda0acb 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -169,11 +169,10 @@ func (t *Transitive) Gossip(ctx context.Context) error { // Uniform sampling is used here to reduce bandwidth requirements of // nodes with a large amount of stake weight. - vdrIDs, err := t.Validators.UniformSample(t.Ctx.SubnetID, 1) - if err != nil { + vdrID, ok := t.ConnectedValidators.SampleValidator() + if !ok { t.Ctx.Log.Error("skipping block gossip", - zap.String("reason", "no validators"), - zap.Error(err), + zap.String("reason", "no connected validators"), ) return nil } @@ -190,9 +189,13 @@ func (t *Transitive) Gossip(ctx context.Context) error { } t.requestID++ - vdrSet := set.Of(vdrIDs...) - preferredID := t.Consensus.Preference() - t.Sender.SendPullQuery(ctx, vdrSet, t.requestID, preferredID, nextHeightToAccept) + t.Sender.SendPullQuery( + ctx, + set.Of(vdrID), + t.requestID, + t.Consensus.Preference(), + nextHeightToAccept, + ) } else { t.Ctx.Log.Debug("skipping block gossip", zap.String("reason", "blocks currently processing"), diff --git a/snow/engine/snowman/transitive_test.go b/snow/engine/snowman/transitive_test.go index 26f6c1127bbf..738f20440c58 100644 --- a/snow/engine/snowman/transitive_test.go +++ b/snow/engine/snowman/transitive_test.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/version" ) var ( @@ -41,6 +42,9 @@ func setup(t *testing.T, engCfg Config) (ids.NodeID, validators.Manager, *common vdr := ids.GenerateTestNodeID() require.NoError(vals.AddStaker(engCfg.Ctx.SubnetID, vdr, nil, ids.Empty, 1)) + require.NoError(engCfg.ConnectedValidators.Connected(context.Background(), vdr, version.CurrentApp)) + + vals.RegisterCallbackListener(engCfg.Ctx.SubnetID, engCfg.ConnectedValidators) sender := &common.SenderTest{T: t} engCfg.Sender = sender diff --git a/snow/validators/manager.go b/snow/validators/manager.go index 8cf634f29bd7..c42ea779d96b 100644 --- a/snow/validators/manager.go +++ b/snow/validators/manager.go @@ -85,10 +85,6 @@ type Manager interface { // If sampling the requested size isn't possible, an error will be returned. Sample(subnetID ids.ID, size int) ([]ids.NodeID, error) - // UniformSample returns a collection of validatorIDs in the subnet. - // If sampling the requested size isn't possible, an error will be returned. - UniformSample(subnetID ids.ID, size int) ([]ids.NodeID, error) - // Map of the validators in this subnet GetMap(subnetID ids.ID) map[ids.NodeID]*GetValidatorOutput @@ -257,21 +253,6 @@ func (m *manager) Sample(subnetID ids.ID, size int) ([]ids.NodeID, error) { return set.Sample(size) } -func (m *manager) UniformSample(subnetID ids.ID, size int) ([]ids.NodeID, error) { - if size == 0 { - return nil, nil - } - - m.lock.RLock() - set, exists := m.subnetToVdrs[subnetID] - m.lock.RUnlock() - if !exists { - return nil, ErrMissingValidators - } - - return set.UniformSample(size) -} - func (m *manager) GetMap(subnetID ids.ID) map[ids.NodeID]*GetValidatorOutput { m.lock.RLock() set, exists := m.subnetToVdrs[subnetID] diff --git a/snow/validators/set.go b/snow/validators/set.go index 564cd107153a..dfa294a70bbe 100644 --- a/snow/validators/set.go +++ b/snow/validators/set.go @@ -243,13 +243,6 @@ func (s *vdrSet) Sample(size int) ([]ids.NodeID, error) { return s.sample(size) } -func (s *vdrSet) UniformSample(size int) ([]ids.NodeID, error) { - s.lock.RLock() - defer s.lock.RUnlock() - - return s.uniformSample(size) -} - func (s *vdrSet) sample(size int) ([]ids.NodeID, error) { if !s.samplerInitialized { if err := s.sampler.Initialize(s.weights); err != nil { @@ -270,22 +263,6 @@ func (s *vdrSet) sample(size int) ([]ids.NodeID, error) { return list, nil } -func (s *vdrSet) uniformSample(size int) ([]ids.NodeID, error) { - uniform := sampler.NewUniform() - uniform.Initialize(uint64(len(s.vdrSlice))) - - indices, err := uniform.Sample(size) - if err != nil { - return nil, err - } - - list := make([]ids.NodeID, size) - for i, index := range indices { - list[i] = s.vdrSlice[index].NodeID - } - return list, nil -} - func (s *vdrSet) TotalWeight() (uint64, error) { s.lock.RLock() defer s.lock.RUnlock() diff --git a/utils/set/set.go b/utils/set/set.go index 7ab330fcc066..fd6525b6b127 100644 --- a/utils/set/set.go +++ b/utils/set/set.go @@ -184,7 +184,7 @@ func (s Set[_]) MarshalJSON() ([]byte, error) { return jsonBuf.Bytes(), errs.Err } -// Returns an element. If the set is empty, returns false +// Returns a random element. If the set is empty, returns false func (s *Set[T]) Peek() (T, bool) { for elt := range *s { return elt, true From 907b34c5aa0cf0037c765183101bfcf0f2850f5b Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 29 Nov 2023 21:32:43 -0500 Subject: [PATCH 087/267] Update bootstrap IPs (#2396) --- genesis/bootstrappers.json | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/genesis/bootstrappers.json b/genesis/bootstrappers.json index 62784fc7b4da..341828bc7c23 100644 --- a/genesis/bootstrappers.json +++ b/genesis/bootstrappers.json @@ -2,99 +2,99 @@ "mainnet": [ { "id": "NodeID-A6onFGyJjA37EZ7kYHANMR1PFRT8NmXrF", - "ip": "54.94.43.49:9651" + "ip": "54.232.137.108:9651" }, { "id": "NodeID-6SwnPJLH8cWfrJ162JjZekbmzaFpjPcf", - "ip": "52.79.47.77:9651" + "ip": "13.124.187.98:9651" }, { "id": "NodeID-GSgaA47umS1px2ohVjodW9621Ks63xDxD", - "ip": "18.229.206.191:9651" + "ip": "54.232.142.167:9651" }, { "id": "NodeID-BQEo5Fy1FRKLbX51ejqDd14cuSXJKArH2", - "ip": "3.34.221.73:9651" + "ip": "3.39.67.183:9651" }, { "id": "NodeID-Drv1Qh7iJvW3zGBBeRnYfCzk56VCRM2GQ", - "ip": "13.244.155.170:9651" + "ip": "13.245.185.253:9651" }, { "id": "NodeID-DAtCoXfLT6Y83dgJ7FmQg8eR53hz37J79", - "ip": "13.244.47.224:9651" + "ip": "13.246.169.11:9651" }, { "id": "NodeID-FGRoKnyYKFWYFMb6Xbocf4hKuyCBENgWM", - "ip": "122.248.200.212:9651" + "ip": "13.251.82.39:9651" }, { "id": "NodeID-Dw7tuwxpAmcpvVGp9JzaHAR3REPoJ8f2R", - "ip": "52.30.9.211:9651" + "ip": "34.250.50.224:9651" }, { "id": "NodeID-4kCLS16Wy73nt1Zm54jFZsL7Msrv3UCeJ", - "ip": "122.248.199.127:9651" + "ip": "18.142.247.237:9651" }, { "id": "NodeID-9T7NXBFpp8LWCyc58YdKNoowDipdVKAWz", - "ip": "18.202.190.40:9651" + "ip": "34.252.106.116:9651" }, { "id": "NodeID-6ghBh6yof5ouMCya2n9fHzhpWouiZFVVj", - "ip": "15.206.182.45:9651" + "ip": "43.205.156.229:9651" }, { "id": "NodeID-HiFv1DpKXkAAfJ1NHWVqQoojjznibZXHP", - "ip": "15.207.11.193:9651" + "ip": "13.233.176.118:9651" }, { "id": "NodeID-Fv3t2shrpkmvLnvNzcv1rqRKbDAYFnUor", - "ip": "44.226.118.72:9651" + "ip": "35.164.160.193:9651" }, { "id": "NodeID-AaxT2P4uuPAHb7vAD8mNvjQ3jgyaV7tu9", - "ip": "54.185.87.50:9651" + "ip": "54.185.77.104:9651" }, { "id": "NodeID-kZNuQMHhydefgnwjYX1fhHMpRNAs9my1", - "ip": "18.158.15.12:9651" + "ip": "3.74.3.14:9651" }, { "id": "NodeID-A7GwTSd47AcDVqpTVj7YtxtjHREM33EJw", - "ip": "3.21.38.33:9651" + "ip": "3.135.107.20:9651" }, { "id": "NodeID-Hr78Fy8uDYiRYocRYHXp4eLCYeb8x5UuM", - "ip": "54.93.182.129:9651" + "ip": "3.77.28.168:9651" }, { "id": "NodeID-9CkG9MBNavnw7EVSRsuFr7ws9gascDQy3", - "ip": "3.128.138.36:9651" + "ip": "18.216.88.69:9651" }, { "id": "NodeID-A8jypu63CWp76STwKdqP6e9hjL675kdiG", - "ip": "3.104.107.241:9651" + "ip": "3.24.26.175:9651" }, { "id": "NodeID-HsBEx3L71EHWSXaE6gvk2VsNntFEZsxqc", - "ip": "3.106.25.139:9651" + "ip": "52.64.55.185:9651" }, { "id": "NodeID-Nr584bLpGgbCUbZFSBaBz3Xum5wpca9Ym", - "ip": "18.162.129.129:9651" + "ip": "16.162.27.145:9651" }, { "id": "NodeID-QKGoUvqcgormCoMj6yPw9isY7DX9H4mdd", - "ip": "18.162.161.230:9651" + "ip": "18.163.169.191:9651" }, { "id": "NodeID-HCw7S2TVbFPDWNBo1GnFWqJ47f9rDJtt1", - "ip": "52.47.181.114:9651" + "ip": "13.39.184.151:9651" }, { "id": "NodeID-FYv1Lb29SqMpywYXH7yNkcFAzRF2jvm3K", - "ip": "15.188.9.42:9651" + "ip": "13.36.28.133:9651" } ], "fuji": [ From 0ab2046ef3987bb513ea8c33d11b817169a84e98 Mon Sep 17 00:00:00 2001 From: marun Date: Thu, 30 Nov 2023 09:18:59 -0800 Subject: [PATCH 088/267] Rename `testnet` fixture to `tmpnet` (#2307) --- ...e.persistent.yml => test.e2e.existing.yml} | 14 ++--- .github/workflows/test.e2e.yml | 6 +- .github/workflows/test.upgrade.yml | 8 +-- ...build_testnetctl.sh => build_tmpnetctl.sh} | 6 +- scripts/tests.e2e.existing.sh | 63 +++++++++++++++++++ scripts/tests.e2e.persistent.sh | 60 ------------------ scripts/tests.e2e.sh | 12 ++-- tests/e2e/README.md | 42 +++++++------ tests/e2e/c/dynamic_fees.go | 4 +- tests/e2e/faultinjection/duplicate_node_id.go | 10 +-- tests/e2e/p/interchain_workflow.go | 6 +- tests/e2e/p/staking_rewards.go | 8 +-- tests/e2e/p/workflow.go | 2 +- tests/fixture/e2e/env.go | 21 +++---- tests/fixture/e2e/flags.go | 35 ++++++----- tests/fixture/e2e/helpers.go | 22 +++---- tests/fixture/testnet/README.md | 8 --- tests/fixture/tmpnet/README.md | 20 ++++++ tests/fixture/{testnet => tmpnet}/cmd/main.go | 16 ++--- tests/fixture/{testnet => tmpnet}/common.go | 2 +- tests/fixture/{testnet => tmpnet}/config.go | 2 +- .../fixture/{testnet => tmpnet}/interfaces.go | 2 +- .../{testnet => tmpnet}/local/README.md | 44 ++++++------- .../{testnet => tmpnet}/local/config.go | 16 ++--- .../{testnet => tmpnet}/local/network.go | 36 +++++------ .../{testnet => tmpnet}/local/network_test.go | 0 .../fixture/{testnet => tmpnet}/local/node.go | 22 +++---- .../{testnet => tmpnet}/local/node_test.go | 0 28 files changed, 253 insertions(+), 234 deletions(-) rename .github/workflows/{test.e2e.persistent.yml => test.e2e.existing.yml} (67%) rename scripts/{build_testnetctl.sh => build_tmpnetctl.sh} (71%) create mode 100755 scripts/tests.e2e.existing.sh delete mode 100755 scripts/tests.e2e.persistent.sh delete mode 100644 tests/fixture/testnet/README.md create mode 100644 tests/fixture/tmpnet/README.md rename tests/fixture/{testnet => tmpnet}/cmd/main.go (86%) rename tests/fixture/{testnet => tmpnet}/common.go (98%) rename tests/fixture/{testnet => tmpnet}/config.go (99%) rename tests/fixture/{testnet => tmpnet}/interfaces.go (97%) rename tests/fixture/{testnet => tmpnet}/local/README.md (86%) rename tests/fixture/{testnet => tmpnet}/local/config.go (79%) rename tests/fixture/{testnet => tmpnet}/local/network.go (95%) rename tests/fixture/{testnet => tmpnet}/local/network_test.go (100%) rename tests/fixture/{testnet => tmpnet}/local/node.go (95%) rename tests/fixture/{testnet => tmpnet}/local/node_test.go (100%) diff --git a/.github/workflows/test.e2e.persistent.yml b/.github/workflows/test.e2e.existing.yml similarity index 67% rename from .github/workflows/test.e2e.persistent.yml rename to .github/workflows/test.e2e.existing.yml index d3448904d4c5..a50943888f48 100644 --- a/.github/workflows/test.e2e.persistent.yml +++ b/.github/workflows/test.e2e.existing.yml @@ -1,4 +1,4 @@ -name: Test e2e with persistent network +name: Test e2e with existing network on: push: @@ -15,7 +15,7 @@ permissions: contents: read jobs: - test_e2e_persistent: + test_e2e_existing: runs-on: ubuntu-latest steps: - name: Git checkout @@ -28,12 +28,12 @@ jobs: - name: Build the avalanchego binary shell: bash run: ./scripts/build.sh -r - - name: Run e2e tests with persistent network + - name: Run e2e tests with existing network shell: bash - run: E2E_SERIAL=1 ./scripts/tests.e2e.persistent.sh - - name: Upload testnet network dir + run: E2E_SERIAL=1 ./scripts/tests.e2e.existing.sh + - name: Upload tmpnet network dir uses: actions/upload-artifact@v3 if: always() with: - name: testnet-data - path: ~/.testnetctl/networks/1000 + name: tmpnet-data + path: ~/.tmpnet/networks/1000 diff --git a/.github/workflows/test.e2e.yml b/.github/workflows/test.e2e.yml index 4e7c70ad8a11..0edc46afebb0 100644 --- a/.github/workflows/test.e2e.yml +++ b/.github/workflows/test.e2e.yml @@ -31,9 +31,9 @@ jobs: - name: Run e2e tests shell: bash run: E2E_SERIAL=1 ./scripts/tests.e2e.sh - - name: Upload testnet network dir + - name: Upload tmpnet network dir uses: actions/upload-artifact@v3 if: always() with: - name: testnet-data - path: ~/.testnetctl/networks/1000 + name: tmpnet-data + path: ~/.tmpnet/networks/1000 diff --git a/.github/workflows/test.upgrade.yml b/.github/workflows/test.upgrade.yml index e564a51f5630..61be20787900 100644 --- a/.github/workflows/test.upgrade.yml +++ b/.github/workflows/test.upgrade.yml @@ -30,12 +30,12 @@ jobs: run: ./scripts/build.sh - name: Run upgrade tests shell: bash - # 1.10.7 is the first version compatible with the testnet fixture by + # 1.10.7 is the first version compatible with the ephnet fixture by # virtue of writing a process context file on node start. run: ./scripts/tests.upgrade.sh 1.10.7 - - name: Upload testnet network dir + - name: Upload ephnet network dir uses: actions/upload-artifact@v3 if: always() with: - name: testnet-data - path: ~/.testnetctl/networks/1000 + name: ephnet-data + path: ~/.ephnet/networks/1000 diff --git a/scripts/build_testnetctl.sh b/scripts/build_tmpnetctl.sh similarity index 71% rename from scripts/build_testnetctl.sh rename to scripts/build_tmpnetctl.sh index b84c9e40577d..132cf09ee38d 100755 --- a/scripts/build_testnetctl.sh +++ b/scripts/build_tmpnetctl.sh @@ -7,8 +7,8 @@ AVALANCHE_PATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )"; cd .. && pwd ) # Load the constants source "$AVALANCHE_PATH"/scripts/constants.sh -echo "Building testnetctl..." +echo "Building tmpnetctl..." go build -ldflags\ "-X github.com/ava-labs/avalanchego/version.GitCommit=$git_commit $static_ld_flags"\ - -o "$AVALANCHE_PATH/build/testnetctl"\ - "$AVALANCHE_PATH/tests/fixture/testnet/cmd/"*.go + -o "$AVALANCHE_PATH/build/tmpnetctl"\ + "$AVALANCHE_PATH/tests/fixture/tmpnet/cmd/"*.go diff --git a/scripts/tests.e2e.existing.sh b/scripts/tests.e2e.existing.sh new file mode 100755 index 000000000000..bc1f8104977b --- /dev/null +++ b/scripts/tests.e2e.existing.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +set -euo pipefail + +################################################################ +# This script deploys a temporary network and configures +# tests.e2e.sh to execute the e2e suite against it. This +# validates that tmpnetctl is capable of starting a network and +# that the e2e suite is capable of executing against a network +# that it did not create. +################################################################ + +# e.g., +# ./scripts/build.sh +# ./scripts/tests.e2e.existing.sh --ginkgo.label-filter=x # All arguments are supplied to ginkgo +# E2E_SERIAL=1 ./scripts/tests.e2e.sh # Run tests serially +# AVALANCHEGO_PATH=./build/avalanchego ./scripts/tests.e2e.existing.sh # Customization of avalanchego path +if ! [[ "$0" =~ scripts/tests.e2e.existing.sh ]]; then + echo "must be run from repository root" + exit 255 +fi + +# Ensure an absolute path to avoid dependency on the working directory +# of script execution. +export AVALANCHEGO_PATH="$(realpath ${AVALANCHEGO_PATH:-./build/avalanchego})" + +# Provide visual separation between testing and setup/teardown +function print_separator { + printf '%*s\n' "${COLUMNS:-80}" '' | tr ' ' ─ +} + +# Ensure network cleanup on teardown +function cleanup { + print_separator + echo "cleaning up temporary network" + if [[ -n "${TMPNET_NETWORK_DIR:-}" ]]; then + ./build/tmpnetctl stop-network + fi +} +trap cleanup EXIT + +# Start a temporary network +./scripts/build_tmpnetctl.sh +print_separator +./build/tmpnetctl start-network + +# Determine the network configuration path from the latest symlink +LATEST_SYMLINK_PATH="${HOME}/.tmpnet/networks/latest" +if [[ -h "${LATEST_SYMLINK_PATH}" ]]; then + export TMPNET_NETWORK_DIR="$(realpath ${LATEST_SYMLINK_PATH})" +else + echo "failed to find configuration path: ${LATEST_SYMLINK_PATH} symlink not found" + exit 255 +fi + +print_separator +# - Setting E2E_USE_EXISTING_NETWORK configures tests.e2e.sh to use +# the temporary network identified by TMPNET_NETWORK_DIR. +# - Only a single test (selected with --ginkgo.focus-file) is required +# to validate that an existing network can be used by an e2e test +# suite run. Executing more tests would be duplicative of the testing +# performed against a network created by the test suite. +E2E_USE_EXISTING_NETWORK=1 ./scripts/tests.e2e.sh --ginkgo.focus-file=permissionless_subnets.go diff --git a/scripts/tests.e2e.persistent.sh b/scripts/tests.e2e.persistent.sh deleted file mode 100755 index fec3b3db0f88..000000000000 --- a/scripts/tests.e2e.persistent.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -################################################################ -# This script deploys a persistent local network and configures -# tests.e2e.sh to execute the e2e suite against it. -################################################################ - -# e.g., -# ./scripts/build.sh -# ./scripts/tests.e2e.persistent.sh --ginkgo.label-filter=x # All arguments are supplied to ginkgo -# E2E_SERIAL=1 ./scripts/tests.e2e.sh # Run tests serially -# AVALANCHEGO_PATH=./build/avalanchego ./scripts/tests.e2e.persistent.sh # Customization of avalanchego path -if ! [[ "$0" =~ scripts/tests.e2e.persistent.sh ]]; then - echo "must be run from repository root" - exit 255 -fi - -# Ensure an absolute path to avoid dependency on the working directory -# of script execution. -export AVALANCHEGO_PATH="$(realpath ${AVALANCHEGO_PATH:-./build/avalanchego})" - -# Provide visual separation between testing and setup/teardown -function print_separator { - printf '%*s\n' "${COLUMNS:-80}" '' | tr ' ' ─ -} - -# Ensure network cleanup on teardown -function cleanup { - print_separator - echo "cleaning up persistent network" - if [[ -n "${TESTNETCTL_NETWORK_DIR:-}" ]]; then - ./build/testnetctl stop-network - fi -} -trap cleanup EXIT - -# Start a persistent network -./scripts/build_testnetctl.sh -print_separator -./build/testnetctl start-network - -# Determine the network configuration path from the latest symlink -LATEST_SYMLINK_PATH="${HOME}/.testnetctl/networks/latest" -if [[ -h "${LATEST_SYMLINK_PATH}" ]]; then - export TESTNETCTL_NETWORK_DIR="$(realpath ${LATEST_SYMLINK_PATH})" -else - echo "failed to find configuration path: ${LATEST_SYMLINK_PATH} symlink not found" - exit 255 -fi - -print_separator -# - Setting E2E_USE_PERSISTENT_NETWORK configures tests.e2e.sh to use -# the persistent network identified by TESTNETCTL_NETWORK_DIR. -# - Only a single test (selected with --ginkgo.focus-file) is required -# to validate that a persistent network can be used by an e2e test -# suite run. Executing more tests would be duplicative of the testing -# performed against an ephemeral test network. -E2E_USE_PERSISTENT_NETWORK=1 ./scripts/tests.e2e.sh --ginkgo.focus-file=permissionless_subnets.go diff --git a/scripts/tests.e2e.sh b/scripts/tests.e2e.sh index c9acd924ae20..638700c9cc47 100755 --- a/scripts/tests.e2e.sh +++ b/scripts/tests.e2e.sh @@ -7,7 +7,7 @@ set -euo pipefail # ./scripts/tests.e2e.sh --ginkgo.label-filter=x # All arguments are supplied to ginkgo # E2E_SERIAL=1 ./scripts/tests.e2e.sh # Run tests serially # AVALANCHEGO_PATH=./build/avalanchego ./scripts/tests.e2e.sh # Customization of avalanchego path -# E2E_USE_PERSISTENT_NETWORK=1 TESTNETCTL_NETWORK_DIR=/path/to ./scripts/tests.e2e.sh # Execute against a persistent network +# E2E_USE_EXISTING_NETWORK=1 TMPNET_NETWORK_DIR=/path/to ./scripts/tests.e2e.sh # Execute against an existing network if ! [[ "$0" =~ scripts/tests.e2e.sh ]]; then echo "must be run from repository root" exit 255 @@ -28,11 +28,11 @@ ACK_GINKGO_RC=true ginkgo build ./tests/e2e ./tests/e2e/e2e.test --help ################################# -# Since TESTNETCTL_NETWORK_DIR may be persistently set in the environment (e.g. to configure -# ginkgo or testnetctl), configuring the use of a persistent network with this script -# requires the extra step of setting E2E_USE_PERSISTENT_NETWORK=1. -if [[ -n "${E2E_USE_PERSISTENT_NETWORK:-}" && -n "${TESTNETCTL_NETWORK_DIR:-}" ]]; then - E2E_ARGS="--use-persistent-network" +# Since TMPNET_NETWORK_DIR may be set in the environment (e.g. to configure ginkgo +# or tmpnetctl), configuring the use of an existing network with this script +# requires the extra step of setting E2E_USE_EXISTING_NETWORK=1. +if [[ -n "${E2E_USE_EXISTING_NETWORK:-}" && -n "${TMPNET_NETWORK_DIR:-}" ]]; then + E2E_ARGS="--use-existing-network" else AVALANCHEGO_PATH="$(realpath ${AVALANCHEGO_PATH:-./build/avalanchego})" E2E_ARGS="--avalanchego-path=${AVALANCHEGO_PATH}" diff --git a/tests/e2e/README.md b/tests/e2e/README.md index da7ca7a82612..032795b6436e 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -1,6 +1,6 @@ # Avalanche e2e test suites -- Works with fixture-managed networks. +- Works with fixture-managed temporary networks. - Compiles to a single binary with customizable configurations. ## Running tests @@ -57,44 +57,46 @@ packages. `x/transfer/virtuous.go` defines X-Chain transfer tests, labeled with `x`, which can be selected by `./tests/e2e/e2e.test --ginkgo.label-filter "x"`. -## Testing against a persistent network +## Testing against an existing network -By default, a new ephemeral test network will be started before each -test run. When developing e2e tests, it may be helpful to create a -persistent test network to test against. This can increase the speed -of iteration by removing the requirement to start a new network for -every invocation of the test under development. +By default, a new temporary test network will be started before each +test run and stopped at the end of the run. When developing e2e tests, +it may be helpful to create a temporary network that can be used +across multiple test runs. This can increase the speed of iteration by +removing the requirement to start a new network for every invocation +of the test under development. -To use a persistent network: +To create an temporary network for use across test runs: ```bash # From the root of the avalanchego repo -# Build the testnetctl binary -$ ./scripts/build_testnetctl.sh +# Build the tmpnetctl binary +$ ./scripts/build_tmpnetctl.sh # Start a new network -$ ./build/testnetctl start-network --avalanchego-path=/path/to/avalanchego +$ ./build/tmpnetctl start-network --avalanchego-path=/path/to/avalanchego ... -Started network 1000 @ /home/me/.testnetctl/networks/1000 +Started network 1000 @ /home/me/.tmpnet/networks/1000 -Configure testnetctl to target this network by default with one of the following statements: - - source /home/me/.testnetctl/networks/1000/network.env - - export TESTNETCTL_NETWORK_DIR=/home/me/.testnetctl/networks/1000 - - export TESTNETCTL_NETWORK_DIR=/home/me/.testnetctl/networks/latest +Configure tmpnetctl and the test suite to target this network by default +with one of the following statements: + - source /home/me/.tmpnet/networks/1000/network.env + - export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/1000 + - export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/latest -# Start a new test run using the persistent network +# Start a new test run using the existing network ginkgo -v ./tests/e2e -- \ --avalanchego-path=/path/to/avalanchego \ --ginkgo.focus-file=[name of file containing test] \ - --use-persistent-network \ + --use-existing-network \ --network-dir=/path/to/network # It is also possible to set the AVALANCHEGO_PATH env var instead of supplying --avalanchego-path -# and to set TESTNETCTL_NETWORK_DIR instead of supplying --network-dir. +# and to set TMPNET_NETWORK_DIR instead of supplying --network-dir. ``` -See the testnet fixture [README](../fixture/testnet/README.md) for more details. +See the tmpnet fixture [README](../fixture/tmpnet/README.md) for more details. ## Skipping bootstrap checks diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 8f15b6d43caf..38bbd668079b 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -20,7 +20,7 @@ import ( "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" ) @@ -47,7 +47,7 @@ var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { ginkgo.By("initializing a coreth client") node := privateNetwork.GetNodes()[0] - nodeURI := testnet.NodeURI{ + nodeURI := tmpnet.NodeURI{ NodeID: node.GetID(), URI: node.GetProcessContext().URI, } diff --git a/tests/e2e/faultinjection/duplicate_node_id.go b/tests/e2e/faultinjection/duplicate_node_id.go index 1d865d840f51..9278c1bd5b8d 100644 --- a/tests/e2e/faultinjection/duplicate_node_id.go +++ b/tests/e2e/faultinjection/duplicate_node_id.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/set" ) @@ -27,7 +27,7 @@ var _ = ginkgo.Describe("Duplicate node handling", func() { nodes := network.GetNodes() ginkgo.By("creating new node") - node1 := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) + node1 := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) e2e.WaitForHealthy(node1) ginkgo.By("checking that the new node is connected to its peers") @@ -35,7 +35,7 @@ var _ = ginkgo.Describe("Duplicate node handling", func() { ginkgo.By("creating a second new node with the same staking keypair as the first new node") node1Flags := node1.GetConfig().Flags - node2Flags := testnet.FlagsMap{ + node2Flags := tmpnet.FlagsMap{ config.StakingTLSKeyContentKey: node1Flags[config.StakingTLSKeyContentKey], config.StakingCertContentKey: node1Flags[config.StakingCertContentKey], // Construct a unique data dir to ensure the two nodes' data will be stored @@ -46,7 +46,7 @@ var _ = ginkgo.Describe("Duplicate node handling", func() { node2 := e2e.AddEphemeralNode(network, node2Flags) ginkgo.By("checking that the second new node fails to become healthy before timeout") - err := testnet.WaitForHealthy(e2e.DefaultContext(), node2) + err := tmpnet.WaitForHealthy(e2e.DefaultContext(), node2) require.ErrorIs(err, context.DeadlineExceeded) ginkgo.By("stopping the first new node") @@ -63,7 +63,7 @@ var _ = ginkgo.Describe("Duplicate node handling", func() { }) // Check that a new node is connected to existing nodes and vice versa -func checkConnectedPeers(existingNodes []testnet.Node, newNode testnet.Node) { +func checkConnectedPeers(existingNodes []tmpnet.Node, newNode tmpnet.Node) { require := require.New(ginkgo.GinkgoT()) // Collect the node ids of the new node's peers diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 44a6912715ef..678f9b5cc204 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -19,7 +19,7 @@ import ( "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/set" @@ -44,7 +44,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL ginkgo.By("checking that the network has a compatible minimum stake duration", func() { minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) - require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) + require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) }) ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") @@ -87,7 +87,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL } ginkgo.By("adding new node and waiting for it to report healthy") - node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) + node := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) e2e.WaitForHealthy(node) ginkgo.By("retrieving new node's id and pop") diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index 41a77985729b..f05b3bfbf64a 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -20,7 +20,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/units" @@ -43,13 +43,13 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { ginkgo.By("checking that the network has a compatible minimum stake duration", func() { minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) - require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) + require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) }) ginkgo.By("adding alpha node, whose uptime should result in a staking reward") - alphaNode := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) + alphaNode := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) ginkgo.By("adding beta node, whose uptime should not result in a staking reward") - betaNode := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) + betaNode := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) // Wait to check health until both nodes have started to minimize the duration // required for both nodes to report healthy. diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 3f0440ac49b6..8cc7c109d3a4 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -73,7 +73,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { vdrStartTime := time.Now().Add(validatorStartTimeDiff) // Use a random node ID to ensure that repeated test runs - // will succeed against a persistent network. + // will succeed against a network that persists across runs. validatorID, err := ids.ToNodeID(utils.RandomBytes(ids.NodeIDLen)) require.NoError(err) diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index 54a4676482e1..07c24866a9f0 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -16,8 +16,8 @@ import ( "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" - "github.com/ava-labs/avalanchego/tests/fixture/testnet/local" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet/local" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -40,7 +40,7 @@ type TestEnvironment struct { // The directory where the test network configuration is stored NetworkDir string // URIs used to access the API endpoints of nodes of the network - URIs []testnet.NodeURI + URIs []tmpnet.NodeURI // The URI used to access the http server that allocates test data TestDataServerURI string @@ -57,16 +57,15 @@ func (te *TestEnvironment) Marshal() []byte { func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { require := require.New(ginkgo.GinkgoT()) - persistentNetworkDir := flagVars.PersistentNetworkDir() + networkDir := flagVars.NetworkDir() // Load or create a test network var network *local.LocalNetwork - if len(persistentNetworkDir) > 0 { - tests.Outf("{{yellow}}Using a persistent network configured at %s{{/}}\n", persistentNetworkDir) - + if len(networkDir) > 0 { var err error - network, err = local.ReadNetwork(persistentNetworkDir) + network, err = local.ReadNetwork(networkDir) require.NoError(err) + tests.Outf("{{yellow}}Using an existing network configured at %s{{/}}\n", network.Dir) } else { network = StartLocalNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir) } @@ -90,7 +89,7 @@ func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { // Retrieve a random URI to naively attempt to spread API load across // nodes. -func (te *TestEnvironment) GetRandomNodeURI() testnet.NodeURI { +func (te *TestEnvironment) GetRandomNodeURI() tmpnet.NodeURI { r := rand.New(rand.NewSource(time.Now().Unix())) //#nosec G404 nodeURI := te.URIs[r.Intn(len(te.URIs))] tests.Outf("{{blue}} targeting node %s with URI: %s{{/}}\n", nodeURI.NodeID, nodeURI.URI) @@ -98,7 +97,7 @@ func (te *TestEnvironment) GetRandomNodeURI() testnet.NodeURI { } // Retrieve the network to target for testing. -func (te *TestEnvironment) GetNetwork() testnet.Network { +func (te *TestEnvironment) GetNetwork() tmpnet.Network { network, err := local.ReadNetwork(te.NetworkDir) te.require.NoError(err) return network @@ -124,7 +123,7 @@ func (te *TestEnvironment) NewKeychain(count int) *secp256k1fx.Keychain { } // Create a new private network that is not shared with other tests. -func (te *TestEnvironment) NewPrivateNetwork() testnet.Network { +func (te *TestEnvironment) NewPrivateNetwork() tmpnet.Network { // Load the shared network to retrieve its path and exec path sharedNetwork, err := local.ReadNetwork(te.NetworkDir) te.require.NoError(err) diff --git a/tests/fixture/e2e/flags.go b/tests/fixture/e2e/flags.go index c7838cb7c761..23952b5dcd91 100644 --- a/tests/fixture/e2e/flags.go +++ b/tests/fixture/e2e/flags.go @@ -8,28 +8,31 @@ import ( "fmt" "os" - "github.com/ava-labs/avalanchego/tests/fixture/testnet/local" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet/local" ) type FlagVars struct { - avalancheGoExecPath string - persistentNetworkDir string - usePersistentNetwork bool + avalancheGoExecPath string + networkDir string + useExistingNetwork bool } -func (v *FlagVars) PersistentNetworkDir() string { - if v.usePersistentNetwork && len(v.persistentNetworkDir) == 0 { - return os.Getenv(local.NetworkDirEnvName) +func (v *FlagVars) NetworkDir() string { + if !v.useExistingNetwork { + return "" } - return v.persistentNetworkDir + if len(v.networkDir) > 0 { + return v.networkDir + } + return os.Getenv(local.NetworkDirEnvName) } func (v *FlagVars) AvalancheGoExecPath() string { return v.avalancheGoExecPath } -func (v *FlagVars) UsePersistentNetwork() bool { - return v.usePersistentNetwork +func (v *FlagVars) UseExistingNetwork() bool { + return v.useExistingNetwork } func RegisterFlags() *FlagVars { @@ -38,19 +41,19 @@ func RegisterFlags() *FlagVars { &vars.avalancheGoExecPath, "avalanchego-path", os.Getenv(local.AvalancheGoPathEnvName), - fmt.Sprintf("avalanchego executable path (required if not using a persistent network). Also possible to configure via the %s env variable.", local.AvalancheGoPathEnvName), + fmt.Sprintf("avalanchego executable path (required if not using an existing network). Also possible to configure via the %s env variable.", local.AvalancheGoPathEnvName), ) flag.StringVar( - &vars.persistentNetworkDir, + &vars.networkDir, "network-dir", "", - fmt.Sprintf("[optional] the dir containing the configuration of a persistent network to target for testing. Useful for speeding up test development. Also possible to configure via the %s env variable.", local.NetworkDirEnvName), + fmt.Sprintf("[optional] the dir containing the configuration of an existing network to target for testing. Will only be used if --use-existing-network is specified. Also possible to configure via the %s env variable.", local.NetworkDirEnvName), ) flag.BoolVar( - &vars.usePersistentNetwork, - "use-persistent-network", + &vars.useExistingNetwork, + "use-existing-network", false, - "[optional] whether to target the persistent network identified by --network-dir.", + "[optional] whether to target the existing network identified by --network-dir.", ) return &vars diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 15da611324e0..8b7eb5260b8c 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -22,8 +22,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" - "github.com/ava-labs/avalanchego/tests/fixture/testnet/local" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet/local" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary" @@ -62,7 +62,7 @@ const ( ) // Create a new wallet for the provided keychain against the specified node URI. -func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary.Wallet { +func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.Wallet { tests.Outf("{{blue}} initializing a new wallet for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, @@ -81,7 +81,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. } // Create a new eth client targeting the specified node URI. -func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { +func NewEthClient(nodeURI tmpnet.NodeURI) ethclient.Client { tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) nodeAddress := strings.Split(nodeURI.URI, "//")[1] uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) @@ -128,7 +128,7 @@ func Eventually(condition func() bool, waitFor time.Duration, tick time.Duration // Add an ephemeral node that is only intended to be used by a single test. Its ID and // URI are not intended to be returned from the Network instance to minimize // accessibility from other tests. -func AddEphemeralNode(network testnet.Network, flags testnet.FlagsMap) testnet.Node { +func AddEphemeralNode(network tmpnet.Network, flags tmpnet.FlagsMap) tmpnet.Node { require := require.New(ginkgo.GinkgoT()) node, err := network.AddEphemeralNode(ginkgo.GinkgoWriter, flags) @@ -145,11 +145,11 @@ func AddEphemeralNode(network testnet.Network, flags testnet.FlagsMap) testnet.N } // Wait for the given node to report healthy. -func WaitForHealthy(node testnet.Node) { +func WaitForHealthy(node tmpnet.Node) { // Need to use explicit context (vs DefaultContext()) to support use with DeferCleanup ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) defer cancel() - require.NoError(ginkgo.GinkgoT(), testnet.WaitForHealthy(ctx, node)) + require.NoError(ginkgo.GinkgoT(), tmpnet.WaitForHealthy(ctx, node)) } // Sends an eth transaction, waits for the transaction receipt to be issued @@ -197,7 +197,7 @@ func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { } // Verify that a new node can bootstrap into the network. -func CheckBootstrapIsPossible(network testnet.Network) { +func CheckBootstrapIsPossible(network tmpnet.Network) { require := require.New(ginkgo.GinkgoT()) if len(os.Getenv(SkipBootstrapChecksEnvName)) > 0 { @@ -210,7 +210,7 @@ func CheckBootstrapIsPossible(network testnet.Network) { // checking for bootstrap implicitly on teardown via a function registered // with ginkgo.DeferCleanup. It's not possible to call DeferCleanup from // within a function called by DeferCleanup. - node, err := network.AddEphemeralNode(ginkgo.GinkgoWriter, testnet.FlagsMap{}) + node, err := network.AddEphemeralNode(ginkgo.GinkgoWriter, tmpnet.FlagsMap{}) require.NoError(err) defer func() { @@ -234,8 +234,8 @@ func StartLocalNetwork(avalancheGoExecPath string, networkDir string) *local.Loc ExecPath: avalancheGoExecPath, }, }, - testnet.DefaultNodeCount, - testnet.DefaultFundedKeyCount, + tmpnet.DefaultNodeCount, + tmpnet.DefaultFundedKeyCount, ) require.NoError(err) ginkgo.DeferCleanup(func() { diff --git a/tests/fixture/testnet/README.md b/tests/fixture/testnet/README.md deleted file mode 100644 index ef2e5fb4df75..000000000000 --- a/tests/fixture/testnet/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Test Network Fixture - -This package contains configuration and interfaces that are -independent of a given orchestration mechanism -(e.g. [local](local/README.md)). The intent is to enable tests to be -written against the interfaces defined in this package and for -implementation-specific details of test network orchestration to be -limited to test setup and teardown. diff --git a/tests/fixture/tmpnet/README.md b/tests/fixture/tmpnet/README.md new file mode 100644 index 000000000000..ca48d553105e --- /dev/null +++ b/tests/fixture/tmpnet/README.md @@ -0,0 +1,20 @@ +# tmpnet (temporary network fixture) + +This package contains configuration and interfaces that are +independent of a given orchestration mechanism +(e.g. [local](local/README.md)). The intent is to enable tests to be +written against the interfaces defined in this package and for +implementation-specific details of test network orchestration to be +limited to test setup and teardown. + +## What's in a name? + +The name of this package was originally `testnet` and its cli was +`testnetctl`. This name was chosen in ignorance that `testnet` +commonly refers to a persistent blockchain network used for testing. + +To avoid confusion, the name was changed to `tmpnet` and its cli +`tmpnetctl`. `tmpnet` is short for `temporary network` since the +networks it deploys are likely to live for a limited duration in +support of the development and testing of avalanchego and its related +repositories. diff --git a/tests/fixture/testnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go similarity index 86% rename from tests/fixture/testnet/cmd/main.go rename to tests/fixture/tmpnet/cmd/main.go index 92dc846edca8..a9f5c1865291 100644 --- a/tests/fixture/testnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -13,8 +13,8 @@ import ( "github.com/spf13/cobra" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" - "github.com/ava-labs/avalanchego/tests/fixture/testnet/local" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet/local" "github.com/ava-labs/avalanchego/version" ) @@ -27,8 +27,8 @@ var ( func main() { rootCmd := &cobra.Command{ - Use: "testnetctl", - Short: "testnetctl commands", + Use: "tmpnetctl", + Short: "tmpnetctl commands", } versionCmd := &cobra.Command{ @@ -84,7 +84,7 @@ func main() { return err } - fmt.Fprintf(os.Stdout, "\nConfigure testnetctl to target this network by default with one of the following statements:") + fmt.Fprintf(os.Stdout, "\nConfigure tmpnetctl to target this network by default with one of the following statements:") fmt.Fprintf(os.Stdout, "\n - source %s\n", network.EnvFilePath()) fmt.Fprintf(os.Stdout, " - %s\n", network.EnvFileContents()) fmt.Fprintf(os.Stdout, " - export %s=%s\n", local.NetworkDirEnvName, latestSymlinkPath) @@ -94,8 +94,8 @@ func main() { } startNetworkCmd.PersistentFlags().StringVar(&rootDir, "root-dir", os.Getenv(local.RootDirEnvName), "The path to the root directory for local networks") startNetworkCmd.PersistentFlags().StringVar(&execPath, "avalanchego-path", os.Getenv(local.AvalancheGoPathEnvName), "The path to an avalanchego binary") - startNetworkCmd.PersistentFlags().Uint8Var(&nodeCount, "node-count", testnet.DefaultNodeCount, "Number of nodes the network should initially consist of") - startNetworkCmd.PersistentFlags().Uint8Var(&fundedKeyCount, "funded-key-count", testnet.DefaultFundedKeyCount, "Number of funded keys the network should start with") + startNetworkCmd.PersistentFlags().Uint8Var(&nodeCount, "node-count", tmpnet.DefaultNodeCount, "Number of nodes the network should initially consist of") + startNetworkCmd.PersistentFlags().Uint8Var(&fundedKeyCount, "funded-key-count", tmpnet.DefaultFundedKeyCount, "Number of funded keys the network should start with") rootCmd.AddCommand(startNetworkCmd) var networkDir string @@ -117,7 +117,7 @@ func main() { rootCmd.AddCommand(stopNetworkCmd) if err := rootCmd.Execute(); err != nil { - fmt.Fprintf(os.Stderr, "testnetctl failed: %v\n", err) + fmt.Fprintf(os.Stderr, "tmpnetctl failed: %v\n", err) os.Exit(1) } os.Exit(0) diff --git a/tests/fixture/testnet/common.go b/tests/fixture/tmpnet/common.go similarity index 98% rename from tests/fixture/testnet/common.go rename to tests/fixture/tmpnet/common.go index ab983e893e46..4b0281f45242 100644 --- a/tests/fixture/testnet/common.go +++ b/tests/fixture/tmpnet/common.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package testnet +package tmpnet import ( "context" diff --git a/tests/fixture/testnet/config.go b/tests/fixture/tmpnet/config.go similarity index 99% rename from tests/fixture/testnet/config.go rename to tests/fixture/tmpnet/config.go index 425aa646a690..f504eb84d20d 100644 --- a/tests/fixture/testnet/config.go +++ b/tests/fixture/tmpnet/config.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package testnet +package tmpnet import ( "encoding/base64" diff --git a/tests/fixture/testnet/interfaces.go b/tests/fixture/tmpnet/interfaces.go similarity index 97% rename from tests/fixture/testnet/interfaces.go rename to tests/fixture/tmpnet/interfaces.go index 2c1479ec48bd..2fd03cbc2a98 100644 --- a/tests/fixture/testnet/interfaces.go +++ b/tests/fixture/tmpnet/interfaces.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package testnet +package tmpnet import ( "context" diff --git a/tests/fixture/testnet/local/README.md b/tests/fixture/tmpnet/local/README.md similarity index 86% rename from tests/fixture/testnet/local/README.md rename to tests/fixture/tmpnet/local/README.md index fdfbbdb4d58b..91af35a9b805 100644 --- a/tests/fixture/testnet/local/README.md +++ b/tests/fixture/tmpnet/local/README.md @@ -4,7 +4,7 @@ This package implements a simple orchestrator for the avalanchego nodes of a local network. Configuration is stored on disk, and nodes run as independent processes whose process details are also written to disk. Using the filesystem to store configuration and process details -allows for the `testnetctl` cli and e2e test fixture to orchestrate +allows for the `tmpnetctl` cli and e2e test fixture to orchestrate the same local networks without the use of an rpc daemon. ## Package details @@ -27,36 +27,36 @@ abstractions. ## Usage -### Via testnetctl +### Via tmpnetctl -A local network can be managed by the `testnetctl` cli tool: +A local network can be managed by the `tmpnetctl` cli tool: ```bash # From the root of the avalanchego repo -# Build the testnetctl binary -$ ./scripts/build_testnetctl.sh +# Build the tmpnetctl binary +$ ./scripts/build_tmpnetctl.sh # Start a new network -$ ./build/testnetctl start-network --avalanchego-path=/path/to/avalanchego +$ ./build/tmpnetctl start-network --avalanchego-path=/path/to/avalanchego ... -Started network 1000 @ /home/me/.testnetctl/networks/1000 +Started network 1000 @ /home/me/.tmpnet/networks/1000 -Configure testnetctl to target this network by default with one of the following statements: - - source /home/me/.testnetctl/networks/1000/network.env - - export TESTNETCTL_NETWORK_DIR=/home/me/.testnetctl/networks/1000 - - export TESTNETCTL_NETWORK_DIR=/home/me/.testnetctl/networks/latest +Configure tmpnetctl to target this network by default with one of the following statements: + - source /home/me/.tmpnet/networks/1000/network.env + - export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/1000 + - export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/latest # Stop the network -$ ./build/testnetctl stop-network --network-dir=/path/to/network +$ ./build/tmpnetctl stop-network --network-dir=/path/to/network ``` Note the export of the path ending in `latest`. This is a symlink that -set to the last network created by `testnetctl start-network`. Setting -the `TESTNETCTL_NETWORK_DIR` env var to this symlink ensures that -`testnetctl` commands and e2e execution with -`--use-persistent-network` will target the most recently deployed -local network. +is set to the last network created by `tmpnetctl start-network`. Setting +the `TMPNET_NETWORK_DIR` env var to this symlink ensures that +`tmpnetctl` commands and e2e execution with +`--use-existing-network` will target the most recently deployed local +network. ### Via code @@ -66,7 +66,7 @@ A local network can be managed in code: network, _ := local.StartNetwork( ctx, // Context used to limit duration of waiting for network health ginkgo.GinkgoWriter, // Writer to report progress of network start - "", // Use default root dir (~/.testnetctl) + "", // Use default root dir (~/.tmpnet) &local.LocalNetwork{ LocalConfig: local.LocalConfig{ ExecPath: "/path/to/avalanchego", // Defining the avalanchego exec path is required @@ -121,7 +121,7 @@ tests](../../../e2e/e2e_test.go). By default, nodes in a local network will be started with staking and API ports set to `0` to ensure that ports will be dynamically -chosen. The testnet fixture discovers the ports used by a given node +chosen. The tmpnet fixture discovers the ports used by a given node by reading the `[base-data-dir]/process.json` file written by avalanchego on node start. The use of dynamic ports supports testing with many local networks without having to manually select compatible @@ -133,7 +133,7 @@ A local network relies on configuration written to disk in the following structu ``` HOME -└── .testnetctl // Root path for tool +└── .tmpnet // Root path for the temporary network fixture └── networks // Default parent directory for local networks └── 1000 // The networkID is used to name the network dir and starts at 1000 ├── NodeID-37E8UK3x2YFsHE3RdALmfWcppcZ1eTuj9 // The ID of a node is the name of its data dir @@ -189,10 +189,10 @@ TODO(marun) Enable configuration of X-Chain and P-Chain. ### Network env -A shell script that sets the `TESTNETCTL_NETWORK_DIR` env var to the +A shell script that sets the `TMPNET_NETWORK_DIR` env var to the path of the network is stored at `[network-dir]/network.env`. Sourcing this file (i.e. `source network.env`) in a shell will configure ginkgo -e2e and the `testnetctl` cli to target the network path specified in +e2e and the `tmpnetctl` cli to target the network path specified in the env var. ### Node configuration diff --git a/tests/fixture/testnet/local/config.go b/tests/fixture/tmpnet/local/config.go similarity index 79% rename from tests/fixture/testnet/local/config.go rename to tests/fixture/tmpnet/local/config.go index 317975a2395c..70ef9a443185 100644 --- a/tests/fixture/testnet/local/config.go +++ b/tests/fixture/tmpnet/local/config.go @@ -7,15 +7,15 @@ import ( "time" "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" ) const ( // Constants defining the names of shell variables whose value can // configure local network orchestration. AvalancheGoPathEnvName = "AVALANCHEGO_PATH" - NetworkDirEnvName = "TESTNETCTL_NETWORK_DIR" - RootDirEnvName = "TESTNETCTL_ROOT_DIR" + NetworkDirEnvName = "TMPNET_NETWORK_DIR" + RootDirEnvName = "TMPNET_ROOT_DIR" DefaultNetworkStartTimeout = 2 * time.Minute DefaultNodeInitTimeout = 10 * time.Second @@ -23,9 +23,9 @@ const ( ) // A set of flags appropriate for local testing. -func LocalFlags() testnet.FlagsMap { +func LocalFlags() tmpnet.FlagsMap { // Supply only non-default configuration to ensure that default values will be used. - return testnet.FlagsMap{ + return tmpnet.FlagsMap{ config.NetworkPeerListGossipFreqKey: "250ms", config.NetworkMaxReconnectDelayKey: "1s", config.PublicIPKey: "127.0.0.1", @@ -37,16 +37,16 @@ func LocalFlags() testnet.FlagsMap { config.IndexEnabledKey: true, config.LogDisplayLevelKey: "INFO", config.LogLevelKey: "DEBUG", - config.MinStakeDurationKey: testnet.DefaultMinStakeDuration.String(), + config.MinStakeDurationKey: tmpnet.DefaultMinStakeDuration.String(), } } // C-Chain config for local testing. -func LocalCChainConfig() testnet.FlagsMap { +func LocalCChainConfig() tmpnet.FlagsMap { // Supply only non-default configuration to ensure that default // values will be used. Available C-Chain configuration options are // defined in the `github.com/ava-labs/coreth/evm` package. - return testnet.FlagsMap{ + return tmpnet.FlagsMap{ "log-level": "trace", } } diff --git a/tests/fixture/testnet/local/network.go b/tests/fixture/tmpnet/local/network.go similarity index 95% rename from tests/fixture/testnet/local/network.go rename to tests/fixture/tmpnet/local/network.go index 836a1489c2dd..70411d4afcde 100644 --- a/tests/fixture/testnet/local/network.go +++ b/tests/fixture/tmpnet/local/network.go @@ -18,7 +18,7 @@ import ( "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/perms" @@ -48,7 +48,7 @@ func GetDefaultRootDir() (string, error) { if err != nil { return "", err } - return filepath.Join(homeDir, ".testnetctl", "networks"), nil + return filepath.Join(homeDir, ".tmpnet", "networks"), nil } // Find the next available network ID by attempting to create a @@ -83,7 +83,7 @@ func FindNextNetworkID(rootDir string) (uint32, string, error) { // Defines the configuration required for a local network (i.e. one composed of local processes). type LocalNetwork struct { - testnet.NetworkConfig + tmpnet.NetworkConfig LocalConfig // Nodes with local configuration @@ -94,13 +94,13 @@ type LocalNetwork struct { } // Returns the configuration of the network in backend-agnostic form. -func (ln *LocalNetwork) GetConfig() testnet.NetworkConfig { +func (ln *LocalNetwork) GetConfig() tmpnet.NetworkConfig { return ln.NetworkConfig } // Returns the nodes of the network in backend-agnostic form. -func (ln *LocalNetwork) GetNodes() []testnet.Node { - nodes := make([]testnet.Node, 0, len(ln.Nodes)) +func (ln *LocalNetwork) GetNodes() []tmpnet.Node { + nodes := make([]tmpnet.Node, 0, len(ln.Nodes)) for _, node := range ln.Nodes { nodes = append(nodes, node) } @@ -108,12 +108,12 @@ func (ln *LocalNetwork) GetNodes() []testnet.Node { } // Adds a backend-agnostic ephemeral node to the network -func (ln *LocalNetwork) AddEphemeralNode(w io.Writer, flags testnet.FlagsMap) (testnet.Node, error) { +func (ln *LocalNetwork) AddEphemeralNode(w io.Writer, flags tmpnet.FlagsMap) (tmpnet.Node, error) { if flags == nil { - flags = testnet.FlagsMap{} + flags = tmpnet.FlagsMap{} } return ln.AddLocalNode(w, &LocalNode{ - NodeConfig: testnet.NodeConfig{ + NodeConfig: tmpnet.NodeConfig{ Flags: flags, }, }, true /* isEphemeral */) @@ -298,7 +298,7 @@ func (ln *LocalNetwork) PopulateNodeConfig(node *LocalNode, nodeParentDir string // Set values common to all nodes flags.SetDefaults(ln.DefaultFlags) - flags.SetDefaults(testnet.FlagsMap{ + flags.SetDefaults(tmpnet.FlagsMap{ config.GenesisFileKey: ln.GetGenesisPath(), config.ChainConfigDirKey: ln.GetChainConfigDir(), }) @@ -385,7 +385,7 @@ func (ln *LocalNetwork) WaitForHealthy(ctx context.Context, w io.Writer) error { } healthy, err := node.IsHealthy(ctx) - if err != nil && !errors.Is(err, testnet.ErrNotRunning) { + if err != nil && !errors.Is(err, tmpnet.ErrNotRunning) { return err } if !healthy { @@ -409,14 +409,14 @@ func (ln *LocalNetwork) WaitForHealthy(ctx context.Context, w io.Writer) error { // Retrieve API URIs for all running primary validator nodes. URIs for // ephemeral nodes are not returned. -func (ln *LocalNetwork) GetURIs() []testnet.NodeURI { - uris := make([]testnet.NodeURI, 0, len(ln.Nodes)) +func (ln *LocalNetwork) GetURIs() []tmpnet.NodeURI { + uris := make([]tmpnet.NodeURI, 0, len(ln.Nodes)) for _, node := range ln.Nodes { // Only append URIs that are not empty. A node may have an // empty URI if it was not running at the time // node.ReadProcessContext() was called. if len(node.URI) > 0 { - uris = append(uris, testnet.NodeURI{ + uris = append(uris, tmpnet.NodeURI{ NodeID: node.NodeID, URI: node.URI, }) @@ -458,7 +458,7 @@ func (ln *LocalNetwork) ReadGenesis() error { } func (ln *LocalNetwork) WriteGenesis() error { - bytes, err := testnet.DefaultJSONMarshal(ln.Genesis) + bytes, err := tmpnet.DefaultJSONMarshal(ln.Genesis) if err != nil { return fmt.Errorf("failed to marshal genesis: %w", err) } @@ -477,7 +477,7 @@ func (ln *LocalNetwork) GetCChainConfigPath() string { } func (ln *LocalNetwork) ReadCChainConfig() error { - chainConfig, err := testnet.ReadFlagsMap(ln.GetCChainConfigPath(), "C-Chain config") + chainConfig, err := tmpnet.ReadFlagsMap(ln.GetCChainConfigPath(), "C-Chain config") if err != nil { return err } @@ -496,7 +496,7 @@ func (ln *LocalNetwork) WriteCChainConfig() error { // Used to marshal/unmarshal persistent local network defaults. type localDefaults struct { - Flags testnet.FlagsMap + Flags tmpnet.FlagsMap ExecPath string FundedKeys []*secp256k1.PrivateKey } @@ -526,7 +526,7 @@ func (ln *LocalNetwork) WriteDefaults() error { ExecPath: ln.ExecPath, FundedKeys: ln.FundedKeys, } - bytes, err := testnet.DefaultJSONMarshal(defaults) + bytes, err := tmpnet.DefaultJSONMarshal(defaults) if err != nil { return fmt.Errorf("failed to marshal defaults: %w", err) } diff --git a/tests/fixture/testnet/local/network_test.go b/tests/fixture/tmpnet/local/network_test.go similarity index 100% rename from tests/fixture/testnet/local/network_test.go rename to tests/fixture/tmpnet/local/network_test.go diff --git a/tests/fixture/testnet/local/node.go b/tests/fixture/tmpnet/local/node.go similarity index 95% rename from tests/fixture/testnet/local/node.go rename to tests/fixture/tmpnet/local/node.go index 2de516825677..908d3fd5f474 100644 --- a/tests/fixture/testnet/local/node.go +++ b/tests/fixture/tmpnet/local/node.go @@ -23,7 +23,7 @@ import ( "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/node" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/perms" ) @@ -42,7 +42,7 @@ type LocalConfig struct { // Stores the configuration and process details of a node in a local network. type LocalNode struct { - testnet.NodeConfig + tmpnet.NodeConfig LocalConfig node.NodeProcessContext @@ -51,8 +51,8 @@ type LocalNode struct { func NewLocalNode(dataDir string) *LocalNode { return &LocalNode{ - NodeConfig: testnet.NodeConfig{ - Flags: testnet.FlagsMap{ + NodeConfig: tmpnet.NodeConfig{ + Flags: tmpnet.FlagsMap{ config.DataDirKey: dataDir, }, }, @@ -76,7 +76,7 @@ func (n *LocalNode) GetID() ids.NodeID { } // Retrieve backend-agnostic node configuration. -func (n *LocalNode) GetConfig() testnet.NodeConfig { +func (n *LocalNode) GetConfig() tmpnet.NodeConfig { return n.NodeConfig } @@ -98,11 +98,11 @@ func (n *LocalNode) ReadConfig() error { if err != nil { return fmt.Errorf("failed to read local node config: %w", err) } - flags := testnet.FlagsMap{} + flags := tmpnet.FlagsMap{} if err := json.Unmarshal(bytes, &flags); err != nil { return fmt.Errorf("failed to unmarshal local node config: %w", err) } - config := testnet.NodeConfig{Flags: flags} + config := tmpnet.NodeConfig{Flags: flags} if err := config.EnsureNodeID(); err != nil { return err } @@ -115,7 +115,7 @@ func (n *LocalNode) WriteConfig() error { return fmt.Errorf("failed to create node dir: %w", err) } - bytes, err := testnet.DefaultJSONMarshal(n.Flags) + bytes, err := tmpnet.DefaultJSONMarshal(n.Flags) if err != nil { return fmt.Errorf("failed to marshal local node config: %w", err) } @@ -265,7 +265,7 @@ func (n *LocalNode) Stop() error { } // Wait for the node process to stop - ticker := time.NewTicker(testnet.DefaultNodeTickerInterval) + ticker := time.NewTicker(tmpnet.DefaultNodeTickerInterval) defer ticker.Stop() ctx, cancel := context.WithTimeout(context.Background(), DefaultNodeStopTimeout) defer cancel() @@ -295,7 +295,7 @@ func (n *LocalNode) IsHealthy(ctx context.Context) (bool, error) { return false, fmt.Errorf("failed to determine process status: %w", err) } if proc == nil { - return false, testnet.ErrNotRunning + return false, tmpnet.ErrNotRunning } // Check that the node is reporting healthy @@ -321,7 +321,7 @@ func (n *LocalNode) IsHealthy(ctx context.Context) (bool, error) { } func (n *LocalNode) WaitForProcessContext(ctx context.Context) error { - ticker := time.NewTicker(testnet.DefaultNodeTickerInterval) + ticker := time.NewTicker(tmpnet.DefaultNodeTickerInterval) defer ticker.Stop() ctx, cancel := context.WithTimeout(ctx, DefaultNodeInitTimeout) diff --git a/tests/fixture/testnet/local/node_test.go b/tests/fixture/tmpnet/local/node_test.go similarity index 100% rename from tests/fixture/testnet/local/node_test.go rename to tests/fixture/tmpnet/local/node_test.go From de3b16cac8a7f61c92b7c695599071de482d709f Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:49:53 -0500 Subject: [PATCH 089/267] Add `p2p.Network` component (#2283) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- go.mod | 2 +- go.sum | 4 +- network/p2p/client.go | 7 +- network/p2p/gossip/gossip_test.go | 42 +-- network/p2p/network.go | 188 ++++++++++ network/p2p/network_test.go | 596 ++++++++++++++++++++++++++++++ network/p2p/peers.go | 50 --- network/p2p/peers_test.go | 150 -------- network/p2p/router.go | 63 ++-- network/p2p/router_test.go | 360 ------------------ network/p2p/validators.go | 29 +- network/p2p/validators_test.go | 13 +- 12 files changed, 871 insertions(+), 633 deletions(-) create mode 100644 network/p2p/network.go create mode 100644 network/p2p/network_test.go delete mode 100644 network/p2p/peers.go delete mode 100644 network/p2p/peers_test.go delete mode 100644 network/p2p/router_test.go diff --git a/go.mod b/go.mod index f5dfa499d1d5..9a629725cdef 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.5 + github.com/ava-labs/coreth v0.12.9-rc.7 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 35141a6c1638..3478c17b2d6b 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.5 h1:xYBgNm1uOPfUdUNm8+fS8ellHnEd4qfFNb6uZHo9tqI= -github.com/ava-labs/coreth v0.12.9-rc.5/go.mod h1:rECKQfGFDeodrwGPlJSvFUJDbVr30jSMIVjQLi6pNX4= +github.com/ava-labs/coreth v0.12.9-rc.7 h1:AlCmXnrJwo0NxlEXQHysQgRQSCA14PZW6iyJmeVYB34= +github.com/ava-labs/coreth v0.12.9-rc.7/go.mod h1:yrf2vEah4Fgj6sJ4UpHewo4DLolwdpf2bJuLRT80PGw= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/network/p2p/client.go b/network/p2p/client.go index d950a4b0a227..1c3c9bee01da 100644 --- a/network/p2p/client.go +++ b/network/p2p/client.go @@ -42,10 +42,9 @@ type CrossChainAppResponseCallback func( type Client struct { handlerID uint64 handlerPrefix []byte - router *Router + router *router sender common.AppSender - // nodeSampler is used to select nodes to route AppRequestAny to - nodeSampler NodeSampler + options *clientOptions } // AppRequestAny issues an AppRequest to an arbitrary node decided by Client. @@ -56,7 +55,7 @@ func (c *Client) AppRequestAny( appRequestBytes []byte, onResponse AppResponseCallback, ) error { - sampled := c.nodeSampler.Sample(ctx, 1) + sampled := c.options.nodeSampler.Sample(ctx, 1) if len(sampled) != 1 { return ErrNoPeers } diff --git a/network/p2p/gossip/gossip_test.go b/network/p2p/gossip/gossip_test.go index eb4b23ecd9c8..d30fac0008e7 100644 --- a/network/p2p/gossip/gossip_test.go +++ b/network/p2p/gossip/gossip_test.go @@ -13,8 +13,6 @@ import ( "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/snow/engine/common" @@ -117,10 +115,9 @@ func TestGossiperGossip(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - ctrl := gomock.NewController(t) - responseSender := common.NewMockSender(ctrl) - responseRouter := p2p.NewRouter(logging.NoLog{}, responseSender, prometheus.NewRegistry(), "") + responseSender := &common.SenderTest{} + responseNetwork := p2p.NewNetwork(logging.NoLog{}, responseSender, prometheus.NewRegistry(), "") responseBloom, err := NewBloomFilter(1000, 0.01) require.NoError(err) responseSet := testSet{ @@ -130,31 +127,30 @@ func TestGossiperGossip(t *testing.T) { for _, item := range tt.responder { require.NoError(responseSet.Add(item)) } - peers := &p2p.Peers{} - require.NoError(peers.Connected(context.Background(), ids.EmptyNodeID, nil)) handler, err := NewHandler[*testTx](responseSet, tt.config, prometheus.NewRegistry()) require.NoError(err) - _, err = responseRouter.RegisterAppProtocol(0x0, handler, peers) + _, err = responseNetwork.NewAppProtocol(0x0, handler) require.NoError(err) - requestSender := common.NewMockSender(ctrl) - requestRouter := p2p.NewRouter(logging.NoLog{}, requestSender, prometheus.NewRegistry(), "") - - gossiped := make(chan struct{}) - requestSender.EXPECT().SendAppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) { + requestSender := &common.SenderTest{ + SendAppRequestF: func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { go func() { - require.NoError(responseRouter.AppRequest(ctx, ids.EmptyNodeID, requestID, time.Time{}, request)) + require.NoError(responseNetwork.AppRequest(ctx, ids.EmptyNodeID, requestID, time.Time{}, request)) }() - }).AnyTimes() + return nil + }, + } - responseSender.EXPECT(). - SendAppResponse(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appResponseBytes []byte) { - require.NoError(requestRouter.AppResponse(ctx, nodeID, requestID, appResponseBytes)) - close(gossiped) - }).AnyTimes() + requestNetwork := p2p.NewNetwork(logging.NoLog{}, requestSender, prometheus.NewRegistry(), "") + require.NoError(requestNetwork.Connected(context.Background(), ids.EmptyNodeID, nil)) + + gossiped := make(chan struct{}) + responseSender.SendAppResponseF = func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appResponseBytes []byte) error { + require.NoError(requestNetwork.AppResponse(ctx, nodeID, requestID, appResponseBytes)) + close(gossiped) + return nil + } bloom, err := NewBloomFilter(1000, 0.01) require.NoError(err) @@ -166,7 +162,7 @@ func TestGossiperGossip(t *testing.T) { require.NoError(requestSet.Add(item)) } - requestClient, err := requestRouter.RegisterAppProtocol(0x0, nil, peers) + requestClient, err := requestNetwork.NewAppProtocol(0x0, nil) require.NoError(err) config := Config{ diff --git a/network/p2p/network.go b/network/p2p/network.go new file mode 100644 index 000000000000..444c2e4b9408 --- /dev/null +++ b/network/p2p/network.go @@ -0,0 +1,188 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package p2p + +import ( + "context" + "encoding/binary" + "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/version" +) + +var ( + _ validators.Connector = (*Network)(nil) + _ common.AppHandler = (*Network)(nil) + _ NodeSampler = (*peerSampler)(nil) +) + +// ClientOption configures Client +type ClientOption interface { + apply(options *clientOptions) +} + +type clientOptionFunc func(options *clientOptions) + +func (o clientOptionFunc) apply(options *clientOptions) { + o(options) +} + +// WithValidatorSampling configures Client.AppRequestAny to sample validators +func WithValidatorSampling(validators *Validators) ClientOption { + return clientOptionFunc(func(options *clientOptions) { + options.nodeSampler = validators + }) +} + +// clientOptions holds client-configurable values +type clientOptions struct { + // nodeSampler is used to select nodes to route Client.AppRequestAny to + nodeSampler NodeSampler +} + +// NewNetwork returns an instance of Network +func NewNetwork( + log logging.Logger, + sender common.AppSender, + metrics prometheus.Registerer, + namespace string, +) *Network { + return &Network{ + Peers: &Peers{}, + log: log, + sender: sender, + metrics: metrics, + namespace: namespace, + router: newRouter(log, sender, metrics, namespace), + } +} + +// Network exposes networking state and supports building p2p application +// protocols +type Network struct { + Peers *Peers + + log logging.Logger + sender common.AppSender + metrics prometheus.Registerer + namespace string + + router *router +} + +func (n *Network) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { + return n.router.AppRequest(ctx, nodeID, requestID, deadline, request) +} + +func (n *Network) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { + return n.router.AppResponse(ctx, nodeID, requestID, response) +} + +func (n *Network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + return n.router.AppRequestFailed(ctx, nodeID, requestID) +} + +func (n *Network) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error { + return n.router.AppGossip(ctx, nodeID, msg) +} + +func (n *Network) CrossChainAppRequest(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, request []byte) error { + return n.router.CrossChainAppRequest(ctx, chainID, requestID, deadline, request) +} + +func (n *Network) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error { + return n.router.CrossChainAppResponse(ctx, chainID, requestID, response) +} + +func (n *Network) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { + return n.router.CrossChainAppRequestFailed(ctx, chainID, requestID) +} + +func (n *Network) Connected(_ context.Context, nodeID ids.NodeID, _ *version.Application) error { + n.Peers.add(nodeID) + return nil +} + +func (n *Network) Disconnected(_ context.Context, nodeID ids.NodeID) error { + n.Peers.remove(nodeID) + return nil +} + +// NewAppProtocol reserves an identifier for an application protocol handler and +// returns a Client that can be used to send messages for the corresponding +// protocol. +func (n *Network) NewAppProtocol(handlerID uint64, handler Handler, options ...ClientOption) (*Client, error) { + if err := n.router.addHandler(handlerID, handler); err != nil { + return nil, err + } + + client := &Client{ + handlerID: handlerID, + handlerPrefix: binary.AppendUvarint(nil, handlerID), + sender: n.sender, + router: n.router, + options: &clientOptions{ + nodeSampler: &peerSampler{ + peers: n.Peers, + }, + }, + } + + for _, option := range options { + option.apply(client.options) + } + + return client, nil +} + +// Peers contains metadata about the current set of connected peers +type Peers struct { + lock sync.RWMutex + set set.SampleableSet[ids.NodeID] +} + +func (p *Peers) add(nodeID ids.NodeID) { + p.lock.Lock() + defer p.lock.Unlock() + + p.set.Add(nodeID) +} + +func (p *Peers) remove(nodeID ids.NodeID) { + p.lock.Lock() + defer p.lock.Unlock() + + p.set.Remove(nodeID) +} + +func (p *Peers) has(nodeID ids.NodeID) bool { + p.lock.RLock() + defer p.lock.RUnlock() + + return p.set.Contains(nodeID) +} + +// Sample returns a pseudo-random sample of up to limit Peers +func (p *Peers) Sample(limit int) []ids.NodeID { + p.lock.RLock() + defer p.lock.RUnlock() + + return p.set.Sample(limit) +} + +type peerSampler struct { + peers *Peers +} + +func (p peerSampler) Sample(_ context.Context, limit int) []ids.NodeID { + return p.peers.Sample(limit) +} diff --git a/network/p2p/network_test.go b/network/p2p/network_test.go new file mode 100644 index 000000000000..590858a0c467 --- /dev/null +++ b/network/p2p/network_test.go @@ -0,0 +1,596 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package p2p + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" + + "github.com/stretchr/testify/require" + + "go.uber.org/mock/gomock" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/network/p2p/mocks" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/version" +) + +func TestAppRequestResponse(t *testing.T) { + handlerID := uint64(0x0) + request := []byte("request") + response := []byte("response") + nodeID := ids.GenerateTestNodeID() + chainID := ids.GenerateTestID() + + ctxKey := new(string) + ctxVal := new(string) + *ctxKey = "foo" + *ctxVal = "bar" + + tests := []struct { + name string + requestFunc func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) + }{ + { + name: "app request", + requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { + sender.SendAppRequestF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { + for range nodeIDs { + go func() { + require.NoError(t, network.AppRequest(ctx, nodeID, requestID, time.Time{}, request)) + }() + } + + return nil + } + sender.SendAppResponseF = func(ctx context.Context, _ ids.NodeID, requestID uint32, response []byte) error { + go func() { + ctx = context.WithValue(ctx, ctxKey, ctxVal) + require.NoError(t, network.AppResponse(ctx, nodeID, requestID, response)) + }() + + return nil + } + handler.EXPECT(). + AppRequest(context.Background(), nodeID, gomock.Any(), request). + DoAndReturn(func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { + return response, nil + }) + + callback := func(ctx context.Context, actualNodeID ids.NodeID, actualResponse []byte, err error) { + defer wg.Done() + + require.NoError(t, err) + require.Equal(t, ctxVal, ctx.Value(ctxKey)) + require.Equal(t, nodeID, actualNodeID) + require.Equal(t, response, actualResponse) + } + + require.NoError(t, client.AppRequestAny(context.Background(), request, callback)) + }, + }, + { + name: "app request failed", + requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { + sender.SendAppRequestF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { + for range nodeIDs { + go func() { + require.NoError(t, network.AppRequestFailed(ctx, nodeID, requestID)) + }() + } + + return nil + } + + callback := func(_ context.Context, actualNodeID ids.NodeID, actualResponse []byte, err error) { + defer wg.Done() + + require.ErrorIs(t, err, ErrAppRequestFailed) + require.Equal(t, nodeID, actualNodeID) + require.Nil(t, actualResponse) + } + + require.NoError(t, client.AppRequest(context.Background(), set.Of(nodeID), request, callback)) + }, + }, + { + name: "cross-chain app request", + requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { + chainID := ids.GenerateTestID() + sender.SendCrossChainAppRequestF = func(ctx context.Context, chainID ids.ID, requestID uint32, request []byte) { + go func() { + require.NoError(t, network.CrossChainAppRequest(ctx, chainID, requestID, time.Time{}, request)) + }() + } + sender.SendCrossChainAppResponseF = func(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) { + go func() { + ctx = context.WithValue(ctx, ctxKey, ctxVal) + require.NoError(t, network.CrossChainAppResponse(ctx, chainID, requestID, response)) + }() + } + handler.EXPECT(). + CrossChainAppRequest(context.Background(), chainID, gomock.Any(), request). + DoAndReturn(func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { + return response, nil + }) + + callback := func(ctx context.Context, actualChainID ids.ID, actualResponse []byte, err error) { + defer wg.Done() + require.NoError(t, err) + require.Equal(t, ctxVal, ctx.Value(ctxKey)) + require.Equal(t, chainID, actualChainID) + require.Equal(t, response, actualResponse) + } + + require.NoError(t, client.CrossChainAppRequest(context.Background(), chainID, request, callback)) + }, + }, + { + name: "cross-chain app request failed", + requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { + sender.SendCrossChainAppRequestF = func(ctx context.Context, chainID ids.ID, requestID uint32, request []byte) { + go func() { + require.NoError(t, network.CrossChainAppRequestFailed(ctx, chainID, requestID)) + }() + } + + callback := func(_ context.Context, actualChainID ids.ID, actualResponse []byte, err error) { + defer wg.Done() + + require.ErrorIs(t, err, ErrAppRequestFailed) + require.Equal(t, chainID, actualChainID) + require.Nil(t, actualResponse) + } + + require.NoError(t, client.CrossChainAppRequest(context.Background(), chainID, request, callback)) + }, + }, + { + name: "app gossip", + requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { + sender.SendAppGossipF = func(ctx context.Context, gossip []byte) error { + go func() { + require.NoError(t, network.AppGossip(ctx, nodeID, gossip)) + }() + + return nil + } + handler.EXPECT(). + AppGossip(context.Background(), nodeID, request). + DoAndReturn(func(context.Context, ids.NodeID, []byte) error { + defer wg.Done() + return nil + }) + + require.NoError(t, client.AppGossip(context.Background(), request)) + }, + }, + { + name: "app gossip specific", + requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { + sender.SendAppGossipSpecificF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], bytes []byte) error { + for n := range nodeIDs { + nodeID := n + go func() { + require.NoError(t, network.AppGossip(ctx, nodeID, bytes)) + }() + } + + return nil + } + handler.EXPECT(). + AppGossip(context.Background(), nodeID, request). + DoAndReturn(func(context.Context, ids.NodeID, []byte) error { + defer wg.Done() + return nil + }) + + require.NoError(t, client.AppGossipSpecific(context.Background(), set.Of(nodeID), request)) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + sender := &common.SenderTest{} + handler := mocks.NewMockHandler(ctrl) + n := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + require.NoError(n.Connected(context.Background(), nodeID, nil)) + client, err := n.NewAppProtocol(handlerID, handler) + require.NoError(err) + + wg := &sync.WaitGroup{} + wg.Add(1) + tt.requestFunc(t, n, client, sender, handler, wg) + wg.Wait() + }) + } +} + +func TestNetworkDropMessage(t *testing.T) { + unregistered := byte(0x0) + + tests := []struct { + name string + requestFunc func(network *Network) error + err error + }{ + { + name: "drop unregistered app request message", + requestFunc: func(network *Network) error { + return network.AppRequest(context.Background(), ids.GenerateTestNodeID(), 0, time.Time{}, []byte{unregistered}) + }, + err: nil, + }, + { + name: "drop empty app request message", + requestFunc: func(network *Network) error { + return network.AppRequest(context.Background(), ids.GenerateTestNodeID(), 0, time.Time{}, []byte{}) + }, + err: nil, + }, + { + name: "drop unregistered cross-chain app request message", + requestFunc: func(network *Network) error { + return network.CrossChainAppRequest(context.Background(), ids.GenerateTestID(), 0, time.Time{}, []byte{unregistered}) + }, + err: nil, + }, + { + name: "drop empty cross-chain app request message", + requestFunc: func(network *Network) error { + return network.CrossChainAppRequest(context.Background(), ids.GenerateTestID(), 0, time.Time{}, []byte{}) + }, + err: nil, + }, + { + name: "drop unregistered gossip message", + requestFunc: func(network *Network) error { + return network.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte{unregistered}) + }, + err: nil, + }, + { + name: "drop empty gossip message", + requestFunc: func(network *Network) error { + return network.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte{}) + }, + err: nil, + }, + { + name: "drop unrequested app request failed", + requestFunc: func(network *Network) error { + return network.AppRequestFailed(context.Background(), ids.GenerateTestNodeID(), 0) + }, + err: ErrUnrequestedResponse, + }, + { + name: "drop unrequested app response", + requestFunc: func(network *Network) error { + return network.AppResponse(context.Background(), ids.GenerateTestNodeID(), 0, nil) + }, + err: ErrUnrequestedResponse, + }, + { + name: "drop unrequested cross-chain request failed", + requestFunc: func(network *Network) error { + return network.CrossChainAppRequestFailed(context.Background(), ids.GenerateTestID(), 0) + }, + err: ErrUnrequestedResponse, + }, + { + name: "drop unrequested cross-chain response", + requestFunc: func(network *Network) error { + return network.CrossChainAppResponse(context.Background(), ids.GenerateTestID(), 0, nil) + }, + err: ErrUnrequestedResponse, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + + network := NewNetwork(logging.NoLog{}, &common.SenderTest{}, prometheus.NewRegistry(), "") + + err := tt.requestFunc(network) + require.ErrorIs(err, tt.err) + }) + } +} + +// It's possible for the request id to overflow and wrap around. +// If there are still pending requests with the same request id, we should +// not attempt to issue another request until the previous one has cleared. +func TestAppRequestDuplicateRequestIDs(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + handler := mocks.NewMockHandler(ctrl) + sender := &common.SenderTest{ + SendAppResponseF: func(context.Context, ids.NodeID, uint32, []byte) error { + return nil + }, + } + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + nodeID := ids.GenerateTestNodeID() + + requestSent := &sync.WaitGroup{} + sender.SendAppRequestF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { + for range nodeIDs { + requestSent.Add(1) + go func() { + require.NoError(network.AppRequest(ctx, nodeID, requestID, time.Time{}, request)) + requestSent.Done() + }() + } + + return nil + } + + timeout := &sync.WaitGroup{} + response := []byte("response") + handler.EXPECT().AppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx context.Context, nodeID ids.NodeID, deadline time.Time, request []byte) ([]byte, error) { + timeout.Wait() + return response, nil + }).AnyTimes() + + require.NoError(network.Connected(context.Background(), nodeID, nil)) + client, err := network.NewAppProtocol(0x1, handler) + require.NoError(err) + + onResponse := func(ctx context.Context, nodeID ids.NodeID, got []byte, err error) { + require.NoError(err) + require.Equal(response, got) + } + + require.NoError(client.AppRequest(context.Background(), set.Of(nodeID), []byte{}, onResponse)) + requestSent.Wait() + + // force the network to use the same requestID + network.router.requestID = 1 + timeout.Add(1) + err = client.AppRequest(context.Background(), set.Of(nodeID), []byte{}, nil) + requestSent.Wait() + require.ErrorIs(err, ErrRequestPending) + + timeout.Done() +} + +// Sample should always return up to [limit] peers, and less if fewer than +// [limit] peers are available. +func TestPeersSample(t *testing.T) { + nodeID1 := ids.GenerateTestNodeID() + nodeID2 := ids.GenerateTestNodeID() + nodeID3 := ids.GenerateTestNodeID() + + tests := []struct { + name string + connected set.Set[ids.NodeID] + disconnected set.Set[ids.NodeID] + limit int + }{ + { + name: "no peers", + limit: 1, + }, + { + name: "one peer connected", + connected: set.Of(nodeID1), + limit: 1, + }, + { + name: "multiple peers connected", + connected: set.Of(nodeID1, nodeID2, nodeID3), + limit: 1, + }, + { + name: "peer connects and disconnects - 1", + connected: set.Of(nodeID1), + disconnected: set.Of(nodeID1), + limit: 1, + }, + { + name: "peer connects and disconnects - 2", + connected: set.Of(nodeID1, nodeID2), + disconnected: set.Of(nodeID2), + limit: 1, + }, + { + name: "peer connects and disconnects - 2", + connected: set.Of(nodeID1, nodeID2, nodeID3), + disconnected: set.Of(nodeID1, nodeID2), + limit: 1, + }, + { + name: "less than limit peers", + connected: set.Of(nodeID1, nodeID2, nodeID3), + limit: 4, + }, + { + name: "limit peers", + connected: set.Of(nodeID1, nodeID2, nodeID3), + limit: 3, + }, + { + name: "more than limit peers", + connected: set.Of(nodeID1, nodeID2, nodeID3), + limit: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + + network := NewNetwork(logging.NoLog{}, &common.SenderTest{}, prometheus.NewRegistry(), "") + + for connected := range tt.connected { + require.NoError(network.Connected(context.Background(), connected, nil)) + } + + for disconnected := range tt.disconnected { + require.NoError(network.Disconnected(context.Background(), disconnected)) + } + + sampleable := set.Set[ids.NodeID]{} + sampleable.Union(tt.connected) + sampleable.Difference(tt.disconnected) + + sampled := network.Peers.Sample(tt.limit) + require.Len(sampled, math.Min(tt.limit, len(sampleable))) + require.Subset(sampleable, sampled) + }) + } +} + +func TestAppRequestAnyNodeSelection(t *testing.T) { + tests := []struct { + name string + peers []ids.NodeID + expected error + }{ + { + name: "no peers", + expected: ErrNoPeers, + }, + { + name: "has peers", + peers: []ids.NodeID{ids.GenerateTestNodeID()}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + + sent := set.Set[ids.NodeID]{} + sender := &common.SenderTest{ + SendAppRequestF: func(_ context.Context, nodeIDs set.Set[ids.NodeID], _ uint32, _ []byte) error { + for nodeID := range nodeIDs { + sent.Add(nodeID) + } + return nil + }, + } + + n := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + for _, peer := range tt.peers { + require.NoError(n.Connected(context.Background(), peer, &version.Application{})) + } + + client, err := n.NewAppProtocol(1, nil) + require.NoError(err) + + err = client.AppRequestAny(context.Background(), []byte("foobar"), nil) + require.ErrorIs(err, tt.expected) + }) + } +} + +func TestNodeSamplerClientOption(t *testing.T) { + nodeID0 := ids.GenerateTestNodeID() + nodeID1 := ids.GenerateTestNodeID() + nodeID2 := ids.GenerateTestNodeID() + + tests := []struct { + name string + peers []ids.NodeID + option func(t *testing.T, n *Network) ClientOption + expected []ids.NodeID + expectedErr error + }{ + { + name: "default", + peers: []ids.NodeID{nodeID0, nodeID1, nodeID2}, + option: func(_ *testing.T, n *Network) ClientOption { + return clientOptionFunc(func(*clientOptions) {}) + }, + expected: []ids.NodeID{nodeID0, nodeID1, nodeID2}, + }, + { + name: "validator connected", + peers: []ids.NodeID{nodeID0, nodeID1}, + option: func(t *testing.T, n *Network) ClientOption { + state := &validators.TestState{ + GetCurrentHeightF: func(context.Context) (uint64, error) { + return 0, nil + }, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + return map[ids.NodeID]*validators.GetValidatorOutput{ + nodeID1: nil, + }, nil + }, + } + + validators := NewValidators(n.Peers, n.log, ids.Empty, state, 0) + return WithValidatorSampling(validators) + }, + expected: []ids.NodeID{nodeID1}, + }, + { + name: "validator disconnected", + peers: []ids.NodeID{nodeID0}, + option: func(t *testing.T, n *Network) ClientOption { + state := &validators.TestState{ + GetCurrentHeightF: func(context.Context) (uint64, error) { + return 0, nil + }, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + return map[ids.NodeID]*validators.GetValidatorOutput{ + nodeID1: nil, + }, nil + }, + } + + validators := NewValidators(n.Peers, n.log, ids.Empty, state, 0) + return WithValidatorSampling(validators) + }, + expectedErr: ErrNoPeers, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + + done := make(chan struct{}) + sender := &common.SenderTest{ + SendAppRequestF: func(_ context.Context, nodeIDs set.Set[ids.NodeID], _ uint32, _ []byte) error { + require.Subset(tt.expected, nodeIDs.List()) + close(done) + return nil + }, + } + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + ctx := context.Background() + for _, peer := range tt.peers { + require.NoError(network.Connected(ctx, peer, nil)) + } + + client, err := network.NewAppProtocol(0x0, nil, tt.option(t, network)) + require.NoError(err) + + if err = client.AppRequestAny(ctx, []byte("request"), nil); err != nil { + close(done) + } + + require.ErrorIs(tt.expectedErr, err) + <-done + }) + } +} diff --git a/network/p2p/peers.go b/network/p2p/peers.go deleted file mode 100644 index 47982aeb2dc4..000000000000 --- a/network/p2p/peers.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package p2p - -import ( - "context" - "sync" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/version" -) - -var ( - _ validators.Connector = (*Peers)(nil) - _ NodeSampler = (*Peers)(nil) -) - -// Peers contains a set of nodes that we are connected to. -type Peers struct { - lock sync.RWMutex - peers set.SampleableSet[ids.NodeID] -} - -func (p *Peers) Connected(_ context.Context, nodeID ids.NodeID, _ *version.Application) error { - p.lock.Lock() - defer p.lock.Unlock() - - p.peers.Add(nodeID) - - return nil -} - -func (p *Peers) Disconnected(_ context.Context, nodeID ids.NodeID) error { - p.lock.Lock() - defer p.lock.Unlock() - - p.peers.Remove(nodeID) - - return nil -} - -func (p *Peers) Sample(_ context.Context, limit int) []ids.NodeID { - p.lock.RLock() - defer p.lock.RUnlock() - - return p.peers.Sample(limit) -} diff --git a/network/p2p/peers_test.go b/network/p2p/peers_test.go deleted file mode 100644 index 9835cf065b0b..000000000000 --- a/network/p2p/peers_test.go +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package p2p - -import ( - "context" - "testing" - - "github.com/prometheus/client_golang/prometheus" - - "github.com/stretchr/testify/require" - - "go.uber.org/mock/gomock" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/utils/set" -) - -// Sample should always return up to [limit] peers, and less if fewer than -// [limit] peers are available. -func TestPeersSample(t *testing.T) { - nodeID1 := ids.GenerateTestNodeID() - nodeID2 := ids.GenerateTestNodeID() - nodeID3 := ids.GenerateTestNodeID() - - tests := []struct { - name string - connected set.Set[ids.NodeID] - disconnected set.Set[ids.NodeID] - limit int - }{ - { - name: "no peers", - limit: 1, - }, - { - name: "one peer connected", - connected: set.Of(nodeID1), - limit: 1, - }, - { - name: "multiple peers connected", - connected: set.Of(nodeID1, nodeID2, nodeID3), - limit: 1, - }, - { - name: "peer connects and disconnects - 1", - connected: set.Of(nodeID1), - disconnected: set.Of(nodeID1), - limit: 1, - }, - { - name: "peer connects and disconnects - 2", - connected: set.Of(nodeID1, nodeID2), - disconnected: set.Of(nodeID2), - limit: 1, - }, - { - name: "peer connects and disconnects - 2", - connected: set.Of(nodeID1, nodeID2, nodeID3), - disconnected: set.Of(nodeID1, nodeID2), - limit: 1, - }, - { - name: "less than limit peers", - connected: set.Of(nodeID1, nodeID2, nodeID3), - limit: 4, - }, - { - name: "limit peers", - connected: set.Of(nodeID1, nodeID2, nodeID3), - limit: 3, - }, - { - name: "more than limit peers", - connected: set.Of(nodeID1, nodeID2, nodeID3), - limit: 2, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require := require.New(t) - peers := &Peers{} - - for connected := range tt.connected { - require.NoError(peers.Connected(context.Background(), connected, nil)) - } - - for disconnected := range tt.disconnected { - require.NoError(peers.Disconnected(context.Background(), disconnected)) - } - - sampleable := set.Set[ids.NodeID]{} - sampleable.Union(tt.connected) - sampleable.Difference(tt.disconnected) - - sampled := peers.Sample(context.Background(), tt.limit) - require.Len(sampled, math.Min(tt.limit, len(sampleable))) - require.Subset(sampleable, sampled) - }) - } -} - -func TestAppRequestAnyNodeSelection(t *testing.T) { - tests := []struct { - name string - peers []ids.NodeID - expected error - }{ - { - name: "no peers", - expected: ErrNoPeers, - }, - { - name: "has peers", - peers: []ids.NodeID{ids.GenerateTestNodeID()}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - mockAppSender := common.NewMockSender(ctrl) - - expectedCalls := 0 - if tt.expected == nil { - expectedCalls = 1 - } - mockAppSender.EXPECT().SendAppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(expectedCalls) - - r := NewRouter(logging.NoLog{}, mockAppSender, prometheus.NewRegistry(), "") - peers := &Peers{} - for _, peer := range tt.peers { - require.NoError(peers.Connected(context.Background(), peer, nil)) - } - - client, err := r.RegisterAppProtocol(1, nil, peers) - require.NoError(err) - - err = client.AppRequestAny(context.Background(), []byte("foobar"), nil) - require.ErrorIs(err, tt.expected) - }) - } -} diff --git a/network/p2p/router.go b/network/p2p/router.go index b689b7ae1a17..110e9b6de627 100644 --- a/network/p2p/router.go +++ b/network/p2p/router.go @@ -26,7 +26,7 @@ var ( ErrExistingAppProtocol = errors.New("existing app protocol") ErrUnrequestedResponse = errors.New("unrequested response") - _ common.AppHandler = (*Router)(nil) + _ common.AppHandler = (*router)(nil) ) type metrics struct { @@ -55,10 +55,10 @@ type meteredHandler struct { *metrics } -// Router routes incoming application messages to the corresponding registered +// router routes incoming application messages to the corresponding registered // app handler. App messages must be made using the registered handler's // corresponding Client. -type Router struct { +type router struct { log logging.Logger sender common.AppSender metrics prometheus.Registerer @@ -71,14 +71,14 @@ type Router struct { requestID uint32 } -// NewRouter returns a new instance of Router -func NewRouter( +// newRouter returns a new instance of Router +func newRouter( log logging.Logger, sender common.AppSender, metrics prometheus.Registerer, namespace string, -) *Router { - return &Router{ +) *router { + return &router{ log: log, sender: sender, metrics: metrics, @@ -91,15 +91,12 @@ func NewRouter( } } -// RegisterAppProtocol reserves an identifier for an application protocol and -// returns a Client that can be used to send messages for the corresponding -// protocol. -func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSampler NodeSampler) (*Client, error) { +func (r *router) addHandler(handlerID uint64, handler Handler) error { r.lock.Lock() defer r.lock.Unlock() if _, ok := r.handlers[handlerID]; ok { - return nil, fmt.Errorf("failed to register handler id %d: %w", handlerID, ErrExistingAppProtocol) + return fmt.Errorf("failed to register handler id %d: %w", handlerID, ErrExistingAppProtocol) } appRequestTime, err := metric.NewAverager( @@ -109,7 +106,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp r.metrics, ) if err != nil { - return nil, fmt.Errorf("failed to register app request metric for handler_%d: %w", handlerID, err) + return fmt.Errorf("failed to register app request metric for handler_%d: %w", handlerID, err) } appRequestFailedTime, err := metric.NewAverager( @@ -119,7 +116,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp r.metrics, ) if err != nil { - return nil, fmt.Errorf("failed to register app request failed metric for handler_%d: %w", handlerID, err) + return fmt.Errorf("failed to register app request failed metric for handler_%d: %w", handlerID, err) } appResponseTime, err := metric.NewAverager( @@ -129,7 +126,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp r.metrics, ) if err != nil { - return nil, fmt.Errorf("failed to register app response metric for handler_%d: %w", handlerID, err) + return fmt.Errorf("failed to register app response metric for handler_%d: %w", handlerID, err) } appGossipTime, err := metric.NewAverager( @@ -139,7 +136,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp r.metrics, ) if err != nil { - return nil, fmt.Errorf("failed to register app gossip metric for handler_%d: %w", handlerID, err) + return fmt.Errorf("failed to register app gossip metric for handler_%d: %w", handlerID, err) } crossChainAppRequestTime, err := metric.NewAverager( @@ -149,7 +146,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp r.metrics, ) if err != nil { - return nil, fmt.Errorf("failed to register cross-chain app request metric for handler_%d: %w", handlerID, err) + return fmt.Errorf("failed to register cross-chain app request metric for handler_%d: %w", handlerID, err) } crossChainAppRequestFailedTime, err := metric.NewAverager( @@ -159,7 +156,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp r.metrics, ) if err != nil { - return nil, fmt.Errorf("failed to register cross-chain app request failed metric for handler_%d: %w", handlerID, err) + return fmt.Errorf("failed to register cross-chain app request failed metric for handler_%d: %w", handlerID, err) } crossChainAppResponseTime, err := metric.NewAverager( @@ -169,7 +166,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp r.metrics, ) if err != nil { - return nil, fmt.Errorf("failed to register cross-chain app response metric for handler_%d: %w", handlerID, err) + return fmt.Errorf("failed to register cross-chain app response metric for handler_%d: %w", handlerID, err) } r.handlers[handlerID] = &meteredHandler{ @@ -190,13 +187,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp }, } - return &Client{ - handlerID: handlerID, - handlerPrefix: binary.AppendUvarint(nil, handlerID), - sender: r.sender, - router: r, - nodeSampler: nodeSampler, - }, nil + return nil } // AppRequest routes an AppRequest to a Handler based on the handler prefix. The @@ -204,7 +195,7 @@ func (r *Router) RegisterAppProtocol(handlerID uint64, handler Handler, nodeSamp // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *Router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { +func (r *router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { start := time.Now() parsedMsg, handler, ok := r.parse(request) if !ok { @@ -232,7 +223,7 @@ func (r *Router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID ui // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *Router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { +func (r *router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { start := time.Now() pending, ok := r.clearAppRequest(requestID) if !ok { @@ -250,7 +241,7 @@ func (r *Router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, reques // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *Router) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { +func (r *router) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { start := time.Now() pending, ok := r.clearAppRequest(requestID) if !ok { @@ -268,7 +259,7 @@ func (r *Router) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID u // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *Router) AppGossip(ctx context.Context, nodeID ids.NodeID, gossip []byte) error { +func (r *router) AppGossip(ctx context.Context, nodeID ids.NodeID, gossip []byte) error { start := time.Now() parsedMsg, handler, ok := r.parse(gossip) if !ok { @@ -292,7 +283,7 @@ func (r *Router) AppGossip(ctx context.Context, nodeID ids.NodeID, gossip []byte // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *Router) CrossChainAppRequest( +func (r *router) CrossChainAppRequest( ctx context.Context, chainID ids.ID, requestID uint32, @@ -325,7 +316,7 @@ func (r *Router) CrossChainAppRequest( // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *Router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { +func (r *router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { start := time.Now() pending, ok := r.clearCrossChainAppRequest(requestID) if !ok { @@ -343,7 +334,7 @@ func (r *Router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *Router) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error { +func (r *router) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error { start := time.Now() pending, ok := r.clearCrossChainAppRequest(requestID) if !ok { @@ -365,7 +356,7 @@ func (r *Router) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requ // - A boolean indicating that parsing succeeded. // // Invariant: Assumes [r.lock] isn't held. -func (r *Router) parse(msg []byte) ([]byte, *meteredHandler, bool) { +func (r *router) parse(msg []byte) ([]byte, *meteredHandler, bool) { handlerID, bytesRead := binary.Uvarint(msg) if bytesRead <= 0 { return nil, nil, false @@ -379,7 +370,7 @@ func (r *Router) parse(msg []byte) ([]byte, *meteredHandler, bool) { } // Invariant: Assumes [r.lock] isn't held. -func (r *Router) clearAppRequest(requestID uint32) (pendingAppRequest, bool) { +func (r *router) clearAppRequest(requestID uint32) (pendingAppRequest, bool) { r.lock.Lock() defer r.lock.Unlock() @@ -389,7 +380,7 @@ func (r *Router) clearAppRequest(requestID uint32) (pendingAppRequest, bool) { } // Invariant: Assumes [r.lock] isn't held. -func (r *Router) clearCrossChainAppRequest(requestID uint32) (pendingCrossChainAppRequest, bool) { +func (r *router) clearCrossChainAppRequest(requestID uint32) (pendingCrossChainAppRequest, bool) { r.lock.Lock() defer r.lock.Unlock() diff --git a/network/p2p/router_test.go b/network/p2p/router_test.go deleted file mode 100644 index 924a72b0b70a..000000000000 --- a/network/p2p/router_test.go +++ /dev/null @@ -1,360 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package p2p - -import ( - "context" - "sync" - "testing" - "time" - - "github.com/prometheus/client_golang/prometheus" - - "github.com/stretchr/testify/require" - - "go.uber.org/mock/gomock" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/network/p2p/mocks" - "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/utils/set" -) - -func TestAppRequestResponse(t *testing.T) { - handlerID := uint64(0x0) - request := []byte("request") - response := []byte("response") - nodeID := ids.GenerateTestNodeID() - chainID := ids.GenerateTestID() - - ctxKey := new(string) - ctxVal := new(string) - *ctxKey = "foo" - *ctxVal = "bar" - - tests := []struct { - name string - requestFunc func(t *testing.T, router *Router, client *Client, sender *common.MockSender, handler *mocks.MockHandler, wg *sync.WaitGroup) - }{ - { - name: "app request", - requestFunc: func(t *testing.T, router *Router, client *Client, sender *common.MockSender, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.EXPECT().SendAppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) { - for range nodeIDs { - go func() { - require.NoError(t, router.AppRequest(ctx, nodeID, requestID, time.Time{}, request)) - }() - } - }).AnyTimes() - sender.EXPECT().SendAppResponse(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, _ ids.NodeID, requestID uint32, response []byte) { - go func() { - ctx = context.WithValue(ctx, ctxKey, ctxVal) - require.NoError(t, router.AppResponse(ctx, nodeID, requestID, response)) - }() - }).AnyTimes() - handler.EXPECT(). - AppRequest(context.Background(), nodeID, gomock.Any(), request). - DoAndReturn(func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { - return response, nil - }) - - callback := func(ctx context.Context, actualNodeID ids.NodeID, actualResponse []byte, err error) { - defer wg.Done() - - require.NoError(t, err) - require.Equal(t, ctxVal, ctx.Value(ctxKey)) - require.Equal(t, nodeID, actualNodeID) - require.Equal(t, response, actualResponse) - } - - require.NoError(t, client.AppRequestAny(context.Background(), request, callback)) - }, - }, - { - name: "app request failed", - requestFunc: func(t *testing.T, router *Router, client *Client, sender *common.MockSender, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.EXPECT().SendAppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) { - for range nodeIDs { - go func() { - require.NoError(t, router.AppRequestFailed(ctx, nodeID, requestID)) - }() - } - }) - - callback := func(_ context.Context, actualNodeID ids.NodeID, actualResponse []byte, err error) { - defer wg.Done() - - require.ErrorIs(t, err, ErrAppRequestFailed) - require.Equal(t, nodeID, actualNodeID) - require.Nil(t, actualResponse) - } - - require.NoError(t, client.AppRequest(context.Background(), set.Of(nodeID), request, callback)) - }, - }, - { - name: "cross-chain app request", - requestFunc: func(t *testing.T, router *Router, client *Client, sender *common.MockSender, handler *mocks.MockHandler, wg *sync.WaitGroup) { - chainID := ids.GenerateTestID() - sender.EXPECT().SendCrossChainAppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, chainID ids.ID, requestID uint32, request []byte) { - go func() { - require.NoError(t, router.CrossChainAppRequest(ctx, chainID, requestID, time.Time{}, request)) - }() - }).AnyTimes() - sender.EXPECT().SendCrossChainAppResponse(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) { - go func() { - ctx = context.WithValue(ctx, ctxKey, ctxVal) - require.NoError(t, router.CrossChainAppResponse(ctx, chainID, requestID, response)) - }() - }).AnyTimes() - handler.EXPECT(). - CrossChainAppRequest(context.Background(), chainID, gomock.Any(), request). - DoAndReturn(func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { - return response, nil - }) - - callback := func(ctx context.Context, actualChainID ids.ID, actualResponse []byte, err error) { - defer wg.Done() - require.NoError(t, err) - require.Equal(t, ctxVal, ctx.Value(ctxKey)) - require.Equal(t, chainID, actualChainID) - require.Equal(t, response, actualResponse) - } - - require.NoError(t, client.CrossChainAppRequest(context.Background(), chainID, request, callback)) - }, - }, - { - name: "cross-chain app request failed", - requestFunc: func(t *testing.T, router *Router, client *Client, sender *common.MockSender, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.EXPECT().SendCrossChainAppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, chainID ids.ID, requestID uint32, request []byte) { - go func() { - require.NoError(t, router.CrossChainAppRequestFailed(ctx, chainID, requestID)) - }() - }) - - callback := func(_ context.Context, actualChainID ids.ID, actualResponse []byte, err error) { - defer wg.Done() - - require.ErrorIs(t, err, ErrAppRequestFailed) - require.Equal(t, chainID, actualChainID) - require.Nil(t, actualResponse) - } - - require.NoError(t, client.CrossChainAppRequest(context.Background(), chainID, request, callback)) - }, - }, - { - name: "app gossip", - requestFunc: func(t *testing.T, router *Router, client *Client, sender *common.MockSender, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, gossip []byte) { - go func() { - require.NoError(t, router.AppGossip(ctx, nodeID, gossip)) - }() - }).AnyTimes() - handler.EXPECT(). - AppGossip(context.Background(), nodeID, request). - DoAndReturn(func(context.Context, ids.NodeID, []byte) error { - defer wg.Done() - return nil - }) - - require.NoError(t, client.AppGossip(context.Background(), request)) - }, - }, - { - name: "app gossip specific", - requestFunc: func(t *testing.T, router *Router, client *Client, sender *common.MockSender, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.EXPECT().SendAppGossipSpecific(gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, nodeIDs set.Set[ids.NodeID], gossip []byte) { - for n := range nodeIDs { - nodeID := n - go func() { - require.NoError(t, router.AppGossip(ctx, nodeID, gossip)) - }() - } - }).AnyTimes() - handler.EXPECT(). - AppGossip(context.Background(), nodeID, request). - DoAndReturn(func(context.Context, ids.NodeID, []byte) error { - defer wg.Done() - return nil - }) - - require.NoError(t, client.AppGossipSpecific(context.Background(), set.Of(nodeID), request)) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - sender := common.NewMockSender(ctrl) - handler := mocks.NewMockHandler(ctrl) - router := NewRouter(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - peers := &Peers{} - require.NoError(peers.Connected(context.Background(), nodeID, nil)) - client, err := router.RegisterAppProtocol(handlerID, handler, peers) - require.NoError(err) - - wg := &sync.WaitGroup{} - wg.Add(1) - tt.requestFunc(t, router, client, sender, handler, wg) - wg.Wait() - }) - } -} - -func TestRouterDropMessage(t *testing.T) { - unregistered := byte(0x0) - - tests := []struct { - name string - requestFunc func(router *Router) error - err error - }{ - { - name: "drop unregistered app request message", - requestFunc: func(router *Router) error { - return router.AppRequest(context.Background(), ids.GenerateTestNodeID(), 0, time.Time{}, []byte{unregistered}) - }, - err: nil, - }, - { - name: "drop empty app request message", - requestFunc: func(router *Router) error { - return router.AppRequest(context.Background(), ids.GenerateTestNodeID(), 0, time.Time{}, []byte{}) - }, - err: nil, - }, - { - name: "drop unregistered cross-chain app request message", - requestFunc: func(router *Router) error { - return router.CrossChainAppRequest(context.Background(), ids.GenerateTestID(), 0, time.Time{}, []byte{unregistered}) - }, - err: nil, - }, - { - name: "drop empty cross-chain app request message", - requestFunc: func(router *Router) error { - return router.CrossChainAppRequest(context.Background(), ids.GenerateTestID(), 0, time.Time{}, []byte{}) - }, - err: nil, - }, - { - name: "drop unregistered gossip message", - requestFunc: func(router *Router) error { - return router.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte{unregistered}) - }, - err: nil, - }, - { - name: "drop empty gossip message", - requestFunc: func(router *Router) error { - return router.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte{}) - }, - err: nil, - }, - { - name: "drop unrequested app request failed", - requestFunc: func(router *Router) error { - return router.AppRequestFailed(context.Background(), ids.GenerateTestNodeID(), 0) - }, - err: ErrUnrequestedResponse, - }, - { - name: "drop unrequested app response", - requestFunc: func(router *Router) error { - return router.AppResponse(context.Background(), ids.GenerateTestNodeID(), 0, nil) - }, - err: ErrUnrequestedResponse, - }, - { - name: "drop unrequested cross-chain request failed", - requestFunc: func(router *Router) error { - return router.CrossChainAppRequestFailed(context.Background(), ids.GenerateTestID(), 0) - }, - err: ErrUnrequestedResponse, - }, - { - name: "drop unrequested cross-chain response", - requestFunc: func(router *Router) error { - return router.CrossChainAppResponse(context.Background(), ids.GenerateTestID(), 0, nil) - }, - err: ErrUnrequestedResponse, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require := require.New(t) - - router := NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), "") - - err := tt.requestFunc(router) - require.ErrorIs(err, tt.err) - }) - } -} - -// It's possible for the request id to overflow and wrap around. -// If there are still pending requests with the same request id, we should -// not attempt to issue another request until the previous one has cleared. -func TestAppRequestDuplicateRequestIDs(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - handler := mocks.NewMockHandler(ctrl) - sender := common.NewMockSender(ctrl) - router := NewRouter(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - nodeID := ids.GenerateTestNodeID() - - requestSent := &sync.WaitGroup{} - sender.EXPECT().SendAppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Do(func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) { - for range nodeIDs { - requestSent.Add(1) - go func() { - require.NoError(router.AppRequest(ctx, nodeID, requestID, time.Time{}, request)) - requestSent.Done() - }() - } - }).AnyTimes() - - timeout := &sync.WaitGroup{} - response := []byte("response") - handler.EXPECT().AppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, nodeID ids.NodeID, deadline time.Time, request []byte) ([]byte, error) { - timeout.Wait() - return response, nil - }).AnyTimes() - sender.EXPECT().SendAppResponse(gomock.Any(), gomock.Any(), gomock.Any(), response) - - peers := &Peers{} - require.NoError(peers.Connected(context.Background(), nodeID, nil)) - client, err := router.RegisterAppProtocol(0x1, handler, peers) - require.NoError(err) - - require.NoError(client.AppRequest(context.Background(), set.Of(nodeID), []byte{}, nil)) - requestSent.Wait() - - // force the router to use the same requestID - router.requestID = 1 - timeout.Add(1) - err = client.AppRequest(context.Background(), set.Of(nodeID), []byte{}, nil) - requestSent.Wait() - require.ErrorIs(err, ErrRequestPending) - - timeout.Done() -} diff --git a/network/p2p/validators.go b/network/p2p/validators.go index edad9b890430..a780c87f0d8c 100644 --- a/network/p2p/validators.go +++ b/network/p2p/validators.go @@ -22,11 +22,18 @@ var ( ) type ValidatorSet interface { - Has(ctx context.Context, nodeID ids.NodeID) bool + Has(ctx context.Context, nodeID ids.NodeID) bool // TODO return error } -func NewValidators(log logging.Logger, subnetID ids.ID, validators validators.State, maxValidatorSetStaleness time.Duration) *Validators { +func NewValidators( + peers *Peers, + log logging.Logger, + subnetID ids.ID, + validators validators.State, + maxValidatorSetStaleness time.Duration, +) *Validators { return &Validators{ + peers: peers, log: log, subnetID: subnetID, validators: validators, @@ -36,6 +43,7 @@ func NewValidators(log logging.Logger, subnetID ids.ID, validators validators.St // Validators contains a set of nodes that are staking. type Validators struct { + peers *Peers log logging.Logger subnetID ids.ID validators validators.State @@ -71,20 +79,33 @@ func (v *Validators) refresh(ctx context.Context) { v.lastUpdated = time.Now() } +// Sample returns a random sample of connected validators func (v *Validators) Sample(ctx context.Context, limit int) []ids.NodeID { v.lock.Lock() defer v.lock.Unlock() v.refresh(ctx) - return v.validatorIDs.Sample(limit) + validatorIDs := v.validatorIDs.Sample(limit) + sampled := validatorIDs[:0] + + for _, validatorID := range validatorIDs { + if !v.peers.has(validatorID) { + continue + } + + sampled = append(sampled, validatorID) + } + + return sampled } +// Has returns if nodeID is a connected validator func (v *Validators) Has(ctx context.Context, nodeID ids.NodeID) bool { v.lock.Lock() defer v.lock.Unlock() v.refresh(ctx) - return v.validatorIDs.Contains(nodeID) + return v.peers.has(nodeID) && v.validatorIDs.Contains(nodeID) } diff --git a/network/p2p/validators_test.go b/network/p2p/validators_test.go index 5db06f7a2efa..e721b4a978af 100644 --- a/network/p2p/validators_test.go +++ b/network/p2p/validators_test.go @@ -9,11 +9,14 @@ import ( "testing" "time" + "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" ) @@ -151,9 +154,8 @@ func TestValidatorsSample(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - ctrl := gomock.NewController(t) - subnetID := ids.GenerateTestID() + ctrl := gomock.NewController(t) mockValidators := validators.NewMockState(ctrl) calls := make([]*gomock.Call, 0) @@ -177,7 +179,12 @@ func TestValidatorsSample(t *testing.T) { } gomock.InOrder(calls...) - v := NewValidators(logging.NoLog{}, subnetID, mockValidators, tt.maxStaleness) + network := NewNetwork(logging.NoLog{}, &common.SenderTest{}, prometheus.NewRegistry(), "") + ctx := context.Background() + require.NoError(network.Connected(ctx, nodeID1, nil)) + require.NoError(network.Connected(ctx, nodeID2, nil)) + + v := NewValidators(network.Peers, network.log, subnetID, mockValidators, tt.maxStaleness) for _, call := range tt.calls { v.lastUpdated = call.time sampled := v.Sample(context.Background(), call.limit) From 9b851419158596a5c200e47d83108a71bea8bddb Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:42:36 -0800 Subject: [PATCH 090/267] `vms/platformvm`: Move `GetRewardUTXOs`, `GetSubnets`, and `GetChains` to `State` interface (#2402) --- vms/platformvm/state/diff.go | 97 +---------------- vms/platformvm/state/diff_test.go | 164 +++++++++++++++-------------- vms/platformvm/state/mock_state.go | 90 ---------------- vms/platformvm/state/state.go | 7 +- 4 files changed, 88 insertions(+), 270 deletions(-) diff --git a/vms/platformvm/state/diff.go b/vms/platformvm/state/diff.go index 1aafcf079969..d509fa69e0dd 100644 --- a/vms/platformvm/state/diff.go +++ b/vms/platformvm/state/diff.go @@ -47,10 +47,8 @@ type diff struct { subnetOwners map[ids.ID]fx.Owner // Subnet ID --> Tx that transforms the subnet transformedSubnets map[ids.ID]*txs.Tx - cachedSubnets []*txs.Tx - addedChains map[ids.ID][]*txs.Tx - cachedChains map[ids.ID][]*txs.Tx + addedChains map[ids.ID][]*txs.Tx addedRewardUTXOs map[ids.ID][]*avax.UTXO @@ -259,41 +257,8 @@ func (d *diff) GetPendingStakerIterator() (StakerIterator, error) { return d.pendingStakerDiffs.GetStakerIterator(parentIterator), nil } -func (d *diff) GetSubnets() ([]*txs.Tx, error) { - if len(d.addedSubnets) == 0 { - parentState, ok := d.stateVersions.GetState(d.parentID) - if !ok { - return nil, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) - } - return parentState.GetSubnets() - } - - if len(d.cachedSubnets) != 0 { - return d.cachedSubnets, nil - } - - parentState, ok := d.stateVersions.GetState(d.parentID) - if !ok { - return nil, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) - } - subnets, err := parentState.GetSubnets() - if err != nil { - return nil, err - } - newSubnets := make([]*txs.Tx, len(subnets)+len(d.addedSubnets)) - copy(newSubnets, subnets) - for i, subnet := range d.addedSubnets { - newSubnets[i+len(subnets)] = subnet - } - d.cachedSubnets = newSubnets - return newSubnets, nil -} - func (d *diff) AddSubnet(createSubnetTx *txs.Tx) { d.addedSubnets = append(d.addedSubnets, createSubnetTx) - if d.cachedSubnets != nil { - d.cachedSubnets = append(d.cachedSubnets, createSubnetTx) - } } func (d *diff) GetSubnetOwner(subnetID ids.ID) (fx.Owner, error) { @@ -339,48 +304,6 @@ func (d *diff) AddSubnetTransformation(transformSubnetTxIntf *txs.Tx) { } } -func (d *diff) GetChains(subnetID ids.ID) ([]*txs.Tx, error) { - addedChains := d.addedChains[subnetID] - if len(addedChains) == 0 { - // No chains have been added to this subnet - parentState, ok := d.stateVersions.GetState(d.parentID) - if !ok { - return nil, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) - } - return parentState.GetChains(subnetID) - } - - // There have been chains added to the requested subnet - - if d.cachedChains == nil { - // This is the first time we are going to be caching the subnet chains - d.cachedChains = make(map[ids.ID][]*txs.Tx) - } - - cachedChains, cached := d.cachedChains[subnetID] - if cached { - return cachedChains, nil - } - - // This chain wasn't cached yet - parentState, ok := d.stateVersions.GetState(d.parentID) - if !ok { - return nil, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) - } - chains, err := parentState.GetChains(subnetID) - if err != nil { - return nil, err - } - - newChains := make([]*txs.Tx, len(chains)+len(addedChains)) - copy(newChains, chains) - for i, chain := range addedChains { - newChains[i+len(chains)] = chain - } - d.cachedChains[subnetID] = newChains - return newChains, nil -} - func (d *diff) AddChain(createChainTx *txs.Tx) { tx := createChainTx.Unsigned.(*txs.CreateChainTx) if d.addedChains == nil { @@ -390,12 +313,6 @@ func (d *diff) AddChain(createChainTx *txs.Tx) { } else { d.addedChains[tx.SubnetID] = append(d.addedChains[tx.SubnetID], createChainTx) } - - cachedChains, cached := d.cachedChains[tx.SubnetID] - if !cached { - return - } - d.cachedChains[tx.SubnetID] = append(cachedChains, createChainTx) } func (d *diff) GetTx(txID ids.ID) (*txs.Tx, status.Status, error) { @@ -425,18 +342,6 @@ func (d *diff) AddTx(tx *txs.Tx, status status.Status) { } } -func (d *diff) GetRewardUTXOs(txID ids.ID) ([]*avax.UTXO, error) { - if utxos, exists := d.addedRewardUTXOs[txID]; exists { - return utxos, nil - } - - parentState, ok := d.stateVersions.GetState(d.parentID) - if !ok { - return nil, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) - } - return parentState.GetRewardUTXOs(txID) -} - func (d *diff) AddRewardUTXO(txID ids.ID, utxo *avax.UTXO) { if d.addedRewardUTXOs == nil { d.addedRewardUTXOs = make(map[ids.ID][]*avax.UTXO) diff --git a/vms/platformvm/state/diff_test.go b/vms/platformvm/state/diff_test.go index 9b833f8482a8..50c87b2d3a53 100644 --- a/vms/platformvm/state/diff_test.go +++ b/vms/platformvm/state/diff_test.go @@ -250,15 +250,28 @@ func TestDiffSubnet(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state := NewMockState(ctrl) - // Called in NewDiff - state.EXPECT().GetTimestamp().Return(time.Now()).Times(1) + state, _ := newInitializedState(require) + + // Initialize parent with one subnet + parentStateCreateSubnetTx := &txs.Tx{ + Unsigned: &txs.CreateSubnetTx{ + Owner: fx.NewMockOwner(ctrl), + }, + } + state.AddSubnet(parentStateCreateSubnetTx) + + // Verify parent returns one subnet + subnets, err := state.GetSubnets() + require.NoError(err) + require.Equal([]*txs.Tx{ + parentStateCreateSubnetTx, + }, subnets) states := NewMockVersions(ctrl) lastAcceptedID := ids.GenerateTestID() states.EXPECT().GetState(lastAcceptedID).Return(state, true).AnyTimes() - d, err := NewDiff(lastAcceptedID, states) + diff, err := NewDiff(lastAcceptedID, states) require.NoError(err) // Put a subnet @@ -267,60 +280,67 @@ func TestDiffSubnet(t *testing.T) { Owner: fx.NewMockOwner(ctrl), }, } - d.AddSubnet(createSubnetTx) + diff.AddSubnet(createSubnetTx) - // Assert that we get the subnet back - // [state] returns 1 subnet. - parentStateCreateSubnetTx := &txs.Tx{ - Unsigned: &txs.CreateSubnetTx{ - Owner: fx.NewMockOwner(ctrl), - }, - } - state.EXPECT().GetSubnets().Return([]*txs.Tx{parentStateCreateSubnetTx}, nil).Times(1) - gotSubnets, err := d.GetSubnets() + // Apply diff to parent state + require.NoError(diff.Apply(state)) + + // Verify parent now returns two subnets + subnets, err = state.GetSubnets() require.NoError(err) - require.Len(gotSubnets, 2) - require.Equal(gotSubnets[0], parentStateCreateSubnetTx) - require.Equal(gotSubnets[1], createSubnetTx) + require.Equal([]*txs.Tx{ + parentStateCreateSubnetTx, + createSubnetTx, + }, subnets) } func TestDiffChain(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state := NewMockState(ctrl) - // Called in NewDiff - state.EXPECT().GetTimestamp().Return(time.Now()).Times(1) + state, _ := newInitializedState(require) + subnetID := ids.GenerateTestID() + + // Initialize parent with one chain + parentStateCreateChainTx := &txs.Tx{ + Unsigned: &txs.CreateChainTx{ + SubnetID: subnetID, + }, + } + state.AddChain(parentStateCreateChainTx) + + // Verify parent returns one chain + chains, err := state.GetChains(subnetID) + require.NoError(err) + require.Equal([]*txs.Tx{ + parentStateCreateChainTx, + }, chains) states := NewMockVersions(ctrl) lastAcceptedID := ids.GenerateTestID() states.EXPECT().GetState(lastAcceptedID).Return(state, true).AnyTimes() - d, err := NewDiff(lastAcceptedID, states) + diff, err := NewDiff(lastAcceptedID, states) require.NoError(err) // Put a chain - subnetID := ids.GenerateTestID() createChainTx := &txs.Tx{ Unsigned: &txs.CreateChainTx{ - SubnetID: subnetID, + SubnetID: subnetID, // note this is the same subnet as [parentStateCreateChainTx] }, } - d.AddChain(createChainTx) + diff.AddChain(createChainTx) - // Assert that we get the chain back - // [state] returns 1 chain. - parentStateCreateChainTx := &txs.Tx{ - Unsigned: &txs.CreateChainTx{ - SubnetID: subnetID, // note this is the same subnet as [createChainTx] - }, - } - state.EXPECT().GetChains(subnetID).Return([]*txs.Tx{parentStateCreateChainTx}, nil).Times(1) - gotChains, err := d.GetChains(subnetID) + // Apply diff to parent state + require.NoError(diff.Apply(state)) + + // Verify parent now returns two chains + chains, err = state.GetChains(subnetID) require.NoError(err) - require.Len(gotChains, 2) - require.Equal(parentStateCreateChainTx, gotChains[0]) - require.Equal(createChainTx, gotChains[1]) + require.Equal([]*txs.Tx{ + parentStateCreateChainTx, + createChainTx, + }, chains) } func TestDiffTx(t *testing.T) { @@ -377,45 +397,46 @@ func TestDiffRewardUTXO(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state := NewMockState(ctrl) - // Called in NewDiff - state.EXPECT().GetTimestamp().Return(time.Now()).Times(1) + state, _ := newInitializedState(require) + + txID := ids.GenerateTestID() + + // Initialize parent with one reward UTXO + parentRewardUTXO := &avax.UTXO{ + UTXOID: avax.UTXOID{TxID: txID}, + } + state.AddRewardUTXO(txID, parentRewardUTXO) + + // Verify parent returns the reward UTXO + rewardUTXOs, err := state.GetRewardUTXOs(txID) + require.NoError(err) + require.Equal([]*avax.UTXO{ + parentRewardUTXO, + }, rewardUTXOs) states := NewMockVersions(ctrl) lastAcceptedID := ids.GenerateTestID() states.EXPECT().GetState(lastAcceptedID).Return(state, true).AnyTimes() - d, err := NewDiff(lastAcceptedID, states) + diff, err := NewDiff(lastAcceptedID, states) require.NoError(err) // Put a reward UTXO - txID := ids.GenerateTestID() rewardUTXO := &avax.UTXO{ UTXOID: avax.UTXOID{TxID: txID}, } - d.AddRewardUTXO(txID, rewardUTXO) + diff.AddRewardUTXO(txID, rewardUTXO) - { - // Assert that we get the UTXO back - gotRewardUTXOs, err := d.GetRewardUTXOs(txID) - require.NoError(err) - require.Len(gotRewardUTXOs, 1) - require.Equal(rewardUTXO, gotRewardUTXOs[0]) - } + // Apply diff to parent state + require.NoError(diff.Apply(state)) - { - // Assert that we can get a UTXO from the parent state - // [state] returns 1 UTXO. - txID2 := ids.GenerateTestID() - parentRewardUTXO := &avax.UTXO{ - UTXOID: avax.UTXOID{TxID: txID2}, - } - state.EXPECT().GetRewardUTXOs(txID2).Return([]*avax.UTXO{parentRewardUTXO}, nil).Times(1) - gotParentRewardUTXOs, err := d.GetRewardUTXOs(txID2) - require.NoError(err) - require.Len(gotParentRewardUTXOs, 1) - require.Equal(parentRewardUTXO, gotParentRewardUTXOs[0]) - } + // Verify parent now returns two reward UTXOs + rewardUTXOs, err = state.GetRewardUTXOs(txID) + require.NoError(err) + require.Equal([]*avax.UTXO{ + parentRewardUTXO, + rewardUTXO, + }, rewardUTXOs) } func TestDiffUTXO(t *testing.T) { @@ -496,25 +517,6 @@ func assertChainsEqual(t *testing.T, expected, actual Chain) { require.NoError(err) require.Equal(expectedCurrentSupply, actualCurrentSupply) - - expectedSubnets, expectedErr := expected.GetSubnets() - actualSubnets, actualErr := actual.GetSubnets() - require.Equal(expectedErr, actualErr) - if expectedErr == nil { - require.Equal(expectedSubnets, actualSubnets) - - for _, subnet := range expectedSubnets { - subnetID := subnet.ID() - - expectedChains, expectedErr := expected.GetChains(subnetID) - actualChains, actualErr := actual.GetChains(subnetID) - require.Equal(expectedErr, actualErr) - if expectedErr != nil { - continue - } - require.Equal(expectedChains, actualChains) - } - } } func TestDiffSubnetOwner(t *testing.T) { diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index 465b3fda2bac..8a3aac7d81f1 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -180,21 +180,6 @@ func (mr *MockChainMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), arg0) } -// GetChains mocks base method. -func (m *MockChain) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChains", arg0) - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChains indicates an expected call of GetChains. -func (mr *MockChainMockRecorder) GetChains(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockChain)(nil).GetChains), arg0) -} - // GetCurrentDelegatorIterator mocks base method. func (m *MockChain) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { m.ctrl.T.Helper() @@ -315,21 +300,6 @@ func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), arg0, arg1) } -// GetRewardUTXOs mocks base method. -func (m *MockChain) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. -func (mr *MockChainMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockChain)(nil).GetRewardUTXOs), arg0) -} - // GetSubnetOwner mocks base method. func (m *MockChain) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { m.ctrl.T.Helper() @@ -360,21 +330,6 @@ func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), arg0) } -// GetSubnets mocks base method. -func (m *MockChain) GetSubnets() ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnets") - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnets indicates an expected call of GetSubnets. -func (mr *MockChainMockRecorder) GetSubnets() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockChain)(nil).GetSubnets)) -} - // GetTimestamp mocks base method. func (m *MockChain) GetTimestamp() time.Time { m.ctrl.T.Helper() @@ -687,21 +642,6 @@ func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) } -// GetChains mocks base method. -func (m *MockDiff) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChains", arg0) - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChains indicates an expected call of GetChains. -func (mr *MockDiffMockRecorder) GetChains(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockDiff)(nil).GetChains), arg0) -} - // GetCurrentDelegatorIterator mocks base method. func (m *MockDiff) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { m.ctrl.T.Helper() @@ -822,21 +762,6 @@ func (mr *MockDiffMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockDiff)(nil).GetPendingValidator), arg0, arg1) } -// GetRewardUTXOs mocks base method. -func (m *MockDiff) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. -func (mr *MockDiffMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockDiff)(nil).GetRewardUTXOs), arg0) -} - // GetSubnetOwner mocks base method. func (m *MockDiff) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { m.ctrl.T.Helper() @@ -867,21 +792,6 @@ func (mr *MockDiffMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).GetSubnetTransformation), arg0) } -// GetSubnets mocks base method. -func (m *MockDiff) GetSubnets() ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnets") - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnets indicates an expected call of GetSubnets. -func (mr *MockDiffMockRecorder) GetSubnets() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockDiff)(nil).GetSubnets)) -} - // GetTimestamp mocks base method. func (m *MockDiff) GetTimestamp() time.Time { m.ctrl.T.Helper() diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 4b2b59cf2f70..4627fc706626 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -106,10 +106,8 @@ type Chain interface { GetCurrentSupply(subnetID ids.ID) (uint64, error) SetCurrentSupply(subnetID ids.ID, cs uint64) - GetRewardUTXOs(txID ids.ID) ([]*avax.UTXO, error) AddRewardUTXO(txID ids.ID, utxo *avax.UTXO) - GetSubnets() ([]*txs.Tx, error) AddSubnet(createSubnetTx *txs.Tx) GetSubnetOwner(subnetID ids.ID) (fx.Owner, error) @@ -118,7 +116,6 @@ type Chain interface { GetSubnetTransformation(subnetID ids.ID) (*txs.Tx, error) AddSubnetTransformation(transformSubnetTx *txs.Tx) - GetChains(subnetID ids.ID) ([]*txs.Tx, error) AddChain(createChainTx *txs.Tx) GetTx(txID ids.ID) (*txs.Tx, status.Status, error) @@ -140,6 +137,10 @@ type State interface { GetBlockIDAtHeight(height uint64) (ids.ID, error) + GetRewardUTXOs(txID ids.ID) ([]*avax.UTXO, error) + GetSubnets() ([]*txs.Tx, error) + GetChains(subnetID ids.ID) ([]*txs.Tx, error) + // ApplyValidatorWeightDiffs iterates from [startHeight] towards the genesis // block until it has applied all of the diffs up to and including // [endHeight]. Applying the diffs modifies [validators]. From be1a2ad249910c0e4f7606afd8b19d2f48c728fd Mon Sep 17 00:00:00 2001 From: aaronbuchwald Date: Fri, 1 Dec 2023 13:31:49 -0500 Subject: [PATCH 091/267] Add more descriptive formatted error (#2403) Co-authored-by: Stephen Buttolph --- chains/atomic/state.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/chains/atomic/state.go b/chains/atomic/state.go index cd7a3f2a0faa..aee269915ea9 100644 --- a/chains/atomic/state.go +++ b/chains/atomic/state.go @@ -6,6 +6,7 @@ package atomic import ( "bytes" "errors" + "fmt" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/linkeddb" @@ -16,7 +17,10 @@ import ( "github.com/ava-labs/avalanchego/utils/set" ) -var errDuplicatedOperation = errors.New("duplicated operation on provided value") +var ( + errDuplicatePut = errors.New("duplicate put") + errDuplicateRemove = errors.New("duplicate remove") +) type dbElement struct { // Present indicates the value was removed before existing. @@ -86,7 +90,7 @@ func (s *state) SetValue(e *Element) error { } // This key was written twice, which is invalid - return errDuplicatedOperation + return fmt.Errorf("%w: Key=0x%x Value=0x%x", errDuplicatePut, e.Key, e.Value) } if err != database.ErrNotFound { // An unexpected error occurred, so we should propagate that error @@ -160,7 +164,7 @@ func (s *state) RemoveValue(key []byte) error { // Don't allow the removal of something that was already removed. if !value.Present { - return errDuplicatedOperation + return fmt.Errorf("%w: Key=0x%x", errDuplicateRemove, key) } // Remove [key] from the indexDB for each trait that has indexed this key. From 7623ffd4be915a5185c9ed5e11fa9be15a6e1f00 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 1 Dec 2023 19:39:15 -0500 Subject: [PATCH 092/267] Update versions for v1.10.17 (#2394) --- RELEASES.md | 72 ++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +-- version/compatibility.json | 3 +- version/constants.go | 2 +- 5 files changed, 78 insertions(+), 5 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 073214ac4424..a7c232d7674b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,77 @@ # Release Notes +## [v1.10.17](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.17) + +This version is backwards compatible to [v1.10.0](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0). It is optional, but encouraged. + +The plugin version is unchanged at `30` and is compatible with versions `v1.10.15-v1.10.16`. + +### APIs + +- Added `avalanche_{chainID}_blks_build_accept_latency` metric +- Added `avalanche_{chainID}_blks_issued{source}` metric with sources: + - `pull_gossip` + - `push_gossip` + - `put_gossip` which is deprecated + - `built` + - `unknown` +- Added `avalanche_{chainID}_issuer_stake_sum` metric +- Added `avalanche_{chainID}_issuer_stake_count` metric + +### Configs + +- Added: + - `--consensus-frontier-poll-frequency` +- Removed: + - `--consensus-accepted-frontier-gossip-frequency` +- Deprecated: + - `--consensus-accepted-frontier-gossip-validator-size` + - `--consensus-accepted-frontier-gossip-non-validator-size` + - `--consensus-accepted-frontier-gossip-peer-size` + - Updated the default value to 1 to align with the change in default gossip frequency + - `--consensus-on-accept-gossip-validator-size` + - `--consensus-on-accept-gossip-non-validator-size` + - `--consensus-on-accept-gossip-peer-size` + +### Fixes + +- Fixed `duplicated operation on provided value` error when executing atomic operations after state syncing the C-chain +- Removed useage of atomic trie after commitment +- Fixed atomic trie root overwrite during state sync +- Prevented closure of `stdout` and `stderr` when shutting down the logger + +### What's Changed + +- Remove Banff check from mempool verifier by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2360 +- Document storage growth in readme by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2364 +- Add metric for duration between block timestamp and acceptance time by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2366 +- `vms/platformvm`: Remove unused `withMetrics` txheap by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2373 +- Move peerTracker from x/sync to network/p2p by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2356 +- Logging avoid closing standard outputs by @felipemadero in https://github.com/ava-labs/avalanchego/pull/2372 +- `vms/platformvm`: Adjust `Diff.Apply` signature by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2368 +- Add bls validator info to genesis by @felipemadero in https://github.com/ava-labs/avalanchego/pull/2371 +- Remove `engine.GetVM` by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2374 +- `vms/platformvm`: Consolidate `state` pkg mocks by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2370 +- Remove common bootstrapper by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2297 +- `vms/platformvm`: Move `toEngine` channel to mempool by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2333 +- `vms/avm`: Rename `states` pkg to `state` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2381 +- Implement generic bimap by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2383 +- Unexport RequestID from snowman engine by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2384 +- Add metric to track the stake weight of block providers by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2376 +- Add block source metrics to monitor gossip by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2386 +- Rename `D` to `Durango` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2389 +- Replace periodic push accepted gossip with pull preference gossip for block discovery by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2367 +- MerkleDB Remove ID from Node to reduce size and removal channel creation. by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2324 +- Remove method `CappedList` from `set.Set` by @danlaine in https://github.com/ava-labs/avalanchego/pull/2395 +- Periodically PullGossip only from connected validators by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2399 +- Update bootstrap IPs by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2396 +- Rename `testnet` fixture to `tmpnet` by @marun in https://github.com/ava-labs/avalanchego/pull/2307 +- Add `p2p.Network` component by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2283 +- `vms/platformvm`: Move `GetRewardUTXOs`, `GetSubnets`, and `GetChains` to `State` interface by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2402 +- Add more descriptive formatted error by @aaronbuchwald in https://github.com/ava-labs/avalanchego/pull/2403 + +**Full Changelog**: https://github.com/ava-labs/avalanchego/compare/v1.10.16...v1.10.17 + ## [v1.10.16](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.16) This version is backwards compatible to [v1.10.0](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0). It is optional, but encouraged. diff --git a/go.mod b/go.mod index 9a629725cdef..383c70b22cf7 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.7 + github.com/ava-labs/coreth v0.12.9-rc.9 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 3478c17b2d6b..04c29d1a591d 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.7 h1:AlCmXnrJwo0NxlEXQHysQgRQSCA14PZW6iyJmeVYB34= -github.com/ava-labs/coreth v0.12.9-rc.7/go.mod h1:yrf2vEah4Fgj6sJ4UpHewo4DLolwdpf2bJuLRT80PGw= +github.com/ava-labs/coreth v0.12.9-rc.9 h1:mvYxABdyPByXwwwIxnTBCiNO23dsE1Kfnd5H106lric= +github.com/ava-labs/coreth v0.12.9-rc.9/go.mod h1:yrf2vEah4Fgj6sJ4UpHewo4DLolwdpf2bJuLRT80PGw= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/version/compatibility.json b/version/compatibility.json index c3b35ed515ec..d34dfb1a5a28 100644 --- a/version/compatibility.json +++ b/version/compatibility.json @@ -1,7 +1,8 @@ { "30": [ "v1.10.15", - "v1.10.16" + "v1.10.16", + "v1.10.17" ], "29": [ "v1.10.13", diff --git a/version/constants.go b/version/constants.go index a9bc3d2a6f91..f7c27f641395 100644 --- a/version/constants.go +++ b/version/constants.go @@ -22,7 +22,7 @@ var ( Current = &Semantic{ Major: 1, Minor: 10, - Patch: 16, + Patch: 17, } CurrentApp = &Application{ Major: Current.Major, From 04af33e14494f8cdfec6480fdccfe8879a713f70 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Sat, 2 Dec 2023 16:33:07 -0500 Subject: [PATCH 093/267] `vms/platformvm`: Cleanup block builder tests (#2406) Co-authored-by: Stephen Buttolph --- vms/platformvm/block/builder/builder_test.go | 163 ++++++++++--------- vms/platformvm/block/builder/helpers_test.go | 14 -- 2 files changed, 86 insertions(+), 91 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 04abf5d65b71..7d97e88a40d7 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -15,26 +15,22 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/block" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" ) -var errTestingDropped = errors.New("testing dropped") - -// shows that a locally generated CreateChainTx can be added to mempool and then -// removed by inclusion in a block func TestBlockBuilderAddLocalTx(t *testing.T) { require := require.New(t) @@ -44,17 +40,24 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { require.NoError(shutdownEnvironment(env)) }() - // add a tx to it - tx := getValidTx(env.txBuilder, t) + // Create a valid transaction + tx, err := env.txBuilder.NewCreateChainTx( + testSubnet1.ID(), + nil, + constants.AVMID, + nil, + "chain name", + []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, + ids.ShortEmpty, + ) + require.NoError(err) txID := tx.ID() - env.sender.SendAppGossipF = func(context.Context, []byte) error { - return nil - } + // Issue the transaction require.NoError(env.network.IssueTx(context.Background(), tx)) require.True(env.mempool.Has(txID)) - // show that build block include that tx and removes it from mempool + // [BuildBlock] should build a block with the transaction blkIntf, err := env.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -63,7 +66,9 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { require.Len(blk.Txs(), 1) require.Equal(txID, blk.Txs()[0].ID()) + // Mempool should not contain the transaction or have marked it as dropped require.False(env.mempool.Has(txID)) + require.NoError(env.mempool.GetDropReason(txID)) } func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { @@ -75,45 +80,67 @@ func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { require.NoError(shutdownEnvironment(env)) }() - // create candidate tx - tx := getValidTx(env.txBuilder, t) + // Create a valid transaction + tx, err := env.txBuilder.NewCreateChainTx( + testSubnet1.ID(), + nil, + constants.AVMID, + nil, + "chain name", + []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, + ids.ShortEmpty, + ) + require.NoError(err) txID := tx.ID() - // A tx simply added to mempool is obviously not marked as dropped - require.NoError(env.mempool.Add(tx)) + // Issue the transaction + require.NoError(env.network.IssueTx(context.Background(), tx)) require.True(env.mempool.Has(txID)) + + // Transaction should not be marked as dropped when added to the mempool reason := env.mempool.GetDropReason(txID) require.NoError(reason) - // When a tx is marked as dropped, it is still available to allow re-issuance + // Mark the transaction as dropped + errTestingDropped := errors.New("testing dropped") env.mempool.MarkDropped(txID, errTestingDropped) - require.True(env.mempool.Has(txID)) // still available reason = env.mempool.GetDropReason(txID) require.ErrorIs(reason, errTestingDropped) - // A previously dropped tx, popped then re-added to mempool, - // is not dropped anymore + // Dropped transactions should still be in the mempool + require.True(env.mempool.Has(txID)) + + // Remove the transaction from the mempool env.mempool.Remove([]*txs.Tx{tx}) - require.NoError(env.mempool.Add(tx)) + // Issue the transaction again + require.NoError(env.network.IssueTx(context.Background(), tx)) require.True(env.mempool.Has(txID)) + + // When issued again, the mempool should not be marked as dropped reason = env.mempool.GetDropReason(txID) require.NoError(reason) } func TestNoErrorOnUnexpectedSetPreferenceDuringBootstrapping(t *testing.T) { + require := require.New(t) + env := newEnvironment(t) env.ctx.Lock.Lock() env.isBootstrapped.Set(false) - env.ctx.Log = logging.NoWarn{} defer func() { - require.NoError(t, shutdownEnvironment(env)) + require.NoError(shutdownEnvironment(env)) }() - require.False(t, env.blkManager.SetPreference(ids.GenerateTestID())) // should not panic + require.False(env.blkManager.SetPreference(ids.GenerateTestID())) // should not panic } func TestGetNextStakerToReward(t *testing.T) { + var ( + now = time.Now() + txID = ids.GenerateTestID() + ) + type test struct { name string timestamp time.Time @@ -123,10 +150,6 @@ func TestGetNextStakerToReward(t *testing.T) { expectedErr error } - var ( - now = time.Now() - txID = ids.GenerateTestID() - ) tests := []test{ { name: "end of time", @@ -295,49 +318,35 @@ func TestGetNextStakerToReward(t *testing.T) { } func TestBuildBlock(t *testing.T) { + env := newEnvironment(t) + env.ctx.Lock.Lock() + defer func() { + require.NoError(t, shutdownEnvironment(env)) + }() + var ( - parentID = ids.GenerateTestID() - height = uint64(1337) - output = &avax.TransferableOutput{ - Asset: avax.Asset{ID: ids.GenerateTestID()}, - Out: &secp256k1fx.TransferOutput{ - OutputOwners: secp256k1fx.OutputOwners{ - Addrs: []ids.ShortID{ids.GenerateTestShortID()}, - }, - }, - } - now = time.Now() + now = env.backend.Clk.Time() + parentID = ids.GenerateTestID() + height = uint64(1337) parentTimestamp = now.Add(-2 * time.Second) - transactions = []*txs.Tx{{ - Unsigned: &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - Ins: []*avax.TransferableInput{{ - Asset: avax.Asset{ID: ids.GenerateTestID()}, - In: &secp256k1fx.TransferInput{ - Input: secp256k1fx.Input{ - SigIndices: []uint32{0}, - }, - }, - }}, - Outs: []*avax.TransferableOutput{output}, - }}, - Validator: txs.Validator{ - // Shouldn't be dropped - Start: uint64(now.Add(2 * txexecutor.SyncBound).Unix()), - }, - StakeOuts: []*avax.TransferableOutput{output}, - RewardsOwner: &secp256k1fx.OutputOwners{ - Addrs: []ids.ShortID{ids.GenerateTestShortID()}, - }, - }, - Creds: []verify.Verifiable{ - &secp256k1fx.Credential{ - Sigs: [][secp256k1.SignatureLen]byte{{1, 3, 3, 7}}, - }, - }, - }} - stakerTxID = ids.GenerateTestID() + stakerTxID = ids.GenerateTestID() + + defaultValidatorStake = 100 * units.MilliAvax + validatorStartTime = now.Add(2 * txexecutor.SyncBound) + validatorEndTime = validatorStartTime.Add(360 * 24 * time.Hour) + ) + + tx, err := env.txBuilder.NewAddValidatorTx( + defaultValidatorStake, + uint64(validatorStartTime.Unix()), + uint64(validatorEndTime.Unix()), + ids.GenerateTestNodeID(), + preFundedKeys[0].PublicKey().Address(), + reward.PercentDenominator, + []*secp256k1.PrivateKey{preFundedKeys[0]}, + preFundedKeys[0].PublicKey().Address(), ) + require.NoError(t, err) type test struct { name string @@ -357,7 +366,7 @@ func TestBuildBlock(t *testing.T) { // The tx builder should be asked to build a reward tx txBuilder := txbuilder.NewMockBuilder(ctrl) - txBuilder.EXPECT().NewRewardValidatorTx(stakerTxID).Return(transactions[0], nil) + txBuilder.EXPECT().NewRewardValidatorTx(stakerTxID).Return(tx, nil) return &builder{ Mempool: mempool, @@ -388,7 +397,7 @@ func TestBuildBlock(t *testing.T) { parentTimestamp, parentID, height, - transactions[0], + tx, ) require.NoError(err) return expectedBlk @@ -403,7 +412,7 @@ func TestBuildBlock(t *testing.T) { // There are txs. mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) mempool.EXPECT().HasTxs().Return(true) - mempool.EXPECT().PeekTxs(targetBlockSize).Return(transactions) + mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{tx}) return &builder{ Mempool: mempool, } @@ -435,7 +444,7 @@ func TestBuildBlock(t *testing.T) { parentTimestamp, parentID, height, - transactions, + []*txs.Tx{tx}, ) require.NoError(err) return expectedBlk @@ -553,7 +562,7 @@ func TestBuildBlock(t *testing.T) { // There is a tx. mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) mempool.EXPECT().HasTxs().Return(true) - mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{transactions[0]}) + mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{tx}) clk := &mockable.Clock{} clk.Set(now) @@ -591,7 +600,7 @@ func TestBuildBlock(t *testing.T) { parentTimestamp, parentID, height, - []*txs.Tx{transactions[0]}, + []*txs.Tx{tx}, ) require.NoError(err) return expectedBlk @@ -607,7 +616,7 @@ func TestBuildBlock(t *testing.T) { // There is a staker tx. mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) mempool.EXPECT().HasTxs().Return(true) - mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{transactions[0]}) + mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{tx}) clk := &mockable.Clock{} clk.Set(now) @@ -645,7 +654,7 @@ func TestBuildBlock(t *testing.T) { parentTimestamp, parentID, height, - []*txs.Tx{transactions[0]}, + []*txs.Tx{tx}, ) require.NoError(err) return expectedBlk diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index de37d08ff0dd..36a6822ce3e2 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -437,17 +437,3 @@ func shutdownEnvironment(env *environment) error { env.baseDB.Close(), ) } - -func getValidTx(txBuilder txbuilder.Builder, t *testing.T) *txs.Tx { - tx, err := txBuilder.NewCreateChainTx( - testSubnet1.ID(), - nil, - constants.AVMID, - nil, - "chain name", - []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, - ids.ShortEmpty, - ) - require.NoError(t, err) - return tx -} From 05ce36676753359fd1fdc802fb7dcf1c00ecc7a6 Mon Sep 17 00:00:00 2001 From: marun Date: Sat, 2 Dec 2023 13:33:18 -0800 Subject: [PATCH 094/267] testing: Update to latest version of ginkgo (#2390) --- go.mod | 14 ++++++++------ go.sum | 29 ++++++++++++++++++----------- scripts/tests.e2e.sh | 2 +- scripts/tests.upgrade.sh | 2 +- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 383c70b22cf7..3547ac3dc558 100644 --- a/go.mod +++ b/go.mod @@ -32,8 +32,8 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/mr-tron/base58 v1.2.0 github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d - github.com/onsi/ginkgo/v2 v2.4.0 - github.com/onsi/gomega v1.24.0 + github.com/onsi/ginkgo/v2 v2.13.1 + github.com/onsi/gomega v1.29.0 github.com/pires/go-proxyproto v0.6.2 github.com/prometheus/client_golang v1.14.0 github.com/prometheus/client_model v0.3.0 @@ -61,7 +61,7 @@ require ( golang.org/x/crypto v0.14.0 golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df golang.org/x/net v0.17.0 - golang.org/x/sync v0.3.0 + golang.org/x/sync v0.4.0 golang.org/x/term v0.13.0 golang.org/x/time v0.0.0-20220922220347-f3bd1da661af gonum.org/v1/gonum v0.11.0 @@ -93,15 +93,16 @@ require ( github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect @@ -145,8 +146,9 @@ require ( go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 04c29d1a591d..50f6bf7f3245 100644 --- a/go.sum +++ b/go.sum @@ -217,8 +217,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= @@ -230,6 +230,8 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -295,8 +297,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -477,16 +480,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= -github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU= +github.com/onsi/ginkgo/v2 v2.13.1/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= -github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= +github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= @@ -583,6 +586,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -732,6 +736,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -802,8 +807,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -873,8 +878,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= @@ -953,6 +958,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/scripts/tests.e2e.sh b/scripts/tests.e2e.sh index 638700c9cc47..63718428b8fd 100755 --- a/scripts/tests.e2e.sh +++ b/scripts/tests.e2e.sh @@ -23,7 +23,7 @@ source ./scripts/constants.sh ################################# echo "building e2e.test" # to install the ginkgo binary (required for test build and run) -go install -v github.com/onsi/ginkgo/v2/ginkgo@v2.1.4 +go install -v github.com/onsi/ginkgo/v2/ginkgo@v2.13.1 ACK_GINKGO_RC=true ginkgo build ./tests/e2e ./tests/e2e/e2e.test --help diff --git a/scripts/tests.upgrade.sh b/scripts/tests.upgrade.sh index 8da20b2d65c0..34d5617bd128 100755 --- a/scripts/tests.upgrade.sh +++ b/scripts/tests.upgrade.sh @@ -56,7 +56,7 @@ source ./scripts/constants.sh ################################# echo "building upgrade.test" # to install the ginkgo binary (required for test build and run) -go install -v github.com/onsi/ginkgo/v2/ginkgo@v2.1.4 +go install -v github.com/onsi/ginkgo/v2/ginkgo@v2.13.1 ACK_GINKGO_RC=true ginkgo build ./tests/upgrade ./tests/upgrade/upgrade.test --help From c11accdc01890ed8cb5948012daa47686f72e3fd Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 09:16:01 -0700 Subject: [PATCH 095/267] Drop Pending Stakers 0 - De-duplicate staking tx verification (#2335) --- tests/e2e/p/staking_rewards.go | 18 +- vms/platformvm/block/builder/builder.go | 19 +- vms/platformvm/state/staker_test.go | 2 +- vms/platformvm/state/state.go | 25 +-- .../txs/executor/staker_tx_verification.go | 170 ++++++++---------- .../txs/executor/standard_tx_executor.go | 56 +++--- .../txs/executor/tx_mempool_verifier.go | 27 +-- 7 files changed, 151 insertions(+), 166 deletions(-) diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index f05b3bfbf64a..475c3de261dd 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -103,12 +103,18 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { betaNodeID, betaPOP, err := betaInfoClient.GetNodeID(e2e.DefaultContext()) require.NoError(err) + pvmClient := platformvm.NewClient(alphaNode.GetProcessContext().URI) + const ( delegationPercent = 0.10 // 10% delegationShare = reward.PercentDenominator * delegationPercent weight = 2_000 * units.Avax ) + ginkgo.By("retrieving supply before inserting validators") + supplyAtValidatorsStart, _, err := pvmClient.GetCurrentSupply(e2e.DefaultContext(), constants.PrimaryNetworkID) + require.NoError(err) + alphaValidatorStartTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) alphaValidatorEndTime := alphaValidatorStartTime.Add(validationPeriod) tests.Outf("alpha node validation period starting at: %v\n", alphaValidatorStartTime) @@ -171,6 +177,10 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { require.NoError(err) }) + ginkgo.By("retrieving supply before inserting delegators") + supplyAtDelegatorsStart, _, err := pvmClient.GetCurrentSupply(e2e.DefaultContext(), constants.PrimaryNetworkID) + require.NoError(err) + gammaDelegatorStartTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) tests.Outf("gamma delegation period starting at: %v\n", gammaDelegatorStartTime) @@ -227,8 +237,6 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { // delegation periods are shorter than the validation periods. time.Sleep(time.Until(betaValidatorEndTime)) - pvmClient := platformvm.NewClient(alphaNode.GetProcessContext().URI) - ginkgo.By("waiting until the alpha and beta nodes are no longer validators") e2e.Eventually(func() bool { validators, err := pvmClient.GetCurrentValidators(e2e.DefaultContext(), constants.PrimaryNetworkID, nil) @@ -270,11 +278,9 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { require.Len(rewardBalances, len(rewardKeys)) ginkgo.By("determining expected validation and delegation rewards") - currentSupply, _, err := pvmClient.GetCurrentSupply(e2e.DefaultContext(), constants.PrimaryNetworkID) - require.NoError(err) calculator := reward.NewCalculator(rewardConfig) - expectedValidationReward := calculator.Calculate(validationPeriod, weight, currentSupply) - potentialDelegationReward := calculator.Calculate(delegationPeriod, weight, currentSupply) + expectedValidationReward := calculator.Calculate(validationPeriod, weight, supplyAtValidatorsStart) + potentialDelegationReward := calculator.Calculate(delegationPeriod, weight, supplyAtDelegatorsStart) expectedDelegationFee, expectedDelegatorReward := reward.Split(potentialDelegationReward, delegationShare) ginkgo.By("checking expected rewards against actual rewards") diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index b8476e19b032..f16e9353a8ad 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -126,28 +126,11 @@ func (b *builder) buildBlock() (block.Block, error) { return nil, fmt.Errorf("%w: %s", state.ErrMissingParentState, preferredID) } - timestamp := b.txExecutorBackend.Clk.Time() - if parentTime := preferred.Timestamp(); parentTime.After(timestamp) { - timestamp = parentTime - } - // [timestamp] = max(now, parentTime) - - nextStakerChangeTime, err := txexecutor.GetNextStakerChangeTime(preferredState) + timestamp, timeWasCapped, err := txexecutor.NextBlockTime(preferredState, b.txExecutorBackend.Clk) if err != nil { return nil, fmt.Errorf("could not calculate next staker change time: %w", err) } - // timeWasCapped means that [timestamp] was reduced to - // [nextStakerChangeTime]. It is used as a flag for [buildApricotBlock] to - // be willing to issue an advanceTimeTx. It is also used as a flag for - // [buildBanffBlock] to force the issuance of an empty block to advance - // the time forward; if there are no available transactions. - timeWasCapped := !timestamp.Before(nextStakerChangeTime) - if timeWasCapped { - timestamp = nextStakerChangeTime - } - // [timestamp] = min(max(now, parentTime), nextStakerChangeTime) - return buildBlock( b, preferredID, diff --git a/vms/platformvm/state/staker_test.go b/vms/platformvm/state/staker_test.go index 747f442e5eda..a6faa4ab704f 100644 --- a/vms/platformvm/state/staker_test.go +++ b/vms/platformvm/state/staker_test.go @@ -144,7 +144,7 @@ func TestNewCurrentStaker(t *testing.T) { subnetID := ids.GenerateTestID() weight := uint64(12345) startTime := time.Now() - endTime := time.Now() + endTime := startTime.Add(time.Hour) potentialReward := uint64(54321) currentPriority := txs.SubnetPermissionedValidatorCurrentPriority diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 4627fc706626..82ff0107762a 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1448,7 +1448,12 @@ func (s *state) loadCurrentValidators() error { } tx, _, err := s.GetTx(txID) if err != nil { - return err + return fmt.Errorf("failed loading validator transaction txID %s, %w", txID, err) + } + + stakerTx, ok := tx.Unsigned.(txs.Staker) + if !ok { + return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } metadataBytes := validatorIt.Value() @@ -1461,11 +1466,6 @@ func (s *state) loadCurrentValidators() error { return err } - stakerTx, ok := tx.Unsigned.(txs.Staker) - if !ok { - return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) - } - staker, err := NewCurrentStaker(txID, stakerTx, metadata.PotentialReward) if err != nil { return err @@ -1498,11 +1498,12 @@ func (s *state) loadCurrentValidators() error { } metadataBytes := subnetValidatorIt.Value() + startTime := stakerTx.StartTime() metadata := &validatorMetadata{ txID: txID, // use the start time as the fallback value // in case it's not stored in the database - LastUpdated: uint64(stakerTx.StartTime().Unix()), + LastUpdated: uint64(startTime.Unix()), } if err := parseValidatorMetadata(metadataBytes, metadata); err != nil { return err @@ -1538,6 +1539,11 @@ func (s *state) loadCurrentValidators() error { return err } + stakerTx, ok := tx.Unsigned.(txs.Staker) + if !ok { + return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) + } + metadata := &delegatorMetadata{ txID: txID, } @@ -1546,11 +1552,6 @@ func (s *state) loadCurrentValidators() error { return err } - stakerTx, ok := tx.Unsigned.(txs.Staker) - if !ok { - return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) - } - staker, err := NewCurrentStaker(txID, stakerTx, metadata.PotentialReward) if err != nil { return err diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 7fae0e78a85b..8a0c6046d67f 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "math" + "time" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" @@ -92,7 +93,6 @@ func verifyAddValidatorTx( } duration := tx.Validator.Duration() - switch { case tx.Validator.Wght < backend.Config.MinValidatorStake: // Ensure validator is staking at least the minimum amount @@ -123,16 +123,12 @@ func verifyAddValidatorTx( return outs, nil } - currentTimestamp := chainState.GetTimestamp() - // Ensure the proposed validator starts after the current time - startTime := tx.StartTime() - if !currentTimestamp.Before(startTime) { - return nil, fmt.Errorf( - "%w: %s >= %s", - ErrTimestampNotBeforeStartTime, - currentTimestamp, - startTime, - ) + var ( + currentTimestamp = chainState.GetTimestamp() + startTime = tx.StartTime() + ) + if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + return nil, err } _, err := GetValidator(chainState, constants.PrimaryNetworkID, tx.Validator.NodeID) @@ -165,14 +161,9 @@ func verifyAddValidatorTx( return nil, fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) } - // Make sure the tx doesn't start too far in the future. This is done last - // to allow the verifier visitor to explicitly check for this error. - maxStartTime := currentTimestamp.Add(MaxFutureStartTime) - if startTime.After(maxStartTime) { - return nil, ErrFutureStakeTime - } - - return outs, nil + // verifyStakerStartsSoon is checked last to allow + // the verifier visitor to explicitly check for this error. + return outs, verifyStakerStartsSoon(currentTimestamp, startTime) } // verifyAddSubnetValidatorTx carries out the validation for an @@ -203,16 +194,12 @@ func verifyAddSubnetValidatorTx( return nil } - currentTimestamp := chainState.GetTimestamp() - // Ensure the proposed validator starts after the current timestamp - validatorStartTime := tx.StartTime() - if !currentTimestamp.Before(validatorStartTime) { - return fmt.Errorf( - "%w: %s >= %s", - ErrTimestampNotBeforeStartTime, - currentTimestamp, - validatorStartTime, - ) + var ( + currentTimestamp = chainState.GetTimestamp() + startTime = tx.StartTime() + ) + if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + return err } _, err := GetValidator(chainState, tx.SubnetValidator.Subnet, tx.Validator.NodeID) @@ -255,14 +242,9 @@ func verifyAddSubnetValidatorTx( return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) } - // Make sure the tx doesn't start too far in the future. This is done last - // to allow the verifier visitor to explicitly check for this error. - maxStartTime := currentTimestamp.Add(MaxFutureStartTime) - if validatorStartTime.After(maxStartTime) { - return ErrFutureStakeTime - } - - return nil + // verifyStakerStartsSoon is checked last to allow + // the verifier visitor to explicitly check for this error. + return verifyStakerStartsSoon(currentTimestamp, startTime) } // Returns the representation of [tx.NodeID] validating [tx.Subnet]. @@ -372,16 +354,12 @@ func verifyAddDelegatorTx( return outs, nil } - currentTimestamp := chainState.GetTimestamp() - // Ensure the proposed validator starts after the current timestamp - validatorStartTime := tx.StartTime() - if !currentTimestamp.Before(validatorStartTime) { - return nil, fmt.Errorf( - "%w: %s >= %s", - ErrTimestampNotBeforeStartTime, - currentTimestamp, - validatorStartTime, - ) + var ( + currentTimestamp = chainState.GetTimestamp() + startTime = tx.StartTime() + ) + if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + return nil, err } primaryNetworkValidator, err := GetValidator(chainState, constants.PrimaryNetworkID, tx.Validator.NodeID) @@ -438,14 +416,9 @@ func verifyAddDelegatorTx( return nil, fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) } - // Make sure the tx doesn't start too far in the future. This is done last - // to allow the verifier visitor to explicitly check for this error. - maxStartTime := currentTimestamp.Add(MaxFutureStartTime) - if validatorStartTime.After(maxStartTime) { - return nil, ErrFutureStakeTime - } - - return outs, nil + // verifyStakerStartsSoon is checked last to allow + // the verifier visitor to explicitly check for this error. + return outs, verifyStakerStartsSoon(currentTimestamp, startTime) } // verifyAddPermissionlessValidatorTx carries out the validation for an @@ -465,16 +438,12 @@ func verifyAddPermissionlessValidatorTx( return nil } - currentTimestamp := chainState.GetTimestamp() - // Ensure the proposed validator starts after the current time - startTime := tx.StartTime() - if !currentTimestamp.Before(startTime) { - return fmt.Errorf( - "%w: %s >= %s", - ErrTimestampNotBeforeStartTime, - currentTimestamp, - startTime, - ) + var ( + currentTimestamp = chainState.GetTimestamp() + startTime = tx.StartTime() + ) + if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + return err } validatorRules, err := getValidatorRules(backend, chainState, tx.Subnet) @@ -482,8 +451,10 @@ func verifyAddPermissionlessValidatorTx( return err } - duration := tx.Validator.Duration() - stakedAssetID := tx.StakeOuts[0].AssetID() + var ( + duration = tx.Validator.Duration() + stakedAssetID = tx.StakeOuts[0].AssetID() + ) switch { case tx.Validator.Wght < validatorRules.minValidatorStake: // Ensure validator is staking at least the minimum amount @@ -562,14 +533,9 @@ func verifyAddPermissionlessValidatorTx( return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) } - // Make sure the tx doesn't start too far in the future. This is done last - // to allow the verifier visitor to explicitly check for this error. - maxStartTime := currentTimestamp.Add(MaxFutureStartTime) - if startTime.After(maxStartTime) { - return ErrFutureStakeTime - } - - return nil + // verifyStakerStartsSoon is checked last to allow + // the verifier visitor to explicitly check for this error. + return verifyStakerStartsSoon(currentTimestamp, startTime) } // verifyAddPermissionlessDelegatorTx carries out the validation for an @@ -589,15 +555,12 @@ func verifyAddPermissionlessDelegatorTx( return nil } - currentTimestamp := chainState.GetTimestamp() - // Ensure the proposed validator starts after the current timestamp - startTime := tx.StartTime() - if !currentTimestamp.Before(startTime) { - return fmt.Errorf( - "chain timestamp (%s) not before validator's start time (%s)", - currentTimestamp, - startTime, - ) + var ( + currentTimestamp = chainState.GetTimestamp() + startTime = tx.StartTime() + ) + if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + return err } delegatorRules, err := getDelegatorRules(backend, chainState, tx.Subnet) @@ -605,8 +568,10 @@ func verifyAddPermissionlessDelegatorTx( return err } - duration := tx.Validator.Duration() - stakedAssetID := tx.StakeOuts[0].AssetID() + var ( + duration = tx.Validator.Duration() + stakedAssetID = tx.StakeOuts[0].AssetID() + ) switch { case tx.Validator.Wght < delegatorRules.minDelegatorStake: // Ensure delegator is staking at least the minimum amount @@ -706,14 +671,9 @@ func verifyAddPermissionlessDelegatorTx( return fmt.Errorf("%w: %w", ErrFlowCheckFailed, err) } - // Make sure the tx doesn't start too far in the future. This is done last - // to allow the verifier visitor to explicitly check for this error. - maxStartTime := currentTimestamp.Add(MaxFutureStartTime) - if startTime.After(maxStartTime) { - return ErrFutureStakeTime - } - - return nil + // verifyStakerStartsSoon is checked last to allow + // the verifier visitor to explicitly check for this error. + return verifyStakerStartsSoon(currentTimestamp, startTime) } // Returns an error if the given tx is invalid. @@ -762,3 +722,25 @@ func verifyTransferSubnetOwnershipTx( return nil } + +// Ensure the proposed validator starts after the current time +func verifyStakerStartTime(chainTime, stakerTime time.Time) error { + if !chainTime.Before(stakerTime) { + return fmt.Errorf( + "%w: %s >= %s", + ErrTimestampNotBeforeStartTime, + chainTime, + stakerTime, + ) + } + return nil +} + +func verifyStakerStartsSoon(chainTime, stakerStartTime time.Time) error { + // Make sure the tx doesn't start too far in the future. + maxStartTime := chainTime.Add(MaxFutureStartTime) + if stakerStartTime.After(maxStartTime) { + return ErrFutureStakeTime + } + return nil +} diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 63069cb5d5d5..083e4f4c75c7 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -290,13 +290,11 @@ func (e *StandardTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error { return err } - txID := e.Tx.ID() - newStaker, err := state.NewPendingStaker(txID, tx) - if err != nil { + if err := e.putStaker(tx); err != nil { return err } - e.State.PutPendingValidator(newStaker) + txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) @@ -321,16 +319,13 @@ func (e *StandardTxExecutor) AddSubnetValidatorTx(tx *txs.AddSubnetValidatorTx) return err } - txID := e.Tx.ID() - newStaker, err := state.NewPendingStaker(txID, tx) - if err != nil { + if err := e.putStaker(tx); err != nil { return err } - e.State.PutPendingValidator(newStaker) + txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) - return nil } @@ -344,16 +339,13 @@ func (e *StandardTxExecutor) AddDelegatorTx(tx *txs.AddDelegatorTx) error { return err } - txID := e.Tx.ID() - newStaker, err := state.NewPendingStaker(txID, tx) - if err != nil { + if err := e.putStaker(tx); err != nil { return err } - e.State.PutPendingDelegator(newStaker) + txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) - return nil } @@ -444,13 +436,11 @@ func (e *StandardTxExecutor) AddPermissionlessValidatorTx(tx *txs.AddPermissionl return err } - txID := e.Tx.ID() - newStaker, err := state.NewPendingStaker(txID, tx) - if err != nil { + if err := e.putStaker(tx); err != nil { return err } - e.State.PutPendingValidator(newStaker) + txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) @@ -478,16 +468,13 @@ func (e *StandardTxExecutor) AddPermissionlessDelegatorTx(tx *txs.AddPermissionl return err } - txID := e.Tx.ID() - newStaker, err := state.NewPendingStaker(txID, tx) - if err != nil { + if err := e.putStaker(tx); err != nil { return err } - e.State.PutPendingDelegator(newStaker) + txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) - return nil } @@ -511,7 +498,6 @@ func (e *StandardTxExecutor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwn txID := e.Tx.ID() avax.Consume(e.State, tx.Ins) avax.Produce(e.State, txID, tx.Outs) - return nil } @@ -539,9 +525,29 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { return err } + txID := e.Tx.ID() // Consume the UTXOS avax.Consume(e.State, tx.Ins) // Produce the UTXOS - avax.Produce(e.State, e.Tx.ID(), tx.Outs) + avax.Produce(e.State, txID, tx.Outs) + return nil +} + +// Creates the staker as defined in [stakerTx] and adds it to [e.State]. +func (e *StandardTxExecutor) putStaker(stakerTx txs.Staker) error { + txID := e.Tx.ID() + staker, err := state.NewPendingStaker(txID, stakerTx) + if err != nil { + return err + } + + switch priority := staker.Priority; { + case priority.IsPendingValidator(): + e.State.PutPendingValidator(staker) + case priority.IsPendingDelegator(): + e.State.PutPendingDelegator(staker) + default: + return fmt.Errorf("staker %s, unexpected priority %d", staker.TxID, priority) + } return nil } diff --git a/vms/platformvm/txs/executor/tx_mempool_verifier.go b/vms/platformvm/txs/executor/tx_mempool_verifier.go index f6eff499c2ec..378b742ae484 100644 --- a/vms/platformvm/txs/executor/tx_mempool_verifier.go +++ b/vms/platformvm/txs/executor/tx_mempool_verifier.go @@ -9,6 +9,7 @@ import ( "time" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) @@ -108,7 +109,7 @@ func (v *MempoolTxVerifier) standardBaseState() (state.Diff, error) { return nil, err } - nextBlkTime, err := v.nextBlockTime(state) + nextBlkTime, _, err := NextBlockTime(state, v.Clk) if err != nil { return nil, err } @@ -123,20 +124,26 @@ func (v *MempoolTxVerifier) standardBaseState() (state.Diff, error) { return state, nil } -func (v *MempoolTxVerifier) nextBlockTime(state state.Diff) (time.Time, error) { +func NextBlockTime(state state.Chain, clk *mockable.Clock) (time.Time, bool, error) { var ( - parentTime = state.GetTimestamp() - nextBlkTime = v.Clk.Time() + timestamp = clk.Time() + parentTime = state.GetTimestamp() ) - if parentTime.After(nextBlkTime) { - nextBlkTime = parentTime + if parentTime.After(timestamp) { + timestamp = parentTime } + // [timestamp] = max(now, parentTime) + nextStakerChangeTime, err := GetNextStakerChangeTime(state) if err != nil { - return time.Time{}, fmt.Errorf("could not calculate next staker change time: %w", err) + return time.Time{}, false, fmt.Errorf("failed getting next staker change time: %w", err) } - if !nextBlkTime.Before(nextStakerChangeTime) { - nextBlkTime = nextStakerChangeTime + + // timeWasCapped means that [timestamp] was reduced to [nextStakerChangeTime] + timeWasCapped := !timestamp.Before(nextStakerChangeTime) + if timeWasCapped { + timestamp = nextStakerChangeTime } - return nextBlkTime, nil + // [timestamp] = min(max(now, parentTime), nextStakerChangeTime) + return timestamp, timeWasCapped, nil } From 6aa20fc839351d9b8d75cb9a1aef7c9bd07abfef Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:32:07 -0500 Subject: [PATCH 096/267] `vms/platformvm`: Initialize txs in `Transactions` field for `BanffProposalBlock` (#2419) --- vms/platformvm/block/proposal_block.go | 20 ++++++++++++++++++++ vms/platformvm/block/standard_block.go | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/vms/platformvm/block/proposal_block.go b/vms/platformvm/block/proposal_block.go index 05e23b649949..eaea68e9ce55 100644 --- a/vms/platformvm/block/proposal_block.go +++ b/vms/platformvm/block/proposal_block.go @@ -28,6 +28,18 @@ type BanffProposalBlock struct { ApricotProposalBlock `serialize:"true"` } +func (b *BanffProposalBlock) initialize(bytes []byte) error { + if err := b.ApricotProposalBlock.initialize(bytes); err != nil { + return err + } + for _, tx := range b.Transactions { + if err := tx.Initialize(txs.Codec); err != nil { + return fmt.Errorf("failed to initialize tx: %w", err) + } + } + return nil +} + func (b *BanffProposalBlock) InitCtx(ctx *snow.Context) { for _, tx := range b.Transactions { tx.Unsigned.InitCtx(ctx) @@ -39,6 +51,14 @@ func (b *BanffProposalBlock) Timestamp() time.Time { return time.Unix(int64(b.Time), 0) } +func (b *BanffProposalBlock) Txs() []*txs.Tx { + l := len(b.Transactions) + txs := make([]*txs.Tx, l+1) + copy(txs, b.Transactions) + txs[l] = b.Tx + return txs +} + func (b *BanffProposalBlock) Visit(v Visitor) error { return v.BanffProposalBlock(b) } diff --git a/vms/platformvm/block/standard_block.go b/vms/platformvm/block/standard_block.go index a088a9eab696..a3a7ee6fed39 100644 --- a/vms/platformvm/block/standard_block.go +++ b/vms/platformvm/block/standard_block.go @@ -58,7 +58,7 @@ func (b *ApricotStandardBlock) initialize(bytes []byte) error { b.CommonBlock.initialize(bytes) for _, tx := range b.Transactions { if err := tx.Initialize(txs.Codec); err != nil { - return fmt.Errorf("failed to sign block: %w", err) + return fmt.Errorf("failed to initialize tx: %w", err) } } return nil From b741c198ae8e931003d94b104c70fc8200721ad5 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 4 Dec 2023 17:49:15 -0500 Subject: [PATCH 097/267] `vms/platformvm`: Move `VerifyUniqueInputs` from `verifier` to `backend` (#2410) --- vms/avm/block/executor/manager.go | 4 +-- vms/platformvm/block/executor/backend.go | 29 +++++++++++++++++++++ vms/platformvm/block/executor/verifier.go | 31 ++--------------------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/vms/avm/block/executor/manager.go b/vms/avm/block/executor/manager.go index 48eea701bbd9..4ee6c37046ec 100644 --- a/vms/avm/block/executor/manager.go +++ b/vms/avm/block/executor/manager.go @@ -43,8 +43,8 @@ type Manager interface { // preferred state. This should *not* be used to verify transactions in a block. VerifyTx(tx *txs.Tx) error - // VerifyUniqueInputs verifies that the inputs are not duplicated in the - // provided blk or any of its ancestors pinned in memory. + // VerifyUniqueInputs returns nil iff no blocks in the inclusive + // ancestry of [blkID] consume an input in [inputs]. VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error } diff --git a/vms/platformvm/block/executor/backend.go b/vms/platformvm/block/executor/backend.go index fd0e75d0f664..4d915047f560 100644 --- a/vms/platformvm/block/executor/backend.go +++ b/vms/platformvm/block/executor/backend.go @@ -4,15 +4,19 @@ package executor import ( + "errors" "time" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) +var errConflictingParentTxs = errors.New("block contains a transaction that conflicts with a transaction in a parent block") + // Shared fields used by visitors. type backend struct { mempool.Mempool @@ -95,3 +99,28 @@ func (b *backend) getTimestamp(blkID ids.ID) time.Time { // so we just return the chain time. return b.state.GetTimestamp() } + +// verifyUniqueInputs returns nil iff no blocks in the inclusive +// ancestry of [blkID] consume an input in [inputs]. +func (b *backend) verifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error { + if inputs.Len() == 0 { + return nil + } + + // Check for conflicts in ancestors. + for { + state, ok := b.blkIDToState[blkID] + if !ok { + // The parent state isn't pinned in memory. + // This means the parent must be accepted already. + return nil + } + + if state.inputs.Overlaps(inputs) { + return errConflictingParentTxs + } + + blk := state.statelessBlock + blkID = blk.Parent() + } +} diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index c4f25f992da8..abc2aa4e257c 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -9,7 +9,6 @@ import ( "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -26,7 +25,6 @@ var ( errIncorrectBlockHeight = errors.New("incorrect block height") errChildBlockEarlierThanParent = errors.New("proposed timestamp before current chain time") errConflictingBatchTxs = errors.New("block contains conflicting transactions") - errConflictingParentTxs = errors.New("block contains a transaction that conflicts with a transaction in a parent block") errOptionBlockTimestampNotMatchingParent = errors.New("option block proposed timestamp not matching parent block one") ) @@ -203,7 +201,7 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { atomicExecutor.OnAccept.AddTx(b.Tx, status.Committed) - if err := v.verifyUniqueInputs(b, atomicExecutor.Inputs); err != nil { + if err := v.verifyUniqueInputs(b.Parent(), atomicExecutor.Inputs); err != nil { return err } @@ -441,7 +439,7 @@ func (v *verifier) standardBlock( } } - if err := v.verifyUniqueInputs(b, blkState.inputs); err != nil { + if err := v.verifyUniqueInputs(b.Parent(), blkState.inputs); err != nil { return err } @@ -461,28 +459,3 @@ func (v *verifier) standardBlock( v.Mempool.Remove(b.Transactions) return nil } - -// verifyUniqueInputs verifies that the inputs of the given block are not -// duplicated in any of the parent blocks pinned in memory. -func (v *verifier) verifyUniqueInputs(block block.Block, inputs set.Set[ids.ID]) error { - if inputs.Len() == 0 { - return nil - } - - // Check for conflicts in ancestors. - for { - parentID := block.Parent() - parentState, ok := v.blkIDToState[parentID] - if !ok { - // The parent state isn't pinned in memory. - // This means the parent must be accepted already. - return nil - } - - if parentState.inputs.Overlaps(inputs) { - return errConflictingParentTxs - } - - block = parentState.statelessBlock - } -} From 2e32281b623ed5cc0c1b7101deae21667f5cef49 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 4 Dec 2023 18:30:41 -0500 Subject: [PATCH 098/267] Fix duplicated bootstrapper engine termination (#2334) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- snow/engine/snowman/bootstrap/bootstrapper.go | 1 + .../snowman/bootstrap/bootstrapper_test.go | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index 0e2c7e0dab16..b819c9573b48 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -781,6 +781,7 @@ func (b *Bootstrapper) Timeout(ctx context.Context) error { func (b *Bootstrapper) restartBootstrapping(ctx context.Context) error { b.Ctx.Log.Debug("Checking for new frontiers") b.restarted = true + b.outstandingRequests = bimap.New[common.Request, ids.ID]() return b.startBootstrapping(ctx) } diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index 83cbca730ba5..4f7e54882920 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -1423,3 +1423,124 @@ func TestBootstrapNoParseOnNew(t *testing.T) { ) require.NoError(err) } + +func TestBootstrapperReceiveStaleAncestorsMessage(t *testing.T) { + require := require.New(t) + + config, peerID, sender, vm := newConfig(t) + + var ( + blkID0 = ids.GenerateTestID() + blkBytes0 = utils.RandomBytes(1024) + blk0 = &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: blkID0, + StatusV: choices.Accepted, + }, + HeightV: 0, + BytesV: blkBytes0, + } + + blkID1 = ids.GenerateTestID() + blkBytes1 = utils.RandomBytes(1024) + blk1 = &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: blkID1, + StatusV: choices.Processing, + }, + ParentV: blk0.IDV, + HeightV: blk0.HeightV + 1, + BytesV: blkBytes1, + } + + blkID2 = ids.GenerateTestID() + blkBytes2 = utils.RandomBytes(1024) + blk2 = &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: blkID2, + StatusV: choices.Processing, + }, + ParentV: blk1.IDV, + HeightV: blk1.HeightV + 1, + BytesV: blkBytes2, + } + ) + + vm.LastAcceptedF = func(context.Context) (ids.ID, error) { + return blk0.ID(), nil + } + vm.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { + require.Equal(blkID0, blkID) + return blk0, nil + } + bs, err := New( + config, + func(context.Context, uint32) error { + config.Ctx.State.Set(snow.EngineState{ + Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, + State: snow.NormalOp, + }) + return nil + }, + ) + require.NoError(err) + + vm.CantSetState = false + require.NoError(bs.Start(context.Background(), 0)) + + vm.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { + switch blkID { + case blkID0: + return blk0, nil + case blkID1: + if blk1.StatusV == choices.Accepted { + return blk1, nil + } + return nil, database.ErrNotFound + case blkID2: + if blk2.StatusV == choices.Accepted { + return blk2, nil + } + return nil, database.ErrNotFound + default: + require.FailNow(database.ErrNotFound.Error()) + return nil, database.ErrNotFound + } + } + vm.ParseBlockF = func(_ context.Context, blkBytes []byte) (snowman.Block, error) { + switch { + case bytes.Equal(blkBytes, blkBytes0): + return blk0, nil + case bytes.Equal(blkBytes, blkBytes1): + return blk1, nil + case bytes.Equal(blkBytes, blkBytes2): + return blk2, nil + default: + require.FailNow(errUnknownBlock.Error()) + return nil, errUnknownBlock + } + } + + requestIDs := map[ids.ID]uint32{} + sender.SendGetAncestorsF = func(_ context.Context, vdr ids.NodeID, reqID uint32, blkID ids.ID) { + require.Equal(peerID, vdr) + requestIDs[blkID] = reqID + } + + require.NoError(bs.startSyncing(context.Background(), []ids.ID{blkID1, blkID2})) // should request blk2 and blk1 + + reqIDBlk1, ok := requestIDs[blkID1] + require.True(ok) + reqIDBlk2, ok := requestIDs[blkID2] + require.True(ok) + + require.NoError(bs.Ancestors(context.Background(), peerID, reqIDBlk2, [][]byte{blkBytes2, blkBytes1})) + + require.Equal(snow.Bootstrapping, config.Ctx.State.Get().State) + require.Equal(choices.Accepted, blk0.Status()) + require.Equal(choices.Accepted, blk1.Status()) + require.Equal(choices.Accepted, blk2.Status()) + + require.NoError(bs.Ancestors(context.Background(), peerID, reqIDBlk1, [][]byte{blkBytes1})) + require.Equal(snow.Bootstrapping, config.Ctx.State.Get().State) +} From 5d9e482d220657e71312994bb4ce682391dd2e1e Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Mon, 4 Dec 2023 19:27:29 -0500 Subject: [PATCH 099/267] allow user of `build_fuzz.sh` to specify a directory to fuzz in (#2414) --- scripts/build_fuzz.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/build_fuzz.sh b/scripts/build_fuzz.sh index 0f7ad7de8ede..54ed02c27e21 100755 --- a/scripts/build_fuzz.sh +++ b/scripts/build_fuzz.sh @@ -1,5 +1,11 @@ #!/usr/bin/env bash +# First argument is the time, in seconds, to run each fuzz test for. +# If not provided, defaults to 1 second. +# +# Second argument is the directory to run fuzz tests in. +# If not provided, defaults to the current directory. + set -euo pipefail # Mostly taken from https://github.com/golang/go/issues/46312#issuecomment-1153345129 @@ -10,7 +16,9 @@ AVALANCHE_PATH=$( cd "$( dirname "${BASH_SOURCE[0]}" )"; cd .. && pwd ) source "$AVALANCHE_PATH"/scripts/constants.sh fuzzTime=${1:-1} -files=$(grep -r --include='**_test.go' --files-with-matches 'func Fuzz' .) +fuzzDir=${2:-.} + +files=$(grep -r --include='**_test.go' --files-with-matches 'func Fuzz' $fuzzDir) failed=false for file in ${files} do From b6700c956159cba6bdec346dc91343ec51492fe8 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 4 Dec 2023 22:24:34 -0500 Subject: [PATCH 100/267] Update slices dependency to use Compare (#2424) Co-authored-by: James Walker --- api/metrics/multi_gatherer.go | 6 ++- chains/atomic/state.go | 5 ++- codec/reflectcodec/type_codec.go | 4 +- genesis/config.go | 8 ++-- genesis/config_test.go | 35 +++++---------- go.mod | 18 ++++---- go.sum | 38 ++++++++-------- ids/id.go | 4 +- ids/id_test.go | 51 +++++++++++++--------- ids/node_id.go | 4 +- ids/node_id_test.go | 51 +++++++++++++--------- ids/short.go | 4 +- snow/consensus/snowman/test_block.go | 4 +- utils/sampler/weighted_array.go | 4 +- utils/sampler/weighted_array_test.go | 41 +++++++++++------ utils/sampler/weighted_heap.go | 13 +++--- utils/sampler/weighted_heap_test.go | 35 +++++---------- utils/sampler/weighted_linear.go | 4 +- utils/sampler/weighted_linear_test.go | 41 +++++++++++------ utils/set/sampleable_set.go | 2 +- utils/set/set.go | 3 +- utils/sorting.go | 39 ++++++++++------- utils/sorting_test.go | 30 ++++--------- vms/avm/genesis.go | 4 +- vms/avm/genesis_test.go | 41 +++++++++++------ vms/avm/txs/initial_state.go | 4 +- vms/avm/txs/initial_state_test.go | 36 +++++++++++---- vms/avm/txs/operation.go | 8 ++-- vms/components/avax/transferables.go | 4 +- vms/components/avax/utxo_id.go | 13 ++---- vms/components/avax/utxo_id_test.go | 35 +++++---------- vms/platformvm/api/static_service.go | 21 ++++----- vms/platformvm/api/static_service_test.go | 49 ++++++--------------- vms/platformvm/warp/signature_test.go | 4 +- vms/platformvm/warp/validator.go | 4 +- vms/proposervm/proposer/validators.go | 4 +- vms/proposervm/proposer/validators_test.go | 36 ++++++++++----- x/archivedb/key_test.go | 8 +--- x/merkledb/key.go | 13 +++++- x/merkledb/view_iterator.go | 4 +- x/sync/sync_test.go | 14 +++--- x/sync/workheap_test.go | 4 +- 42 files changed, 390 insertions(+), 360 deletions(-) diff --git a/api/metrics/multi_gatherer.go b/api/metrics/multi_gatherer.go index ce9af54936be..e3c88778ad4e 100644 --- a/api/metrics/multi_gatherer.go +++ b/api/metrics/multi_gatherer.go @@ -13,6 +13,8 @@ import ( dto "github.com/prometheus/client_model/go" "golang.org/x/exp/slices" + + "github.com/ava-labs/avalanchego/utils" ) var ( @@ -91,7 +93,7 @@ func (g *multiGatherer) Register(namespace string, gatherer prometheus.Gatherer) } func sortMetrics(m []*dto.MetricFamily) { - slices.SortFunc(m, func(i, j *dto.MetricFamily) bool { - return *i.Name < *j.Name + slices.SortFunc(m, func(i, j *dto.MetricFamily) int { + return utils.Compare(*i.Name, *j.Name) }) } diff --git a/chains/atomic/state.go b/chains/atomic/state.go index aee269915ea9..402477299c21 100644 --- a/chains/atomic/state.go +++ b/chains/atomic/state.go @@ -8,11 +8,12 @@ import ( "errors" "fmt" + "golang.org/x/exp/slices" + "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/linkeddb" "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/set" ) @@ -207,7 +208,7 @@ func (s *state) getKeys(traits [][]byte, startTrait, startKey []byte, limit int) lastKey := startKey // Iterate over the traits in order appending all of the keys that possess // the given [traits]. - utils.SortBytes(traits) + slices.SortFunc(traits, bytes.Compare) for _, trait := range traits { switch bytes.Compare(trait, startTrait) { case -1: diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index 9f9037f43d4e..6f18f8500272 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -490,10 +490,10 @@ func (c *genericCodec) marshal( endOffset = p.Offset } - slices.SortFunc(sortedKeys, func(a, b keyTuple) bool { + slices.SortFunc(sortedKeys, func(a, b keyTuple) int { aBytes := p.Bytes[a.startIndex:a.endIndex] bBytes := p.Bytes[b.startIndex:b.endIndex] - return bytes.Compare(aBytes, bBytes) < 0 + return bytes.Compare(aBytes, bBytes) }) allKeyBytes := slices.Clone(p.Bytes[startOffset:p.Offset]) diff --git a/genesis/config.go b/genesis/config.go index a951e9e078fc..cedaf90127a9 100644 --- a/genesis/config.go +++ b/genesis/config.go @@ -53,9 +53,11 @@ func (a Allocation) Unparse(networkID uint32) (UnparsedAllocation, error) { return ua, err } -func (a Allocation) Less(other Allocation) bool { - return a.InitialAmount < other.InitialAmount || - (a.InitialAmount == other.InitialAmount && a.AVAXAddr.Less(other.AVAXAddr)) +func (a Allocation) Compare(other Allocation) int { + if amountCmp := utils.Compare(a.InitialAmount, other.InitialAmount); amountCmp != 0 { + return amountCmp + } + return a.AVAXAddr.Compare(other.AVAXAddr) } type Staker struct { diff --git a/genesis/config_test.go b/genesis/config_test.go index 455045dad70b..d83815cebfba 100644 --- a/genesis/config_test.go +++ b/genesis/config_test.go @@ -11,56 +11,43 @@ import ( "github.com/ava-labs/avalanchego/ids" ) -func TestAllocationLess(t *testing.T) { +func TestAllocationCompare(t *testing.T) { type test struct { name string alloc1 Allocation alloc2 Allocation - expected bool + expected int } tests := []test{ { name: "equal", alloc1: Allocation{}, alloc2: Allocation{}, - expected: false, + expected: 0, }, { - name: "first initial amount smaller", + name: "initial amount smaller", alloc1: Allocation{}, alloc2: Allocation{ InitialAmount: 1, }, - expected: true, + expected: -1, }, { - name: "first initial amount larger", - alloc1: Allocation{ - InitialAmount: 1, - }, - alloc2: Allocation{}, - expected: false, - }, - { - name: "first bytes smaller", + name: "bytes smaller", alloc1: Allocation{}, alloc2: Allocation{ AVAXAddr: ids.ShortID{1}, }, - expected: true, - }, - { - name: "first bytes larger", - alloc1: Allocation{ - AVAXAddr: ids.ShortID{1}, - }, - alloc2: Allocation{}, - expected: false, + expected: -1, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - require.Equal(t, tt.expected, tt.alloc1.Less(tt.alloc2)) + require := require.New(t) + + require.Equal(tt.expected, tt.alloc1.Compare(tt.alloc2)) + require.Equal(-tt.expected, tt.alloc2.Compare(tt.alloc1)) }) } } diff --git a/go.mod b/go.mod index 3547ac3dc558..b793394d8d24 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.9 + github.com/ava-labs/coreth v0.12.10-rc.0 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -58,11 +58,11 @@ require ( go.uber.org/goleak v1.2.1 go.uber.org/mock v0.2.0 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.14.0 - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df - golang.org/x/net v0.17.0 - golang.org/x/sync v0.4.0 - golang.org/x/term v0.13.0 + golang.org/x/crypto v0.16.0 + golang.org/x/exp v0.0.0-20231127185646-65229373498e + golang.org/x/net v0.19.0 + golang.org/x/sync v0.5.0 + golang.org/x/term v0.15.0 golang.org/x/time v0.0.0-20220922220347-f3bd1da661af gonum.org/v1/gonum v0.11.0 google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 @@ -146,9 +146,9 @@ require ( go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.14.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.16.0 // indirect google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 50f6bf7f3245..7b9a76de9663 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.9 h1:mvYxABdyPByXwwwIxnTBCiNO23dsE1Kfnd5H106lric= -github.com/ava-labs/coreth v0.12.9-rc.9/go.mod h1:yrf2vEah4Fgj6sJ4UpHewo4DLolwdpf2bJuLRT80PGw= +github.com/ava-labs/coreth v0.12.10-rc.0 h1:qmuom7rtH5hc1E3lnqrMFNLFL1TMnEVa/2O8poB1YLU= +github.com/ava-labs/coreth v0.12.10-rc.0/go.mod h1:plFm/xzvWmx1+qJ3JQSTzF8+FdaA2xu7GgY/AdaZDfk= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -696,8 +696,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -708,8 +708,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= +golang.org/x/exp v0.0.0-20231127185646-65229373498e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -736,7 +736,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -783,8 +783,8 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -807,8 +807,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -878,12 +878,12 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -894,8 +894,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -958,8 +958,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= +golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/ids/id.go b/ids/id.go index 68148018b078..6e5aed7876fd 100644 --- a/ids/id.go +++ b/ids/id.go @@ -145,6 +145,6 @@ func (id ID) MarshalText() ([]byte, error) { return []byte(id.String()), nil } -func (id ID) Less(other ID) bool { - return bytes.Compare(id[:], other[:]) < 0 +func (id ID) Compare(other ID) int { + return bytes.Compare(id[:], other[:]) } diff --git a/ids/id_test.go b/ids/id_test.go index 3424b17633e6..3197e7843697 100644 --- a/ids/id_test.go +++ b/ids/id_test.go @@ -5,6 +5,7 @@ package ids import ( "encoding/json" + "fmt" "testing" "github.com/stretchr/testify/require" @@ -200,26 +201,34 @@ func TestIDMapMarshalling(t *testing.T) { require.Equal(originalMap, unmarshalledMap) } -func TestIDLess(t *testing.T) { - require := require.New(t) +func TestIDCompare(t *testing.T) { + tests := []struct { + a ID + b ID + expected int + }{ + { + a: ID{1}, + b: ID{0}, + expected: 1, + }, + { + a: ID{1}, + b: ID{1}, + expected: 0, + }, + { + a: ID{1, 0}, + b: ID{1, 2}, + expected: -1, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%s_%s_%d", test.a, test.b, test.expected), func(t *testing.T) { + require := require.New(t) - id1 := ID{} - id2 := ID{} - require.False(id1.Less(id2)) - require.False(id2.Less(id1)) - - id1 = ID{1} - id2 = ID{0} - require.False(id1.Less(id2)) - require.True(id2.Less(id1)) - - id1 = ID{1} - id2 = ID{1} - require.False(id1.Less(id2)) - require.False(id2.Less(id1)) - - id1 = ID{1, 0} - id2 = ID{1, 2} - require.True(id1.Less(id2)) - require.False(id2.Less(id1)) + require.Equal(test.expected, test.a.Compare(test.b)) + require.Equal(-test.expected, test.b.Compare(test.a)) + }) + } } diff --git a/ids/node_id.go b/ids/node_id.go index 57d0c0b5bc69..a20b00d24462 100644 --- a/ids/node_id.go +++ b/ids/node_id.go @@ -66,8 +66,8 @@ func (id *NodeID) UnmarshalText(text []byte) error { return id.UnmarshalJSON(text) } -func (id NodeID) Less(other NodeID) bool { - return bytes.Compare(id[:], other[:]) == -1 +func (id NodeID) Compare(other NodeID) int { + return bytes.Compare(id[:], other[:]) } // ToNodeID attempt to convert a byte slice into a node id diff --git a/ids/node_id_test.go b/ids/node_id_test.go index b92fb6e19053..f3c11a452d24 100644 --- a/ids/node_id_test.go +++ b/ids/node_id_test.go @@ -5,6 +5,7 @@ package ids import ( "encoding/json" + "fmt" "testing" "github.com/stretchr/testify/require" @@ -174,26 +175,34 @@ func TestNodeIDMapMarshalling(t *testing.T) { require.Equal(originalMap, unmarshalledMap) } -func TestNodeIDLess(t *testing.T) { - require := require.New(t) +func TestNodeIDCompare(t *testing.T) { + tests := []struct { + a NodeID + b NodeID + expected int + }{ + { + a: NodeID{1}, + b: NodeID{0}, + expected: 1, + }, + { + a: NodeID{1}, + b: NodeID{1}, + expected: 0, + }, + { + a: NodeID{1, 0}, + b: NodeID{1, 2}, + expected: -1, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%s_%s_%d", test.a, test.b, test.expected), func(t *testing.T) { + require := require.New(t) - id1 := NodeID{} - id2 := NodeID{} - require.False(id1.Less(id2)) - require.False(id2.Less(id1)) - - id1 = NodeID{1} - id2 = NodeID{} - require.False(id1.Less(id2)) - require.True(id2.Less(id1)) - - id1 = NodeID{1} - id2 = NodeID{1} - require.False(id1.Less(id2)) - require.False(id2.Less(id1)) - - id1 = NodeID{1} - id2 = NodeID{1, 2} - require.True(id1.Less(id2)) - require.False(id2.Less(id1)) + require.Equal(test.expected, test.a.Compare(test.b)) + require.Equal(-test.expected, test.b.Compare(test.a)) + }) + } } diff --git a/ids/short.go b/ids/short.go index 25b96f1755b0..b19e0420690d 100644 --- a/ids/short.go +++ b/ids/short.go @@ -110,8 +110,8 @@ func (id ShortID) MarshalText() ([]byte, error) { return []byte(id.String()), nil } -func (id ShortID) Less(other ShortID) bool { - return bytes.Compare(id[:], other[:]) == -1 +func (id ShortID) Compare(other ShortID) int { + return bytes.Compare(id[:], other[:]) } // ShortIDsToStrings converts an array of shortIDs to an array of their string diff --git a/snow/consensus/snowman/test_block.go b/snow/consensus/snowman/test_block.go index a02bf31787c1..f340a0291b00 100644 --- a/snow/consensus/snowman/test_block.go +++ b/snow/consensus/snowman/test_block.go @@ -48,6 +48,6 @@ func (b *TestBlock) Bytes() []byte { return b.BytesV } -func (b *TestBlock) Less(other *TestBlock) bool { - return b.HeightV < other.HeightV +func (b *TestBlock) Compare(other *TestBlock) int { + return utils.Compare(b.HeightV, other.HeightV) } diff --git a/utils/sampler/weighted_array.go b/utils/sampler/weighted_array.go index 0db1dda17af9..b2dcb593b79b 100644 --- a/utils/sampler/weighted_array.go +++ b/utils/sampler/weighted_array.go @@ -19,8 +19,8 @@ type weightedArrayElement struct { } // Note that this sorts in order of decreasing weight. -func (e weightedArrayElement) Less(other weightedArrayElement) bool { - return e.cumulativeWeight > other.cumulativeWeight +func (e weightedArrayElement) Compare(other weightedArrayElement) int { + return utils.Compare(other.cumulativeWeight, e.cumulativeWeight) } // Sampling is performed by executing a modified binary search over the provided diff --git a/utils/sampler/weighted_array_test.go b/utils/sampler/weighted_array_test.go index e10583633436..0f44869b7dee 100644 --- a/utils/sampler/weighted_array_test.go +++ b/utils/sampler/weighted_array_test.go @@ -4,24 +4,39 @@ package sampler import ( + "fmt" "testing" "github.com/stretchr/testify/require" ) -func TestWeightedArrayElementLess(t *testing.T) { - require := require.New(t) - - var elt1, elt2 weightedArrayElement - require.False(elt1.Less(elt2)) - require.False(elt2.Less(elt1)) - - elt1 = weightedArrayElement{ - cumulativeWeight: 1, +func TestWeightedArrayElementCompare(t *testing.T) { + tests := []struct { + a weightedArrayElement + b weightedArrayElement + expected int + }{ + { + a: weightedArrayElement{}, + b: weightedArrayElement{}, + expected: 0, + }, + { + a: weightedArrayElement{ + cumulativeWeight: 1, + }, + b: weightedArrayElement{ + cumulativeWeight: 2, + }, + expected: 1, + }, } - elt2 = weightedArrayElement{ - cumulativeWeight: 2, + for _, test := range tests { + t.Run(fmt.Sprintf("%d_%d_%d", test.a.cumulativeWeight, test.b.cumulativeWeight, test.expected), func(t *testing.T) { + require := require.New(t) + + require.Equal(test.expected, test.a.Compare(test.b)) + require.Equal(-test.expected, test.b.Compare(test.a)) + }) } - require.False(elt1.Less(elt2)) - require.True(elt2.Less(elt1)) } diff --git a/utils/sampler/weighted_heap.go b/utils/sampler/weighted_heap.go index 4b7fb84df482..ef5a8feb6e9f 100644 --- a/utils/sampler/weighted_heap.go +++ b/utils/sampler/weighted_heap.go @@ -19,17 +19,16 @@ type weightedHeapElement struct { index int } -func (e weightedHeapElement) Less(other weightedHeapElement) bool { +// Compare the elements. Weight is in decreasing order. Index is in increasing +// order. +func (e weightedHeapElement) Compare(other weightedHeapElement) int { // By accounting for the initial index of the weights, this results in a // stable sort. We do this rather than using `sort.Stable` because of the // reported change in performance of the sort used. - if e.weight > other.weight { - return true + if weightCmp := utils.Compare(other.weight, e.weight); weightCmp != 0 { + return weightCmp } - if e.weight < other.weight { - return false - } - return e.index < other.index + return utils.Compare(e.index, other.index) } // Sampling is performed by executing a search over a tree of elements in the diff --git a/utils/sampler/weighted_heap_test.go b/utils/sampler/weighted_heap_test.go index 3187c14fa10a..eb9ff46ab276 100644 --- a/utils/sampler/weighted_heap_test.go +++ b/utils/sampler/weighted_heap_test.go @@ -23,57 +23,44 @@ func TestWeightedHeapInitialize(t *testing.T) { } } -func TestWeightedHeapElementLess(t *testing.T) { +func TestWeightedHeapElementCompare(t *testing.T) { type test struct { name string elt1 weightedHeapElement elt2 weightedHeapElement - expected bool + expected int } tests := []test{ { name: "all same", elt1: weightedHeapElement{}, elt2: weightedHeapElement{}, - expected: false, + expected: 0, }, { - name: "first lower weight", + name: "lower weight", elt1: weightedHeapElement{}, elt2: weightedHeapElement{ weight: 1, }, - expected: false, + expected: 1, }, { - name: "first higher weight", - elt1: weightedHeapElement{ - weight: 1, - }, - elt2: weightedHeapElement{}, - expected: true, - }, - { - name: "first higher index", + name: "higher index", elt1: weightedHeapElement{ index: 1, }, elt2: weightedHeapElement{}, - expected: false, - }, - { - name: "second higher index", - elt1: weightedHeapElement{}, - elt2: weightedHeapElement{ - index: 1, - }, - expected: true, + expected: 1, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - require.Equal(t, tt.expected, tt.elt1.Less(tt.elt2)) + require := require.New(t) + + require.Equal(tt.expected, tt.elt1.Compare(tt.elt2)) + require.Equal(-tt.expected, tt.elt2.Compare(tt.elt1)) }) } } diff --git a/utils/sampler/weighted_linear.go b/utils/sampler/weighted_linear.go index a5d0e3b16711..268ba9ea2652 100644 --- a/utils/sampler/weighted_linear.go +++ b/utils/sampler/weighted_linear.go @@ -19,8 +19,8 @@ type weightedLinearElement struct { } // Note that this sorts in order of decreasing cumulative weight. -func (e weightedLinearElement) Less(other weightedLinearElement) bool { - return e.cumulativeWeight > other.cumulativeWeight +func (e weightedLinearElement) Compare(other weightedLinearElement) int { + return utils.Compare(other.cumulativeWeight, e.cumulativeWeight) } // Sampling is performed by executing a linear search over the provided elements diff --git a/utils/sampler/weighted_linear_test.go b/utils/sampler/weighted_linear_test.go index b34035017b4a..6757158ed8e6 100644 --- a/utils/sampler/weighted_linear_test.go +++ b/utils/sampler/weighted_linear_test.go @@ -4,24 +4,39 @@ package sampler import ( + "fmt" "testing" "github.com/stretchr/testify/require" ) -func TestWeightedLinearElementLess(t *testing.T) { - require := require.New(t) - - var elt1, elt2 weightedLinearElement - require.False(elt1.Less(elt2)) - require.False(elt2.Less(elt1)) - - elt1 = weightedLinearElement{ - cumulativeWeight: 1, +func TestWeightedLinearElementCompare(t *testing.T) { + tests := []struct { + a weightedLinearElement + b weightedLinearElement + expected int + }{ + { + a: weightedLinearElement{}, + b: weightedLinearElement{}, + expected: 0, + }, + { + a: weightedLinearElement{ + cumulativeWeight: 1, + }, + b: weightedLinearElement{ + cumulativeWeight: 2, + }, + expected: 1, + }, } - elt2 = weightedLinearElement{ - cumulativeWeight: 2, + for _, test := range tests { + t.Run(fmt.Sprintf("%d_%d_%d", test.a.cumulativeWeight, test.b.cumulativeWeight, test.expected), func(t *testing.T) { + require := require.New(t) + + require.Equal(test.expected, test.a.Compare(test.b)) + require.Equal(-test.expected, test.b.Compare(test.a)) + }) } - require.False(elt1.Less(elt2)) - require.True(elt2.Less(elt1)) } diff --git a/utils/set/sampleable_set.go b/utils/set/sampleable_set.go index 0d22f40fbf8a..8c4c02461bd9 100644 --- a/utils/set/sampleable_set.go +++ b/utils/set/sampleable_set.go @@ -176,7 +176,7 @@ func (s *SampleableSet[_]) MarshalJSON() ([]byte, error) { } } // Sort for determinism - utils.SortBytes(elementBytes) + slices.SortFunc(elementBytes, bytes.Compare) // Build the JSON var ( diff --git a/utils/set/set.go b/utils/set/set.go index fd6525b6b127..41d8bb712f10 100644 --- a/utils/set/set.go +++ b/utils/set/set.go @@ -9,6 +9,7 @@ import ( stdjson "encoding/json" "golang.org/x/exp/maps" + "golang.org/x/exp/slices" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/json" @@ -161,7 +162,7 @@ func (s Set[_]) MarshalJSON() ([]byte, error) { i++ } // Sort for determinism - utils.SortBytes(eltBytes) + slices.SortFunc(eltBytes, bytes.Compare) // Build the JSON var ( diff --git a/utils/sorting.go b/utils/sorting.go index 74f24abeb69f..cbb982a7f63b 100644 --- a/utils/sorting.go +++ b/utils/sorting.go @@ -12,32 +12,23 @@ import ( "github.com/ava-labs/avalanchego/utils/hashing" ) -// TODO can we handle sorting where the Less function relies on a codec? +// TODO can we handle sorting where the Compare function relies on a codec? type Sortable[T any] interface { - Less(T) bool + Compare(T) int } // Sorts the elements of [s]. func Sort[T Sortable[T]](s []T) { - slices.SortFunc(s, T.Less) + slices.SortFunc(s, T.Compare) } // Sorts the elements of [s] based on their hashes. func SortByHash[T ~[]byte](s []T) { - slices.SortFunc(s, func(i, j T) bool { + slices.SortFunc(s, func(i, j T) int { iHash := hashing.ComputeHash256(i) jHash := hashing.ComputeHash256(j) - return bytes.Compare(iHash, jHash) == -1 - }) -} - -// Sorts a 2D byte slice. -// Each byte slice is not sorted internally; the byte slices are sorted relative -// to one another. -func SortBytes[T ~[]byte](s []T) { - slices.SortFunc(s, func(i, j T) bool { - return bytes.Compare(i, j) == -1 + return bytes.Compare(iHash, jHash) }) } @@ -54,7 +45,7 @@ func IsSortedBytes[T ~[]byte](s []T) bool { // Returns true iff the elements in [s] are unique and sorted. func IsSortedAndUnique[T Sortable[T]](s []T) bool { for i := 0; i < len(s)-1; i++ { - if !s[i].Less(s[i+1]) { + if s[i].Compare(s[i+1]) >= 0 { return false } } @@ -87,3 +78,21 @@ func IsSortedAndUniqueByHash[T ~[]byte](s []T) bool { } return true } + +// Compare returns +// +// -1 if x is less than y, +// 0 if x equals y, +// 1 if x is greater than y. +// +// TODO: Remove after updating to go1.21. +func Compare[T constraints.Ordered](x, y T) int { + switch { + case x < y: + return -1 + case x > y: + return 1 + default: + return 0 + } +} diff --git a/utils/sorting_test.go b/utils/sorting_test.go index 464959dd9588..019834907686 100644 --- a/utils/sorting_test.go +++ b/utils/sorting_test.go @@ -4,9 +4,7 @@ package utils import ( - "math/rand" "testing" - "time" "github.com/stretchr/testify/require" ) @@ -15,8 +13,15 @@ var _ Sortable[sortable] = sortable(0) type sortable int -func (s sortable) Less(other sortable) bool { - return s < other +func (s sortable) Compare(other sortable) int { + switch { + case s < other: + return -1 + case s > other: + return 1 + default: + return 0 + } } func TestSortSliceSortable(t *testing.T) { @@ -59,23 +64,6 @@ func TestSortSliceSortable(t *testing.T) { require.Equal([]sortable{1, 2, 3}, s) } -func TestSortBytesIsSortedBytes(t *testing.T) { - require := require.New(t) - - seed := time.Now().UnixNano() - t.Log("Seed: ", seed) - rand := rand.New(rand.NewSource(seed)) //#nosec G404 - - slices := make([][]byte, 1024) - for j := 0; j < len(slices); j++ { - slices[j] = make([]byte, 32) - _, _ = rand.Read(slices[j]) - } - require.False(IsSortedBytes(slices)) - SortBytes(slices) - require.True(IsSortedBytes(slices)) -} - func TestIsSortedAndUniqueSortable(t *testing.T) { require := require.New(t) diff --git a/vms/avm/genesis.go b/vms/avm/genesis.go index 506d2465d691..20ed5c6ba474 100644 --- a/vms/avm/genesis.go +++ b/vms/avm/genesis.go @@ -19,6 +19,6 @@ type GenesisAsset struct { txs.CreateAssetTx `serialize:"true"` } -func (g *GenesisAsset) Less(other *GenesisAsset) bool { - return g.Alias < other.Alias +func (g *GenesisAsset) Compare(other *GenesisAsset) int { + return utils.Compare(g.Alias, other.Alias) } diff --git a/vms/avm/genesis_test.go b/vms/avm/genesis_test.go index 10c7aac40295..8c26e2a13dae 100644 --- a/vms/avm/genesis_test.go +++ b/vms/avm/genesis_test.go @@ -4,24 +4,39 @@ package avm import ( + "fmt" "testing" "github.com/stretchr/testify/require" ) -func TestGenesisAssetLess(t *testing.T) { - require := require.New(t) - - var g1, g2 GenesisAsset - require.False(g1.Less(&g2)) - require.False(g2.Less(&g1)) - - g1 = GenesisAsset{ - Alias: "a", +func TestGenesisAssetCompare(t *testing.T) { + tests := []struct { + a *GenesisAsset + b *GenesisAsset + expected int + }{ + { + a: &GenesisAsset{}, + b: &GenesisAsset{}, + expected: 0, + }, + { + a: &GenesisAsset{ + Alias: "a", + }, + b: &GenesisAsset{ + Alias: "aa", + }, + expected: -1, + }, } - g2 = GenesisAsset{ - Alias: "aa", + for _, test := range tests { + t.Run(fmt.Sprintf("%s_%s_%d", test.a.Alias, test.b.Alias, test.expected), func(t *testing.T) { + require := require.New(t) + + require.Equal(test.expected, test.a.Compare(test.b)) + require.Equal(-test.expected, test.b.Compare(test.a)) + }) } - require.True(g1.Less(&g2)) - require.False(g2.Less(&g1)) } diff --git a/vms/avm/txs/initial_state.go b/vms/avm/txs/initial_state.go index a50c88c0a294..5df1bc3fd8b6 100644 --- a/vms/avm/txs/initial_state.go +++ b/vms/avm/txs/initial_state.go @@ -59,8 +59,8 @@ func (is *InitialState) Verify(c codec.Manager, numFxs int) error { return nil } -func (is *InitialState) Less(other *InitialState) bool { - return is.FxIndex < other.FxIndex +func (is *InitialState) Compare(other *InitialState) int { + return utils.Compare(is.FxIndex, other.FxIndex) } func (is *InitialState) Sort(c codec.Manager) { diff --git a/vms/avm/txs/initial_state_test.go b/vms/avm/txs/initial_state_test.go index f54f54b3b9ed..15cf6eb284e1 100644 --- a/vms/avm/txs/initial_state_test.go +++ b/vms/avm/txs/initial_state_test.go @@ -5,6 +5,7 @@ package txs import ( "errors" + "fmt" "testing" "github.com/stretchr/testify/require" @@ -159,14 +160,31 @@ func TestInitialStateVerifyUnsortedOutputs(t *testing.T) { require.NoError(is.Verify(m, numFxs)) } -func TestInitialStateLess(t *testing.T) { - require := require.New(t) - - var is1, is2 InitialState - require.False(is1.Less(&is2)) - require.False(is2.Less(&is1)) +func TestInitialStateCompare(t *testing.T) { + tests := []struct { + a *InitialState + b *InitialState + expected int + }{ + { + a: &InitialState{}, + b: &InitialState{}, + expected: 0, + }, + { + a: &InitialState{ + FxIndex: 1, + }, + b: &InitialState{}, + expected: 1, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d_%d_%d", test.a.FxIndex, test.b.FxIndex, test.expected), func(t *testing.T) { + require := require.New(t) - is1.FxIndex = 1 - require.False(is1.Less(&is2)) - require.True(is2.Less(&is1)) + require.Equal(test.expected, test.a.Compare(test.b)) + require.Equal(-test.expected, test.b.Compare(test.a)) + }) + } } diff --git a/vms/avm/txs/operation.go b/vms/avm/txs/operation.go index 4b4cb27aa46b..ded7671e618a 100644 --- a/vms/avm/txs/operation.go +++ b/vms/avm/txs/operation.go @@ -48,16 +48,16 @@ type operationAndCodec struct { codec codec.Manager } -func (o *operationAndCodec) Less(other *operationAndCodec) bool { +func (o *operationAndCodec) Compare(other *operationAndCodec) int { oBytes, err := o.codec.Marshal(CodecVersion, o.op) if err != nil { - return false + return 0 } otherBytes, err := o.codec.Marshal(CodecVersion, other.op) if err != nil { - return false + return 0 } - return bytes.Compare(oBytes, otherBytes) == -1 + return bytes.Compare(oBytes, otherBytes) } func SortOperations(ops []*Operation, c codec.Manager) { diff --git a/vms/components/avax/transferables.go b/vms/components/avax/transferables.go index 3134ac68ff4a..44bafeef8d6c 100644 --- a/vms/components/avax/transferables.go +++ b/vms/components/avax/transferables.go @@ -161,8 +161,8 @@ func (in *TransferableInput) Verify() error { } } -func (in *TransferableInput) Less(other *TransferableInput) bool { - return in.UTXOID.Less(&other.UTXOID) +func (in *TransferableInput) Compare(other *TransferableInput) int { + return in.UTXOID.Compare(&other.UTXOID) } type innerSortTransferableInputsWithSigners struct { diff --git a/vms/components/avax/utxo_id.go b/vms/components/avax/utxo_id.go index 26fe8b83fb98..5b81f2f091a9 100644 --- a/vms/components/avax/utxo_id.go +++ b/vms/components/avax/utxo_id.go @@ -91,16 +91,11 @@ func (utxo *UTXOID) Verify() error { } } -func (utxo *UTXOID) Less(other *UTXOID) bool { +func (utxo *UTXOID) Compare(other *UTXOID) int { utxoID, utxoIndex := utxo.InputSource() otherID, otherIndex := other.InputSource() - - switch bytes.Compare(utxoID[:], otherID[:]) { - case -1: - return true - case 0: - return utxoIndex < otherIndex - default: - return false + if txIDComp := bytes.Compare(utxoID[:], otherID[:]); txIDComp != 0 { + return txIDComp } + return utils.Compare(utxoIndex, otherIndex) } diff --git a/vms/components/avax/utxo_id_test.go b/vms/components/avax/utxo_id_test.go index 5652fa1afa69..e21ef620428b 100644 --- a/vms/components/avax/utxo_id_test.go +++ b/vms/components/avax/utxo_id_test.go @@ -50,56 +50,43 @@ func TestUTXOID(t *testing.T) { require.Equal(utxoID.InputID(), newUTXOID.InputID()) } -func TestUTXOIDLess(t *testing.T) { +func TestUTXOIDCompare(t *testing.T) { type test struct { name string id1 UTXOID id2 UTXOID - expected bool + expected int } tests := []*test{ { name: "same", id1: UTXOID{}, id2: UTXOID{}, - expected: false, + expected: 0, }, { - name: "first id smaller", + name: "id smaller", id1: UTXOID{}, id2: UTXOID{ TxID: ids.ID{1}, }, - expected: true, + expected: -1, }, { - name: "first id larger", - id1: UTXOID{ - TxID: ids.ID{1}, - }, - id2: UTXOID{}, - expected: false, - }, - { - name: "first index smaller", + name: "index smaller", id1: UTXOID{}, id2: UTXOID{ OutputIndex: 1, }, - expected: true, - }, - { - name: "first index larger", - id1: UTXOID{ - OutputIndex: 1, - }, - id2: UTXOID{}, - expected: false, + expected: -1, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - require.Equal(t, tt.expected, tt.id1.Less(&tt.id2)) + require := require.New(t) + + require.Equal(tt.expected, tt.id1.Compare(&tt.id2)) + require.Equal(-tt.expected, tt.id2.Compare(&tt.id1)) }) } } diff --git a/vms/platformvm/api/static_service.go b/vms/platformvm/api/static_service.go index ea1cfcb2d63f..7f37b247b34b 100644 --- a/vms/platformvm/api/static_service.go +++ b/vms/platformvm/api/static_service.go @@ -50,30 +50,25 @@ type UTXO struct { } // TODO can we define this on *UTXO? -func (utxo UTXO) Less(other UTXO) bool { - if utxo.Locktime < other.Locktime { - return true - } else if utxo.Locktime > other.Locktime { - return false +func (utxo UTXO) Compare(other UTXO) int { + if locktimeCmp := utils.Compare(utxo.Locktime, other.Locktime); locktimeCmp != 0 { + return locktimeCmp } - - if utxo.Amount < other.Amount { - return true - } else if utxo.Amount > other.Amount { - return false + if amountCmp := utils.Compare(utxo.Amount, other.Amount); amountCmp != 0 { + return amountCmp } utxoAddr, err := bech32ToID(utxo.Address) if err != nil { - return false + return 0 } otherAddr, err := bech32ToID(other.Address) if err != nil { - return false + return 0 } - return utxoAddr.Less(otherAddr) + return utxoAddr.Compare(otherAddr) } // TODO: Refactor APIStaker, APIValidators and merge them together for diff --git a/vms/platformvm/api/static_service_test.go b/vms/platformvm/api/static_service_test.go index 8bcbf4e766db..402a5fc7c766 100644 --- a/vms/platformvm/api/static_service_test.go +++ b/vms/platformvm/api/static_service_test.go @@ -237,7 +237,7 @@ func TestBuildGenesisReturnsSortedValidators(t *testing.T) { require.Len(validators, 3) } -func TestUTXOLess(t *testing.T) { +func TestUTXOCompare(t *testing.T) { var ( smallerAddr = ids.ShortID{} largerAddr = ids.ShortID{1} @@ -251,72 +251,49 @@ func TestUTXOLess(t *testing.T) { name string utxo1 UTXO utxo2 UTXO - expected bool + expected int } tests := []test{ { name: "both empty", utxo1: UTXO{}, utxo2: UTXO{}, - expected: false, + expected: 0, }, { - name: "first locktime smaller", + name: "locktime smaller", utxo1: UTXO{}, utxo2: UTXO{ Locktime: 1, }, - expected: true, + expected: -1, }, { - name: "first locktime larger", - utxo1: UTXO{ - Locktime: 1, - }, - utxo2: UTXO{}, - expected: false, - }, - { - name: "first amount smaller", + name: "amount smaller", utxo1: UTXO{}, utxo2: UTXO{ Amount: 1, }, - expected: true, + expected: -1, }, { - name: "first amount larger", - utxo1: UTXO{ - Amount: 1, - }, - utxo2: UTXO{}, - expected: false, - }, - { - name: "first address smaller", + name: "address smaller", utxo1: UTXO{ Address: smallerAddrStr, }, utxo2: UTXO{ Address: largerAddrStr, }, - expected: true, - }, - { - name: "first address larger", - utxo1: UTXO{ - Address: largerAddrStr, - }, - utxo2: UTXO{ - Address: smallerAddrStr, - }, - expected: false, + expected: -1, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - require.Equal(t, tt.expected, tt.utxo1.Less(tt.utxo2)) + require := require.New(t) + + require.Equal(tt.expected, tt.utxo1.Compare(tt.utxo2)) + require.Equal(-tt.expected, tt.utxo2.Compare(tt.utxo1)) }) } } diff --git a/vms/platformvm/warp/signature_test.go b/vms/platformvm/warp/signature_test.go index b3eaa88bbfe8..c721eb62938d 100644 --- a/vms/platformvm/warp/signature_test.go +++ b/vms/platformvm/warp/signature_test.go @@ -39,8 +39,8 @@ type testValidator struct { vdr *Validator } -func (v *testValidator) Less(o *testValidator) bool { - return v.vdr.Less(o.vdr) +func (v *testValidator) Compare(o *testValidator) int { + return v.vdr.Compare(o.vdr) } func newTestValidator() *testValidator { diff --git a/vms/platformvm/warp/validator.go b/vms/platformvm/warp/validator.go index 42ff34e7cb5e..5e193ae1815e 100644 --- a/vms/platformvm/warp/validator.go +++ b/vms/platformvm/warp/validator.go @@ -39,8 +39,8 @@ type Validator struct { NodeIDs []ids.NodeID } -func (v *Validator) Less(o *Validator) bool { - return bytes.Compare(v.PublicKeyBytes, o.PublicKeyBytes) < 0 +func (v *Validator) Compare(o *Validator) int { + return bytes.Compare(v.PublicKeyBytes, o.PublicKeyBytes) } // GetCanonicalValidatorSet returns the validator set of [subnetID] at diff --git a/vms/proposervm/proposer/validators.go b/vms/proposervm/proposer/validators.go index ba60a088003a..89ed964d5983 100644 --- a/vms/proposervm/proposer/validators.go +++ b/vms/proposervm/proposer/validators.go @@ -15,6 +15,6 @@ type validatorData struct { weight uint64 } -func (d validatorData) Less(other validatorData) bool { - return d.id.Less(other.id) +func (d validatorData) Compare(other validatorData) int { + return d.id.Compare(other.id) } diff --git a/vms/proposervm/proposer/validators_test.go b/vms/proposervm/proposer/validators_test.go index 2f7913d01e2e..8be1f4c23d99 100644 --- a/vms/proposervm/proposer/validators_test.go +++ b/vms/proposervm/proposer/validators_test.go @@ -4,6 +4,7 @@ package proposer import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -11,16 +12,31 @@ import ( "github.com/ava-labs/avalanchego/ids" ) -func TestValidatorDataLess(t *testing.T) { - require := require.New(t) - - var v1, v2 validatorData - require.False(v1.Less(v2)) - require.False(v2.Less(v1)) +func TestValidatorDataCompare(t *testing.T) { + tests := []struct { + a validatorData + b validatorData + expected int + }{ + { + a: validatorData{}, + b: validatorData{}, + expected: 0, + }, + { + a: validatorData{ + id: ids.BuildTestNodeID([]byte{1}), + }, + b: validatorData{}, + expected: 1, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%s_%s_%d", test.a.id, test.b.id, test.expected), func(t *testing.T) { + require := require.New(t) - v1 = validatorData{ - id: ids.BuildTestNodeID([]byte{1}), + require.Equal(test.expected, test.a.Compare(test.b)) + require.Equal(-test.expected, test.b.Compare(test.a)) + }) } - require.False(v1.Less(v2)) - require.True(v2.Less(v1)) } diff --git a/x/archivedb/key_test.go b/x/archivedb/key_test.go index d56dca5f37fc..18343e725bc0 100644 --- a/x/archivedb/key_test.go +++ b/x/archivedb/key_test.go @@ -21,9 +21,7 @@ func TestNaturalDescSortingForSameKey(t *testing.T) { entry := [][]byte{key0, key1, key2, key3} expected := [][]byte{key3, key2, key1, key0} - slices.SortFunc(entry, func(i, j []byte) bool { - return bytes.Compare(i, j) < 0 - }) + slices.SortFunc(entry, bytes.Compare) require.Equal(t, expected, entry) } @@ -37,9 +35,7 @@ func TestSortingDifferentPrefix(t *testing.T) { entry := [][]byte{key0, key1, key2, key3} expected := [][]byte{key1, key0, key3, key2} - slices.SortFunc(entry, func(i, j []byte) bool { - return bytes.Compare(i, j) < 0 - }) + slices.SortFunc(entry, bytes.Compare) require.Equal(t, expected, entry) } diff --git a/x/merkledb/key.go b/x/merkledb/key.go index d65d9b74a0a6..78e35f59924c 100644 --- a/x/merkledb/key.go +++ b/x/merkledb/key.go @@ -11,6 +11,8 @@ import ( "golang.org/x/exp/maps" "golang.org/x/exp/slices" + + "github.com/ava-labs/avalanchego/utils" ) var ( @@ -164,12 +166,19 @@ func (k Key) Length() int { // Greater returns true if current Key is greater than other Key func (k Key) Greater(other Key) bool { - return k.value > other.value || (k.value == other.value && k.length > other.length) + return k.Compare(other) == 1 } // Less will return true if current Key is less than other Key func (k Key) Less(other Key) bool { - return k.value < other.value || (k.value == other.value && k.length < other.length) + return k.Compare(other) == -1 +} + +func (k Key) Compare(other Key) int { + if valueCmp := utils.Compare(k.value, other.value); valueCmp != 0 { + return valueCmp + } + return utils.Compare(k.length, other.length) } // Extend returns a new Key that is the in-order aggregation of Key [k] with [keys] diff --git a/x/merkledb/view_iterator.go b/x/merkledb/view_iterator.go index fac213bf350b..66f4712daf7a 100644 --- a/x/merkledb/view_iterator.go +++ b/x/merkledb/view_iterator.go @@ -41,8 +41,8 @@ func (t *trieView) NewIteratorWithStartAndPrefix(start, prefix []byte) database. } // sort [changes] so they can be merged with the parent trie's state - slices.SortFunc(changes, func(a, b KeyChange) bool { - return bytes.Compare(a.Key, b.Key) == -1 + slices.SortFunc(changes, func(a, b KeyChange) int { + return bytes.Compare(a.Key, b.Key) }) return &viewIterator{ diff --git a/x/sync/sync_test.go b/x/sync/sync_test.go index af908c9d941c..71871e95db56 100644 --- a/x/sync/sync_test.go +++ b/x/sync/sync_test.go @@ -696,11 +696,11 @@ func TestFindNextKeyRandom(t *testing.T) { } // Sort in ascending order by key prefix. - serializedPathLess := func(i, j keyAndID) bool { - return i.key.Less(j.key) + serializedPathCompare := func(i, j keyAndID) int { + return i.key.Compare(j.key) } - slices.SortFunc(remoteKeyIDs, serializedPathLess) - slices.SortFunc(localKeyIDs, serializedPathLess) + slices.SortFunc(remoteKeyIDs, serializedPathCompare) + slices.SortFunc(localKeyIDs, serializedPathCompare) // Filter out keys that are before the last received key findBounds := func(keyIDs []keyAndID) (int, int) { @@ -738,7 +738,7 @@ func TestFindNextKeyRandom(t *testing.T) { for i := 0; i < len(remoteKeyIDs) && i < len(localKeyIDs); i++ { // See if the keys are different. smaller, bigger := remoteKeyIDs[i], localKeyIDs[i] - if serializedPathLess(localKeyIDs[i], remoteKeyIDs[i]) { + if serializedPathCompare(localKeyIDs[i], remoteKeyIDs[i]) == -1 { smaller, bigger = localKeyIDs[i], remoteKeyIDs[i] } @@ -1194,8 +1194,6 @@ func generateTrieWithMinKeyLen(t *testing.T, r *rand.Rand, count int, minKeyLen } i++ } - slices.SortFunc(allKeys, func(a, b []byte) bool { - return bytes.Compare(a, b) < 0 - }) + slices.SortFunc(allKeys, bytes.Compare) return db, allKeys, batch.Write() } diff --git a/x/sync/workheap_test.go b/x/sync/workheap_test.go index 0a3262a9310f..826011dbdebd 100644 --- a/x/sync/workheap_test.go +++ b/x/sync/workheap_test.go @@ -4,6 +4,7 @@ package sync import ( + "bytes" "math/rand" "testing" "time" @@ -13,7 +14,6 @@ import ( "golang.org/x/exp/slices" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/maybe" ) @@ -199,7 +199,7 @@ func TestWorkHeapMergeInsertRandom(t *testing.T) { _, _ = rand.Read(bound) bounds = append(bounds, bound) } - utils.SortBytes(bounds) + slices.SortFunc(bounds, bytes.Compare) // Note that start < end for all ranges. // It is possible but extremely unlikely that From 477157d27d607da50d51464dd2a4a6743ab0a891 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:10:56 -0500 Subject: [PATCH 101/267] `vms/platformvm`: Cleanup some block tests (#2422) Co-authored-by: Dan Laine --- vms/platformvm/block/parse_test.go | 28 +++++------ vms/platformvm/block/proposal_block_test.go | 52 ++++----------------- 2 files changed, 22 insertions(+), 58 deletions(-) diff --git a/vms/platformvm/block/parse_test.go b/vms/platformvm/block/parse_test.go index 906824effd96..28dea498d48f 100644 --- a/vms/platformvm/block/parse_test.go +++ b/vms/platformvm/block/parse_test.go @@ -25,12 +25,12 @@ func TestStandardBlocks(t *testing.T) { blkTimestamp := time.Now() parentID := ids.ID{'p', 'a', 'r', 'e', 'n', 't', 'I', 'D'} height := uint64(2022) - txs, err := testDecisionTxs() + decisionTxs, err := testDecisionTxs() require.NoError(err) for _, cdc := range []codec.Manager{Codec, GenesisCodec} { // build block - apricotStandardBlk, err := NewApricotStandardBlock(parentID, height, txs) + apricotStandardBlk, err := NewApricotStandardBlock(parentID, height, decisionTxs) require.NoError(err) // parse block @@ -44,10 +44,10 @@ func TestStandardBlocks(t *testing.T) { require.Equal(apricotStandardBlk.Height(), parsed.Height()) require.IsType(&ApricotStandardBlock{}, parsed) - require.Equal(txs, parsed.Txs()) + require.Equal(decisionTxs, parsed.Txs()) // check that banff standard block can be built and parsed - banffStandardBlk, err := NewBanffStandardBlock(blkTimestamp, parentID, height, txs) + banffStandardBlk, err := NewBanffStandardBlock(blkTimestamp, parentID, height, decisionTxs) require.NoError(err) // parse block @@ -61,7 +61,7 @@ func TestStandardBlocks(t *testing.T) { require.Equal(banffStandardBlk.Height(), parsed.Height()) require.IsType(&BanffStandardBlock{}, parsed) parsedBanffStandardBlk := parsed.(*BanffStandardBlock) - require.Equal(txs, parsedBanffStandardBlk.Txs()) + require.Equal(decisionTxs, parsedBanffStandardBlk.Txs()) // timestamp check for banff blocks only require.Equal(banffStandardBlk.Timestamp(), parsedBanffStandardBlk.Timestamp()) @@ -77,7 +77,7 @@ func TestProposalBlocks(t *testing.T) { blkTimestamp := time.Now() parentID := ids.ID{'p', 'a', 'r', 'e', 'n', 't', 'I', 'D'} height := uint64(2022) - tx, err := testProposalTx() + proposalTx, err := testProposalTx() require.NoError(err) for _, cdc := range []codec.Manager{Codec, GenesisCodec} { @@ -85,7 +85,7 @@ func TestProposalBlocks(t *testing.T) { apricotProposalBlk, err := NewApricotProposalBlock( parentID, height, - tx, + proposalTx, ) require.NoError(err) @@ -101,14 +101,14 @@ func TestProposalBlocks(t *testing.T) { require.IsType(&ApricotProposalBlock{}, parsed) parsedApricotProposalBlk := parsed.(*ApricotProposalBlock) - require.Equal([]*txs.Tx{tx}, parsedApricotProposalBlk.Txs()) + require.Equal([]*txs.Tx{proposalTx}, parsedApricotProposalBlk.Txs()) // check that banff proposal block can be built and parsed banffProposalBlk, err := NewBanffProposalBlock( blkTimestamp, parentID, height, - tx, + proposalTx, ) require.NoError(err) @@ -119,11 +119,11 @@ func TestProposalBlocks(t *testing.T) { // compare content require.Equal(banffProposalBlk.ID(), parsed.ID()) require.Equal(banffProposalBlk.Bytes(), parsed.Bytes()) - require.Equal(banffProposalBlk.Parent(), banffProposalBlk.Parent()) + require.Equal(banffProposalBlk.Parent(), parsed.Parent()) require.Equal(banffProposalBlk.Height(), parsed.Height()) require.IsType(&BanffProposalBlock{}, parsed) parsedBanffProposalBlk := parsed.(*BanffProposalBlock) - require.Equal([]*txs.Tx{tx}, parsedBanffProposalBlk.Txs()) + require.Equal([]*txs.Tx{proposalTx}, parsedBanffProposalBlk.Txs()) // timestamp check for banff blocks only require.Equal(banffProposalBlk.Timestamp(), parsedBanffProposalBlk.Timestamp()) @@ -224,7 +224,7 @@ func TestAtomicBlock(t *testing.T) { require := require.New(t) parentID := ids.ID{'p', 'a', 'r', 'e', 'n', 't', 'I', 'D'} height := uint64(2022) - tx, err := testAtomicTx() + atomicTx, err := testAtomicTx() require.NoError(err) for _, cdc := range []codec.Manager{Codec, GenesisCodec} { @@ -232,7 +232,7 @@ func TestAtomicBlock(t *testing.T) { atomicBlk, err := NewApricotAtomicBlock( parentID, height, - tx, + atomicTx, ) require.NoError(err) @@ -248,7 +248,7 @@ func TestAtomicBlock(t *testing.T) { require.IsType(&ApricotAtomicBlock{}, parsed) parsedAtomicBlk := parsed.(*ApricotAtomicBlock) - require.Equal([]*txs.Tx{tx}, parsedAtomicBlk.Txs()) + require.Equal([]*txs.Tx{atomicTx}, parsedAtomicBlk.Txs()) } } diff --git a/vms/platformvm/block/proposal_block_test.go b/vms/platformvm/block/proposal_block_test.go index 9c1038c51c98..f8c03189b604 100644 --- a/vms/platformvm/block/proposal_block_test.go +++ b/vms/platformvm/block/proposal_block_test.go @@ -10,10 +10,6 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) func TestNewBanffProposalBlock(t *testing.T) { @@ -22,30 +18,14 @@ func TestNewBanffProposalBlock(t *testing.T) { timestamp := time.Now().Truncate(time.Second) parentID := ids.GenerateTestID() height := uint64(1337) - - tx := &txs.Tx{ - Unsigned: &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - Ins: []*avax.TransferableInput{}, - Outs: []*avax.TransferableOutput{}, - }, - }, - StakeOuts: []*avax.TransferableOutput{}, - Validator: txs.Validator{}, - RewardsOwner: &secp256k1fx.OutputOwners{ - Addrs: []ids.ShortID{}, - }, - }, - Creds: []verify.Verifiable{}, - } - require.NoError(tx.Initialize(txs.Codec)) + proposalTx, err := testProposalTx() + require.NoError(err) blk, err := NewBanffProposalBlock( timestamp, parentID, height, - tx, + proposalTx, ) require.NoError(err) @@ -53,7 +33,7 @@ func TestNewBanffProposalBlock(t *testing.T) { require.NotEmpty(blk.Bytes()) require.NotEmpty(blk.Tx.Bytes()) require.NotEqual(ids.Empty, blk.Tx.ID()) - require.Equal(tx.Bytes(), blk.Tx.Bytes()) + require.Equal(proposalTx.Bytes(), blk.Tx.Bytes()) require.Equal(timestamp, blk.Timestamp()) require.Equal(parentID, blk.Parent()) require.Equal(height, blk.Height()) @@ -64,29 +44,13 @@ func TestNewApricotProposalBlock(t *testing.T) { parentID := ids.GenerateTestID() height := uint64(1337) - - tx := &txs.Tx{ - Unsigned: &txs.AddValidatorTx{ - BaseTx: txs.BaseTx{ - BaseTx: avax.BaseTx{ - Ins: []*avax.TransferableInput{}, - Outs: []*avax.TransferableOutput{}, - }, - }, - StakeOuts: []*avax.TransferableOutput{}, - Validator: txs.Validator{}, - RewardsOwner: &secp256k1fx.OutputOwners{ - Addrs: []ids.ShortID{}, - }, - }, - Creds: []verify.Verifiable{}, - } - require.NoError(tx.Initialize(txs.Codec)) + proposalTx, err := testProposalTx() + require.NoError(err) blk, err := NewApricotProposalBlock( parentID, height, - tx, + proposalTx, ) require.NoError(err) @@ -94,7 +58,7 @@ func TestNewApricotProposalBlock(t *testing.T) { require.NotEmpty(blk.Bytes()) require.NotEmpty(blk.Tx.Bytes()) require.NotEqual(ids.Empty, blk.Tx.ID()) - require.Equal(tx.Bytes(), blk.Tx.Bytes()) + require.Equal(proposalTx.Bytes(), blk.Tx.Bytes()) require.Equal(parentID, blk.Parent()) require.Equal(height, blk.Height()) } From 439dc1e55216d612a11b463949bf7be7cf3138ec Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 5 Dec 2023 10:46:13 -0700 Subject: [PATCH 102/267] ProposerVM Extend windows 0 - Cleanup (#2404) Co-authored-by: Stephen Buttolph --- chains/manager.go | 28 ++-- vms/proposervm/batched_vm_test.go | 14 +- vms/proposervm/block.go | 133 ++++++++++++------ vms/proposervm/block_test.go | 8 +- vms/proposervm/config.go | 32 +++++ vms/proposervm/height_indexed_vm.go | 10 +- vms/proposervm/post_fork_block_test.go | 40 +++--- vms/proposervm/post_fork_option_test.go | 14 +- vms/proposervm/pre_fork_block.go | 10 +- vms/proposervm/pre_fork_block_test.go | 10 +- vms/proposervm/state_syncable_vm_test.go | 38 ++--- vms/proposervm/vm.go | 33 +---- vms/proposervm/vm_regression_test.go | 15 +- vms/proposervm/vm_test.go | 170 +++++++++++++---------- 14 files changed, 321 insertions(+), 234 deletions(-) create mode 100644 vms/proposervm/config.go diff --git a/chains/manager.go b/chains/manager.go index e764a5dfb3ce..86da6811c41a 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -769,12 +769,14 @@ func (m *manager) createAvalancheChain( // using. var vmWrappingProposerVM block.ChainVM = proposervm.New( vmWrappedInsideProposerVM, - m.ApricotPhase4Time, - m.ApricotPhase4MinPChainHeight, - minBlockDelay, - numHistoricalBlocks, - m.stakingSigner, - m.stakingCert, + proposervm.Config{ + ActivationTime: m.ApricotPhase4Time, + MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, + MinBlkDelay: minBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: m.stakingSigner, + StakingCertLeaf: m.stakingCert, + }, ) if m.MeterVMEnabled { @@ -1112,12 +1114,14 @@ func (m *manager) createSnowmanChain( vm = proposervm.New( vm, - m.ApricotPhase4Time, - m.ApricotPhase4MinPChainHeight, - minBlockDelay, - numHistoricalBlocks, - m.stakingSigner, - m.stakingCert, + proposervm.Config{ + ActivationTime: m.ApricotPhase4Time, + MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, + MinBlkDelay: minBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: m.stakingSigner, + StakingCertLeaf: m.stakingCert, + }, ) if m.MeterVMEnabled { diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 684d91ceb3df..c55c5ffc13b4 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -1020,12 +1020,14 @@ func initTestRemoteProposerVM( proVM := New( coreVM, - proBlkStartTime, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: proBlkStartTime, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) valState := &validators.TestState{ diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 489d325f8f70..fdea5464edb8 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -124,12 +124,11 @@ func (p *postForkCommonComponents) Verify( // If the node is currently syncing - we don't assume that the P-chain has // been synced up to this point yet. if p.vm.consensusState == snow.NormalOp { - childID := child.ID() currentPChainHeight, err := p.vm.ctx.ValidatorState.GetCurrentHeight(ctx) if err != nil { p.vm.ctx.Log.Error("block verification failed", zap.String("reason", "failed to get current P-Chain height"), - zap.Stringer("blkID", childID), + zap.Stringer("blkID", child.ID()), zap.Error(err), ) return err @@ -142,18 +141,11 @@ func (p *postForkCommonComponents) Verify( ) } - childHeight := child.Height() - proposerID := child.Proposer() - minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) + delay, err := p.verifyBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) if err != nil { return err } - delay := childTimestamp.Sub(parentTimestamp) - if delay < minDelay { - return errProposerWindowNotStarted - } - // Verify the signature of the node shouldHaveProposer := delay < proposer.MaxVerifyDelay if err := child.SignedBlock.Verify(shouldHaveProposer, p.vm.ctx.ChainID); err != nil { @@ -161,9 +153,8 @@ func (p *postForkCommonComponents) Verify( } p.vm.ctx.Log.Debug("verified post-fork block", - zap.Stringer("blkID", childID), + zap.Stringer("blkID", child.ID()), zap.Time("parentTimestamp", parentTimestamp), - zap.Duration("minDelay", minDelay), zap.Time("blockTimestamp", childTimestamp), ) } @@ -202,37 +193,15 @@ func (p *postForkCommonComponents) buildChild( return nil, err } - delay := newTimestamp.Sub(parentTimestamp) - if delay < proposer.MaxBuildDelay { - parentHeight := p.innerBlk.Height() - proposerID := p.vm.ctx.NodeID - minDelay, err := p.vm.Windower.Delay(ctx, parentHeight+1, parentPChainHeight, proposerID, proposer.MaxBuildWindows) - if err != nil { - p.vm.ctx.Log.Error("unexpected build block failure", - zap.String("reason", "failed to calculate required timestamp delay"), - zap.Stringer("parentID", parentID), - zap.Error(err), - ) - return nil, err - } - - if delay < minDelay { - // It's not our turn to propose a block yet. This is likely caused - // by having previously notified the consensus engine to attempt to - // build a block on top of a block that is no longer the preferred - // block. - p.vm.ctx.Log.Debug("build block dropped", - zap.Time("parentTimestamp", parentTimestamp), - zap.Duration("minDelay", minDelay), - zap.Time("blockTimestamp", newTimestamp), - ) - - // In case the inner VM only issued one pendingTxs message, we - // should attempt to re-handle that once it is our turn to build the - // block. - p.vm.notifyInnerBlockReady() - return nil, errProposerWindowNotStarted - } + shouldBuildUnsignedBlock, err := p.shouldBuildUnsignedBlock( + ctx, + parentID, + parentTimestamp, + parentPChainHeight, + newTimestamp, + ) + if err != nil { + return nil, err } var innerBlock snowman.Block @@ -249,7 +218,7 @@ func (p *postForkCommonComponents) buildChild( // Build the child var statelessChild block.SignedBlock - if delay >= proposer.MaxVerifyDelay { + if shouldBuildUnsignedBlock { statelessChild, err = block.BuildUnsigned( parentID, newTimestamp, @@ -261,10 +230,10 @@ func (p *postForkCommonComponents) buildChild( parentID, newTimestamp, pChainHeight, - p.vm.stakingCertLeaf, + p.vm.StakingCertLeaf, innerBlock.Bytes(), p.vm.ctx.ChainID, - p.vm.stakingLeafSigner, + p.vm.StakingLeafSigner, ) } if err != nil { @@ -334,3 +303,75 @@ func verifyIsNotOracleBlock(ctx context.Context, b snowman.Block) error { return err } } + +func (p *postForkCommonComponents) verifyBlockDelay( + ctx context.Context, + parentTimestamp time.Time, + parentPChainHeight uint64, + blk *postForkBlock, +) (time.Duration, error) { + var ( + blkTimestamp = blk.Timestamp() + childHeight = blk.Height() + proposerID = blk.Proposer() + ) + minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) + if err != nil { + return 0, err + } + + delay := blkTimestamp.Sub(parentTimestamp) + if delay < minDelay { + return 0, errProposerWindowNotStarted + } + + return delay, nil +} + +func (p *postForkCommonComponents) shouldBuildUnsignedBlock( + ctx context.Context, + parentID ids.ID, + parentTimestamp time.Time, + parentPChainHeight uint64, + newTimestamp time.Time, +) (bool, error) { + delay := newTimestamp.Sub(parentTimestamp) + if delay >= proposer.MaxBuildDelay { + // time for any node to build an unsigned block + return true, nil + } + + parentHeight := p.innerBlk.Height() + proposerID := p.vm.ctx.NodeID + minDelay, err := p.vm.Windower.Delay(ctx, parentHeight+1, parentPChainHeight, proposerID, proposer.MaxBuildWindows) + if err != nil { + p.vm.ctx.Log.Error("unexpected build block failure", + zap.String("reason", "failed to calculate required timestamp delay"), + zap.Stringer("parentID", parentID), + zap.Error(err), + ) + return false, err + } + + if delay >= minDelay { + // it's time for this node to propose a block. It'll be signed or unsigned + // depending on the delay + return delay >= proposer.MaxVerifyDelay, nil + } + + // It's not our turn to propose a block yet. This is likely caused + // by having previously notified the consensus engine to attempt to + // build a block on top of a block that is no longer the preferred + // block. + p.vm.ctx.Log.Debug("build block dropped", + zap.Time("parentTimestamp", parentTimestamp), + zap.Duration("minDelay", minDelay), + zap.Time("blockTimestamp", newTimestamp), + ) + + // In case the inner VM only issued one pendingTxs message, we + // should attempt to re-handle that once it is our turn to build the + // block. + p.vm.notifyInnerBlockReady() + return false, errProposerWindowNotStarted +} diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 04ac66ecf34e..5cca837a7a84 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -60,15 +60,17 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) vm := &VM{ + Config: Config{ + StakingCertLeaf: &staking.Certificate{}, + StakingLeafSigner: pk, + }, ChainVM: innerVM, blockBuilderVM: innerBlockBuilderVM, ctx: &snow.Context{ ValidatorState: vdrState, Log: logging.NoLog{}, }, - Windower: windower, - stakingCertLeaf: &staking.Certificate{}, - stakingLeafSigner: pk, + Windower: windower, } blk := &postForkCommonComponents{ diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go new file mode 100644 index 000000000000..96645c9489a8 --- /dev/null +++ b/vms/proposervm/config.go @@ -0,0 +1,32 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package proposervm + +import ( + "crypto" + "time" + + "github.com/ava-labs/avalanchego/staking" +) + +type Config struct { + // Time at which proposerVM activates its congestion control mechanism + ActivationTime time.Time + + // Minimal P-chain height referenced upon block building + MinimumPChainHeight uint64 + + // Configurable minimal delay among blocks issued consecutively + MinBlkDelay time.Duration + + // Maximal number of block indexed. + // Zero signals all blocks are indexed. + NumHistoricalBlocks uint64 + + // Block signer + StakingLeafSigner crypto.Signer + + // Block certificate + StakingCertLeaf *staking.Certificate +} diff --git a/vms/proposervm/height_indexed_vm.go b/vms/proposervm/height_indexed_vm.go index 99b911c5be64..6c8d6967ee14 100644 --- a/vms/proposervm/height_indexed_vm.go +++ b/vms/proposervm/height_indexed_vm.go @@ -136,7 +136,7 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { zap.Uint64("height", height), ) - if vm.numHistoricalBlocks == 0 { + if vm.NumHistoricalBlocks == 0 { return nil } @@ -145,13 +145,13 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { // is why <= is used rather than <. This prevents the user from only storing // the last accepted block, which can never be safe due to the non-atomic // commits between the proposervm database and the innerVM's database. - if blocksSinceFork <= vm.numHistoricalBlocks { + if blocksSinceFork <= vm.NumHistoricalBlocks { return nil } // Note: heightToDelete is >= forkHeight, so it is guaranteed not to // underflow. - heightToDelete := height - vm.numHistoricalBlocks - 1 + heightToDelete := height - vm.NumHistoricalBlocks - 1 blockToDelete, err := vm.State.GetBlockIDAtHeight(heightToDelete) if err == database.ErrNotFound { // Block may have already been deleted. This can happen due to a @@ -180,7 +180,7 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { // TODO: Support async deletion of old blocks. func (vm *VM) pruneOldBlocks() error { - if vm.numHistoricalBlocks == 0 { + if vm.NumHistoricalBlocks == 0 { return nil } @@ -194,7 +194,7 @@ func (vm *VM) pruneOldBlocks() error { // // Note: vm.lastAcceptedHeight is guaranteed to be >= height, so the // subtraction can never underflow. - for vm.lastAcceptedHeight-height > vm.numHistoricalBlocks { + for vm.lastAcceptedHeight-height > vm.NumHistoricalBlocks { blockToDelete, err := vm.State.GetBlockIDAtHeight(height) if err != nil { return err diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 659bdd1e5fd3..25dfd4f63e8f 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -70,10 +70,10 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { ids.Empty, // refer unknown parent time.Time{}, 0, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerOracleBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk = postForkBlock{ @@ -155,10 +155,10 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { ids.Empty, // refer unknown parent childCoreBlk.Timestamp(), pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -260,10 +260,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), childCoreBlk.Timestamp(), pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -287,10 +287,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), beforeWinStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -305,10 +305,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), atWindowStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -322,10 +322,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), afterWindowStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -350,10 +350,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), afterSubWinEnd, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -431,10 +431,10 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { prntProBlk.ID(), childCoreBlk.Timestamp(), prntBlkPChainHeight-1, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -611,10 +611,10 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) parentBlk.ID(), childCoreBlk.Timestamp(), prntBlkPChainHeight-1, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -986,10 +986,10 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { postForkOracleBlk.ID(), postForkOracleBlk.Timestamp().Add(proposer.WindowDuration), postForkOracleBlk.PChainHeight(), - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, oracleCoreBlk.opts[0].Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 8e93e2aad05f..e142b391a348 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -660,12 +660,14 @@ func TestOptionTimestampValidity(t *testing.T) { ctx := proVM.ctx proVM = New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) coreVM.InitializeF = func( diff --git a/vms/proposervm/pre_fork_block.go b/vms/proposervm/pre_fork_block.go index ed665e473910..8e952d9d7758 100644 --- a/vms/proposervm/pre_fork_block.go +++ b/vms/proposervm/pre_fork_block.go @@ -97,7 +97,7 @@ func (b *preForkBlock) getInnerBlk() snowman.Block { func (b *preForkBlock) verifyPreForkChild(ctx context.Context, child *preForkBlock) error { parentTimestamp := b.Timestamp() - if !parentTimestamp.Before(b.vm.activationTime) { + if !parentTimestamp.Before(b.vm.ActivationTime) { if err := verifyIsOracleBlock(ctx, b.Block); err != nil { return err } @@ -135,7 +135,7 @@ func (b *preForkBlock) verifyPostForkChild(ctx context.Context, child *postForkB currentPChainHeight, ) } - if childPChainHeight < b.vm.minimumPChainHeight { + if childPChainHeight < b.vm.MinimumPChainHeight { return errPChainHeightTooLow } @@ -150,7 +150,7 @@ func (b *preForkBlock) verifyPostForkChild(ctx context.Context, child *postForkB // if the *preForkBlock is the last *preForkBlock before activation takes effect // (its timestamp is at or after the activation time) parentTimestamp := b.Timestamp() - if parentTimestamp.Before(b.vm.activationTime) { + if parentTimestamp.Before(b.vm.ActivationTime) { return errProposersNotActivated } @@ -181,7 +181,7 @@ func (*preForkBlock) verifyPostForkOption(context.Context, *postForkOption) erro func (b *preForkBlock) buildChild(ctx context.Context) (Block, error) { parentTimestamp := b.Timestamp() - if parentTimestamp.Before(b.vm.activationTime) { + if parentTimestamp.Before(b.vm.ActivationTime) { // The chain hasn't forked yet innerBlock, err := b.vm.ChainVM.BuildBlock(ctx) if err != nil { @@ -210,7 +210,7 @@ func (b *preForkBlock) buildChild(ctx context.Context) (Block, error) { // The child's P-Chain height is proposed as the optimal P-Chain height that // is at least the minimum height - pChainHeight, err := b.vm.optimalPChainHeight(ctx, b.vm.minimumPChainHeight) + pChainHeight, err := b.vm.optimalPChainHeight(ctx, b.vm.MinimumPChainHeight) if err != nil { b.vm.ctx.Log.Error("unexpected build block failure", zap.String("reason", "failed to calculate optimal P-chain height"), diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 1366482a0d9b..4308f9ba05f1 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -342,10 +342,10 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { coreGenBlk.ID(), coreBlk.Timestamp(), 0, // pChainHeight - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, coreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) postForkChild := &postForkBlock{ @@ -740,10 +740,10 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { firstBlock.ID(), // refer unknown parent firstBlock.Timestamp(), 0, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, coreBlk.opts[0].Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) @@ -798,7 +798,7 @@ func TestPreForkBlock_BuildBlockWithContext(t *testing.T) { // Should call BuildBlock since proposervm is not activated innerBlk.EXPECT().Timestamp().Return(time.Time{}) - vm.activationTime = mockable.MaxTime + vm.ActivationTime = mockable.MaxTime gotChild, err = blk.buildChild(context.Background()) require.NoError(err) diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 826f8b877987..b2295d50017b 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -70,12 +70,14 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { // create the VM vm := New( innerVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) ctx := snow.DefaultContextTest() @@ -186,10 +188,10 @@ func TestStateSyncGetOngoingSyncStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -271,10 +273,10 @@ func TestStateSyncGetLastStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -359,10 +361,10 @@ func TestStateSyncGetStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -432,10 +434,10 @@ func TestParseStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -487,10 +489,10 @@ func TestStateSummaryAccept(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) @@ -567,10 +569,10 @@ func TestStateSummaryAcceptOlderBlock(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index a7bb897932d3..ae9afe6562cd 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -5,7 +5,6 @@ package proposervm import ( "context" - "crypto" "errors" "fmt" "time" @@ -26,7 +25,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/math" @@ -86,19 +84,11 @@ func cachedBlockSize(_ ids.ID, blk snowman.Block) int { type VM struct { block.ChainVM + Config blockBuilderVM block.BuildBlockWithContextChainVM batchedVM block.BatchedChainVM ssVM block.StateSyncableVM - activationTime time.Time - minimumPChainHeight uint64 - minBlkDelay time.Duration - numHistoricalBlocks uint64 - // block signer - stakingLeafSigner crypto.Signer - // block certificate - stakingCertLeaf *staking.Certificate - state.State hIndexer indexer.HeightIndexer @@ -138,28 +128,17 @@ type VM struct { // timestamps are only specific to the second. func New( vm block.ChainVM, - activationTime time.Time, - minimumPChainHeight uint64, - minBlkDelay time.Duration, - numHistoricalBlocks uint64, - stakingLeafSigner crypto.Signer, - stakingCertLeaf *staking.Certificate, + config Config, ) *VM { blockBuilderVM, _ := vm.(block.BuildBlockWithContextChainVM) batchedVM, _ := vm.(block.BatchedChainVM) ssVM, _ := vm.(block.StateSyncableVM) return &VM{ ChainVM: vm, + Config: config, blockBuilderVM: blockBuilderVM, batchedVM: batchedVM, ssVM: ssVM, - - activationTime: activationTime, - minimumPChainHeight: minimumPChainHeight, - minBlkDelay: minBlkDelay, - numHistoricalBlocks: numHistoricalBlocks, - stakingLeafSigner: stakingLeafSigner, - stakingCertLeaf: stakingCertLeaf, } } @@ -373,9 +352,7 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { // validators can specify. This delay may be an issue for high performance, // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. - if minDelay < vm.minBlkDelay { - minDelay = vm.minBlkDelay - } + minDelay = math.Max(minDelay, vm.MinBlkDelay) preferredTime := blk.Timestamp() nextStartTime := preferredTime.Add(minDelay) @@ -418,7 +395,7 @@ func (vm *VM) repair(ctx context.Context) error { return err } - if vm.numHistoricalBlocks != 0 { + if vm.NumHistoricalBlocks != 0 { vm.ctx.Log.Fatal("block height index must be valid when pruning historical blocks") return errHeightIndexInvalidWhilePruning } diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index 0a27c43e112a..fba3f5974332 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -46,13 +46,16 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test proVM := New( innerVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) + defer func() { // avoids leaking goroutines require.NoError(proVM.Shutdown(context.Background())) diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index fb8672d8b2f4..d3e2282f25c0 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -134,12 +134,14 @@ func initTestProposerVM( proVM := New( coreVM, - proBlkStartTime, - minPChainHeight, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: proBlkStartTime, + MinimumPChainHeight: minPChainHeight, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) valState := &validators.TestState{ @@ -526,10 +528,10 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk := postForkBlock{ @@ -570,10 +572,10 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk1 := postForkBlock{ @@ -589,10 +591,10 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 200, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk2 := postForkBlock{ @@ -880,12 +882,14 @@ func TestExpiredBuildBlock(t *testing.T) { proVM := New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) valState := &validators.TestState{ @@ -1224,12 +1228,14 @@ func TestInnerVMRollback(t *testing.T) { proVM := New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) require.NoError(proVM.Initialize( @@ -1311,12 +1317,14 @@ func TestInnerVMRollback(t *testing.T) { proVM = New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) require.NoError(proVM.Initialize( @@ -1803,12 +1811,14 @@ func TestRejectedHeightNotIndexed(t *testing.T) { proVM := New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) valState := &validators.TestState{ @@ -2010,12 +2020,14 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { proVM := New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) valState := &validators.TestState{ @@ -2173,12 +2185,14 @@ func TestVMInnerBlkCache(t *testing.T) { innerVM := mocks.NewMockChainVM(ctrl) vm := New( innerVM, - time.Time{}, // fork is active - 0, // minimum P-Chain height - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) innerVM.EXPECT().Initialize( @@ -2229,10 +2243,10 @@ func TestVMInnerBlkCache(t *testing.T) { ids.GenerateTestID(), // parent time.Time{}, // timestamp 1, // pChainHeight, - vm.stakingCertLeaf, // cert + vm.StakingCertLeaf, // cert blkNearTipInnerBytes, // inner blk bytes vm.ctx.ChainID, // chain ID - vm.stakingLeafSigner, // key + vm.StakingLeafSigner, // key ) require.NoError(err) @@ -2402,12 +2416,14 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { innerVM := mocks.NewMockChainVM(ctrl) vm := New( innerVM, - time.Time{}, // fork is active - 0, // minimum P-Chain height - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) // make sure that DBs are compressed correctly @@ -2613,12 +2629,14 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM := New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) require.NoError(proVM.Initialize( @@ -2711,12 +2729,14 @@ func TestHistoricalBlockDeletion(t *testing.T) { numHistoricalBlocks := uint64(2) proVM = New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - numHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) require.NoError(proVM.Initialize( @@ -2753,12 +2773,14 @@ func TestHistoricalBlockDeletion(t *testing.T) { newNumHistoricalBlocks := numHistoricalBlocks + 2 proVM = New( coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - newNumHistoricalBlocks, - pTestSigner, - pTestCert, + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: newNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, ) require.NoError(proVM.Initialize( From 004a23e0275ab2af5c63232015495b3e0f236139 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:56:25 -0500 Subject: [PATCH 103/267] `vms/platformvm`: Add `decisionTxs` parameter to `NewBanffProposalBlock` (#2411) Co-authored-by: Dan Laine --- vms/platformvm/block/builder/builder.go | 1 + vms/platformvm/block/builder/builder_test.go | 1 + .../block/executor/proposal_block_test.go | 14 +++ .../block/executor/rejector_test.go | 1 + vms/platformvm/block/parse_test.go | 33 +++++++ vms/platformvm/block/proposal_block.go | 8 +- vms/platformvm/block/proposal_block_test.go | 88 ++++++++++++++----- vms/platformvm/state/state_test.go | 2 +- 8 files changed, 122 insertions(+), 26 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index f16e9353a8ad..79c05992bf53 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -237,6 +237,7 @@ func buildBlock( parentID, height, rewardValidatorTx, + []*txs.Tx{}, // TODO: Populate with StandardBlock txs ) } diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 7d97e88a40d7..0bc5a37afaa4 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -398,6 +398,7 @@ func TestBuildBlock(t *testing.T) { parentID, height, tx, + []*txs.Tx{}, ) require.NoError(err) return expectedBlk diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index b69708f8ca9f..77c36c08dec3 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -258,6 +258,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { parentID, banffParentBlk.Height(), blkTx, + []*txs.Tx{}, ) require.NoError(err) @@ -287,6 +288,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { parentID, banffParentBlk.Height()+1, blkTx, + []*txs.Tx{}, ) require.NoError(err) @@ -304,6 +306,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { parentID, banffParentBlk.Height()+1, blkTx, + []*txs.Tx{}, ) require.NoError(err) @@ -321,6 +324,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { parentID, banffParentBlk.Height()+1, blkTx, + []*txs.Tx{}, ) require.NoError(err) @@ -342,6 +346,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { parentID, banffParentBlk.Height()+1, invalidTx, + []*txs.Tx{}, ) require.NoError(err) @@ -357,6 +362,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { parentID, banffParentBlk.Height()+1, blkTx, + []*txs.Tx{}, ) require.NoError(err) @@ -373,6 +379,7 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { parentID, banffParentBlk.Height()+1, blkTx, + []*txs.Tx{}, ) require.NoError(err) @@ -662,6 +669,7 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { parentBlk.ID(), parentBlk.Height()+1, s0RewardTx, + []*txs.Tx{}, ) require.NoError(err) @@ -819,6 +827,7 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { parentBlk.ID(), parentBlk.Height()+1, s0RewardTx, + []*txs.Tx{}, ) require.NoError(err) propBlk := env.blkManager.NewBlock(statelessProposalBlock) @@ -931,6 +940,7 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { parentBlk.ID(), parentBlk.Height()+1, s0RewardTx, + []*txs.Tx{}, ) require.NoError(err) propBlk := env.blkManager.NewBlock(statelessProposalBlock) @@ -1017,6 +1027,7 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { parentBlk.ID(), parentBlk.Height()+1, s0RewardTx, + []*txs.Tx{}, ) require.NoError(err) propBlk := env.blkManager.NewBlock(statelessProposalBlock) @@ -1108,6 +1119,7 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { parentBlk.ID(), parentBlk.Height()+1, s0RewardTx, + []*txs.Tx{}, ) require.NoError(err) @@ -1198,6 +1210,7 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { parentBlk.ID(), parentBlk.Height()+1, s0RewardTx, + []*txs.Tx{}, ) require.NoError(err) propBlk := env.blkManager.NewBlock(statelessProposalBlock) @@ -1288,6 +1301,7 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { parentBlk.ID(), parentBlk.Height()+1, s0RewardTx, + []*txs.Tx{}, ) require.NoError(err) propBlk = env.blkManager.NewBlock(statelessProposalBlock) diff --git a/vms/platformvm/block/executor/rejector_test.go b/vms/platformvm/block/executor/rejector_test.go index 3ccd9c0d66b1..5e06a885fd5e 100644 --- a/vms/platformvm/block/executor/rejector_test.go +++ b/vms/platformvm/block/executor/rejector_test.go @@ -44,6 +44,7 @@ func TestRejectBlock(t *testing.T) { }, Creds: []verify.Verifiable{}, }, + []*txs.Tx{}, ) }, rejectFunc: func(r *rejector, b block.Block) error { diff --git a/vms/platformvm/block/parse_test.go b/vms/platformvm/block/parse_test.go index 28dea498d48f..799310aa2f51 100644 --- a/vms/platformvm/block/parse_test.go +++ b/vms/platformvm/block/parse_test.go @@ -79,6 +79,8 @@ func TestProposalBlocks(t *testing.T) { height := uint64(2022) proposalTx, err := testProposalTx() require.NoError(err) + decisionTxs, err := testDecisionTxs() + require.NoError(err) for _, cdc := range []codec.Manager{Codec, GenesisCodec} { // build block @@ -109,6 +111,7 @@ func TestProposalBlocks(t *testing.T) { parentID, height, proposalTx, + []*txs.Tx{}, ) require.NoError(err) @@ -130,6 +133,36 @@ func TestProposalBlocks(t *testing.T) { // backward compatibility check require.Equal(parsedApricotProposalBlk.Txs(), parsedBanffProposalBlk.Txs()) + + // check that banff proposal block with decisionTxs can be built and parsed + banffProposalBlkWithDecisionTxs, err := NewBanffProposalBlock( + blkTimestamp, + parentID, + height, + proposalTx, + decisionTxs, + ) + require.NoError(err) + + // parse block + parsed, err = Parse(cdc, banffProposalBlkWithDecisionTxs.Bytes()) + require.NoError(err) + + // compare content + require.Equal(banffProposalBlkWithDecisionTxs.ID(), parsed.ID()) + require.Equal(banffProposalBlkWithDecisionTxs.Bytes(), parsed.Bytes()) + require.Equal(banffProposalBlkWithDecisionTxs.Parent(), parsed.Parent()) + require.Equal(banffProposalBlkWithDecisionTxs.Height(), parsed.Height()) + require.IsType(&BanffProposalBlock{}, parsed) + parsedBanffProposalBlkWithDecisionTxs := parsed.(*BanffProposalBlock) + + l := len(decisionTxs) + expectedTxs := make([]*txs.Tx, l+1) + copy(expectedTxs, decisionTxs) + expectedTxs[l] = proposalTx + require.Equal(expectedTxs, parsedBanffProposalBlkWithDecisionTxs.Txs()) + + require.Equal(banffProposalBlkWithDecisionTxs.Timestamp(), parsedBanffProposalBlkWithDecisionTxs.Timestamp()) } } diff --git a/vms/platformvm/block/proposal_block.go b/vms/platformvm/block/proposal_block.go index eaea68e9ce55..1986218aa0a5 100644 --- a/vms/platformvm/block/proposal_block.go +++ b/vms/platformvm/block/proposal_block.go @@ -67,16 +67,18 @@ func NewBanffProposalBlock( timestamp time.Time, parentID ids.ID, height uint64, - tx *txs.Tx, + proposalTx *txs.Tx, + decisionTxs []*txs.Tx, ) (*BanffProposalBlock, error) { blk := &BanffProposalBlock{ - Time: uint64(timestamp.Unix()), + Transactions: decisionTxs, + Time: uint64(timestamp.Unix()), ApricotProposalBlock: ApricotProposalBlock{ CommonBlock: CommonBlock{ PrntID: parentID, Hght: height, }, - Tx: tx, + Tx: proposalTx, }, } return blk, initialize(blk) diff --git a/vms/platformvm/block/proposal_block_test.go b/vms/platformvm/block/proposal_block_test.go index f8c03189b604..bdb65e4a2404 100644 --- a/vms/platformvm/block/proposal_block_test.go +++ b/vms/platformvm/block/proposal_block_test.go @@ -10,33 +10,70 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) func TestNewBanffProposalBlock(t *testing.T) { - require := require.New(t) - timestamp := time.Now().Truncate(time.Second) parentID := ids.GenerateTestID() height := uint64(1337) proposalTx, err := testProposalTx() - require.NoError(err) + require.NoError(t, err) + decisionTxs, err := testDecisionTxs() + require.NoError(t, err) - blk, err := NewBanffProposalBlock( - timestamp, - parentID, - height, - proposalTx, - ) - require.NoError(err) + type test struct { + name string + proposalTx *txs.Tx + decisionTxs []*txs.Tx + } - // Make sure the block and tx are initialized - require.NotEmpty(blk.Bytes()) - require.NotEmpty(blk.Tx.Bytes()) - require.NotEqual(ids.Empty, blk.Tx.ID()) - require.Equal(proposalTx.Bytes(), blk.Tx.Bytes()) - require.Equal(timestamp, blk.Timestamp()) - require.Equal(parentID, blk.Parent()) - require.Equal(height, blk.Height()) + tests := []test{ + { + name: "no decision txs", + proposalTx: proposalTx, + decisionTxs: []*txs.Tx{}, + }, + { + name: "decision txs", + proposalTx: proposalTx, + decisionTxs: decisionTxs, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + blk, err := NewBanffProposalBlock( + timestamp, + parentID, + height, + test.proposalTx, + test.decisionTxs, + ) + require.NoError(err) + + require.NotEmpty(blk.Bytes()) + require.Equal(parentID, blk.Parent()) + require.Equal(height, blk.Height()) + require.Equal(timestamp, blk.Timestamp()) + + l := len(test.decisionTxs) + expectedTxs := make([]*txs.Tx, l+1) + copy(expectedTxs, test.decisionTxs) + expectedTxs[l] = test.proposalTx + + blkTxs := blk.Txs() + require.Equal(expectedTxs, blkTxs) + for i, blkTx := range blkTxs { + expectedTx := expectedTxs[i] + require.NotEmpty(blkTx.Bytes()) + require.NotEqual(ids.Empty, blkTx.ID()) + require.Equal(expectedTx.Bytes(), blkTx.Bytes()) + } + }) + } } func TestNewApricotProposalBlock(t *testing.T) { @@ -54,11 +91,18 @@ func TestNewApricotProposalBlock(t *testing.T) { ) require.NoError(err) - // Make sure the block and tx are initialized require.NotEmpty(blk.Bytes()) - require.NotEmpty(blk.Tx.Bytes()) - require.NotEqual(ids.Empty, blk.Tx.ID()) - require.Equal(proposalTx.Bytes(), blk.Tx.Bytes()) require.Equal(parentID, blk.Parent()) require.Equal(height, blk.Height()) + + expectedTxs := []*txs.Tx{proposalTx} + + blkTxs := blk.Txs() + require.Equal(blkTxs, expectedTxs) + for i, blkTx := range blkTxs { + expectedTx := expectedTxs[i] + require.NotEmpty(blkTx.Bytes()) + require.NotEqual(ids.Empty, blkTx.ID()) + require.Equal(expectedTx.Bytes(), blkTx.Bytes()) + } } diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index 3c36310c0576..1d0e02938f1c 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -617,7 +617,7 @@ func TestParsedStateBlock(t *testing.T) { Unsigned: &txs.RewardValidatorTx{ TxID: ids.GenerateTestID(), }, - }) + }, []*txs.Tx{}) require.NoError(err) blks = append(blks, blk) } From ada692a8ee3e88c3d780a75cf13fd4ad4517aa49 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 5 Dec 2023 17:40:03 -0500 Subject: [PATCH 104/267] Update minimum golang version to v1.20.12 (#2427) --- .github/workflows/auto-generated-checker.yml | 6 +++--- .github/workflows/build-linux-binaries.yml | 4 ++-- .github/workflows/build-macos-release.yml | 2 +- .github/workflows/build-public-ami.yml | 2 +- .github/workflows/build-ubuntu-amd64-release.yml | 4 ++-- .github/workflows/build-ubuntu-arm64-release.yml | 4 ++-- .github/workflows/build-win-release.yml | 2 +- .github/workflows/fuzz.yml | 2 +- .github/workflows/static-analysis.yml | 2 +- .github/workflows/test.e2e.existing.yml | 2 +- .github/workflows/test.e2e.yml | 2 +- .github/workflows/test.unit.yml | 2 +- .github/workflows/test.upgrade.yml | 2 +- CONTRIBUTING.md | 2 +- Dockerfile | 2 +- README.md | 2 +- proto/Dockerfile.buf | 2 +- scripts/build_avalanche.sh | 2 +- 18 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/auto-generated-checker.yml b/.github/workflows/auto-generated-checker.yml index eb53ff4c5b83..cca52dfa382a 100644 --- a/.github/workflows/auto-generated-checker.yml +++ b/.github/workflows/auto-generated-checker.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - uses: bufbuild/buf-setup-action@v1.26.1 - shell: bash @@ -32,7 +32,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - shell: bash run: scripts/mock.gen.sh @@ -45,7 +45,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - shell: bash run: go mod tidy diff --git a/.github/workflows/build-linux-binaries.yml b/.github/workflows/build-linux-binaries.yml index dc1a358da550..7053379ef508 100644 --- a/.github/workflows/build-linux-binaries.yml +++ b/.github/workflows/build-linux-binaries.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version @@ -81,7 +81,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version diff --git a/.github/workflows/build-macos-release.yml b/.github/workflows/build-macos-release.yml index 3699fc0b5e37..c1a884aebf4f 100644 --- a/.github/workflows/build-macos-release.yml +++ b/.github/workflows/build-macos-release.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version diff --git a/.github/workflows/build-public-ami.yml b/.github/workflows/build-public-ami.yml index 1e483ccd7f6a..32c816efdd3d 100644 --- a/.github/workflows/build-public-ami.yml +++ b/.github/workflows/build-public-ami.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version diff --git a/.github/workflows/build-ubuntu-amd64-release.yml b/.github/workflows/build-ubuntu-amd64-release.yml index bbb0cbd3f4a2..640cff56a53f 100644 --- a/.github/workflows/build-ubuntu-amd64-release.yml +++ b/.github/workflows/build-ubuntu-amd64-release.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version @@ -78,7 +78,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version diff --git a/.github/workflows/build-ubuntu-arm64-release.yml b/.github/workflows/build-ubuntu-arm64-release.yml index 8d1ba4a2ea2e..ac660b8cd678 100644 --- a/.github/workflows/build-ubuntu-arm64-release.yml +++ b/.github/workflows/build-ubuntu-arm64-release.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version @@ -78,7 +78,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version diff --git a/.github/workflows/build-win-release.yml b/.github/workflows/build-win-release.yml index c84767d4c87d..d71725d124c2 100644 --- a/.github/workflows/build-win-release.yml +++ b/.github/workflows/build-win-release.yml @@ -26,7 +26,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - run: go version diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 7fa95a88e7f3..b0ede2b349b7 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: Run fuzz tests shell: bash diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 8510a693632c..81f488a55ef3 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: Run static analysis tests shell: bash diff --git a/.github/workflows/test.e2e.existing.yml b/.github/workflows/test.e2e.existing.yml index a50943888f48..c00a328610d1 100644 --- a/.github/workflows/test.e2e.existing.yml +++ b/.github/workflows/test.e2e.existing.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: Build the avalanchego binary shell: bash diff --git a/.github/workflows/test.e2e.yml b/.github/workflows/test.e2e.yml index 0edc46afebb0..2f8e30156f72 100644 --- a/.github/workflows/test.e2e.yml +++ b/.github/workflows/test.e2e.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: Build the avalanchego binary shell: bash diff --git a/.github/workflows/test.unit.yml b/.github/workflows/test.unit.yml index ae4cb85983c3..dc766f07484f 100644 --- a/.github/workflows/test.unit.yml +++ b/.github/workflows/test.unit.yml @@ -27,7 +27,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: Set timeout on Windows # Windows UT run slower and need a longer timeout shell: bash diff --git a/.github/workflows/test.upgrade.yml b/.github/workflows/test.upgrade.yml index 61be20787900..8f8ec5fc35ed 100644 --- a/.github/workflows/test.upgrade.yml +++ b/.github/workflows/test.upgrade.yml @@ -23,7 +23,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.20.10' + go-version: '~1.20.12' check-latest: true - name: Build the avalanchego binary shell: bash diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 968f72ef24fe..4abb6a4d82ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ To start developing on AvalancheGo, you'll need a few things installed. -- Golang version >= 1.20.8 +- Golang version >= 1.20.12 - gcc - g++ diff --git a/Dockerfile b/Dockerfile index f4e6c21441cf..21ab344ef4b0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ # README.md # go.mod # ============= Compilation Stage ================ -FROM golang:1.20.10-bullseye AS builder +FROM golang:1.20.12-bullseye AS builder WORKDIR /build # Copy and download avalanche dependencies using go mod diff --git a/README.md b/README.md index 7842615f35be..ac3cd62841a9 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ The minimum recommended hardware specification for nodes connected to Mainnet is If you plan to build AvalancheGo from source, you will also need the following software: -- [Go](https://golang.org/doc/install) version >= 1.20.10 +- [Go](https://golang.org/doc/install) version >= 1.20.12 - [gcc](https://gcc.gnu.org/) - g++ diff --git a/proto/Dockerfile.buf b/proto/Dockerfile.buf index 40d0a5420b4a..3c8864e636b7 100644 --- a/proto/Dockerfile.buf +++ b/proto/Dockerfile.buf @@ -6,7 +6,7 @@ RUN apt-get update && apt -y install bash curl unzip git WORKDIR /opt RUN \ - curl -L https://golang.org/dl/go1.20.8.linux-amd64.tar.gz > golang.tar.gz && \ + curl -L https://golang.org/dl/go1.20.12.linux-amd64.tar.gz > golang.tar.gz && \ mkdir golang && \ tar -zxvf golang.tar.gz -C golang/ diff --git a/scripts/build_avalanche.sh b/scripts/build_avalanche.sh index 1db63eb946f4..dcfaed4c420d 100755 --- a/scripts/build_avalanche.sh +++ b/scripts/build_avalanche.sh @@ -27,7 +27,7 @@ done # Dockerfile # README.md # go.mod -go_version_minimum="1.20.10" +go_version_minimum="1.20.12" go_version() { go version | sed -nE -e 's/[^0-9.]+([0-9.]+).+/\1/p' From 21b7ab880c197f567068dc5870bf38ad632670fc Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 5 Dec 2023 19:43:00 -0500 Subject: [PATCH 105/267] Fix platformvm.SetPreference (#2429) --- vms/platformvm/block/builder/builder_test.go | 2 +- vms/platformvm/block/executor/manager.go | 6 +++--- vms/platformvm/block/executor/manager_test.go | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 0bc5a37afaa4..434d5b7b2552 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -132,7 +132,7 @@ func TestNoErrorOnUnexpectedSetPreferenceDuringBootstrapping(t *testing.T) { require.NoError(shutdownEnvironment(env)) }() - require.False(env.blkManager.SetPreference(ids.GenerateTestID())) // should not panic + require.True(env.blkManager.SetPreference(ids.GenerateTestID())) // should not panic } func TestGetNextStakerToReward(t *testing.T) { diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 9af9cbce2c4a..ebecbf968e5f 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -107,9 +107,9 @@ func (m *manager) NewBlock(blk block.Block) snowman.Block { } } -func (m *manager) SetPreference(blockID ids.ID) (updated bool) { - updated = m.preferred == blockID - m.preferred = blockID +func (m *manager) SetPreference(blkID ids.ID) bool { + updated := m.preferred != blkID + m.preferred = blkID return updated } diff --git a/vms/platformvm/block/executor/manager_test.go b/vms/platformvm/block/executor/manager_test.go index 8ee784c4f9f1..ce887d987992 100644 --- a/vms/platformvm/block/executor/manager_test.go +++ b/vms/platformvm/block/executor/manager_test.go @@ -72,3 +72,18 @@ func TestManagerLastAccepted(t *testing.T) { require.Equal(t, lastAcceptedID, manager.LastAccepted()) } + +func TestManagerSetPreference(t *testing.T) { + require := require.New(t) + + initialPreference := ids.GenerateTestID() + manager := &manager{ + preferred: initialPreference, + } + require.False(manager.SetPreference(initialPreference)) + + newPreference := ids.GenerateTestID() + require.True(manager.SetPreference(newPreference)) + require.False(manager.SetPreference(newPreference)) + require.True(manager.SetPreference(initialPreference)) +} From 7df1f3a1c26eada44c44efacc8ee7414963ad4f6 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 6 Dec 2023 13:46:56 -0500 Subject: [PATCH 106/267] Restrict GOPROXY (#2434) --- scripts/constants.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/constants.sh b/scripts/constants.sh index 433e424f7acc..c175bffd57cf 100755 --- a/scripts/constants.sh +++ b/scripts/constants.sh @@ -36,3 +36,6 @@ export CGO_CFLAGS="-O2 -D__BLST_PORTABLE__" # While CGO_ENABLED doesn't need to be explicitly set, it produces a much more # clear error due to the default value change in go1.20. export CGO_ENABLED=1 + +# Disable version control fallbacks +export GOPROXY="https://proxy.golang.org" From b36416da40fd03f4d75c023a203079e814c5aa8d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 6 Dec 2023 12:12:11 -0700 Subject: [PATCH 107/267] Drop Pending Stakers 1 - introduced ScheduledStaker txs (#2323) Co-authored-by: Stephen Buttolph --- vms/platformvm/state/staker.go | 4 +- vms/platformvm/state/staker_test.go | 4 +- vms/platformvm/state/state.go | 18 ++- vms/platformvm/txs/add_delegator_tx.go | 3 +- .../txs/add_permissionless_delegator_tx.go | 5 +- .../txs/add_permissionless_validator_tx.go | 3 +- vms/platformvm/txs/add_subnet_validator_tx.go | 3 +- vms/platformvm/txs/add_validator_tx.go | 3 +- .../txs/executor/standard_tx_executor.go | 2 +- vms/platformvm/txs/mempool/mempool.go | 2 +- vms/platformvm/txs/mock_scheduled_staker.go | 151 ++++++++++++++++++ vms/platformvm/txs/mock_staker.go | 28 ---- vms/platformvm/txs/staker_tx.go | 8 +- vms/platformvm/validator_set_property_test.go | 2 +- 14 files changed, 187 insertions(+), 49 deletions(-) create mode 100644 vms/platformvm/txs/mock_scheduled_staker.go diff --git a/vms/platformvm/state/staker.go b/vms/platformvm/state/staker.go index 37bc512e36cb..2488e4aff79e 100644 --- a/vms/platformvm/state/staker.go +++ b/vms/platformvm/state/staker.go @@ -83,7 +83,7 @@ func (s *Staker) Less(than *Staker) bool { return bytes.Compare(s.TxID[:], than.TxID[:]) == -1 } -func NewCurrentStaker(txID ids.ID, staker txs.Staker, potentialReward uint64) (*Staker, error) { +func NewCurrentStaker(txID ids.ID, staker txs.ScheduledStaker, potentialReward uint64) (*Staker, error) { publicKey, _, err := staker.PublicKey() if err != nil { return nil, err @@ -103,7 +103,7 @@ func NewCurrentStaker(txID ids.ID, staker txs.Staker, potentialReward uint64) (* }, nil } -func NewPendingStaker(txID ids.ID, staker txs.Staker) (*Staker, error) { +func NewPendingStaker(txID ids.ID, staker txs.ScheduledStaker) (*Staker, error) { publicKey, _, err := staker.PublicKey() if err != nil { return nil, err diff --git a/vms/platformvm/state/staker_test.go b/vms/platformvm/state/staker_test.go index a6faa4ab704f..9482e33b793a 100644 --- a/vms/platformvm/state/staker_test.go +++ b/vms/platformvm/state/staker_test.go @@ -148,7 +148,7 @@ func TestNewCurrentStaker(t *testing.T) { potentialReward := uint64(54321) currentPriority := txs.SubnetPermissionedValidatorCurrentPriority - stakerTx := txs.NewMockStaker(ctrl) + stakerTx := txs.NewMockScheduledStaker(ctrl) stakerTx.EXPECT().NodeID().Return(nodeID) stakerTx.EXPECT().PublicKey().Return(publicKey, true, nil) stakerTx.EXPECT().SubnetID().Return(subnetID) @@ -192,7 +192,7 @@ func TestNewPendingStaker(t *testing.T) { endTime := time.Now() pendingPriority := txs.SubnetPermissionedValidatorPendingPriority - stakerTx := txs.NewMockStaker(ctrl) + stakerTx := txs.NewMockScheduledStaker(ctrl) stakerTx.EXPECT().NodeID().Return(nodeID) stakerTx.EXPECT().PublicKey().Return(publicKey, true, nil) stakerTx.EXPECT().SubnetID().Return(subnetID) diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 82ff0107762a..36a49428020c 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1320,9 +1320,13 @@ func (s *state) syncGenesis(genesisBlk block.Block, genesis *genesis.Genesis) er // Persist primary network validator set at genesis for _, vdrTx := range genesis.Validators { - validatorTx, ok := vdrTx.Unsigned.(txs.ValidatorTx) + // We expect genesis validator txs to be either AddValidatorTx or + // AddPermissionlessValidatorTx. + // + // TODO: Enforce stricter type check + validatorTx, ok := vdrTx.Unsigned.(txs.ScheduledStaker) if !ok { - return fmt.Errorf("expected tx type txs.ValidatorTx but got %T", vdrTx.Unsigned) + return fmt.Errorf("expected a scheduled staker but got %T", vdrTx.Unsigned) } stakeAmount := validatorTx.Weight() @@ -1451,7 +1455,7 @@ func (s *state) loadCurrentValidators() error { return fmt.Errorf("failed loading validator transaction txID %s, %w", txID, err) } - stakerTx, ok := tx.Unsigned.(txs.Staker) + stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } @@ -1492,7 +1496,7 @@ func (s *state) loadCurrentValidators() error { return err } - stakerTx, ok := tx.Unsigned.(txs.Staker) + stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } @@ -1539,7 +1543,7 @@ func (s *state) loadCurrentValidators() error { return err } - stakerTx, ok := tx.Unsigned.(txs.Staker) + stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } @@ -1596,7 +1600,7 @@ func (s *state) loadPendingValidators() error { return err } - stakerTx, ok := tx.Unsigned.(txs.Staker) + stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } @@ -1631,7 +1635,7 @@ func (s *state) loadPendingValidators() error { return err } - stakerTx, ok := tx.Unsigned.(txs.Staker) + stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } diff --git a/vms/platformvm/txs/add_delegator_tx.go b/vms/platformvm/txs/add_delegator_tx.go index 4f6fbe395b02..af328cc693bf 100644 --- a/vms/platformvm/txs/add_delegator_tx.go +++ b/vms/platformvm/txs/add_delegator_tx.go @@ -19,7 +19,8 @@ import ( ) var ( - _ DelegatorTx = (*AddDelegatorTx)(nil) + _ DelegatorTx = (*AddDelegatorTx)(nil) + _ ScheduledStaker = (*AddDelegatorTx)(nil) errDelegatorWeightMismatch = errors.New("delegator weight is not equal to total stake weight") errStakeMustBeAVAX = errors.New("stake must be AVAX") diff --git a/vms/platformvm/txs/add_permissionless_delegator_tx.go b/vms/platformvm/txs/add_permissionless_delegator_tx.go index 43db685d7629..346a80dd61f7 100644 --- a/vms/platformvm/txs/add_permissionless_delegator_tx.go +++ b/vms/platformvm/txs/add_permissionless_delegator_tx.go @@ -17,7 +17,10 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -var _ DelegatorTx = (*AddPermissionlessDelegatorTx)(nil) +var ( + _ DelegatorTx = (*AddPermissionlessDelegatorTx)(nil) + _ ScheduledStaker = (*AddPermissionlessDelegatorTx)(nil) +) // AddPermissionlessDelegatorTx is an unsigned addPermissionlessDelegatorTx type AddPermissionlessDelegatorTx struct { diff --git a/vms/platformvm/txs/add_permissionless_validator_tx.go b/vms/platformvm/txs/add_permissionless_validator_tx.go index 8f313ae000b9..34b13129ade8 100644 --- a/vms/platformvm/txs/add_permissionless_validator_tx.go +++ b/vms/platformvm/txs/add_permissionless_validator_tx.go @@ -21,7 +21,8 @@ import ( ) var ( - _ ValidatorTx = (*AddPermissionlessValidatorTx)(nil) + _ ValidatorTx = (*AddPermissionlessValidatorTx)(nil) + _ ScheduledStaker = (*AddPermissionlessDelegatorTx)(nil) errEmptyNodeID = errors.New("validator nodeID cannot be empty") errNoStake = errors.New("no stake") diff --git a/vms/platformvm/txs/add_subnet_validator_tx.go b/vms/platformvm/txs/add_subnet_validator_tx.go index 0ac3474e1bd6..53fd43562c02 100644 --- a/vms/platformvm/txs/add_subnet_validator_tx.go +++ b/vms/platformvm/txs/add_subnet_validator_tx.go @@ -14,7 +14,8 @@ import ( ) var ( - _ StakerTx = (*AddSubnetValidatorTx)(nil) + _ StakerTx = (*AddSubnetValidatorTx)(nil) + _ ScheduledStaker = (*AddSubnetValidatorTx)(nil) errAddPrimaryNetworkValidator = errors.New("can't add primary network validator with AddSubnetValidatorTx") ) diff --git a/vms/platformvm/txs/add_validator_tx.go b/vms/platformvm/txs/add_validator_tx.go index be6a93c2e42b..a0e82dba7c77 100644 --- a/vms/platformvm/txs/add_validator_tx.go +++ b/vms/platformvm/txs/add_validator_tx.go @@ -19,7 +19,8 @@ import ( ) var ( - _ ValidatorTx = (*AddValidatorTx)(nil) + _ ValidatorTx = (*AddValidatorTx)(nil) + _ ScheduledStaker = (*AddValidatorTx)(nil) errTooManyShares = fmt.Errorf("a staker can only require at most %d shares from delegators", reward.PercentDenominator) ) diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 083e4f4c75c7..b9930075875a 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -534,7 +534,7 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Creates the staker as defined in [stakerTx] and adds it to [e.State]. -func (e *StandardTxExecutor) putStaker(stakerTx txs.Staker) error { +func (e *StandardTxExecutor) putStaker(stakerTx txs.ScheduledStaker) error { txID := e.Tx.ID() staker, err := state.NewPendingStaker(txID, stakerTx) if err != nil { diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index ce0d6a96f071..bd219910bd9f 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -280,7 +280,7 @@ func (m *mempool) DropExpiredStakerTxs(minStartTime time.Time) []ids.ID { txIter := m.unissuedTxs.NewIterator() for txIter.Next() { tx := txIter.Value() - stakerTx, ok := tx.Unsigned.(txs.Staker) + stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { continue } diff --git a/vms/platformvm/txs/mock_scheduled_staker.go b/vms/platformvm/txs/mock_scheduled_staker.go new file mode 100644 index 000000000000..ce1a22b4eda0 --- /dev/null +++ b/vms/platformvm/txs/mock_scheduled_staker.go @@ -0,0 +1,151 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ava-labs/avalanchego/vms/platformvm/txs (interfaces: ScheduledStaker) + +// Package txs is a generated GoMock package. +package txs + +import ( + reflect "reflect" + time "time" + + ids "github.com/ava-labs/avalanchego/ids" + bls "github.com/ava-labs/avalanchego/utils/crypto/bls" + gomock "go.uber.org/mock/gomock" +) + +// MockScheduledStaker is a mock of ScheduledStaker interface. +type MockScheduledStaker struct { + ctrl *gomock.Controller + recorder *MockScheduledStakerMockRecorder +} + +// MockScheduledStakerMockRecorder is the mock recorder for MockScheduledStaker. +type MockScheduledStakerMockRecorder struct { + mock *MockScheduledStaker +} + +// NewMockScheduledStaker creates a new mock instance. +func NewMockScheduledStaker(ctrl *gomock.Controller) *MockScheduledStaker { + mock := &MockScheduledStaker{ctrl: ctrl} + mock.recorder = &MockScheduledStakerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockScheduledStaker) EXPECT() *MockScheduledStakerMockRecorder { + return m.recorder +} + +// CurrentPriority mocks base method. +func (m *MockScheduledStaker) CurrentPriority() Priority { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CurrentPriority") + ret0, _ := ret[0].(Priority) + return ret0 +} + +// CurrentPriority indicates an expected call of CurrentPriority. +func (mr *MockScheduledStakerMockRecorder) CurrentPriority() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentPriority", reflect.TypeOf((*MockScheduledStaker)(nil).CurrentPriority)) +} + +// EndTime mocks base method. +func (m *MockScheduledStaker) EndTime() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EndTime") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// EndTime indicates an expected call of EndTime. +func (mr *MockScheduledStakerMockRecorder) EndTime() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EndTime", reflect.TypeOf((*MockScheduledStaker)(nil).EndTime)) +} + +// NodeID mocks base method. +func (m *MockScheduledStaker) NodeID() ids.NodeID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeID") + ret0, _ := ret[0].(ids.NodeID) + return ret0 +} + +// NodeID indicates an expected call of NodeID. +func (mr *MockScheduledStakerMockRecorder) NodeID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeID", reflect.TypeOf((*MockScheduledStaker)(nil).NodeID)) +} + +// PendingPriority mocks base method. +func (m *MockScheduledStaker) PendingPriority() Priority { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PendingPriority") + ret0, _ := ret[0].(Priority) + return ret0 +} + +// PendingPriority indicates an expected call of PendingPriority. +func (mr *MockScheduledStakerMockRecorder) PendingPriority() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PendingPriority", reflect.TypeOf((*MockScheduledStaker)(nil).PendingPriority)) +} + +// PublicKey mocks base method. +func (m *MockScheduledStaker) PublicKey() (*bls.PublicKey, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PublicKey") + ret0, _ := ret[0].(*bls.PublicKey) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// PublicKey indicates an expected call of PublicKey. +func (mr *MockScheduledStakerMockRecorder) PublicKey() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublicKey", reflect.TypeOf((*MockScheduledStaker)(nil).PublicKey)) +} + +// StartTime mocks base method. +func (m *MockScheduledStaker) StartTime() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StartTime") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// StartTime indicates an expected call of StartTime. +func (mr *MockScheduledStakerMockRecorder) StartTime() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartTime", reflect.TypeOf((*MockScheduledStaker)(nil).StartTime)) +} + +// SubnetID mocks base method. +func (m *MockScheduledStaker) SubnetID() ids.ID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SubnetID") + ret0, _ := ret[0].(ids.ID) + return ret0 +} + +// SubnetID indicates an expected call of SubnetID. +func (mr *MockScheduledStakerMockRecorder) SubnetID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubnetID", reflect.TypeOf((*MockScheduledStaker)(nil).SubnetID)) +} + +// Weight mocks base method. +func (m *MockScheduledStaker) Weight() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Weight") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// Weight indicates an expected call of Weight. +func (mr *MockScheduledStakerMockRecorder) Weight() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Weight", reflect.TypeOf((*MockScheduledStaker)(nil).Weight)) +} diff --git a/vms/platformvm/txs/mock_staker.go b/vms/platformvm/txs/mock_staker.go index e01ca66cf9e3..f74c2534ca39 100644 --- a/vms/platformvm/txs/mock_staker.go +++ b/vms/platformvm/txs/mock_staker.go @@ -81,20 +81,6 @@ func (mr *MockStakerMockRecorder) NodeID() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeID", reflect.TypeOf((*MockStaker)(nil).NodeID)) } -// PendingPriority mocks base method. -func (m *MockStaker) PendingPriority() Priority { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PendingPriority") - ret0, _ := ret[0].(Priority) - return ret0 -} - -// PendingPriority indicates an expected call of PendingPriority. -func (mr *MockStakerMockRecorder) PendingPriority() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PendingPriority", reflect.TypeOf((*MockStaker)(nil).PendingPriority)) -} - // PublicKey mocks base method. func (m *MockStaker) PublicKey() (*bls.PublicKey, bool, error) { m.ctrl.T.Helper() @@ -111,20 +97,6 @@ func (mr *MockStakerMockRecorder) PublicKey() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublicKey", reflect.TypeOf((*MockStaker)(nil).PublicKey)) } -// StartTime mocks base method. -func (m *MockStaker) StartTime() time.Time { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StartTime") - ret0, _ := ret[0].(time.Time) - return ret0 -} - -// StartTime indicates an expected call of StartTime. -func (mr *MockStakerMockRecorder) StartTime() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartTime", reflect.TypeOf((*MockStaker)(nil).StartTime)) -} - // SubnetID mocks base method. func (m *MockStaker) SubnetID() ids.ID { m.ctrl.T.Helper() diff --git a/vms/platformvm/txs/staker_tx.go b/vms/platformvm/txs/staker_tx.go index 049d3519375f..1cdcdcc337a8 100644 --- a/vms/platformvm/txs/staker_tx.go +++ b/vms/platformvm/txs/staker_tx.go @@ -48,9 +48,13 @@ type Staker interface { // PublicKey returns the BLS public key registered by this transaction. If // there was no key registered by this transaction, it will return false. PublicKey() (*bls.PublicKey, bool, error) - StartTime() time.Time EndTime() time.Time Weight() uint64 - PendingPriority() Priority CurrentPriority() Priority } + +type ScheduledStaker interface { + Staker + StartTime() time.Time + PendingPriority() Priority +} diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 2ac0d4358d7d..189e220679ff 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -373,7 +373,6 @@ func addPrimaryValidatorWithoutBLSKey(vm *VM, data *validatorInputData) (*state. } func internalAddValidator(vm *VM, signedTx *txs.Tx) (*state.Staker, error) { - stakerTx := signedTx.Unsigned.(txs.StakerTx) if err := vm.Network.IssueTx(context.Background(), signedTx); err != nil { return nil, fmt.Errorf("could not add tx to mempool: %w", err) } @@ -393,6 +392,7 @@ func internalAddValidator(vm *VM, signedTx *txs.Tx) (*state.Staker, error) { } // move time ahead, promoting the validator to current + stakerTx := signedTx.Unsigned.(txs.ScheduledStaker) currentTime := stakerTx.StartTime() vm.clock.Set(currentTime) vm.state.SetTimestamp(currentTime) From 9c1694a7a86d0ffeda1a99f7fc05e8286bc968fa Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 6 Dec 2023 14:18:52 -0500 Subject: [PATCH 108/267] Run merkledb fuzz tests every 6 hours (#2415) Signed-off-by: Dan Laine Signed-off-by: Stephen Buttolph Co-authored-by: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- .github/workflows/fuzz_merkledb.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/fuzz_merkledb.yml diff --git a/.github/workflows/fuzz_merkledb.yml b/.github/workflows/fuzz_merkledb.yml new file mode 100644 index 000000000000..c232bd933d17 --- /dev/null +++ b/.github/workflows/fuzz_merkledb.yml @@ -0,0 +1,27 @@ +name: Scheduled Fuzz Testing + +on: + workflow_dispatch: + schedule: + # Run every 6 hours + - cron: "0 0,6,12,18 * * *" + +permissions: + contents: read + +jobs: + MerkleDB: + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + with: + ref: 'dev' + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: '~1.20.12' + check-latest: true + - name: Run merkledb fuzz tests + shell: bash + run: ./scripts/build_fuzz.sh 900 ./x/merkledb # Run each merkledb fuzz tests 15 minutes From d2ce17fd6a567b65b7f909ebbcb418751d3a9024 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:35:40 -0500 Subject: [PATCH 109/267] Remove unused error (#2426) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- network/p2p/gossip/handler.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/network/p2p/gossip/handler.go b/network/p2p/gossip/handler.go index ecaf58434bc2..695551f9dbc0 100644 --- a/network/p2p/gossip/handler.go +++ b/network/p2p/gossip/handler.go @@ -5,7 +5,6 @@ package gossip import ( "context" - "errors" "time" bloomfilter "github.com/holiman/bloomfilter/v2" @@ -20,11 +19,7 @@ import ( "github.com/ava-labs/avalanchego/utils" ) -var ( - _ p2p.Handler = (*Handler[Gossipable])(nil) - - ErrInvalidID = errors.New("invalid id") -) +var _ p2p.Handler = (*Handler[Gossipable])(nil) type HandlerConfig struct { Namespace string From 470521807a2eb143ce253dbf7fcb06acbe06568a Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Wed, 6 Dec 2023 16:33:35 -0500 Subject: [PATCH 110/267] Make `messageQueue.msgAndCtxs` a circular buffer (#2433) --- snow/networking/handler/message_queue.go | 35 ++++++++++-------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/snow/networking/handler/message_queue.go b/snow/networking/handler/message_queue.go index 6fe4137b940e..bc6ec7908a0f 100644 --- a/snow/networking/handler/message_queue.go +++ b/snow/networking/handler/message_queue.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/buffer" "github.com/ava-labs/avalanchego/utils/timer/mockable" ) @@ -69,7 +70,7 @@ type messageQueue struct { // Node ID --> Messages this node has in [msgs] nodeToUnprocessedMsgs map[ids.NodeID]int // Unprocessed messages - msgAndCtxs []*msgAndContext + msgAndCtxs buffer.Deque[*msgAndContext] } func NewMessageQueue( @@ -85,6 +86,7 @@ func NewMessageQueue( cpuTracker: cpuTracker, cond: sync.NewCond(&sync.Mutex{}), nodeToUnprocessedMsgs: make(map[ids.NodeID]int), + msgAndCtxs: buffer.NewUnboundedDeque[*msgAndContext](1 /*=initSize*/), } return m, m.metrics.initialize(metricsNamespace, ctx.Registerer, ops) } @@ -99,7 +101,7 @@ func (m *messageQueue) Push(ctx context.Context, msg Message) { } // Add the message to the queue - m.msgAndCtxs = append(m.msgAndCtxs, &msgAndContext{ + m.msgAndCtxs.PushRight(&msgAndContext{ msg: msg, ctx: ctx, }) @@ -124,13 +126,13 @@ func (m *messageQueue) Pop() (context.Context, Message, bool) { if m.closed { return nil, Message{}, false } - if len(m.msgAndCtxs) != 0 { + if m.msgAndCtxs.Len() != 0 { break } m.cond.Wait() } - n := len(m.msgAndCtxs) + n := m.msgAndCtxs.Len() // note that n > 0 i := 0 for { if i == n { @@ -140,20 +142,14 @@ func (m *messageQueue) Pop() (context.Context, Message, bool) { } var ( - msgAndCtx = m.msgAndCtxs[0] - msg = msgAndCtx.msg - ctx = msgAndCtx.ctx - nodeID = msg.NodeID() + msgAndCtx, _ = m.msgAndCtxs.PopLeft() + msg = msgAndCtx.msg + ctx = msgAndCtx.ctx + nodeID = msg.NodeID() ) - m.msgAndCtxs[0] = nil // See if it's OK to process [msg] next if m.canPop(msg) || i == n { // i should never == n but handle anyway as a fail-safe - if cap(m.msgAndCtxs) == 1 { - m.msgAndCtxs = nil // Give back memory if possible - } else { - m.msgAndCtxs = m.msgAndCtxs[1:] - } m.nodeToUnprocessedMsgs[nodeID]-- if m.nodeToUnprocessedMsgs[nodeID] == 0 { delete(m.nodeToUnprocessedMsgs, nodeID) @@ -165,8 +161,7 @@ func (m *messageQueue) Pop() (context.Context, Message, bool) { } // [msg.nodeID] is causing excessive CPU usage. // Push [msg] to back of [m.msgs] and handle it later. - m.msgAndCtxs = append(m.msgAndCtxs, msgAndCtx) - m.msgAndCtxs = m.msgAndCtxs[1:] + m.msgAndCtxs.PushRight(msgAndCtx) i++ m.metrics.numExcessiveCPU.Inc() } @@ -176,7 +171,7 @@ func (m *messageQueue) Len() int { m.cond.L.Lock() defer m.cond.L.Unlock() - return len(m.msgAndCtxs) + return m.msgAndCtxs.Len() } func (m *messageQueue) Shutdown() { @@ -184,10 +179,10 @@ func (m *messageQueue) Shutdown() { defer m.cond.L.Unlock() // Remove all the current messages from the queue - for _, msg := range m.msgAndCtxs { - msg.msg.OnFinishedHandling() + for m.msgAndCtxs.Len() > 0 { + msgAndCtx, _ := m.msgAndCtxs.PopLeft() + msgAndCtx.msg.OnFinishedHandling() } - m.msgAndCtxs = nil m.nodeToUnprocessedMsgs = nil // Update metrics From ef2838d168edf367683b015a419a925ca92c5c64 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 6 Dec 2023 14:37:36 -0700 Subject: [PATCH 111/267] ProposerVM Extend windows 1 - UTs Cleanup (#2412) Co-authored-by: Stephen Buttolph --- vms/proposervm/batched_vm_test.go | 117 ++-- vms/proposervm/block_test.go | 16 +- vms/proposervm/post_fork_block_test.go | 743 +++++++++++++---------- vms/proposervm/post_fork_option_test.go | 126 ++-- vms/proposervm/pre_fork_block_test.go | 38 +- vms/proposervm/proposer/windower_test.go | 48 +- vms/proposervm/state_syncable_vm_test.go | 36 +- vms/proposervm/vm_byzantine_test.go | 112 ++-- vms/proposervm/vm_test.go | 157 +++-- 9 files changed, 721 insertions(+), 672 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index c55c5ffc13b4..b95a321f9ddf 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -211,10 +211,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -232,10 +231,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -253,10 +251,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -352,10 +349,13 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { require := require.New(t) - currentTime := time.Now().Truncate(time.Second) - preForkTime := currentTime.Add(5 * time.Minute) - forkTime := currentTime.Add(10 * time.Minute) - postForkTime := currentTime.Add(15 * time.Minute) + + var ( + currentTime = time.Now().Truncate(time.Second) + preForkTime = currentTime.Add(5 * time.Minute) + forkTime = currentTime.Add(10 * time.Minute) + postForkTime = currentTime.Add(15 * time.Minute) + ) // enable ProBlks in next future coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) @@ -428,10 +428,9 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime.Add(proposer.MaxVerifyDelay), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -450,10 +449,9 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{4}, - ParentV: coreBlk3.ID(), - HeightV: coreBlk3.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{4}, + ParentV: coreBlk3.ID(), + HeightV: coreBlk3.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk4, nil @@ -569,10 +567,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -596,10 +593,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -623,10 +619,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -690,10 +685,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -711,10 +705,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -732,10 +725,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -788,10 +780,13 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { require := require.New(t) - currentTime := time.Now().Truncate(time.Second) - preForkTime := currentTime.Add(5 * time.Minute) - forkTime := currentTime.Add(10 * time.Minute) - postForkTime := currentTime.Add(15 * time.Minute) + + var ( + currentTime = time.Now().Truncate(time.Second) + preForkTime = currentTime.Add(5 * time.Minute) + forkTime = currentTime.Add(10 * time.Minute) + postForkTime = currentTime.Add(15 * time.Minute) + ) // enable ProBlks in next future coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) @@ -864,10 +859,9 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime.Add(proposer.MaxVerifyDelay), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -886,10 +880,9 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{4}, - ParentV: coreBlk3.ID(), - HeightV: coreBlk3.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{4}, + ParentV: coreBlk3.ID(), + HeightV: coreBlk3.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk4, nil @@ -956,7 +949,7 @@ type TestRemoteProposerVM struct { func initTestRemoteProposerVM( t *testing.T, - proBlkStartTime time.Time, + activationTime time.Time, ) ( TestRemoteProposerVM, *VM, @@ -1021,7 +1014,7 @@ func initTestRemoteProposerVM( proVM := New( coreVM, Config{ - ActivationTime: proBlkStartTime, + ActivationTime: activationTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 5cca837a7a84..35bd959a6679 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -36,24 +36,31 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - pChainHeight := uint64(1337) - parentID := ids.GenerateTestID() - parentTimestamp := time.Now() - blkID := ids.GenerateTestID() + var ( + pChainHeight uint64 = 1337 + parentID = ids.GenerateTestID() + parentTimestamp = time.Now().Truncate(time.Second) + blkID = ids.GenerateTestID() + ) + innerBlk := snowman.NewMockBlock(ctrl) innerBlk.EXPECT().ID().Return(blkID).AnyTimes() innerBlk.EXPECT().Height().Return(pChainHeight - 1).AnyTimes() + builtBlk := snowman.NewMockBlock(ctrl) builtBlk.EXPECT().Bytes().Return([]byte{1, 2, 3}).AnyTimes() builtBlk.EXPECT().ID().Return(ids.GenerateTestID()).AnyTimes() builtBlk.EXPECT().Height().Return(pChainHeight).AnyTimes() + innerVM := mocks.NewMockChainVM(ctrl) innerBlockBuilderVM := mocks.NewMockBuildBlockWithContextChainVM(ctrl) innerBlockBuilderVM.EXPECT().BuildBlockWithContext(gomock.Any(), &block.Context{ PChainHeight: pChainHeight - 1, }).Return(builtBlk, nil).AnyTimes() + vdrState := validators.NewMockState(ctrl) vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() + windower := proposer.NewMockWindower(ctrl) windower.EXPECT().Delay(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(time.Duration(0), nil).AnyTimes() @@ -61,6 +68,7 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require.NoError(err) vm := &VM{ Config: Config{ + ActivationTime: time.Unix(0, 0), StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 25dfd4f63e8f..c0b3850b243f 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" + "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -105,24 +106,24 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { } // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -131,38 +132,26 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) // .. create child block ... childCoreBlk := &snowman.TestBlock{ - ParentV: prntCoreBlk.ID(), - BytesV: []byte{2}, - TimestampV: prntCoreBlk.Timestamp(), + ParentV: parentCoreBlk.ID(), + BytesV: []byte{2}, + HeightV: parentCoreBlk.Height() + 1, } - childSlb, err := block.Build( - ids.Empty, // refer unknown parent - childCoreBlk.Timestamp(), - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk := postForkBlock{ - SignedBlock: childSlb, + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -170,23 +159,37 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { }, } - // child block referring unknown parent does not verify - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, database.ErrNotFound) + // set proVM to be able to build unsigned blocks + proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) - // child block referring known parent does verify - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), // refer known parent - prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay), - pChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(err) + { + // child block referring unknown parent does not verify + childSlb, err := block.BuildUnsigned( + ids.Empty, // refer unknown parent + proVM.Time(), + pChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, database.ErrNotFound) + } - proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) - require.NoError(childProBlk.Verify(context.Background())) + { + // child block referring known parent does verify + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), // refer known parent + proVM.Time(), + pChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } } func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { @@ -197,30 +200,49 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require.NoError(proVM.Shutdown(context.Background())) }() + // reduce validator state to allow proVM.ctx.NodeID to be easily selected as proposer + valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + var ( + thisNode = proVM.ctx.NodeID + nodeID1 = ids.BuildTestNodeID([]byte{1}) + ) + return map[ids.NodeID]*validators.GetValidatorOutput{ + thisNode: { + NodeID: thisNode, + Weight: 5, + }, + nodeID1: { + NodeID: nodeID1, + Weight: 100, + }, + }, nil + } + proVM.ctx.ValidatorState = valState + pChainHeight := uint64(100) valState.GetCurrentHeightF = func(context.Context) (uint64, error) { return pChainHeight, nil } // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -229,45 +251,34 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - prntTimestamp := prntProBlk.Timestamp() + var ( + parentTimestamp = parentBlk.Timestamp() + parentPChainHeight = parentBlk.(*postForkBlock).PChainHeight() + ) childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: prntCoreBlk.ID(), + ParentV: parentCoreBlk.ID(), + HeightV: parentCoreBlk.Height() + 1, BytesV: []byte{2}, } - - // child block timestamp cannot be lower than parent timestamp - childCoreBlk.TimestampV = prntTimestamp.Add(-1 * time.Second) - proVM.Clock.Set(childCoreBlk.TimestampV) - childSlb, err := block.Build( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk := postForkBlock{ - SignedBlock: childSlb, + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -275,90 +286,127 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { }, } - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeNotMonotonic) + { + // child block timestamp cannot be lower than parent timestamp + newTime := parentTimestamp.Add(-1 * time.Second) + proVM.Clock.Set(newTime) + + childSlb, err := block.Build( + parentBlk.ID(), + newTime, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errTimeNotMonotonic) + } - // block cannot arrive before its creator window starts - blkWinDelay, err := proVM.Delay(context.Background(), childCoreBlk.Height(), pChainHeight, proVM.ctx.NodeID, proposer.MaxVerifyWindows) - require.NoError(err) - beforeWinStart := prntTimestamp.Add(blkWinDelay).Add(-1 * time.Second) - proVM.Clock.Set(beforeWinStart) - childSlb, err = block.Build( - prntProBlk.ID(), - beforeWinStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) + blkWinDelay, err := proVM.Delay(context.Background(), childCoreBlk.Height(), parentPChainHeight, proVM.ctx.NodeID, proposer.MaxVerifyWindows) require.NoError(err) - childProBlk.SignedBlock = childSlb - - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errProposerWindowNotStarted) - - // block can arrive at its creator window starts - atWindowStart := prntTimestamp.Add(blkWinDelay) - proVM.Clock.Set(atWindowStart) - childSlb, err = block.Build( - prntProBlk.ID(), - atWindowStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + { + // block cannot arrive before its creator window starts + beforeWinStart := parentTimestamp.Add(blkWinDelay).Add(-1 * time.Second) + proVM.Clock.Set(beforeWinStart) + + childSlb, err := block.Build( + parentBlk.ID(), + beforeWinStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errProposerWindowNotStarted) + } - // block can arrive after its creator window starts - afterWindowStart := prntTimestamp.Add(blkWinDelay).Add(5 * time.Second) - proVM.Clock.Set(afterWindowStart) - childSlb, err = block.Build( - prntProBlk.ID(), - afterWindowStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) - - // block can arrive within submission window - atSubWindowEnd := proVM.Time().Add(proposer.MaxVerifyDelay) - proVM.Clock.Set(atSubWindowEnd) - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - atSubWindowEnd, - pChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) - - // block timestamp cannot be too much in the future - afterSubWinEnd := proVM.Time().Add(maxSkew).Add(time.Second) - childSlb, err = block.Build( - prntProBlk.ID(), - afterSubWinEnd, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + { + // block can arrive at its creator window starts + atWindowStart := parentTimestamp.Add(blkWinDelay) + proVM.Clock.Set(atWindowStart) + + childSlb, err := block.Build( + parentBlk.ID(), + atWindowStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } + + { + // block can arrive after its creator window starts + afterWindowStart := parentTimestamp.Add(blkWinDelay).Add(5 * time.Second) + proVM.Clock.Set(afterWindowStart) + + childSlb, err := block.Build( + parentBlk.ID(), + afterWindowStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } + + { + // block can arrive within submission window + atSubWindowEnd := proVM.Time().Add(proposer.MaxVerifyDelay) + proVM.Clock.Set(atSubWindowEnd) + + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + atSubWindowEnd, + pChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } + + { + // block timestamp cannot be too much in the future + afterSubWinEnd := proVM.Time().Add(maxSkew).Add(time.Second) + + childSlb, err := block.Build( + parentBlk.ID(), + afterSubWinEnd, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errTimeTooAdvanced) + } } func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { @@ -373,26 +421,29 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { valState.GetCurrentHeightF = func(context.Context) (uint64, error) { return pChainHeight, nil } + valState.GetMinimumHeightF = func(context.Context) (uint64, error) { + return pChainHeight / 50, nil + } // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -401,44 +452,35 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) + + // set VM to be ready to build next block. We set it to generate unsigned blocks + // for simplicity. + nextTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) + proVM.Set(nextTime) - prntBlkPChainHeight := pChainHeight + parentBlkPChainHeight := parentBlk.(*postForkBlock).PChainHeight() childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: prntCoreBlk.ID(), - BytesV: []byte{2}, - TimestampV: prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay), + ParentV: parentCoreBlk.ID(), + BytesV: []byte{2}, } - - // child P-Chain height must not precede parent P-Chain height - childSlb, err := block.Build( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight-1, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk := postForkBlock{ - SignedBlock: childSlb, + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -446,57 +488,78 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { }, } - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + { + // child P-Chain height must not precede parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight-1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotMonotonic) + } - // child P-Chain height can be equal to parent P-Chain height - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - - proVM.Set(childCoreBlk.Timestamp()) - require.NoError(childProBlk.Verify(context.Background())) - - // child P-Chain height may follow parent P-Chain height - pChainHeight = prntBlkPChainHeight * 2 // move ahead pChainHeight - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight+1, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + { + // child P-Chain height can be equal to parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } + + { + // child P-Chain height may follow parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight+1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } - // block P-Chain height can be equal to current P-Chain height currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) - - // block P-Chain height cannot be at higher than current P-Chain height - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight*2, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errPChainHeightNotReached) + { + // block P-Chain height can be equal to current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + currPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } + + { + // block P-Chain height cannot be at higher than current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + currPChainHeight*2, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotReached) + } } func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) { @@ -511,7 +574,9 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) valState.GetCurrentHeightF = func(context.Context) (uint64, error) { return pChainHeight, nil } - // proVM.SetStartTime(timer.MaxTime) // switch off scheduler for current test + valState.GetMinimumHeightF = func(context.Context) (uint64, error) { + return pChainHeight / 50, nil + } // create post fork oracle block ... oracleCoreBlk := &TestOptionsBlock{ @@ -520,9 +585,9 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -531,18 +596,18 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -594,31 +659,23 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) require.NoError(parentBlk.Verify(context.Background())) require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - prntBlkPChainHeight := pChainHeight + // set VM to be ready to build next block. We set it to generate unsigned blocks + // for simplicity. + nextTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) + proVM.Set(nextTime) + + parentBlkPChainHeight := postForkOracleBlk.PChainHeight() // option takes proposal blocks' Pchain height childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: oracleCoreBlk.opts[0].ID(), - BytesV: []byte{2}, - TimestampV: parentBlk.Timestamp().Add(proposer.MaxVerifyDelay), + ParentV: oracleCoreBlk.opts[0].ID(), + BytesV: []byte{2}, + HeightV: oracleCoreBlk.opts[0].Height() + 1, } - - // child P-Chain height must not precede parent P-Chain height - childSlb, err := block.Build( - parentBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight-1, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk := postForkBlock{ - SignedBlock: childSlb, + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -626,57 +683,77 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) }, } - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + { + // child P-Chain height must not precede parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight-1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotMonotonic) + } - // child P-Chain height can be equal to parent P-Chain height - childSlb, err = block.BuildUnsigned( - parentBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - - proVM.Set(childCoreBlk.Timestamp()) - require.NoError(childProBlk.Verify(context.Background())) - - // child P-Chain height may follow parent P-Chain height - pChainHeight = prntBlkPChainHeight * 2 // move ahead pChainHeight - childSlb, err = block.BuildUnsigned( - parentBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight+1, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + { + // child P-Chain height can be equal to parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } + + { + // child P-Chain height may follow parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight+1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } - // block P-Chain height can be equal to current P-Chain height currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) - childSlb, err = block.BuildUnsigned( - parentBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) - - // block P-Chain height cannot be at higher than current P-Chain height - childSlb, err = block.BuildUnsigned( - parentBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight*2, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errPChainHeightNotReached) + { + // block P-Chain height can be equal to current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + currPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } + + { + // block P-Chain height cannot be at higher than current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + currPChainHeight*2, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotReached) + } } func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { @@ -699,9 +776,9 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -762,9 +839,9 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -826,10 +903,9 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -868,10 +944,9 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -892,7 +967,6 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -904,9 +978,9 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } coreOpt0 := &snowman.TestBlock{ @@ -914,18 +988,18 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } coreOpt1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } oracleCoreBlk.opts = [2]snowman.Block{ coreOpt0, @@ -1007,7 +1081,6 @@ func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 5) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1017,9 +1090,9 @@ func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index e142b391a348..febecc1843d0 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) var _ snowman.OracleBlock = (*TestOptionsBlock)(nil) @@ -38,7 +37,6 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -50,9 +48,9 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -61,18 +59,18 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -133,14 +131,13 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(4444), StatusV: choices.Processing, }, - ParentV: oracleCoreBlk.opts[0].ID(), - BytesV: []byte{4}, - TimestampV: oracleCoreBlk.opts[0].Timestamp().Add(proposer.MaxVerifyDelay), + ParentV: oracleCoreBlk.opts[0].ID(), + BytesV: []byte{4}, + HeightV: oracleCoreBlk.opts[0].Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return childCoreBlk, nil } - proVM.Set(childCoreBlk.Timestamp()) proChild, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -154,7 +151,6 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -166,9 +162,9 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } coreOpt0 := &snowman.TestBlock{ @@ -176,18 +172,18 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } coreOpt1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } oracleCoreBlk.opts = [2]snowman.Block{ coreOpt0, @@ -256,7 +252,6 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -268,9 +263,9 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -279,18 +274,18 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -366,7 +361,6 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -378,9 +372,9 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -389,18 +383,18 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -468,7 +462,6 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -479,9 +472,9 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, optsErr: snowman.ErrNotOracle, } @@ -491,10 +484,9 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk.ID(), - HeightV: coreBlk.Height() + 1, - TimestampV: coreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk.ID(), + HeightV: coreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { @@ -562,10 +554,9 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: coreOracleBlkID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -573,24 +564,26 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreOracleBlkID, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{2}, + ParentV: coreOracleBlkID, + HeightV: coreGenBlk.Height() + 2, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreOracleBlkID, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{3}, + ParentV: coreOracleBlkID, + HeightV: coreGenBlk.Height() + 2, }, }, } + + oracleBlkTime := proVM.Time().Truncate(time.Second) statelessBlock, err := block.BuildUnsigned( coreGenBlk.ID(), - coreGenBlk.Timestamp(), + oracleBlkTime, 0, coreOracleBlk.Bytes(), ) @@ -650,8 +643,7 @@ func TestOptionTimestampValidity(t *testing.T) { return nil, nil } - expectedTime := coreGenBlk.Timestamp() - require.Equal(expectedTime, option.Timestamp()) + require.Equal(oracleBlkTime, option.Timestamp()) require.NoError(option.Accept(context.Background())) require.NoError(proVM.Shutdown(context.Background())) @@ -745,5 +737,5 @@ func TestOptionTimestampValidity(t *testing.T) { return nil, nil } - require.Equal(expectedTime, statefulOptionBlock.Timestamp()) + require.Equal(oracleBlkTime, statefulOptionBlock.Timestamp()) } diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 4308f9ba05f1..35efbbaeaaa4 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) func TestOracle_PreForkBlkImplementsInterface(t *testing.T) { @@ -242,7 +241,7 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { require.True(coreGenBlk.Timestamp().Before(activationTime)) // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, @@ -252,14 +251,14 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { TimestampV: coreGenBlk.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -268,15 +267,14 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) // .. create child block ... @@ -286,21 +284,25 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { StatusV: choices.Processing, }, BytesV: []byte{2}, - TimestampV: prntCoreBlk.Timestamp().Add(proposer.MaxVerifyDelay), + TimestampV: parentCoreBlk.Timestamp(), } - childProBlk := preForkBlock{ + childBlk := preForkBlock{ Block: childCoreBlk, vm: proVM, } - // child block referring unknown parent does not verify - childCoreBlk.ParentV = ids.Empty - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, database.ErrNotFound) + { + // child block referring unknown parent does not verify + childCoreBlk.ParentV = ids.Empty + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, database.ErrNotFound) + } - // child block referring known parent does verify - childCoreBlk.ParentV = prntProBlk.ID() - require.NoError(childProBlk.Verify(context.Background())) + { + // child block referring known parent does verify + childCoreBlk.ParentV = parentBlk.ID() + require.NoError(childBlk.Verify(context.Background())) + } } func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 2a141a361ea2..854c7b737213 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -18,9 +18,12 @@ import ( func TestWindowerNoValidators(t *testing.T) { require := require.New(t) - subnetID := ids.GenerateTestID() - chainID := ids.GenerateTestID() - nodeID := ids.GenerateTestNodeID() + var ( + subnetID = ids.GenerateTestID() + chainID = ids.GenerateTestID() + nodeID = ids.GenerateTestNodeID() + ) + vdrState := &validators.TestState{ T: t, GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { @@ -30,7 +33,11 @@ func TestWindowerNoValidators(t *testing.T) { w := New(vdrState, subnetID, chainID) - delay, err := w.Delay(context.Background(), 1, 0, nodeID, MaxVerifyWindows) + var ( + chainHeight uint64 = 1 + pChainHeight uint64 = 0 + ) + delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) require.NoError(err) require.Zero(delay) } @@ -38,10 +45,13 @@ func TestWindowerNoValidators(t *testing.T) { func TestWindowerRepeatedValidator(t *testing.T) { require := require.New(t) - subnetID := ids.GenerateTestID() - chainID := ids.GenerateTestID() - validatorID := ids.GenerateTestNodeID() - nonValidatorID := ids.GenerateTestNodeID() + var ( + subnetID = ids.GenerateTestID() + chainID = ids.GenerateTestID() + validatorID = ids.GenerateTestNodeID() + nonValidatorID = ids.GenerateTestNodeID() + ) + vdrState := &validators.TestState{ T: t, GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { @@ -65,11 +75,14 @@ func TestWindowerRepeatedValidator(t *testing.T) { require.Equal(MaxVerifyDelay, nonValidatorDelay) } -func TestWindowerChangeByHeight(t *testing.T) { +func TestDelayChangeByHeight(t *testing.T) { require := require.New(t) - subnetID := ids.ID{0, 1} - chainID := ids.ID{0, 2} + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + ) + validatorIDs := make([]ids.NodeID, MaxVerifyWindows) for i := range validatorIDs { validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) @@ -121,16 +134,21 @@ func TestWindowerChangeByHeight(t *testing.T) { } } -func TestWindowerChangeByChain(t *testing.T) { +func TestDelayChangeByChain(t *testing.T) { require := require.New(t) subnetID := ids.ID{0, 1} - rand.Seed(0) + source := rand.NewSource(int64(0)) + rng := rand.New(source) // #nosec G404 + chainID0 := ids.ID{} - _, _ = rand.Read(chainID0[:]) // #nosec G404 + _, err := rng.Read(chainID0[:]) + require.NoError(err) + chainID1 := ids.ID{} - _, _ = rand.Read(chainID1[:]) // #nosec G404 + _, err = rng.Read(chainID1[:]) + require.NoError(err) validatorIDs := make([]ids.NodeID, MaxVerifyWindows) for i := range validatorIDs { diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index b2295d50017b..31695ec9876e 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -175,9 +175,9 @@ func TestStateSyncGetOngoingSyncStateSummary(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) @@ -260,9 +260,9 @@ func TestStateSyncGetLastStateSummary(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) @@ -348,9 +348,9 @@ func TestStateSyncGetStateSummary(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) @@ -421,9 +421,9 @@ func TestParseStateSummary(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) @@ -480,9 +480,9 @@ func TestStateSummaryAccept(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } slb, err := statelessblock.Build( @@ -552,9 +552,9 @@ func TestStateSummaryAcceptOlderBlock(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.GetStateSummaryF = func(_ context.Context, h uint64) (block.StateSummary, error) { require.Equal(reqHeight, h) diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index dcfebf847cf3..5b6c29ee6a63 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) // Ensure that a byzantine node issuing an invalid PreForkBlock (Y) when the @@ -44,10 +43,9 @@ func TestInvalidByzantineProposerParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return xBlock, nil @@ -67,10 +65,9 @@ func TestInvalidByzantineProposerParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: yBlockBytes, - ParentV: xBlock.ID(), - HeightV: xBlock.Height() + 1, - TimestampV: xBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: yBlockBytes, + ParentV: xBlock.ID(), + HeightV: xBlock.Height() + 1, } coreVM.ParseBlockF = func(_ context.Context, blockBytes []byte) (snowman.Block, error) { @@ -116,9 +113,8 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { IDV: xBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -126,18 +122,16 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: xBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: xBlockID, }, }, } @@ -222,10 +216,9 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return xBlock, nil @@ -237,10 +230,9 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: yBlockBytes, - ParentV: xBlock.ID(), - HeightV: xBlock.Height() + 1, - TimestampV: xBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: yBlockBytes, + ParentV: xBlock.ID(), + HeightV: xBlock.Height() + 1, } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { @@ -312,9 +304,8 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -322,18 +313,16 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), // valid block should reference xBlock - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), // valid block should reference xBlock }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreGenBlk.ID(), // valid block should reference xBlock - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: coreGenBlk.ID(), // valid block should reference xBlock }, }, } @@ -413,9 +402,8 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: xBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -423,18 +411,16 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: xBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: xBlockID, }, }, } @@ -449,10 +435,9 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } ySlb, err := block.BuildUnsigned( @@ -529,9 +514,8 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: zBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -539,18 +523,16 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: zBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: zBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: zBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: zBlockID, }, }, } @@ -609,10 +591,9 @@ func TestGetBlock_MutatedSignature(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreBlk1 := &snowman.TestBlock{ @@ -620,10 +601,9 @@ func TestGetBlock_MutatedSignature(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk0.ID(), - HeightV: coreBlk0.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk0.ID(), + HeightV: coreBlk0.Height() + 1, } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { @@ -663,7 +643,7 @@ func TestGetBlock_MutatedSignature(t *testing.T) { require.NoError(proVM.SetPreference(context.Background(), builtBlk0.ID())) - // The second propsal block will need to be signed because the timestamp + // The second proposal block will need to be signed because the timestamp // hasn't moved forward // Craft what would be the next block, but with an invalid signature: diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index d3e2282f25c0..b716a6fa3c3d 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -210,6 +210,8 @@ func initTestProposerVM( require.NoError(proVM.SetState(context.Background(), snow.NormalOp)) require.NoError(proVM.SetPreference(context.Background(), coreGenBlk.IDV)) + proVM.Set(coreGenBlk.Timestamp()) + return coreVM, valState, proVM, coreGenBlk, db } @@ -232,10 +234,9 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -262,10 +263,9 @@ func TestBuildBlockIsIdempotent(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -297,10 +297,9 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -332,10 +331,9 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -348,10 +346,9 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { IDV: ids.Empty.Prefix(222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -396,10 +393,9 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { IDV: ids.Empty.Prefix(333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: prefcoreBlk.ID(), - HeightV: prefcoreBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: prefcoreBlk.ID(), + HeightV: prefcoreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -426,10 +422,9 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -442,10 +437,9 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -491,10 +485,9 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: wronglyPreferredcoreBlk.ID(), - HeightV: wronglyPreferredcoreBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: wronglyPreferredcoreBlk.ID(), + HeightV: wronglyPreferredcoreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -518,15 +511,14 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { }() innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: proVM.Time(), + BytesV: []byte{1}, } coreVM.ParseBlockF = func(context.Context, []byte) (snowman.Block, error) { return nil, errMarshallingFailed } slb, err := statelessblock.Build( proVM.preferred, - innerBlk.Timestamp(), + proVM.Time(), 100, // pChainHeight, proVM.StakingCertLeaf, innerBlk.Bytes(), @@ -558,19 +550,20 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { // create two Proposer blocks at the same height innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - ParentV: gencoreBlk.ID(), - HeightV: gencoreBlk.Height() + 1, - TimestampV: proVM.Time(), + BytesV: []byte{1}, + ParentV: gencoreBlk.ID(), + HeightV: gencoreBlk.Height() + 1, } coreVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) return innerBlk, nil } + blkTimestamp := proVM.Time() + slb1, err := statelessblock.Build( proVM.preferred, - innerBlk.Timestamp(), + blkTimestamp, 100, // pChainHeight, proVM.StakingCertLeaf, innerBlk.Bytes(), @@ -589,7 +582,7 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { slb2, err := statelessblock.Build( proVM.preferred, - innerBlk.Timestamp(), + blkTimestamp, 200, // pChainHeight, proVM.StakingCertLeaf, innerBlk.Bytes(), @@ -629,10 +622,9 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { // one block is built from this proVM localcoreBlk := &snowman.TestBlock{ - BytesV: []byte{111}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: genesisTimestamp, + BytesV: []byte{111}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return localcoreBlk, nil @@ -644,10 +636,9 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { // another block with same parent comes from network and is parsed netcoreBlk := &snowman.TestBlock{ - BytesV: []byte{222}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: genesisTimestamp, + BytesV: []byte{222}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { switch { @@ -668,7 +659,7 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { netSlb, err := statelessblock.BuildUnsigned( proVM.preferred, - netcoreBlk.Timestamp(), + proVM.Time(), pChainHeight, netcoreBlk.Bytes(), ) @@ -719,10 +710,9 @@ func TestPreFork_BuildBlock(t *testing.T) { IDV: ids.Empty.Prefix(333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{3}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -971,14 +961,13 @@ func TestExpiredBuildBlock(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } statelessBlock, err := statelessblock.BuildUnsigned( coreGenBlk.ID(), - coreBlk.Timestamp(), + proVM.Time(), 0, coreBlk.Bytes(), ) @@ -1375,24 +1364,22 @@ func TestBuildBlockDuringWindow(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreBlk1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk0.ID(), - HeightV: coreBlk0.Height() + 1, - TimestampV: coreBlk0.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk0.ID(), + HeightV: coreBlk0.Height() + 1, } statelessBlock0, err := statelessblock.BuildUnsigned( coreGenBlk.ID(), - coreBlk0.Timestamp(), + proVM.Time(), 0, coreBlk0.Bytes(), ) @@ -1471,10 +1458,9 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp(), + BytesV: []byte{1}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { @@ -1491,15 +1477,14 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp(), + BytesV: []byte{2}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } ySlb, err := statelessblock.BuildUnsigned( gBlock.ID(), - gBlock.Timestamp(), + proVM.Time(), defaultPChainHeight, yBlock.Bytes(), ) @@ -1522,16 +1507,16 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: yBlock.ID(), - HeightV: yBlock.Height() + 1, - TimestampV: yBlock.Timestamp(), + BytesV: []byte{3}, + ParentV: yBlock.ID(), + HeightV: yBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return zBlock, nil } require.NoError(proVM.SetPreference(context.Background(), bBlock.ID())) + proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) cBlock, err := proVM.BuildBlock(context.Background()) require.NoError(err) coreVM.BuildBlockF = nil @@ -1647,7 +1632,6 @@ func TestTwoOptions_OneIsAccepted(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1722,7 +1706,6 @@ func TestLaggedPChainHeight(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() From 930879d86d1ea509033d0b6213788b99044cae32 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 6 Dec 2023 18:05:43 -0500 Subject: [PATCH 112/267] Change seed from int64 to uint64 (#2438) --- .../snowball/consensus_performance_test.go | 38 ++++++++++--------- .../snowball/consensus_reversibility_test.go | 14 ++++--- snow/consensus/snowball/tree_test.go | 22 ++++++----- snow/consensus/snowman/consensus_test.go | 30 ++++++++------- utils/sampler/rand.go | 6 +-- utils/sampler/uniform.go | 2 +- utils/sampler/uniform_replacer.go | 2 +- utils/sampler/uniform_resample.go | 2 +- utils/sampler/weighted_without_replacement.go | 2 +- .../weighted_without_replacement_generic.go | 2 +- vms/proposervm/proposer/windower.go | 2 +- 11 files changed, 66 insertions(+), 56 deletions(-) diff --git a/snow/consensus/snowball/consensus_performance_test.go b/snow/consensus/snowball/consensus_performance_test.go index a84e1e60a9c7..bd2752a2ec5c 100644 --- a/snow/consensus/snowball/consensus_performance_test.go +++ b/snow/consensus/snowball/consensus_performance_test.go @@ -16,16 +16,18 @@ import ( func TestDualAlphaOptimization(t *testing.T) { require := require.New(t) - numColors := 10 - numNodes := 100 - params := Parameters{ - K: 20, - AlphaPreference: 15, - AlphaConfidence: 15, - BetaVirtuous: 15, - BetaRogue: 20, - } - seed := int64(0) + var ( + numColors = 10 + numNodes = 100 + params = Parameters{ + K: 20, + AlphaPreference: 15, + AlphaConfidence: 15, + BetaVirtuous: 15, + BetaRogue: 20, + } + seed uint64 = 0 + ) singleAlphaNetwork := Network{} singleAlphaNetwork.Initialize(params, numColors) @@ -54,10 +56,12 @@ func TestDualAlphaOptimization(t *testing.T) { func TestTreeConvergenceOptimization(t *testing.T) { require := require.New(t) - numColors := 10 - numNodes := 100 - params := DefaultParameters - seed := int64(0) + var ( + numColors = 10 + numNodes = 100 + params = DefaultParameters + seed uint64 = 0 + ) treeNetwork := Network{} treeNetwork.Initialize(params, numColors) @@ -79,13 +83,13 @@ func TestTreeConvergenceOptimization(t *testing.T) { runNetworksInLockstep(require, seed, &treeNetwork, &flatNetwork) } -func runNetworksInLockstep(require *require.Assertions, seed int64, fast *Network, slow *Network) { +func runNetworksInLockstep(require *require.Assertions, seed uint64, fast *Network, slow *Network) { numRounds := 0 for !fast.Finalized() && !fast.Disagreement() && !slow.Finalized() && !slow.Disagreement() { - sampler.Seed(int64(numRounds) + seed) + sampler.Seed(uint64(numRounds) + seed) fast.Round() - sampler.Seed(int64(numRounds) + seed) + sampler.Seed(uint64(numRounds) + seed) slow.Round() numRounds++ } diff --git a/snow/consensus/snowball/consensus_reversibility_test.go b/snow/consensus/snowball/consensus_reversibility_test.go index fd03a0411581..48d35cc7dde5 100644 --- a/snow/consensus/snowball/consensus_reversibility_test.go +++ b/snow/consensus/snowball/consensus_reversibility_test.go @@ -14,12 +14,14 @@ import ( func TestSnowballGovernance(t *testing.T) { require := require.New(t) - numColors := 2 - numNodes := 100 - numByzantine := 10 - numRed := 55 - params := DefaultParameters - seed := int64(0) + var ( + numColors = 2 + numNodes = 100 + numByzantine = 10 + numRed = 55 + params = DefaultParameters + seed uint64 = 0 + ) nBitwise := Network{} nBitwise.Initialize(params, numColors) diff --git a/snow/consensus/snowball/tree_test.go b/snow/consensus/snowball/tree_test.go index 8b0f6159df72..8517a8559fcc 100644 --- a/snow/consensus/snowball/tree_test.go +++ b/snow/consensus/snowball/tree_test.go @@ -796,16 +796,18 @@ func TestSnowballDoubleAdd(t *testing.T) { func TestSnowballConsistent(t *testing.T) { require := require.New(t) - numColors := 50 - numNodes := 100 - params := Parameters{ - K: 20, - AlphaPreference: 15, - AlphaConfidence: 15, - BetaVirtuous: 20, - BetaRogue: 30, - } - seed := int64(0) + var ( + numColors = 50 + numNodes = 100 + params = Parameters{ + K: 20, + AlphaPreference: 15, + AlphaConfidence: 15, + BetaVirtuous: 20, + BetaRogue: 30, + } + seed uint64 = 0 + ) sampler.Seed(seed) diff --git a/snow/consensus/snowman/consensus_test.go b/snow/consensus/snowman/consensus_test.go index 401435738b18..024a8f69974d 100644 --- a/snow/consensus/snowman/consensus_test.go +++ b/snow/consensus/snowman/consensus_test.go @@ -1585,20 +1585,22 @@ func ErrorOnTransitiveRejectionTest(t *testing.T, factory Factory) { func RandomizedConsistencyTest(t *testing.T, factory Factory) { require := require.New(t) - numColors := 50 - numNodes := 100 - params := snowball.Parameters{ - K: 20, - AlphaPreference: 15, - AlphaConfidence: 15, - BetaVirtuous: 20, - BetaRogue: 30, - ConcurrentRepolls: 1, - OptimalProcessing: 1, - MaxOutstandingItems: 1, - MaxItemProcessingTime: 1, - } - seed := int64(0) + var ( + numColors = 50 + numNodes = 100 + params = snowball.Parameters{ + K: 20, + AlphaPreference: 15, + AlphaConfidence: 15, + BetaVirtuous: 20, + BetaRogue: 30, + ConcurrentRepolls: 1, + OptimalProcessing: 1, + MaxOutstandingItems: 1, + MaxItemProcessingTime: 1, + } + seed uint64 = 0 + ) sampler.Seed(seed) diff --git a/utils/sampler/rand.go b/utils/sampler/rand.go index 7ec14e6b275a..1b335f718be0 100644 --- a/utils/sampler/rand.go +++ b/utils/sampler/rand.go @@ -21,7 +21,7 @@ func newRNG() *rng { return &rng{rng: source} } -func Seed(seed int64) { +func Seed(seed uint64) { globalRNG.Seed(seed) } @@ -37,9 +37,9 @@ type rng struct { // Seed uses the provided seed value to initialize the generator to a // deterministic state. -func (r *rng) Seed(seed int64) { +func (r *rng) Seed(seed uint64) { r.lock.Lock() - r.rng.Seed(uint64(seed)) + r.rng.Seed(seed) r.lock.Unlock() } diff --git a/utils/sampler/uniform.go b/utils/sampler/uniform.go index 65c97f40b1a8..262de753a6f7 100644 --- a/utils/sampler/uniform.go +++ b/utils/sampler/uniform.go @@ -11,7 +11,7 @@ type Uniform interface { // negative the implementation may panic. Sample(length int) ([]uint64, error) - Seed(int64) + Seed(uint64) ClearSeed() Reset() diff --git a/utils/sampler/uniform_replacer.go b/utils/sampler/uniform_replacer.go index 9ac1811c4b47..8551907da7d1 100644 --- a/utils/sampler/uniform_replacer.go +++ b/utils/sampler/uniform_replacer.go @@ -55,7 +55,7 @@ func (s *uniformReplacer) Sample(count int) ([]uint64, error) { return results, nil } -func (s *uniformReplacer) Seed(seed int64) { +func (s *uniformReplacer) Seed(seed uint64) { s.rng = s.seededRNG s.rng.Seed(seed) } diff --git a/utils/sampler/uniform_resample.go b/utils/sampler/uniform_resample.go index 8f09e95f777c..ce3e41fe15c4 100644 --- a/utils/sampler/uniform_resample.go +++ b/utils/sampler/uniform_resample.go @@ -42,7 +42,7 @@ func (s *uniformResample) Sample(count int) ([]uint64, error) { return results, nil } -func (s *uniformResample) Seed(seed int64) { +func (s *uniformResample) Seed(seed uint64) { s.rng = s.seededRNG s.rng.Seed(seed) } diff --git a/utils/sampler/weighted_without_replacement.go b/utils/sampler/weighted_without_replacement.go index a6039a65d82c..1a3699613525 100644 --- a/utils/sampler/weighted_without_replacement.go +++ b/utils/sampler/weighted_without_replacement.go @@ -10,7 +10,7 @@ type WeightedWithoutReplacement interface { Initialize(weights []uint64) error Sample(count int) ([]int, error) - Seed(int64) + Seed(uint64) ClearSeed() } diff --git a/utils/sampler/weighted_without_replacement_generic.go b/utils/sampler/weighted_without_replacement_generic.go index 17bd8a648185..5fefb826c46a 100644 --- a/utils/sampler/weighted_without_replacement_generic.go +++ b/utils/sampler/weighted_without_replacement_generic.go @@ -42,7 +42,7 @@ func (s *weightedWithoutReplacementGeneric) Sample(count int) ([]int, error) { return indices, nil } -func (s *weightedWithoutReplacementGeneric) Seed(seed int64) { +func (s *weightedWithoutReplacementGeneric) Seed(seed uint64) { s.u.Seed(seed) } diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 8cb7bc43b24d..12afc711cfc9 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -113,7 +113,7 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint } seed := chainHeight ^ w.chainSource - w.sampler.Seed(int64(seed)) + w.sampler.Seed(seed) indices, err := w.sampler.Sample(numToSample) if err != nil { From 54c1ecf1550f7b42bcfeea6b3b86b058117324a6 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 6 Dec 2023 23:35:37 -0500 Subject: [PATCH 113/267] Remove usage of timer.Timer in node (#2441) --- node/beacon_manager.go | 15 ++++++++------ node/beacon_manager_test.go | 9 ++++----- node/node.go | 39 ++++++++++++++++++++----------------- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/node/beacon_manager.go b/node/beacon_manager.go index af088f3b4845..8e6ddeb23cc1 100644 --- a/node/beacon_manager.go +++ b/node/beacon_manager.go @@ -4,13 +4,13 @@ package node import ( + "sync" "sync/atomic" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/version" ) @@ -18,10 +18,11 @@ var _ router.Router = (*beaconManager)(nil) type beaconManager struct { router.Router - timer *timer.Timer - beacons validators.Manager - requiredConns int64 - numConns int64 + beacons validators.Manager + requiredConns int64 + numConns int64 + onSufficientlyConnected chan struct{} + onceOnSufficientlyConnected sync.Once } func (b *beaconManager) Connected(nodeID ids.NodeID, nodeVersion *version.Application, subnetID ids.ID) { @@ -29,7 +30,9 @@ func (b *beaconManager) Connected(nodeID ids.NodeID, nodeVersion *version.Applic if isBeacon && constants.PrimaryNetworkID == subnetID && atomic.AddInt64(&b.numConns, 1) >= b.requiredConns { - b.timer.Cancel() + b.onceOnSufficientlyConnected.Do(func() { + close(b.onSufficientlyConnected) + }) } b.Router.Connected(nodeID, nodeVersion, subnetID) } diff --git a/node/beacon_manager_test.go b/node/beacon_manager_test.go index 82be435e92f1..2e282d06015c 100644 --- a/node/beacon_manager_test.go +++ b/node/beacon_manager_test.go @@ -15,7 +15,6 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/version" ) @@ -41,10 +40,10 @@ func TestBeaconManager_DataRace(t *testing.T) { mockRouter := router.NewMockRouter(ctrl) b := beaconManager{ - Router: mockRouter, - timer: timer.NewTimer(nil), - beacons: validatorSet, - requiredConns: numValidators, + Router: mockRouter, + beacons: validatorSet, + requiredConns: numValidators, + onSufficientlyConnected: make(chan struct{}), } // connect numValidators validators, each with a weight of 1 diff --git a/node/node.go b/node/node.go index 40eb8dc16bef..1dbe4c6cc0df 100644 --- a/node/node.go +++ b/node/node.go @@ -73,7 +73,6 @@ import ( "github.com/ava-labs/avalanchego/utils/profiler" "github.com/ava-labs/avalanchego/utils/resource" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms" "github.com/ava-labs/avalanchego/vms/avm" @@ -480,28 +479,32 @@ func (n *Node) initNetworking() error { requiredConns := (3*numBootstrappers + 3) / 4 if requiredConns > 0 { - // Set a timer that will fire after a given timeout unless we connect - // to a sufficient portion of nodes. If the timeout fires, the node will - // shutdown. - timer := timer.NewTimer(func() { - // If the timeout fires and we're already shutting down, nothing to do. - if !n.shuttingDown.Get() { + onSufficientlyConnected := make(chan struct{}) + consensusRouter = &beaconManager{ + Router: consensusRouter, + beacons: n.bootstrappers, + requiredConns: int64(requiredConns), + onSufficientlyConnected: onSufficientlyConnected, + } + + // Log a warning if we aren't able to connect to a sufficient portion of + // nodes. + go func() { + timer := time.NewTimer(n.Config.BootstrapBeaconConnectionTimeout) + defer timer.Stop() + + select { + case <-timer.C: + if n.shuttingDown.Get() { + return + } n.Log.Warn("failed to connect to bootstrap nodes", zap.Stringer("bootstrappers", n.bootstrappers), zap.Duration("duration", n.Config.BootstrapBeaconConnectionTimeout), ) + case <-onSufficientlyConnected: } - }) - - go timer.Dispatch() - timer.SetTimeoutIn(n.Config.BootstrapBeaconConnectionTimeout) - - consensusRouter = &beaconManager{ - Router: consensusRouter, - timer: timer, - beacons: n.bootstrappers, - requiredConns: int64(requiredConns), - } + }() } // initialize gossip tracker From 7c33fa32ad669761a2075ce7ee0dc9bc9f9412bc Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 7 Dec 2023 01:13:34 -0500 Subject: [PATCH 114/267] Remove staged timer again (#2440) --- utils/timer/staged_timer.go | 23 ---------------- utils/timer/staged_timer_test.go | 47 -------------------------------- 2 files changed, 70 deletions(-) delete mode 100644 utils/timer/staged_timer.go delete mode 100644 utils/timer/staged_timer_test.go diff --git a/utils/timer/staged_timer.go b/utils/timer/staged_timer.go deleted file mode 100644 index eec885ee63d9..000000000000 --- a/utils/timer/staged_timer.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package timer - -import "time" - -// NewStagedTimer returns a timer that will execute [f] -// when a timeout occurs and execute an additional timeout after -// the returned duration if [f] returns true and some duration. -// -// Deprecated: NewStagedTimer exists for historical compatibility -// and should not be used. -func NewStagedTimer(f func() (time.Duration, bool)) *Timer { - t := NewTimer(nil) - t.handler = func() { - delay, repeat := f() - if repeat { - t.SetTimeoutIn(delay) - } - } - return t -} diff --git a/utils/timer/staged_timer_test.go b/utils/timer/staged_timer_test.go deleted file mode 100644 index bd83ef206078..000000000000 --- a/utils/timer/staged_timer_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package timer - -import ( - "sync" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestSingleStagedTimer(t *testing.T) { - wg := sync.WaitGroup{} - wg.Add(1) - ticks := 1 - i := 0 - timer := NewStagedTimer(func() (time.Duration, bool) { - defer wg.Done() - i++ - return 0, false - }) - go timer.Dispatch() - - timer.SetTimeoutIn(time.Millisecond) - wg.Wait() - require.Equal(t, i, ticks) -} - -func TestMultiStageTimer(t *testing.T) { - wg := sync.WaitGroup{} - ticks := 3 - wg.Add(ticks) - - i := 0 - timer := NewStagedTimer(func() (time.Duration, bool) { - defer wg.Done() - i++ - return time.Millisecond, i < ticks - }) - go timer.Dispatch() - - timer.SetTimeoutIn(time.Millisecond) - wg.Wait() - require.Equal(t, i, ticks) -} From a7541187e567d1121f52f07645a3903274896bac Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 7 Dec 2023 13:52:47 -0500 Subject: [PATCH 115/267] `merkledb` / `sync` -- Disambiguate no end root from no start root (#2437) --- x/merkledb/db.go | 2 ++ x/merkledb/history.go | 9 +++++++-- x/merkledb/history_test.go | 21 ++++++++++----------- x/merkledb/proof_test.go | 1 + x/sync/g_db/db_client.go | 3 +++ x/sync/network_server.go | 7 +++++++ x/sync/network_server_test.go | 2 +- 7 files changed, 31 insertions(+), 14 deletions(-) diff --git a/x/merkledb/db.go b/x/merkledb/db.go index c813a9478b1f..4e70c02fbd8f 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -64,6 +64,8 @@ type ChangeProofer interface { // Returns at most [maxLength] key/value pairs. // Returns [ErrInsufficientHistory] if this node has insufficient history // to generate the proof. + // Returns [ErrNoEndRoot], which wraps [ErrInsufficientHistory], if the + // history doesn't contain the [endRootID]. GetChangeProof( ctx context.Context, startRootID ids.ID, diff --git a/x/merkledb/history.go b/x/merkledb/history.go index c52385445cd2..dd4ff4f93c8c 100644 --- a/x/merkledb/history.go +++ b/x/merkledb/history.go @@ -15,7 +15,10 @@ import ( "github.com/ava-labs/avalanchego/utils/set" ) -var ErrInsufficientHistory = errors.New("insufficient history to generate proof") +var ( + ErrInsufficientHistory = errors.New("insufficient history to generate proof") + ErrNoEndRoot = fmt.Errorf("%w: end root not found", ErrInsufficientHistory) +) // stores previous trie states type trieHistory struct { @@ -77,6 +80,8 @@ func newTrieHistory(maxHistoryLookback int) *trieHistory { // If [end] is Nothing, there's no upper bound on the range. // Returns [ErrInsufficientHistory] if the history is insufficient // to generate the proof. +// Returns [ErrNoEndRoot], which wraps [ErrInsufficientHistory], if +// the [endRoot] isn't in the history. func (th *trieHistory) getValueChanges( startRoot ids.ID, endRoot ids.ID, @@ -99,7 +104,7 @@ func (th *trieHistory) getValueChanges( // lack the necessary history. endRootChanges, ok := th.lastChanges[endRoot] if !ok { - return nil, fmt.Errorf("%w: end root %s not found", ErrInsufficientHistory, endRoot) + return nil, fmt.Errorf("%w: %s", ErrNoEndRoot, endRoot) } // Confirm there's a change resulting in [startRoot] before diff --git a/x/merkledb/history_test.go b/x/merkledb/history_test.go index d2945c9c5018..3c8e8700d567 100644 --- a/x/merkledb/history_test.go +++ b/x/merkledb/history_test.go @@ -165,13 +165,13 @@ func Test_History_Bad_GetValueChanges_Input(t *testing.T) { require.NoError(batch.Put([]byte("key"), []byte("value"))) require.NoError(batch.Write()) - toBeDeletedRoot := db.getMerkleRoot() + root1 := db.getMerkleRoot() batch = db.NewBatch() require.NoError(batch.Put([]byte("key"), []byte("value0"))) require.NoError(batch.Write()) - startRoot := db.getMerkleRoot() + root2 := db.getMerkleRoot() batch = db.NewBatch() require.NoError(batch.Put([]byte("key1"), []byte("value0"))) @@ -185,31 +185,30 @@ func Test_History_Bad_GetValueChanges_Input(t *testing.T) { require.NoError(batch.Put([]byte("key2"), []byte("value3"))) require.NoError(batch.Write()) - endRoot := db.getMerkleRoot() + root3 := db.getMerkleRoot() // ensure these start as valid calls - _, err = db.history.getValueChanges(toBeDeletedRoot, endRoot, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 1) + _, err = db.history.getValueChanges(root1, root3, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 1) require.NoError(err) - _, err = db.history.getValueChanges(startRoot, endRoot, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 1) + _, err = db.history.getValueChanges(root2, root3, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 1) require.NoError(err) - _, err = db.history.getValueChanges(startRoot, endRoot, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), -1) + _, err = db.history.getValueChanges(root2, root3, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), -1) require.ErrorIs(err, ErrInvalidMaxLength) - _, err = db.history.getValueChanges(endRoot, startRoot, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 1) + _, err = db.history.getValueChanges(root3, root2, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 1) require.ErrorIs(err, ErrInsufficientHistory) - // trigger the first root to be deleted by exiting the lookback window + // Cause root1 to be removed from the history batch = db.NewBatch() require.NoError(batch.Put([]byte("key2"), []byte("value4"))) require.NoError(batch.Write()) - // now this root should no longer be present - _, err = db.history.getValueChanges(toBeDeletedRoot, endRoot, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 1) + _, err = db.history.getValueChanges(root1, root3, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 1) require.ErrorIs(err, ErrInsufficientHistory) // same start/end roots should yield an empty changelist - changes, err := db.history.getValueChanges(endRoot, endRoot, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 10) + changes, err := db.history.getValueChanges(root3, root3, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 10) require.NoError(err) require.Empty(changes.values) } diff --git a/x/merkledb/proof_test.go b/x/merkledb/proof_test.go index b22b80ffd09d..fbee117d4e68 100644 --- a/x/merkledb/proof_test.go +++ b/x/merkledb/proof_test.go @@ -654,6 +654,7 @@ func Test_ChangeProof_Missing_History_For_EndRoot(t *testing.T) { require.NoError(err) _, err = db.GetChangeProof(context.Background(), startRoot, ids.Empty, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 50) + require.ErrorIs(err, ErrNoEndRoot) require.ErrorIs(err, ErrInsufficientHistory) } diff --git a/x/sync/g_db/db_client.go b/x/sync/g_db/db_client.go index 64e63bb76652..af1ce1c9080b 100644 --- a/x/sync/g_db/db_client.go +++ b/x/sync/g_db/db_client.go @@ -63,6 +63,9 @@ func (c *DBClient) GetChangeProof( } // TODO handle merkledb.ErrInvalidMaxLength + // TODO disambiguate between the root not being present due to + // the end root not being present and the start root not being + // present before the end root. i.e. ErrNoEndRoot vs ErrInsufficientHistory. if resp.GetRootNotPresent() { return nil, merkledb.ErrInsufficientHistory } diff --git a/x/sync/network_server.go b/x/sync/network_server.go index c213bee6a739..8027a05042f1 100644 --- a/x/sync/network_server.go +++ b/x/sync/network_server.go @@ -198,8 +198,15 @@ func (s *NetworkServer) HandleChangeProofRequest( changeProof, err := s.db.GetChangeProof(ctx, startRoot, endRoot, start, end, int(keyLimit)) if err != nil { if !errors.Is(err, merkledb.ErrInsufficientHistory) { + // We should only fail to get a change proof if we have insufficient history. + // Other errors are unexpected. return err } + if errors.Is(err, merkledb.ErrNoEndRoot) { + // [s.db] doesn't have [endRoot] in its history. + // We can't generate a change/range proof. Drop this request. + return nil + } // [s.db] doesn't have sufficient history to generate change proof. // Generate a range proof for the end root ID instead. diff --git a/x/sync/network_server_test.go b/x/sync/network_server_test.go index d79b27a14c44..7b83afc3e7d5 100644 --- a/x/sync/network_server_test.go +++ b/x/sync/network_server_test.go @@ -263,7 +263,7 @@ func Test_Server_GetChangeProof(t *testing.T) { "insufficient history for change proof or range proof": { request: &pb.SyncGetChangeProofRequest{ // These roots don't exist so server has insufficient history - // to serve a change proof + // to serve a change proof or range proof StartRootHash: ids.Empty[:], EndRootHash: fakeRootID[:], KeyLimit: defaultRequestKeyLimit, From c9911578e9d1aa968dc4650747cc6a977cf18dae Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 7 Dec 2023 14:18:11 -0700 Subject: [PATCH 116/267] Drop Pending Stakers 2 - Replace txs.ScheduledStaker with txs.Staker (#2305) Co-authored-by: Stephen Buttolph --- .../block/executor/proposal_block_test.go | 32 ++++++++++++++----- .../block/executor/standard_block_test.go | 4 ++- vms/platformvm/service_test.go | 8 +++-- vms/platformvm/state/staker.go | 9 ++++-- vms/platformvm/state/staker_test.go | 9 +++--- vms/platformvm/state/state.go | 28 ++++++++++++---- .../txs/executor/advance_time_test.go | 4 ++- .../txs/executor/proposal_tx_executor_test.go | 20 +++++++++--- .../txs/executor/reward_validator_test.go | 32 ++++++++++++++----- .../txs/executor/standard_tx_executor_test.go | 24 ++++++++++---- 10 files changed, 125 insertions(+), 45 deletions(-) diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 77c36c08dec3..18a1131b6126 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -641,9 +641,11 @@ func TestBanffProposalBlockUpdateStakers(t *testing.T) { require.NoError(err) // store Staker0 to state + addValTx := addStaker0.Unsigned.(*txs.AddValidatorTx) staker0, err := state.NewCurrentStaker( addStaker0.ID(), - addStaker0.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) @@ -741,9 +743,11 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { ) require.NoError(err) + addSubnetValTx := tx.Unsigned.(*txs.AddSubnetValidatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddSubnetValidatorTx), + addSubnetValTx, + addSubnetValTx.StartTime(), 0, ) require.NoError(err) @@ -799,9 +803,11 @@ func TestBanffProposalBlockRemoveSubnetValidator(t *testing.T) { require.NoError(err) // store Staker0 to state + addValTx := addStaker0.Unsigned.(*txs.AddValidatorTx) staker, err = state.NewCurrentStaker( addStaker0.ID(), - addStaker0.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) @@ -912,9 +918,11 @@ func TestBanffProposalBlockTrackedSubnet(t *testing.T) { require.NoError(err) // store Staker0 to state + addValTx := addStaker0.Unsigned.(*txs.AddValidatorTx) staker, err = state.NewCurrentStaker( addStaker0.ID(), - addStaker0.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) @@ -999,9 +1007,11 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { require.NoError(err) // store Staker0 to state + addValTx := addStaker0.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( addStaker0.ID(), - addStaker0.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) @@ -1091,9 +1101,11 @@ func TestBanffProposalBlockDelegatorStakerWeight(t *testing.T) { require.NoError(err) // store Staker0 to state + addValTx = addStaker0.Unsigned.(*txs.AddValidatorTx) staker, err = state.NewCurrentStaker( addStaker0.ID(), - addStaker0.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) @@ -1182,9 +1194,11 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { require.NoError(err) // store Staker0 to state + addValTx := addStaker0.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( addStaker0.ID(), - addStaker0.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) @@ -1273,9 +1287,11 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { require.NoError(err) // store Staker0 to state + addValTx = addStaker0.Unsigned.(*txs.AddValidatorTx) staker, err = state.NewCurrentStaker( addStaker0.ID(), - addStaker0.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index af1a7562cdd0..7731d450a533 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -628,9 +628,11 @@ func TestBanffStandardBlockRemoveSubnetValidator(t *testing.T) { ) require.NoError(err) + addSubnetValTx := tx.Unsigned.(*txs.AddSubnetValidatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddSubnetValidatorTx), + addSubnetValTx, + addSubnetValTx.StartTime(), 0, ) require.NoError(err) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 8e2cc3790fc3..f5e61a9e4e72 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -507,9 +507,11 @@ func TestGetStake(t *testing.T) { ) require.NoError(err) + addDelTx := tx.Unsigned.(*txs.AddDelegatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddDelegatorTx), + addDelTx, + addDelTx.StartTime(), 0, ) require.NoError(err) @@ -643,9 +645,11 @@ func TestGetCurrentValidators(t *testing.T) { ) require.NoError(err) + addDelTx := delTx.Unsigned.(*txs.AddDelegatorTx) staker, err := state.NewCurrentStaker( delTx.ID(), - delTx.Unsigned.(*txs.AddDelegatorTx), + addDelTx, + addDelTx.StartTime(), 0, ) require.NoError(err) diff --git a/vms/platformvm/state/staker.go b/vms/platformvm/state/staker.go index 2488e4aff79e..ae070f3c91d2 100644 --- a/vms/platformvm/state/staker.go +++ b/vms/platformvm/state/staker.go @@ -83,7 +83,12 @@ func (s *Staker) Less(than *Staker) bool { return bytes.Compare(s.TxID[:], than.TxID[:]) == -1 } -func NewCurrentStaker(txID ids.ID, staker txs.ScheduledStaker, potentialReward uint64) (*Staker, error) { +func NewCurrentStaker( + txID ids.ID, + staker txs.Staker, + startTime time.Time, + potentialReward uint64, +) (*Staker, error) { publicKey, _, err := staker.PublicKey() if err != nil { return nil, err @@ -95,7 +100,7 @@ func NewCurrentStaker(txID ids.ID, staker txs.ScheduledStaker, potentialReward u PublicKey: publicKey, SubnetID: staker.SubnetID(), Weight: staker.Weight(), - StartTime: staker.StartTime(), + StartTime: startTime, EndTime: endTime, PotentialReward: potentialReward, NextTime: endTime, diff --git a/vms/platformvm/state/staker_test.go b/vms/platformvm/state/staker_test.go index 9482e33b793a..f4a7b8657997 100644 --- a/vms/platformvm/state/staker_test.go +++ b/vms/platformvm/state/staker_test.go @@ -148,16 +148,15 @@ func TestNewCurrentStaker(t *testing.T) { potentialReward := uint64(54321) currentPriority := txs.SubnetPermissionedValidatorCurrentPriority - stakerTx := txs.NewMockScheduledStaker(ctrl) + stakerTx := txs.NewMockStaker(ctrl) + stakerTx.EXPECT().EndTime().Return(endTime) stakerTx.EXPECT().NodeID().Return(nodeID) stakerTx.EXPECT().PublicKey().Return(publicKey, true, nil) stakerTx.EXPECT().SubnetID().Return(subnetID) stakerTx.EXPECT().Weight().Return(weight) - stakerTx.EXPECT().StartTime().Return(startTime) - stakerTx.EXPECT().EndTime().Return(endTime) stakerTx.EXPECT().CurrentPriority().Return(currentPriority) - staker, err := NewCurrentStaker(txID, stakerTx, potentialReward) + staker, err := NewCurrentStaker(txID, stakerTx, startTime, potentialReward) require.NotNil(staker) require.NoError(err) require.Equal(txID, staker.TxID) @@ -173,7 +172,7 @@ func TestNewCurrentStaker(t *testing.T) { stakerTx.EXPECT().PublicKey().Return(nil, false, errCustom) - _, err = NewCurrentStaker(txID, stakerTx, potentialReward) + _, err = NewCurrentStaker(txID, stakerTx, startTime, potentialReward) require.ErrorIs(err, errCustom) } diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 36a49428020c..c130326ef26b 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1346,7 +1346,7 @@ func (s *state) syncGenesis(genesisBlk block.Block, genesis *genesis.Genesis) er return err } - staker, err := NewCurrentStaker(vdrTx.ID(), validatorTx, potentialReward) + staker, err := NewCurrentStaker(vdrTx.ID(), validatorTx, validatorTx.StartTime(), potentialReward) if err != nil { return err } @@ -1457,7 +1457,7 @@ func (s *state) loadCurrentValidators() error { stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { - return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) + return fmt.Errorf("expected tx type txs.ScheduledStaker but got %T", tx.Unsigned) } metadataBytes := validatorIt.Value() @@ -1470,7 +1470,11 @@ func (s *state) loadCurrentValidators() error { return err } - staker, err := NewCurrentStaker(txID, stakerTx, metadata.PotentialReward) + staker, err := NewCurrentStaker( + txID, + stakerTx, + stakerTx.StartTime(), + metadata.PotentialReward) if err != nil { return err } @@ -1498,7 +1502,7 @@ func (s *state) loadCurrentValidators() error { stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { - return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) + return fmt.Errorf("expected tx type txs.ScheduledStaker but got %T", tx.Unsigned) } metadataBytes := subnetValidatorIt.Value() @@ -1513,7 +1517,12 @@ func (s *state) loadCurrentValidators() error { return err } - staker, err := NewCurrentStaker(txID, stakerTx, metadata.PotentialReward) + staker, err := NewCurrentStaker( + txID, + stakerTx, + startTime, + metadata.PotentialReward, + ) if err != nil { return err } @@ -1545,7 +1554,7 @@ func (s *state) loadCurrentValidators() error { stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { - return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) + return fmt.Errorf("expected tx type txs.ScheduledStaker but got %T", tx.Unsigned) } metadata := &delegatorMetadata{ @@ -1556,7 +1565,12 @@ func (s *state) loadCurrentValidators() error { return err } - staker, err := NewCurrentStaker(txID, stakerTx, metadata.PotentialReward) + staker, err := NewCurrentStaker( + txID, + stakerTx, + stakerTx.StartTime(), + metadata.PotentialReward, + ) if err != nil { return err } diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 694d6b7ff7fa..ad87af9a7fed 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -476,9 +476,11 @@ func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { ) require.NoError(err) + addSubnetValTx := tx.Unsigned.(*txs.AddSubnetValidatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddSubnetValidatorTx), + addSubnetValTx, + addSubnetValTx.StartTime(), 0, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index bc95f3ed39b2..cf05193983b5 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -46,9 +46,11 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { ) require.NoError(t, err) + addValTx := tx.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(t, err) @@ -74,9 +76,11 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { ) require.NoError(t, err) + addValTx := tx.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(t, err) @@ -398,9 +402,11 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { require.ErrorIs(err, ErrNotValidator) } + addValTx := addDSTx.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( addDSTx.ID(), - addDSTx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) @@ -551,9 +557,11 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { ) require.NoError(err) + addSubnetValTx := subnetTx.Unsigned.(*txs.AddSubnetValidatorTx) staker, err = state.NewCurrentStaker( subnetTx.ID(), - subnetTx.Unsigned.(*txs.AddSubnetValidatorTx), + addSubnetValTx, + addSubnetValTx.StartTime(), 0, ) require.NoError(err) @@ -680,9 +688,11 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { ) require.NoError(err) + addSubnetValTx := subnetTx.Unsigned.(*txs.AddSubnetValidatorTx) staker, err = state.NewCurrentStaker( subnetTx.ID(), - subnetTx.Unsigned.(*txs.AddSubnetValidatorTx), + addSubnetValTx, + addSubnetValTx.StartTime(), 0, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 5871b9eef531..4060bbbb9497 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -264,16 +264,20 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { ) require.NoError(err) + addValTx := vdrTx.Unsigned.(*txs.AddValidatorTx) vdrStaker, err := state.NewCurrentStaker( vdrTx.ID(), - vdrTx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) + addDelTx := delTx.Unsigned.(*txs.AddDelegatorTx) delStaker, err := state.NewCurrentStaker( delTx.ID(), - delTx.Unsigned.(*txs.AddDelegatorTx), + addDelTx, + addDelTx.StartTime(), 1000000, ) require.NoError(err) @@ -384,18 +388,22 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { ) require.NoError(err) + addValTx := vdrTx.Unsigned.(*txs.AddValidatorTx) vdrRewardAmt := uint64(2000000) vdrStaker, err := state.NewCurrentStaker( vdrTx.ID(), - vdrTx.Unsigned.(*txs.AddValidatorTx), + addValTx, + time.Unix(int64(vdrStartTime), 0), vdrRewardAmt, ) require.NoError(err) + addDelTx := delTx.Unsigned.(*txs.AddDelegatorTx) delRewardAmt := uint64(1000000) delStaker, err := state.NewCurrentStaker( delTx.ID(), - delTx.Unsigned.(*txs.AddDelegatorTx), + addDelTx, + time.Unix(int64(delStartTime), 0), delRewardAmt, ) require.NoError(err) @@ -599,18 +607,22 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * ) require.NoError(err) + addValTx := vdrTx.Unsigned.(*txs.AddValidatorTx) vdrRewardAmt := uint64(2000000) vdrStaker, err := state.NewCurrentStaker( vdrTx.ID(), - vdrTx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), vdrRewardAmt, ) require.NoError(err) + addDelTx := delTx.Unsigned.(*txs.AddDelegatorTx) delRewardAmt := uint64(1000000) delStaker, err := state.NewCurrentStaker( delTx.ID(), - delTx.Unsigned.(*txs.AddDelegatorTx), + addDelTx, + time.Unix(int64(delStartTime), 0), delRewardAmt, ) require.NoError(err) @@ -759,16 +771,20 @@ func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { ) require.NoError(err) + addValTx := vdrTx.Unsigned.(*txs.AddValidatorTx) vdrStaker, err := state.NewCurrentStaker( vdrTx.ID(), - vdrTx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(err) + addDelTx := delTx.Unsigned.(*txs.AddDelegatorTx) delStaker, err := state.NewCurrentStaker( delTx.ID(), - delTx.Unsigned.(*txs.AddDelegatorTx), + addDelTx, + addDelTx.StartTime(), 1000000, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 78e15078e133..d545c07d0a45 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -120,9 +120,11 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { ) require.NoError(t, err) + addValTx := tx.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(t, err) @@ -148,9 +150,11 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { ) require.NoError(t, err) + addValTx := tx.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), 0, ) require.NoError(t, err) @@ -481,9 +485,11 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { require.ErrorIs(err, ErrNotValidator) } + addValTx := addDSTx.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( addDSTx.ID(), - addDSTx.Unsigned.(*txs.AddValidatorTx), + addValTx, + dsStartTime, 0, ) require.NoError(err) @@ -617,9 +623,11 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { ) require.NoError(err) + addSubnetValTx := subnetTx.Unsigned.(*txs.AddSubnetValidatorTx) staker, err = state.NewCurrentStaker( subnetTx.ID(), - subnetTx.Unsigned.(*txs.AddSubnetValidatorTx), + addSubnetValTx, + defaultValidateStartTime, 0, ) require.NoError(err) @@ -771,9 +779,11 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { ) require.NoError(err) + addSubnetValTx := subnetTx.Unsigned.(*txs.AddSubnetValidatorTx) staker, err = state.NewCurrentStaker( subnetTx.ID(), - subnetTx.Unsigned.(*txs.AddSubnetValidatorTx), + addSubnetValTx, + defaultValidateStartTime, 0, ) require.NoError(err) @@ -875,9 +885,11 @@ func TestStandardTxExecutorAddValidator(t *testing.T) { ) require.NoError(err) + addValTx := tx.Unsigned.(*txs.AddValidatorTx) staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddValidatorTx), + addValTx, + startTime, 0, ) require.NoError(err) From eb570dd13485beb058facc74df63e055111cb3fb Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Fri, 8 Dec 2023 13:36:20 -0500 Subject: [PATCH 117/267] `vms/platformvm`: Remove double block building logic (#2380) Signed-off-by: Stephen Buttolph Co-authored-by: Stephen Buttolph Co-authored-by: aaronbuchwald --- vms/platformvm/block/builder/builder.go | 239 ++++++++++-------- vms/platformvm/block/builder/builder_test.go | 4 + vms/platformvm/block/builder/helpers_test.go | 3 +- .../block/builder/standard_block_test.go | 1 + vms/platformvm/block/executor/rejector.go | 2 +- vms/platformvm/network/network.go | 2 +- vms/platformvm/vm.go | 4 +- 7 files changed, 147 insertions(+), 108 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 79c05992bf53..dd46253aeb4e 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -7,13 +7,13 @@ import ( "context" "errors" "fmt" + "sync" "time" "go.uber.org/zap" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" - "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/block" @@ -33,24 +33,31 @@ const targetBlockSize = 128 * units.KiB var ( _ Builder = (*builder)(nil) - ErrEndOfTime = errors.New("program time is suspiciously far in the future") - ErrNoPendingBlocks = errors.New("no pending blocks") + ErrEndOfTime = errors.New("program time is suspiciously far in the future") + ErrNoPendingBlocks = errors.New("no pending blocks") + errMissingPreferredState = errors.New("missing preferred block state") + errCalculatingNextStakerTime = errors.New("failed calculating next staker time") ) type Builder interface { mempool.Mempool - // ResetBlockTimer schedules a timer to notify the consensus engine once - // there is a block ready to be built. If a block is ready to be built when - // this function is called, the engine will be notified directly. + // StartBlockTimer starts to issue block creation requests to advance the + // chain timestamp. + StartBlockTimer() + + // ResetBlockTimer forces the block timer to recalculate when it should + // advance the chain timestamp. ResetBlockTimer() - // BuildBlock is called on timer clock to attempt to create - // next block - BuildBlock(context.Context) (snowman.Block, error) + // ShutdownBlockTimer stops block creation requests to advance the chain + // timestamp. + // + // Invariant: Assumes the context lock is held when calling. + ShutdownBlockTimer() - // Shutdown cleanly shuts Builder down - Shutdown() + // BuildBlock can be called to attempt to create a new block + BuildBlock(context.Context) (snowman.Block, error) } // builder implements a simple builder to convert txs into valid blocks @@ -61,10 +68,11 @@ type builder struct { txExecutorBackend *txexecutor.Backend blkManager blockexecutor.Manager - // This timer goes off when it is time for the next validator to add/leave - // the validator set. When it goes off ResetTimer() is called, potentially - // triggering creation of a new block. - timer *timer.Timer + // resetTimer is used to signal that the block builder timer should update + // when it will trigger building of a block. + resetTimer chan struct{} + closed chan struct{} + closeOnce sync.Once } func New( @@ -73,17 +81,111 @@ func New( txExecutorBackend *txexecutor.Backend, blkManager blockexecutor.Manager, ) Builder { - builder := &builder{ + return &builder{ Mempool: mempool, txBuilder: txBuilder, txExecutorBackend: txExecutorBackend, blkManager: blkManager, + resetTimer: make(chan struct{}, 1), + closed: make(chan struct{}), + } +} + +func (b *builder) StartBlockTimer() { + go func() { + timer := time.NewTimer(0) + defer timer.Stop() + + for { + // Invariant: The [timer] is not stopped. + select { + case <-timer.C: + case <-b.resetTimer: + if !timer.Stop() { + <-timer.C + } + case <-b.closed: + return + } + + // Note: Because the context lock is not held here, it is possible + // that [ShutdownBlockTimer] is called concurrently with this + // execution. + for { + duration, err := b.durationToSleep() + if err != nil { + b.txExecutorBackend.Ctx.Log.Error("block builder encountered a fatal error", + zap.Error(err), + ) + return + } + + if duration > 0 { + timer.Reset(duration) + break + } + + // Block needs to be issued to advance time. + b.Mempool.RequestBuildBlock(true /*=emptyBlockPermitted*/) + + // Invariant: ResetBlockTimer is guaranteed to be called after + // [durationToSleep] returns a value <= 0. This is because we + // are guaranteed to attempt to build block. After building a + // valid block, the chain will have its preference updated which + // may change the duration to sleep and trigger a timer reset. + select { + case <-b.resetTimer: + case <-b.closed: + return + } + } + } + }() +} + +func (b *builder) durationToSleep() (time.Duration, error) { + // Grabbing the lock here enforces that this function is not called mid-way + // through modifying of the state. + b.txExecutorBackend.Ctx.Lock.Lock() + defer b.txExecutorBackend.Ctx.Lock.Unlock() + + // If [ShutdownBlockTimer] was called, we want to exit the block timer + // goroutine. We check this with the context lock held because + // [ShutdownBlockTimer] is expected to only be called with the context lock + // held. + select { + case <-b.closed: + return 0, nil + default: + } + + preferredID := b.blkManager.Preferred() + preferredState, ok := b.blkManager.GetState(preferredID) + if !ok { + return 0, fmt.Errorf("%w: %s", errMissingPreferredState, preferredID) + } + + nextStakerChangeTime, err := txexecutor.GetNextStakerChangeTime(preferredState) + if err != nil { + return 0, fmt.Errorf("%w of %s: %w", errCalculatingNextStakerTime, preferredID, err) } - builder.timer = timer.NewTimer(builder.setNextBuildBlockTime) + now := b.txExecutorBackend.Clk.Time() + return nextStakerChangeTime.Sub(now), nil +} + +func (b *builder) ResetBlockTimer() { + // Ensure that the timer will be reset at least once. + select { + case b.resetTimer <- struct{}{}: + default: + } +} - go txExecutorBackend.Ctx.Log.RecoverAndPanic(builder.timer.Dispatch) - return builder +func (b *builder) ShutdownBlockTimer() { + b.closeOnce.Do(func() { + close(b.closed) + }) } // BuildBlock builds a block to be added to consensus. @@ -93,27 +195,18 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { b.Mempool.DisableAdding() defer func() { b.Mempool.EnableAdding() + // If we need to advance the chain's timestamp in a standard block, but + // we build an invalid block, then we need to re-trigger block building. + // + // TODO: Remove once we are guaranteed to build a valid block. b.ResetBlockTimer() + // If there are still transactions in the mempool, then we need to + // re-trigger block building. + b.Mempool.RequestBuildBlock(false /*=emptyBlockPermitted*/) }() - ctx := b.txExecutorBackend.Ctx - ctx.Log.Debug("starting to attempt to build a block") - - statelessBlk, err := b.buildBlock() - if err != nil { - return nil, err - } - - // Remove selected txs from mempool now that we are returning the block to - // the consensus engine. - txs := statelessBlk.Txs() - b.Mempool.Remove(txs) - return b.blkManager.NewBlock(statelessBlk), nil -} + b.txExecutorBackend.Ctx.Log.Debug("starting to attempt to build a block") -// Returns the block we want to build and issue. -// Only modifies state to remove expired proposal txs. -func (b *builder) buildBlock() (block.Block, error) { // Get the block to build on top of and retrieve the new block's context. preferredID := b.blkManager.Preferred() preferred, err := b.blkManager.GetBlock(preferredID) @@ -131,7 +224,7 @@ func (b *builder) buildBlock() (block.Block, error) { return nil, fmt.Errorf("could not calculate next staker change time: %w", err) } - return buildBlock( + statelessBlk, err := buildBlock( b, preferredID, nextHeight, @@ -139,75 +232,15 @@ func (b *builder) buildBlock() (block.Block, error) { timeWasCapped, preferredState, ) -} - -func (b *builder) Shutdown() { - // There is a potential deadlock if the timer is about to execute a timeout. - // So, the lock must be released before stopping the timer. - ctx := b.txExecutorBackend.Ctx - ctx.Lock.Unlock() - b.timer.Stop() - ctx.Lock.Lock() -} - -func (b *builder) ResetBlockTimer() { - // Next time the context lock is released, we can attempt to reset the block - // timer. - b.timer.SetTimeoutIn(0) -} - -func (b *builder) setNextBuildBlockTime() { - ctx := b.txExecutorBackend.Ctx - - // Grabbing the lock here enforces that this function is not called mid-way - // through modifying of the state. - ctx.Lock.Lock() - defer ctx.Lock.Unlock() - - if !b.txExecutorBackend.Bootstrapped.Get() { - ctx.Log.Verbo("skipping block timer reset", - zap.String("reason", "not bootstrapped"), - ) - return - } - - if _, err := b.buildBlock(); err == nil { - // We can build a block now - b.Mempool.RequestBuildBlock(true /*=emptyBlockPermitted*/) - return - } - - // Wake up when it's time to add/remove the next validator/delegator - preferredID := b.blkManager.Preferred() - preferredState, ok := b.blkManager.GetState(preferredID) - if !ok { - // The preferred block should always be a decision block - ctx.Log.Error("couldn't get preferred block state", - zap.Stringer("preferredID", preferredID), - zap.Stringer("lastAcceptedID", b.blkManager.LastAccepted()), - ) - return - } - - nextStakerChangeTime, err := txexecutor.GetNextStakerChangeTime(preferredState) if err != nil { - ctx.Log.Error("couldn't get next staker change time", - zap.Stringer("preferredID", preferredID), - zap.Stringer("lastAcceptedID", b.blkManager.LastAccepted()), - zap.Error(err), - ) - return + return nil, err } - now := b.txExecutorBackend.Clk.Time() - waitTime := nextStakerChangeTime.Sub(now) - ctx.Log.Debug("setting next scheduled event", - zap.Time("nextEventTime", nextStakerChangeTime), - zap.Duration("timeUntil", waitTime), - ) - - // Wake up when it's time to add/remove the next validator - b.timer.SetTimeoutIn(waitTime) + // Remove selected txs from mempool now that we are returning the block to + // the consensus engine. + txs := statelessBlk.Txs() + b.Mempool.Remove(txs) + return b.blkManager.NewBlock(statelessBlk), nil } // [timestamp] is min(max(now, parent timestamp), next staker change time) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 434d5b7b2552..3a030cdedcce 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -38,6 +38,7 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() }() // Create a valid transaction @@ -78,6 +79,7 @@ func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() }() // Create a valid transaction @@ -130,6 +132,7 @@ func TestNoErrorOnUnexpectedSetPreferenceDuringBootstrapping(t *testing.T) { env.isBootstrapped.Set(false) defer func() { require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() }() require.True(env.blkManager.SetPreference(ids.GenerateTestID())) // should not panic @@ -322,6 +325,7 @@ func TestBuildBlock(t *testing.T) { env.ctx.Lock.Lock() defer func() { require.NoError(t, shutdownEnvironment(env)) + env.ctx.Lock.Unlock() }() var ( diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 36a6822ce3e2..529c06a52d1b 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -194,6 +194,7 @@ func newEnvironment(t *testing.T) *environment { &res.backend, res.blkManager, ) + res.Builder.StartBlockTimer() res.blkManager.SetPreference(genesisID) addSubnet(t, res) @@ -419,7 +420,7 @@ func buildGenesisTest(t *testing.T, ctx *snow.Context) []byte { } func shutdownEnvironment(env *environment) error { - env.Builder.Shutdown() + env.Builder.ShutdownBlockTimer() if env.isBootstrapped.Get() { validatorIDs := env.config.Validators.GetValidatorIDs(constants.PrimaryNetworkID) diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index 827d7357728b..74177e1f88b0 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -26,6 +26,7 @@ func TestAtomicTxImports(t *testing.T) { env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() }() utxoID := avax.UTXOID{ diff --git a/vms/platformvm/block/executor/rejector.go b/vms/platformvm/block/executor/rejector.go index cfc64b050be4..6b2565288fca 100644 --- a/vms/platformvm/block/executor/rejector.go +++ b/vms/platformvm/block/executor/rejector.go @@ -82,7 +82,7 @@ func (r *rejector) rejectBlock(b block.Block, blockType string) error { } } - r.Mempool.RequestBuildBlock(false) + r.Mempool.RequestBuildBlock(false /*=emptyBlockPermitted*/) return nil } diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index 5f4945093d60..4600cce7f581 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -181,7 +181,7 @@ func (n *network) issueTx(tx *txs.Tx) error { return err } - n.mempool.RequestBuildBlock(false) + n.mempool.RequestBuildBlock(false /*=emptyBlockPermitted*/) return nil } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index d9898b873137..4c1e10c645d6 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -330,7 +330,7 @@ func (vm *VM) onNormalOperationsStarted() error { } // Start the block builder - vm.Builder.ResetBlockTimer() + vm.Builder.StartBlockTimer() return nil } @@ -351,7 +351,7 @@ func (vm *VM) Shutdown(context.Context) error { return nil } - vm.Builder.Shutdown() + vm.Builder.ShutdownBlockTimer() if vm.bootstrapped.Get() { primaryVdrIDs := vm.Validators.GetValidatorIDs(constants.PrimaryNetworkID) From dd2c6efe07f47598d6a3287f6b37eb61dfcad2f1 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 8 Dec 2023 15:40:09 -0500 Subject: [PATCH 118/267] Remove usage of timer.Timer in benchlist (#2446) --- snow/networking/benchlist/benchlist.go | 150 ++++++++++++-------- snow/networking/benchlist/benchlist_test.go | 57 +++----- 2 files changed, 109 insertions(+), 98 deletions(-) diff --git a/snow/networking/benchlist/benchlist.go b/snow/networking/benchlist/benchlist.go index 394899a1f37a..15b42b76b467 100644 --- a/snow/networking/benchlist/benchlist.go +++ b/snow/networking/benchlist/benchlist.go @@ -16,7 +16,6 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/heap" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/utils/timer/mockable" safemath "github.com/ava-labs/avalanchego/utils/math" @@ -54,9 +53,8 @@ type benchlist struct { ctx *snow.ConsensusContext metrics metrics - // Fires when the next validator should leave the bench - // Calls [update] when it fires - timer *timer.Timer + // Used to notify the timer that it should recalculate when it should fire + resetTimer chan struct{} // Tells the time. Can be faked for testing. clock mockable.Clock @@ -105,8 +103,10 @@ func NewBenchlist( if maxPortion < 0 || maxPortion >= 1 { return nil, fmt.Errorf("max portion of benched stake must be in [0,1) but got %f", maxPortion) } + benchlist := &benchlist{ ctx: ctx, + resetTimer: make(chan struct{}, 1), failureStreaks: make(map[ids.NodeID]failureStreak), benchlistSet: set.Set[ids.NodeID]{}, benchable: benchable, @@ -117,38 +117,77 @@ func NewBenchlist( duration: duration, maxPortion: maxPortion, } - benchlist.timer = timer.NewTimer(benchlist.update) - go benchlist.timer.Dispatch() - return benchlist, benchlist.metrics.Initialize(ctx.Registerer) + if err := benchlist.metrics.Initialize(ctx.Registerer); err != nil { + return nil, err + } + + go benchlist.run() + return benchlist, nil +} + +// TODO: Close this goroutine during node shutdown +func (b *benchlist) run() { + timer := time.NewTimer(0) + defer timer.Stop() + + for { + // Invariant: The [timer] is not stopped. + select { + case <-timer.C: + case <-b.resetTimer: + if !timer.Stop() { + <-timer.C + } + } + + b.waitForBenchedNodes() + + b.removedExpiredNodes() + + // Note: If there are no nodes to remove, [duration] will be 0 and we + // will immediately wait until there are benched nodes. + duration := b.durationToSleep() + timer.Reset(duration) + } } -// Update removes benched validators whose time on the bench is over -func (b *benchlist) update() { +func (b *benchlist) waitForBenchedNodes() { + for { + b.lock.RLock() + _, _, ok := b.benchedHeap.Peek() + b.lock.RUnlock() + if ok { + return + } + + // Invariant: Whenever a new node is benched we ensure that resetTimer + // has a pending message while the write lock is held. + <-b.resetTimer + } +} + +func (b *benchlist) removedExpiredNodes() { b.lock.Lock() defer b.lock.Unlock() now := b.clock.Time() for { - if !b.canUnbench(now) { + _, next, ok := b.benchedHeap.Peek() + if !ok { + break + } + if now.Before(next) { break } - b.remove() - } - // Set next time update will be called - b.setNextLeaveTime() -} -// Removes the next node from the benchlist -// Assumes [b.lock] is held -func (b *benchlist) remove() { - nodeID, _, _ := b.benchedHeap.Pop() - b.ctx.Log.Debug("removing node from benchlist", - zap.Stringer("nodeID", nodeID), - ) - b.benchlistSet.Remove(nodeID) - b.benchable.Unbenched(b.ctx.ChainID, nodeID) + nodeID, _, _ := b.benchedHeap.Pop() + b.ctx.Log.Debug("removing node from benchlist", + zap.Stringer("nodeID", nodeID), + ) + b.benchlistSet.Remove(nodeID) + b.benchable.Unbenched(b.ctx.ChainID, nodeID) + } - // Update metrics b.metrics.numBenched.Set(float64(b.benchedHeap.Len())) benchedStake, err := b.vdrs.SubsetWeight(b.ctx.SubnetID, b.benchlistSet) if err != nil { @@ -161,56 +200,37 @@ func (b *benchlist) remove() { b.metrics.weightBenched.Set(float64(benchedStake)) } -// Returns if a validator should leave the bench at time [now]. -// False if no validator should. -// Assumes [b.lock] is held -func (b *benchlist) canUnbench(now time.Time) bool { - _, next, ok := b.benchedHeap.Peek() - if !ok { - return false - } - return now.After(next) -} +func (b *benchlist) durationToSleep() time.Duration { + b.lock.RLock() + defer b.lock.RUnlock() -// Set [b.timer] to fire when the next validator should leave the bench -// Assumes [b.lock] is held -func (b *benchlist) setNextLeaveTime() { _, next, ok := b.benchedHeap.Peek() if !ok { - b.timer.Cancel() - return + return 0 } + now := b.clock.Time() - nextLeave := next.Sub(now) - b.timer.SetTimeoutIn(nextLeave) + return next.Sub(now) } -// IsBenched returns true if messages to [nodeID] -// should not be sent over the network and should immediately fail. +// IsBenched returns true if messages to [nodeID] should not be sent over the +// network and should immediately fail. func (b *benchlist) IsBenched(nodeID ids.NodeID) bool { b.lock.RLock() defer b.lock.RUnlock() - return b.isBenched(nodeID) -} -// isBenched checks if [nodeID] is currently benched -// and calls cleanup if its benching period has elapsed -// Assumes [b.lock] is held. -func (b *benchlist) isBenched(nodeID ids.NodeID) bool { - if _, ok := b.benchlistSet[nodeID]; ok { - return true - } - return false + return b.benchlistSet.Contains(nodeID) } -// RegisterResponse notes that we received a response from validator [validatorID] +// RegisterResponse notes that we received a response from [nodeID] func (b *benchlist) RegisterResponse(nodeID ids.NodeID) { b.streaklock.Lock() defer b.streaklock.Unlock() + delete(b.failureStreaks, nodeID) } -// RegisterResponse notes that a request to validator [validatorID] timed out +// RegisterResponse notes that a request to [nodeID] timed out func (b *benchlist) RegisterFailure(nodeID ids.NodeID) { b.lock.Lock() defer b.lock.Unlock() @@ -295,6 +315,12 @@ func (b *benchlist) bench(nodeID ids.NodeID) { diff := maxBenchedUntil.Sub(minBenchedUntil) benchedUntil := minBenchedUntil.Add(time.Duration(rand.Float64() * float64(diff))) // #nosec G404 + b.ctx.Log.Debug("benching validator after consecutive failed queries", + zap.Stringer("nodeID", nodeID), + zap.Duration("benchDuration", benchedUntil.Sub(now)), + zap.Int("numFailedQueries", b.threshold), + ) + // Add to benchlist times with randomized delay b.benchlistSet.Add(nodeID) b.benchable.Benched(b.ctx.ChainID, nodeID) @@ -304,14 +330,12 @@ func (b *benchlist) bench(nodeID ids.NodeID) { b.streaklock.Unlock() b.benchedHeap.Push(nodeID, benchedUntil) - b.ctx.Log.Debug("benching validator after consecutive failed queries", - zap.Stringer("nodeID", nodeID), - zap.Duration("benchDuration", benchedUntil.Sub(now)), - zap.Int("numFailedQueries", b.threshold), - ) - // Set [b.timer] to fire when next validator should leave bench - b.setNextLeaveTime() + // Update the timer to account for the newly benched node. + select { + case b.resetTimer <- struct{}{}: + default: + } // Update metrics b.metrics.numBenched.Set(float64(b.benchedHeap.Len())) diff --git a/snow/networking/benchlist/benchlist_test.go b/snow/networking/benchlist/benchlist_test.go index 75df4f454292..394d38c8e8c1 100644 --- a/snow/networking/benchlist/benchlist_test.go +++ b/snow/networking/benchlist/benchlist_test.go @@ -51,20 +51,14 @@ func TestBenchlistAdd(t *testing.T) { ) require.NoError(err) b := benchIntf.(*benchlist) - defer b.timer.Stop() now := time.Now() b.clock.Set(now) // Nobody should be benched at the start b.lock.Lock() - require.False(b.isBenched(vdrID0)) - require.False(b.isBenched(vdrID1)) - require.False(b.isBenched(vdrID2)) - require.False(b.isBenched(vdrID3)) - require.False(b.isBenched(vdrID4)) + require.Empty(b.benchlistSet) require.Empty(b.failureStreaks) require.Zero(b.benchedHeap.Len()) - require.Empty(b.benchlistSet) b.lock.Unlock() // Register [threshold - 1] failures in a row for vdr0 @@ -73,9 +67,8 @@ func TestBenchlistAdd(t *testing.T) { } // Still shouldn't be benched due to not enough consecutive failure - require.False(b.isBenched(vdrID0)) - require.Zero(b.benchedHeap.Len()) require.Empty(b.benchlistSet) + require.Zero(b.benchedHeap.Len()) require.Len(b.failureStreaks, 1) fs := b.failureStreaks[vdrID0] require.Equal(threshold-1, fs.consecutive) @@ -87,9 +80,8 @@ func TestBenchlistAdd(t *testing.T) { // Still shouldn't be benched because not enough time (any in this case) // has passed since the first failure b.lock.Lock() - require.False(b.isBenched(vdrID0)) - require.Zero(b.benchedHeap.Len()) require.Empty(b.benchlistSet) + require.Zero(b.benchedHeap.Len()) b.lock.Unlock() // Move the time up @@ -108,9 +100,9 @@ func TestBenchlistAdd(t *testing.T) { // Now this validator should be benched b.lock.Lock() - require.True(b.isBenched(vdrID0)) - require.Equal(b.benchedHeap.Len(), 1) - require.Equal(b.benchlistSet.Len(), 1) + require.Contains(b.benchlistSet, vdrID0) + require.Equal(1, b.benchedHeap.Len()) + require.Equal(1, b.benchlistSet.Len()) nodeID, benchedUntil, ok := b.benchedHeap.Peek() require.True(ok) @@ -133,10 +125,9 @@ func TestBenchlistAdd(t *testing.T) { // vdr1 shouldn't be benched // The response should have cleared its consecutive failures b.lock.Lock() - require.True(b.isBenched(vdrID0)) - require.False(b.isBenched(vdrID1)) - require.Equal(b.benchedHeap.Len(), 1) - require.Equal(b.benchlistSet.Len(), 1) + require.Contains(b.benchlistSet, vdrID0) + require.Equal(1, b.benchedHeap.Len()) + require.Equal(1, b.benchlistSet.Len()) require.Empty(b.failureStreaks) b.lock.Unlock() @@ -183,7 +174,6 @@ func TestBenchlistMaxStake(t *testing.T) { ) require.NoError(err) b := benchIntf.(*benchlist) - defer b.timer.Stop() now := time.Now() b.clock.Set(now) @@ -209,11 +199,10 @@ func TestBenchlistMaxStake(t *testing.T) { // Benching vdr2 (weight 1000) would cause the amount benched // to exceed the maximum b.lock.Lock() - require.True(b.isBenched(vdrID0)) - require.True(b.isBenched(vdrID1)) - require.False(b.isBenched(vdrID2)) - require.Equal(b.benchedHeap.Len(), 2) - require.Equal(b.benchlistSet.Len(), 2) + require.Contains(b.benchlistSet, vdrID0) + require.Contains(b.benchlistSet, vdrID1) + require.Equal(2, b.benchedHeap.Len()) + require.Equal(2, b.benchlistSet.Len()) require.Len(b.failureStreaks, 1) fs := b.failureStreaks[vdrID2] fs.consecutive = threshold @@ -236,9 +225,9 @@ func TestBenchlistMaxStake(t *testing.T) { // vdr4 should be benched now b.lock.Lock() - require.True(b.isBenched(vdrID0)) - require.True(b.isBenched(vdrID1)) - require.True(b.isBenched(vdrID4)) + require.Contains(b.benchlistSet, vdrID0) + require.Contains(b.benchlistSet, vdrID1) + require.Contains(b.benchlistSet, vdrID4) require.Equal(3, b.benchedHeap.Len()) require.Equal(3, b.benchlistSet.Len()) require.Contains(b.benchlistSet, vdrID0) @@ -254,10 +243,9 @@ func TestBenchlistMaxStake(t *testing.T) { } b.lock.Lock() - require.True(b.isBenched(vdrID0)) - require.True(b.isBenched(vdrID1)) - require.True(b.isBenched(vdrID4)) - require.False(b.isBenched(vdrID2)) + require.Contains(b.benchlistSet, vdrID0) + require.Contains(b.benchlistSet, vdrID1) + require.Contains(b.benchlistSet, vdrID4) require.Equal(3, b.benchedHeap.Len()) require.Equal(3, b.benchlistSet.Len()) require.Len(b.failureStreaks, 1) @@ -307,7 +295,6 @@ func TestBenchlistRemove(t *testing.T) { ) require.NoError(err) b := benchIntf.(*benchlist) - defer b.timer.Stop() now := time.Now() b.lock.Lock() b.clock.Set(now) @@ -332,9 +319,9 @@ func TestBenchlistRemove(t *testing.T) { // All 3 should be benched b.lock.Lock() - require.True(b.isBenched(vdrID0)) - require.True(b.isBenched(vdrID1)) - require.True(b.isBenched(vdrID2)) + require.Contains(b.benchlistSet, vdrID0) + require.Contains(b.benchlistSet, vdrID1) + require.Contains(b.benchlistSet, vdrID2) require.Equal(3, b.benchedHeap.Len()) require.Equal(3, b.benchlistSet.Len()) require.Empty(b.failureStreaks) From 80fa254b7e24efa10e9bab5626e84c6c88bb9344 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Sat, 9 Dec 2023 18:17:24 -0500 Subject: [PATCH 119/267] `vms/avm`: Simplify `Peek` function in mempool (#2449) Co-authored-by: Stephen Buttolph --- vms/avm/block/builder/builder.go | 8 ++++++-- vms/avm/block/builder/builder_test.go | 26 ++++++++++++------------- vms/avm/txs/mempool/mempool.go | 17 +++++----------- vms/avm/txs/mempool/mempool_test.go | 28 +++++++++++++++++++++++++++ vms/avm/txs/mempool/mock_mempool.go | 8 ++++---- 5 files changed, 56 insertions(+), 31 deletions(-) diff --git a/vms/avm/block/builder/builder.go b/vms/avm/block/builder/builder.go index a3129d797808..093457c969fe 100644 --- a/vms/avm/block/builder/builder.go +++ b/vms/avm/block/builder/builder.go @@ -93,8 +93,12 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { remainingSize = targetBlockSize ) for { - tx := b.mempool.Peek(remainingSize) - if tx == nil { + tx := b.mempool.Peek() + // Invariant: [mempool.MaxTxSize] < [targetBlockSize]. This guarantees + // that we will only stop building a block once there are no + // transactions in the mempool or the block is at least + // [targetBlockSize - mempool.MaxTxSize] bytes full. + if tx == nil || len(tx.Bytes()) > remainingSize { break } b.mempool.Remove([]*txs.Tx{tx}) diff --git a/vms/avm/block/builder/builder_test.go b/vms/avm/block/builder/builder_test.go index 7faeddbe71e6..a6778a4564bc 100644 --- a/vms/avm/block/builder/builder_test.go +++ b/vms/avm/block/builder/builder_test.go @@ -134,11 +134,11 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek(gomock.Any()).Return(tx) + mempool.EXPECT().Peek().Return(tx) mempool.EXPECT().Remove([]*txs.Tx{tx}) mempool.EXPECT().MarkDropped(tx.ID(), errTest) // Second loop iteration - mempool.EXPECT().Peek(gomock.Any()).Return(nil) + mempool.EXPECT().Peek().Return(nil) mempool.EXPECT().RequestBuildBlock() return New( @@ -179,11 +179,11 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek(gomock.Any()).Return(tx) + mempool.EXPECT().Peek().Return(tx) mempool.EXPECT().Remove([]*txs.Tx{tx}) mempool.EXPECT().MarkDropped(tx.ID(), errTest) // Second loop iteration - mempool.EXPECT().Peek(gomock.Any()).Return(nil) + mempool.EXPECT().Peek().Return(nil) mempool.EXPECT().RequestBuildBlock() return New( @@ -225,11 +225,11 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek(gomock.Any()).Return(tx) + mempool.EXPECT().Peek().Return(tx) mempool.EXPECT().Remove([]*txs.Tx{tx}) mempool.EXPECT().MarkDropped(tx.ID(), errTest) // Second loop iteration - mempool.EXPECT().Peek(gomock.Any()).Return(nil) + mempool.EXPECT().Peek().Return(nil) mempool.EXPECT().RequestBuildBlock() return New( @@ -309,14 +309,14 @@ func TestBuilderBuildBlock(t *testing.T) { ) mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek(targetBlockSize).Return(tx1) + mempool.EXPECT().Peek().Return(tx1) mempool.EXPECT().Remove([]*txs.Tx{tx1}) // Second loop iteration - mempool.EXPECT().Peek(targetBlockSize - len(tx1Bytes)).Return(tx2) + mempool.EXPECT().Peek().Return(tx2) mempool.EXPECT().Remove([]*txs.Tx{tx2}) mempool.EXPECT().MarkDropped(tx2.ID(), blkexecutor.ErrConflictingBlockTxs) // Third loop iteration - mempool.EXPECT().Peek(targetBlockSize - len(tx1Bytes)).Return(nil) + mempool.EXPECT().Peek().Return(nil) mempool.EXPECT().RequestBuildBlock() // To marshal the tx/block @@ -385,10 +385,10 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek(gomock.Any()).Return(tx) + mempool.EXPECT().Peek().Return(tx) mempool.EXPECT().Remove([]*txs.Tx{tx}) // Second loop iteration - mempool.EXPECT().Peek(gomock.Any()).Return(nil) + mempool.EXPECT().Peek().Return(nil) mempool.EXPECT().RequestBuildBlock() // To marshal the tx/block @@ -459,10 +459,10 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek(gomock.Any()).Return(tx) + mempool.EXPECT().Peek().Return(tx) mempool.EXPECT().Remove([]*txs.Tx{tx}) // Second loop iteration - mempool.EXPECT().Peek(gomock.Any()).Return(nil) + mempool.EXPECT().Peek().Return(nil) mempool.EXPECT().RequestBuildBlock() // To marshal the tx/block diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index 84a3583781ef..538f784b652b 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -48,8 +48,8 @@ type Mempool interface { Get(txID ids.ID) *txs.Tx Remove(txs []*txs.Tx) - // Peek returns the first tx in the mempool whose size is <= [maxTxSize]. - Peek(maxTxSize int) *txs.Tx + // Peek returns the oldest tx in the mempool. + Peek() *txs.Tx // RequestBuildBlock notifies the consensus engine that a block should be // built if there is at least one transaction in the mempool. @@ -182,16 +182,9 @@ func (m *mempool) Remove(txsToRemove []*txs.Tx) { } } -func (m *mempool) Peek(maxTxSize int) *txs.Tx { - txIter := m.unissuedTxs.NewIterator() - for txIter.Next() { - tx := txIter.Value() - txSize := len(tx.Bytes()) - if txSize <= maxTxSize { - return tx - } - } - return nil +func (m *mempool) Peek() *txs.Tx { + _, tx, _ := m.unissuedTxs.Oldest() + return tx } func (m *mempool) RequestBuildBlock() { diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index 4e1396ac3d41..86f3e0d5cf5f 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -170,3 +170,31 @@ func createTestTxs(count int) []*txs.Tx { } return testTxs } + +func TestPeekTxs(t *testing.T) { + require := require.New(t) + + registerer := prometheus.NewRegistry() + toEngine := make(chan common.Message, 100) + mempool, err := New("mempool", registerer, toEngine) + require.NoError(err) + + testTxs := createTestTxs(2) + + require.Nil(mempool.Peek()) + + require.NoError(mempool.Add(testTxs[0])) + require.NoError(mempool.Add(testTxs[1])) + + require.Equal(mempool.Peek(), testTxs[0]) + require.NotEqual(mempool.Peek(), testTxs[1]) + + mempool.Remove([]*txs.Tx{testTxs[0]}) + + require.NotEqual(mempool.Peek(), testTxs[0]) + require.Equal(mempool.Peek(), testTxs[1]) + + mempool.Remove([]*txs.Tx{testTxs[1]}) + + require.Nil(mempool.Peek()) +} diff --git a/vms/avm/txs/mempool/mock_mempool.go b/vms/avm/txs/mempool/mock_mempool.go index e84f01e0875e..ada05b2c6501 100644 --- a/vms/avm/txs/mempool/mock_mempool.go +++ b/vms/avm/txs/mempool/mock_mempool.go @@ -107,17 +107,17 @@ func (mr *MockMempoolMockRecorder) MarkDropped(arg0, arg1 interface{}) *gomock.C } // Peek mocks base method. -func (m *MockMempool) Peek(arg0 int) *txs.Tx { +func (m *MockMempool) Peek() *txs.Tx { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Peek", arg0) + ret := m.ctrl.Call(m, "Peek") ret0, _ := ret[0].(*txs.Tx) return ret0 } // Peek indicates an expected call of Peek. -func (mr *MockMempoolMockRecorder) Peek(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Peek() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peek", reflect.TypeOf((*MockMempool)(nil).Peek), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peek", reflect.TypeOf((*MockMempool)(nil).Peek)) } // Remove mocks base method. From 0ee75757c02cbee6ab875abf22ffe5c7daba6543 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Sun, 10 Dec 2023 08:35:49 -0500 Subject: [PATCH 120/267] `vms/platformvm`: Remove `standardBlockState` struct (#2450) --- vms/platformvm/block/executor/acceptor_test.go | 11 +++++------ vms/platformvm/block/executor/block_state.go | 11 ++++------- vms/platformvm/block/executor/verifier.go | 8 ++++---- vms/platformvm/block/executor/verifier_test.go | 8 +------- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/vms/platformvm/block/executor/acceptor_test.go b/vms/platformvm/block/executor/acceptor_test.go index c9fafb4445d0..7b3ec462c556 100644 --- a/vms/platformvm/block/executor/acceptor_test.go +++ b/vms/platformvm/block/executor/acceptor_test.go @@ -210,13 +210,12 @@ func TestAcceptorVisitStandardBlock(t *testing.T) { atomicRequests := map[ids.ID]*atomic.Requests{ids.GenerateTestID(): nil} calledOnAcceptFunc := false acceptor.backend.blkIDToState[blk.ID()] = &blockState{ - onAcceptState: onAcceptState, - atomicRequests: atomicRequests, - standardBlockState: standardBlockState{ - onAcceptFunc: func() { - calledOnAcceptFunc = true - }, + onAcceptState: onAcceptState, + onAcceptFunc: func() { + calledOnAcceptFunc = true }, + + atomicRequests: atomicRequests, } // Give [blk] a child. childOnAcceptState := state.NewMockDiff(ctrl) diff --git a/vms/platformvm/block/executor/block_state.go b/vms/platformvm/block/executor/block_state.go index 9f0cd7e0860d..1386abd58bd4 100644 --- a/vms/platformvm/block/executor/block_state.go +++ b/vms/platformvm/block/executor/block_state.go @@ -13,11 +13,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/state" ) -type standardBlockState struct { - onAcceptFunc func() - inputs set.Set[ids.ID] -} - type proposalBlockState struct { initiallyPreferCommit bool onCommitState state.Diff @@ -27,11 +22,13 @@ type proposalBlockState struct { // The state of a block. // Note that not all fields will be set for a given block. type blockState struct { - standardBlockState proposalBlockState statelessBlock block.Block - onAcceptState state.Diff + onAcceptState state.Diff + onAcceptFunc func() + + inputs set.Set[ids.ID] timestamp time.Time atomicRequests map[ids.ID]*atomic.Requests } diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index abc2aa4e257c..2982c29a2f08 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -207,11 +207,11 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { blkID := b.ID() v.blkIDToState[blkID] = &blockState{ - standardBlockState: standardBlockState{ - inputs: atomicExecutor.Inputs, - }, statelessBlock: b, - onAcceptState: atomicExecutor.OnAccept, + + onAcceptState: atomicExecutor.OnAccept, + + inputs: atomicExecutor.Inputs, timestamp: atomicExecutor.OnAccept.GetTimestamp(), atomicRequests: atomicExecutor.AtomicRequests, } diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index b84b8697b6c0..e4095f6b4f77 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -322,7 +322,6 @@ func TestVerifierVisitCommitBlock(t *testing.T) { onCommitState: parentOnCommitState, onAbortState: parentOnAbortState, }, - standardBlockState: standardBlockState{}, }, }, Mempool: mempool, @@ -392,7 +391,6 @@ func TestVerifierVisitAbortBlock(t *testing.T) { onCommitState: parentOnCommitState, onAbortState: parentOnAbortState, }, - standardBlockState: standardBlockState{}, }, }, Mempool: mempool, @@ -686,11 +684,9 @@ func TestVerifierVisitStandardBlockWithDuplicateInputs(t *testing.T) { backend := &backend{ blkIDToState: map[ids.ID]*blockState{ grandParentID: { - standardBlockState: standardBlockState{ - inputs: atomicInputs, - }, statelessBlock: grandParentStatelessBlk, onAcceptState: grandParentState, + inputs: atomicInputs, }, parentID: { statelessBlock: parentStatelessBlk, @@ -784,7 +780,6 @@ func TestVerifierVisitApricotStandardBlockWithProposalBlockParent(t *testing.T) onCommitState: parentOnCommitState, onAbortState: parentOnAbortState, }, - standardBlockState: standardBlockState{}, }, }, Mempool: mempool, @@ -842,7 +837,6 @@ func TestVerifierVisitBanffStandardBlockWithProposalBlockParent(t *testing.T) { onCommitState: parentOnCommitState, onAbortState: parentOnAbortState, }, - standardBlockState: standardBlockState{}, }, }, Mempool: mempool, From d2457c52209ffdd1fa07bb03bc6bbf3d31e460ac Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 10 Dec 2023 19:33:11 -0500 Subject: [PATCH 121/267] Refactor sampler seeding (#2456) --- .../snowball/consensus_performance_test.go | 36 +++++------ .../snowball/consensus_reversibility_test.go | 8 +-- snow/consensus/snowball/network_test.go | 28 +++++---- snow/consensus/snowball/tree_test.go | 12 ++-- snow/consensus/snowman/consensus_test.go | 11 ++-- snow/consensus/snowman/network_test.go | 63 ++++++++++--------- utils/sampler/rand.go | 21 ++----- utils/sampler/uniform.go | 16 +++-- utils/sampler/uniform_best.go | 8 ++- utils/sampler/uniform_replacer.go | 12 ---- utils/sampler/uniform_resample.go | 18 +----- utils/sampler/uniform_test.go | 62 +++--------------- utils/sampler/weighted_without_replacement.go | 7 +-- .../weighted_without_replacement_generic.go | 8 --- .../weighted_without_replacement_test.go | 4 +- vms/proposervm/proposer/windower.go | 16 ++--- 16 files changed, 131 insertions(+), 199 deletions(-) diff --git a/snow/consensus/snowball/consensus_performance_test.go b/snow/consensus/snowball/consensus_performance_test.go index bd2752a2ec5c..febb7c6877e6 100644 --- a/snow/consensus/snowball/consensus_performance_test.go +++ b/snow/consensus/snowball/consensus_performance_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/utils/sampler" + "gonum.org/v1/gonum/mathext/prng" ) // Test that a network running the lower AlphaPreference converges faster than a @@ -26,29 +26,28 @@ func TestDualAlphaOptimization(t *testing.T) { BetaVirtuous: 15, BetaRogue: 20, } - seed uint64 = 0 + seed uint64 = 0 + source = prng.NewMT19937() ) - singleAlphaNetwork := Network{} - singleAlphaNetwork.Initialize(params, numColors) + singleAlphaNetwork := NewNetwork(params, numColors, source) params.AlphaPreference = params.K/2 + 1 - dualAlphaNetwork := Network{} - dualAlphaNetwork.Initialize(params, numColors) + dualAlphaNetwork := NewNetwork(params, numColors, source) - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numNodes; i++ { dualAlphaNetwork.AddNode(NewTree) } - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numNodes; i++ { singleAlphaNetwork.AddNode(NewTree) } // Although this can theoretically fail with a correct implementation, it // shouldn't in practice - runNetworksInLockstep(require, seed, &dualAlphaNetwork, &singleAlphaNetwork) + runNetworksInLockstep(require, seed, source, dualAlphaNetwork, singleAlphaNetwork) } // Test that a network running the snowball tree converges faster than a network @@ -61,35 +60,34 @@ func TestTreeConvergenceOptimization(t *testing.T) { numNodes = 100 params = DefaultParameters seed uint64 = 0 + source = prng.NewMT19937() ) - treeNetwork := Network{} - treeNetwork.Initialize(params, numColors) + treeNetwork := NewNetwork(params, numColors, source) + flatNetwork := NewNetwork(params, numColors, source) - flatNetwork := treeNetwork - - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numNodes; i++ { treeNetwork.AddNode(NewTree) } - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numNodes; i++ { flatNetwork.AddNode(NewFlat) } // Although this can theoretically fail with a correct implementation, it // shouldn't in practice - runNetworksInLockstep(require, seed, &treeNetwork, &flatNetwork) + runNetworksInLockstep(require, seed, source, treeNetwork, flatNetwork) } -func runNetworksInLockstep(require *require.Assertions, seed uint64, fast *Network, slow *Network) { +func runNetworksInLockstep(require *require.Assertions, seed uint64, source *prng.MT19937, fast *Network, slow *Network) { numRounds := 0 for !fast.Finalized() && !fast.Disagreement() && !slow.Finalized() && !slow.Disagreement() { - sampler.Seed(uint64(numRounds) + seed) + source.Seed(uint64(numRounds) + seed) fast.Round() - sampler.Seed(uint64(numRounds) + seed) + source.Seed(uint64(numRounds) + seed) slow.Round() numRounds++ } diff --git a/snow/consensus/snowball/consensus_reversibility_test.go b/snow/consensus/snowball/consensus_reversibility_test.go index 48d35cc7dde5..a3c5d3e98690 100644 --- a/snow/consensus/snowball/consensus_reversibility_test.go +++ b/snow/consensus/snowball/consensus_reversibility_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/utils/sampler" + "gonum.org/v1/gonum/mathext/prng" ) func TestSnowballGovernance(t *testing.T) { @@ -21,12 +21,12 @@ func TestSnowballGovernance(t *testing.T) { numRed = 55 params = DefaultParameters seed uint64 = 0 + source = prng.NewMT19937() ) - nBitwise := Network{} - nBitwise.Initialize(params, numColors) + nBitwise := NewNetwork(params, numColors, source) - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numRed; i++ { nBitwise.AddNodeSpecificColor(NewTree, 0, []int{1}) } diff --git a/snow/consensus/snowball/network_test.go b/snow/consensus/snowball/network_test.go index 711bbf89010e..747b51087926 100644 --- a/snow/consensus/snowball/network_test.go +++ b/snow/consensus/snowball/network_test.go @@ -4,10 +4,9 @@ package snowball import ( - "math/rand" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/bag" + "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/sampler" ) @@ -16,20 +15,24 @@ type newConsensusFunc func(params Parameters, choice ids.ID) Consensus type Network struct { params Parameters colors []ids.ID + rngSource sampler.Source nodes, running []Consensus } -// Initialize sets the parameters for the network and adds [numColors] different -// possible colors to the network configuration. -func (n *Network) Initialize(params Parameters, numColors int) { - n.params = params +// Create a new network with [numColors] different possible colors to finalize. +func NewNetwork(params Parameters, numColors int, rngSource sampler.Source) *Network { + n := &Network{ + params: params, + rngSource: rngSource, + } for i := 0; i < numColors; i++ { n.colors = append(n.colors, ids.Empty.Prefix(uint64(i))) } + return n } func (n *Network) AddNode(newConsensusFunc newConsensusFunc) Consensus { - s := sampler.NewUniform() + s := sampler.NewDeterministicUniform(n.rngSource) s.Initialize(uint64(len(n.colors))) indices, _ := s.Sample(len(n.colors)) @@ -78,15 +81,14 @@ func (n *Network) Finalized() bool { // performing an unbiased poll of the nodes in the network for that node. func (n *Network) Round() { if len(n.running) > 0 { - runningInd := rand.Intn(len(n.running)) // #nosec G404 + s := sampler.NewDeterministicUniform(n.rngSource) + + s.Initialize(uint64(len(n.running))) + runningInd, _ := s.Next() running := n.running[runningInd] - s := sampler.NewUniform() s.Initialize(uint64(len(n.nodes))) - count := len(n.nodes) - if count > n.params.K { - count = n.params.K - } + count := math.Min(n.params.K, len(n.nodes)) indices, _ := s.Sample(count) sampledColors := bag.Bag[ids.ID]{} for _, index := range indices { diff --git a/snow/consensus/snowball/tree_test.go b/snow/consensus/snowball/tree_test.go index 8517a8559fcc..39252ea01624 100644 --- a/snow/consensus/snowball/tree_test.go +++ b/snow/consensus/snowball/tree_test.go @@ -10,9 +10,10 @@ import ( "github.com/stretchr/testify/require" + "gonum.org/v1/gonum/mathext/prng" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/bag" - "github.com/ava-labs/avalanchego/utils/sampler" ) const initialUnaryDescription = "SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [0, 256)" @@ -806,14 +807,13 @@ func TestSnowballConsistent(t *testing.T) { BetaVirtuous: 20, BetaRogue: 30, } - seed uint64 = 0 + seed uint64 = 0 + source = prng.NewMT19937() ) - sampler.Seed(seed) - - n := Network{} - n.Initialize(params, numColors) + n := NewNetwork(params, numColors, source) + source.Seed(seed) for i := 0; i < numNodes; i++ { n.AddNode(NewTree) } diff --git a/snow/consensus/snowman/consensus_test.go b/snow/consensus/snowman/consensus_test.go index 024a8f69974d..a7558e67034d 100644 --- a/snow/consensus/snowman/consensus_test.go +++ b/snow/consensus/snowman/consensus_test.go @@ -17,12 +17,13 @@ import ( "github.com/stretchr/testify/require" + "gonum.org/v1/gonum/mathext/prng" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/utils/bag" - "github.com/ava-labs/avalanchego/utils/sampler" ) type testFunc func(*testing.T, Factory) @@ -1599,13 +1600,13 @@ func RandomizedConsistencyTest(t *testing.T, factory Factory) { MaxOutstandingItems: 1, MaxItemProcessingTime: 1, } - seed uint64 = 0 + seed uint64 = 0 + source = prng.NewMT19937() ) - sampler.Seed(seed) + source.Seed(seed) - n := Network{} - n.Initialize(params, numColors) + n := NewNetwork(params, numColors, source) for i := 0; i < numNodes; i++ { require.NoError(n.AddNode(factory.New())) diff --git a/snow/consensus/snowman/network_test.go b/snow/consensus/snowman/network_test.go index ae855ab84ac6..f6e734f3cbce 100644 --- a/snow/consensus/snowman/network_test.go +++ b/snow/consensus/snowman/network_test.go @@ -5,7 +5,6 @@ package snowman import ( "context" - "math/rand" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" @@ -19,45 +18,51 @@ import ( type Network struct { params snowball.Parameters colors []*TestBlock + rngSource sampler.Source nodes, running []Consensus } -func (n *Network) shuffleColors() { - s := sampler.NewUniform() - s.Initialize(uint64(len(n.colors))) - indices, _ := s.Sample(len(n.colors)) - colors := []*TestBlock(nil) - for _, index := range indices { - colors = append(colors, n.colors[int(index)]) +func NewNetwork(params snowball.Parameters, numColors int, rngSource sampler.Source) *Network { + n := &Network{ + params: params, + colors: []*TestBlock{{ + TestDecidable: choices.TestDecidable{ + IDV: ids.Empty.Prefix(rngSource.Uint64()), + StatusV: choices.Processing, + }, + ParentV: Genesis.IDV, + HeightV: 1, + }}, + rngSource: rngSource, } - n.colors = colors - utils.Sort(n.colors) -} - -func (n *Network) Initialize(params snowball.Parameters, numColors int) { - n.params = params - // #nosec G404 - n.colors = append(n.colors, &TestBlock{ - TestDecidable: choices.TestDecidable{ - IDV: ids.Empty.Prefix(uint64(rand.Int63())), - StatusV: choices.Processing, - }, - ParentV: Genesis.IDV, - HeightV: 1, - }) + s := sampler.NewDeterministicUniform(n.rngSource) for i := 1; i < numColors; i++ { - dependency := n.colors[rand.Intn(len(n.colors))] // #nosec G404 - // #nosec G404 + s.Initialize(uint64(len(n.colors))) + dependencyInd, _ := s.Next() + dependency := n.colors[dependencyInd] n.colors = append(n.colors, &TestBlock{ TestDecidable: choices.TestDecidable{ - IDV: ids.Empty.Prefix(uint64(rand.Int63())), + IDV: ids.Empty.Prefix(rngSource.Uint64()), StatusV: choices.Processing, }, ParentV: dependency.IDV, HeightV: dependency.HeightV + 1, }) } + return n +} + +func (n *Network) shuffleColors() { + s := sampler.NewDeterministicUniform(n.rngSource) + s.Initialize(uint64(len(n.colors))) + indices, _ := s.Sample(len(n.colors)) + colors := []*TestBlock(nil) + for _, index := range indices { + colors = append(colors, n.colors[int(index)]) + } + n.colors = colors + utils.Sort(n.colors) } func (n *Network) AddNode(sm Consensus) error { @@ -101,10 +106,12 @@ func (n *Network) Round() error { return nil } - runningInd := rand.Intn(len(n.running)) // #nosec G404 + s := sampler.NewDeterministicUniform(n.rngSource) + s.Initialize(uint64(len(n.running))) + + runningInd, _ := s.Next() running := n.running[runningInd] - s := sampler.NewUniform() s.Initialize(uint64(len(n.nodes))) indices, _ := s.Sample(n.params.K) sampledColors := bag.Bag[ids.ID]{} diff --git a/utils/sampler/rand.go b/utils/sampler/rand.go index 1b335f718be0..0dc347dad659 100644 --- a/utils/sampler/rand.go +++ b/utils/sampler/rand.go @@ -21,26 +21,15 @@ func newRNG() *rng { return &rng{rng: source} } -func Seed(seed uint64) { - globalRNG.Seed(seed) -} - -type source interface { - Seed(uint64) - Uint64() uint64 -} - type rng struct { lock sync.Mutex - rng source + rng Source } -// Seed uses the provided seed value to initialize the generator to a -// deterministic state. -func (r *rng) Seed(seed uint64) { - r.lock.Lock() - r.rng.Seed(seed) - r.lock.Unlock() +type Source interface { + // Uint64 returns a random number in [0, MaxUint64] and advances the + // generator's state. + Uint64() uint64 } // Uint64Inclusive returns a pseudo-random number in [0,n]. diff --git a/utils/sampler/uniform.go b/utils/sampler/uniform.go index 262de753a6f7..e673aefa2616 100644 --- a/utils/sampler/uniform.go +++ b/utils/sampler/uniform.go @@ -11,14 +11,22 @@ type Uniform interface { // negative the implementation may panic. Sample(length int) ([]uint64, error) - Seed(uint64) - ClearSeed() - Reset() Next() (uint64, error) } // NewUniform returns a new sampler func NewUniform() Uniform { - return &uniformReplacer{} + return &uniformReplacer{ + rng: globalRNG, + } +} + +// NewDeterministicUniform returns a new sampler +func NewDeterministicUniform(source Source) Uniform { + return &uniformReplacer{ + rng: &rng{ + rng: source, + }, + } } diff --git a/utils/sampler/uniform_best.go b/utils/sampler/uniform_best.go index 9ce1ed7f7187..69f78bd24ce8 100644 --- a/utils/sampler/uniform_best.go +++ b/utils/sampler/uniform_best.go @@ -29,8 +29,12 @@ type uniformBest struct { func NewBestUniform(expectedSampleSize int) Uniform { return &uniformBest{ samplers: []Uniform{ - &uniformReplacer{}, - &uniformResample{}, + &uniformReplacer{ + rng: globalRNG, + }, + &uniformResample{ + rng: globalRNG, + }, }, maxSampleSize: expectedSampleSize, benchmarkIterations: 100, diff --git a/utils/sampler/uniform_replacer.go b/utils/sampler/uniform_replacer.go index 8551907da7d1..2053c22e875a 100644 --- a/utils/sampler/uniform_replacer.go +++ b/utils/sampler/uniform_replacer.go @@ -27,15 +27,12 @@ func (m defaultMap) get(key uint64, defaultVal uint64) uint64 { // Sampling is performed in O(count) time and O(count) space. type uniformReplacer struct { rng *rng - seededRNG *rng length uint64 drawn defaultMap drawsCount uint64 } func (s *uniformReplacer) Initialize(length uint64) { - s.rng = globalRNG - s.seededRNG = newRNG() s.length = length s.drawn = make(defaultMap) s.drawsCount = 0 @@ -55,15 +52,6 @@ func (s *uniformReplacer) Sample(count int) ([]uint64, error) { return results, nil } -func (s *uniformReplacer) Seed(seed uint64) { - s.rng = s.seededRNG - s.rng.Seed(seed) -} - -func (s *uniformReplacer) ClearSeed() { - s.rng = globalRNG -} - func (s *uniformReplacer) Reset() { maps.Clear(s.drawn) s.drawsCount = 0 diff --git a/utils/sampler/uniform_resample.go b/utils/sampler/uniform_resample.go index ce3e41fe15c4..b2ddbdeb09df 100644 --- a/utils/sampler/uniform_resample.go +++ b/utils/sampler/uniform_resample.go @@ -15,15 +15,12 @@ import "golang.org/x/exp/maps" // // Sampling is performed in O(count) time and O(count) space. type uniformResample struct { - rng *rng - seededRNG *rng - length uint64 - drawn map[uint64]struct{} + rng *rng + length uint64 + drawn map[uint64]struct{} } func (s *uniformResample) Initialize(length uint64) { - s.rng = globalRNG - s.seededRNG = newRNG() s.length = length s.drawn = make(map[uint64]struct{}) } @@ -42,15 +39,6 @@ func (s *uniformResample) Sample(count int) ([]uint64, error) { return results, nil } -func (s *uniformResample) Seed(seed uint64) { - s.rng = s.seededRNG - s.rng.Seed(seed) -} - -func (s *uniformResample) ClearSeed() { - s.rng = globalRNG -} - func (s *uniformResample) Reset() { maps.Clear(s.drawn) } diff --git a/utils/sampler/uniform_test.go b/utils/sampler/uniform_test.go index e5b00af31c26..96aabb73be57 100644 --- a/utils/sampler/uniform_test.go +++ b/utils/sampler/uniform_test.go @@ -19,12 +19,16 @@ var ( sampler Uniform }{ { - name: "replacer", - sampler: &uniformReplacer{}, + name: "replacer", + sampler: &uniformReplacer{ + rng: globalRNG, + }, }, { - name: "resampler", - sampler: &uniformResample{}, + name: "resampler", + sampler: &uniformResample{ + rng: globalRNG, + }, }, { name: "best", @@ -156,53 +160,3 @@ func UniformLazilySample(t *testing.T, s Uniform) { s.Reset() } } - -func TestSeeding(t *testing.T) { - require := require.New(t) - - s1 := NewBestUniform(30) - s2 := NewBestUniform(30) - - s1.Initialize(50) - s2.Initialize(50) - - s1.Seed(0) - - s1.Reset() - s1Val, err := s1.Next() - require.NoError(err) - - s2.Seed(1) - s2.Reset() - - s1.Seed(0) - v, err := s2.Next() - require.NoError(err) - require.NotEqual(s1Val, v) - - s1.ClearSeed() - - _, err = s1.Next() - require.NoError(err) -} - -func TestSeedingProducesTheSame(t *testing.T) { - require := require.New(t) - - s := NewBestUniform(30) - - s.Initialize(50) - - s.Seed(0) - s.Reset() - - val0, err := s.Next() - require.NoError(err) - - s.Seed(0) - s.Reset() - - val1, err := s.Next() - require.NoError(err) - require.Equal(val0, val1) -} diff --git a/utils/sampler/weighted_without_replacement.go b/utils/sampler/weighted_without_replacement.go index 1a3699613525..2f592a783bc0 100644 --- a/utils/sampler/weighted_without_replacement.go +++ b/utils/sampler/weighted_without_replacement.go @@ -9,15 +9,12 @@ package sampler type WeightedWithoutReplacement interface { Initialize(weights []uint64) error Sample(count int) ([]int, error) - - Seed(uint64) - ClearSeed() } // NewWeightedWithoutReplacement returns a new sampler -func NewDeterministicWeightedWithoutReplacement() WeightedWithoutReplacement { +func NewDeterministicWeightedWithoutReplacement(source Source) WeightedWithoutReplacement { return &weightedWithoutReplacementGeneric{ - u: NewUniform(), + u: NewDeterministicUniform(source), w: NewDeterministicWeighted(), } } diff --git a/utils/sampler/weighted_without_replacement_generic.go b/utils/sampler/weighted_without_replacement_generic.go index 5fefb826c46a..a62185146f4c 100644 --- a/utils/sampler/weighted_without_replacement_generic.go +++ b/utils/sampler/weighted_without_replacement_generic.go @@ -41,11 +41,3 @@ func (s *weightedWithoutReplacementGeneric) Sample(count int) ([]int, error) { } return indices, nil } - -func (s *weightedWithoutReplacementGeneric) Seed(seed uint64) { - s.u.Seed(seed) -} - -func (s *weightedWithoutReplacementGeneric) ClearSeed() { - s.u.ClearSeed() -} diff --git a/utils/sampler/weighted_without_replacement_test.go b/utils/sampler/weighted_without_replacement_test.go index fe2dadaeb5c6..79a26075605d 100644 --- a/utils/sampler/weighted_without_replacement_test.go +++ b/utils/sampler/weighted_without_replacement_test.go @@ -23,7 +23,9 @@ var ( { name: "generic with replacer and best", sampler: &weightedWithoutReplacementGeneric{ - u: &uniformReplacer{}, + u: &uniformReplacer{ + rng: globalRNG, + }, w: &weightedBest{ samplers: []Weighted{ &weightedArray{}, diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 12afc711cfc9..9abfbcfd60d4 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -7,6 +7,8 @@ import ( "context" "time" + "gonum.org/v1/gonum/mathext/prng" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils" @@ -57,7 +59,6 @@ type windower struct { state validators.State subnetID ids.ID chainSource uint64 - sampler sampler.WeightedWithoutReplacement } func New(state validators.State, subnetID, chainID ids.ID) Windower { @@ -66,7 +67,6 @@ func New(state validators.State, subnetID, chainID ids.ID) Windower { state: state, subnetID: subnetID, chainSource: w.UnpackLong(), - sampler: sampler.NewDeterministicWeightedWithoutReplacement(), } } @@ -103,7 +103,12 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint validatorWeights[i] = v.weight } - if err := w.sampler.Initialize(validatorWeights); err != nil { + seed := chainHeight ^ w.chainSource + + source := prng.NewMT19937() + source.Seed(seed) + sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) + if err := sampler.Initialize(validatorWeights); err != nil { return nil, err } @@ -112,10 +117,7 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint numToSample = int(weight) } - seed := chainHeight ^ w.chainSource - w.sampler.Seed(seed) - - indices, err := w.sampler.Sample(numToSample) + indices, err := sampler.Sample(numToSample) if err != nil { return nil, err } From 159aafbf32a4ae219d0394a7d80af19a11244507 Mon Sep 17 00:00:00 2001 From: marun Date: Sun, 10 Dec 2023 16:53:13 -0800 Subject: [PATCH 122/267] Update tmpnet fixture to include Proof-of-Possession for initial stakers (#2391) --- tests/fixture/tmpnet/config.go | 73 +++++++++++++-------------- tests/fixture/tmpnet/local/network.go | 44 +++++++++++++--- 2 files changed, 71 insertions(+), 46 deletions(-) diff --git a/tests/fixture/tmpnet/config.go b/tests/fixture/tmpnet/config.go index f504eb84d20d..a86b2f26c51a 100644 --- a/tests/fixture/tmpnet/config.go +++ b/tests/fixture/tmpnet/config.go @@ -29,7 +29,7 @@ import ( "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) const ( @@ -49,14 +49,13 @@ var ( // Arbitrarily large amount of AVAX (10^12) to fund keys on the C-Chain for testing DefaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) - errEmptyValidatorsForGenesis = errors.New("failed to generate genesis: empty validator IDs") - errNoKeysForGenesis = errors.New("failed to generate genesis: no keys to fund") - errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID") - errMissingValidatorsForGenesis = errors.New("no genesis validators provided") - errMissingBalancesForGenesis = errors.New("no genesis balances given") - errMissingTLSKeyForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingTLSKeyContentKey) - errMissingCertForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingCertContentKey) - errInvalidKeypair = fmt.Errorf("%q and %q must be provided together or not at all", config.StakingTLSKeyContentKey, config.StakingCertContentKey) + errNoKeysForGenesis = errors.New("failed to generate genesis: no keys to fund") + errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID") + errMissingStakersForGenesis = errors.New("no genesis stakers provided") + errMissingBalancesForGenesis = errors.New("no genesis balances given") + errMissingTLSKeyForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingTLSKeyContentKey) + errMissingCertForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingCertContentKey) + errInvalidKeypair = fmt.Errorf("%q and %q must be provided together or not at all", config.StakingTLSKeyContentKey, config.StakingCertContentKey) ) // Defines a mapping of flag keys to values intended to be supplied to @@ -129,14 +128,11 @@ type NetworkConfig struct { } // Ensure genesis is generated if not already present. -func (c *NetworkConfig) EnsureGenesis(networkID uint32, validatorIDs []ids.NodeID) error { +func (c *NetworkConfig) EnsureGenesis(networkID uint32, initialStakers []genesis.UnparsedStaker) error { if c.Genesis != nil { return nil } - if len(validatorIDs) == 0 { - return errEmptyValidatorsForGenesis - } if len(c.FundedKeys) == 0 { return errNoKeysForGenesis } @@ -151,7 +147,7 @@ func (c *NetworkConfig) EnsureGenesis(networkID uint32, validatorIDs []ids.NodeI } } - genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, validatorIDs) + genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, initialStakers) if err != nil { return err } @@ -206,6 +202,24 @@ func (nc *NodeConfig) EnsureKeys() error { return nc.EnsureNodeID() } +// Derives the nodes proof-of-possession. Requires the node to have a +// BLS signing key. +func (nc *NodeConfig) GetProofOfPossession() (*signer.ProofOfPossession, error) { + signingKey, err := nc.Flags.GetStringVal(config.StakingSignerKeyContentKey) + if err != nil { + return nil, err + } + signingKeyBytes, err := base64.StdEncoding.DecodeString(signingKey) + if err != nil { + return nil, err + } + secretKey, err := bls.SecretKeyFromBytes(signingKeyBytes) + if err != nil { + return nil, err + } + return signer.NewProofOfPossession(secretKey), nil +} + // Ensures a BLS signing key is generated if not already present. func (nc *NodeConfig) EnsureBLSSigningKey() error { // Attempt to retrieve an existing key @@ -312,15 +326,15 @@ func NewTestGenesis( networkID uint32, xChainBalances XChainBalanceMap, cChainBalances core.GenesisAlloc, - validatorIDs []ids.NodeID, + initialStakers []genesis.UnparsedStaker, ) (*genesis.UnparsedConfig, error) { // Validate inputs switch networkID { case constants.TestnetID, constants.MainnetID, constants.LocalID: return nil, errInvalidNetworkIDForGenesis } - if len(validatorIDs) == 0 { - return nil, errMissingValidatorsForGenesis + if len(initialStakers) == 0 { + return nil, errMissingStakersForGenesis } if len(xChainBalances) == 0 || len(cChainBalances) == 0 { return nil, errMissingBalancesForGenesis @@ -336,8 +350,8 @@ func NewTestGenesis( return nil, fmt.Errorf("failed to format stake address: %w", err) } - // Ensure the total stake allows a MegaAvax per validator - totalStake := uint64(len(validatorIDs)) * units.MegaAvax + // Ensure the total stake allows a MegaAvax per staker + totalStake := uint64(len(initialStakers)) * units.MegaAvax // The eth address is only needed to link pre-mainnet assets. Until that capability // becomes necessary for testing, use a bogus address. @@ -367,6 +381,7 @@ func NewTestGenesis( InitialStakeDuration: 365 * 24 * 60 * 60, // 1 year InitialStakeDurationOffset: 90 * 60, // 90 minutes Message: "hello avalanche!", + InitialStakers: initialStakers, } // Set X-Chain balances @@ -409,25 +424,5 @@ func NewTestGenesis( } config.CChainGenesis = string(cChainGenesisBytes) - // Give staking rewards for initial validators to a random address. Any testing of staking rewards - // will be easier to perform with nodes other than the initial validators since the timing of - // staking can be more easily controlled. - rewardAddr, err := address.Format("X", constants.GetHRP(networkID), ids.GenerateTestShortID().Bytes()) - if err != nil { - return nil, fmt.Errorf("failed to format reward address: %w", err) - } - - // Configure provided validator node IDs as initial stakers - for _, validatorID := range validatorIDs { - config.InitialStakers = append( - config.InitialStakers, - genesis.UnparsedStaker{ - NodeID: validatorID, - RewardAddress: rewardAddr, - DelegationFee: .01 * reward.PercentDenominator, - }, - ) - } - return config, nil } diff --git a/tests/fixture/tmpnet/local/network.go b/tests/fixture/tmpnet/local/network.go index 70411d4afcde..ea55f5f5968c 100644 --- a/tests/fixture/tmpnet/local/network.go +++ b/tests/fixture/tmpnet/local/network.go @@ -21,8 +21,10 @@ import ( "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" ) const ( @@ -238,18 +240,18 @@ func (ln *LocalNetwork) PopulateLocalNetworkConfig(networkID uint32, nodeCount i } // Ensure each node has keys and an associated node ID. This - // ensures the availability of validator node IDs for genesis - // generation. + // ensures the availability of node IDs and proofs of possession + // for genesis generation. for _, node := range ln.Nodes { if err := node.EnsureKeys(); err != nil { return err } } - // Assume all initial nodes are validator ids - validatorIDs := make([]ids.NodeID, 0, len(ln.Nodes)) - for _, node := range ln.Nodes { - validatorIDs = append(validatorIDs, node.NodeID) + // Assume all the initial nodes are stakers + initialStakers, err := stakersForNodes(networkID, ln.Nodes) + if err != nil { + return err } if keyCount > 0 { @@ -265,7 +267,7 @@ func (ln *LocalNetwork) PopulateLocalNetworkConfig(networkID uint32, nodeCount i ln.FundedKeys = keys } - if err := ln.EnsureGenesis(networkID, validatorIDs); err != nil { + if err := ln.EnsureGenesis(networkID, initialStakers); err != nil { return err } @@ -713,3 +715,31 @@ func (ln *LocalNetwork) GetBootstrapIPsAndIDs() ([]string, []string, error) { return bootstrapIPs, bootstrapIDs, nil } + +// Returns staker configuration for the given set of nodes. +func stakersForNodes(networkID uint32, nodes []*LocalNode) ([]genesis.UnparsedStaker, error) { + // Give staking rewards for initial validators to a random address. Any testing of staking rewards + // will be easier to perform with nodes other than the initial validators since the timing of + // staking can be more easily controlled. + rewardAddr, err := address.Format("X", constants.GetHRP(networkID), ids.GenerateTestShortID().Bytes()) + if err != nil { + return nil, fmt.Errorf("failed to format reward address: %w", err) + } + + // Configure provided nodes as initial stakers + initialStakers := make([]genesis.UnparsedStaker, len(nodes)) + for i, node := range nodes { + pop, err := node.GetProofOfPossession() + if err != nil { + return nil, fmt.Errorf("failed to derive proof of possession: %w", err) + } + initialStakers[i] = genesis.UnparsedStaker{ + NodeID: node.NodeID, + RewardAddress: rewardAddr, + DelegationFee: .01 * reward.PercentDenominator, + Signer: pop, + } + } + + return initialStakers, nil +} From 4e5b20e4a5b227d3bf84c608925b50b1a3869eb9 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 11 Dec 2023 01:57:59 -0500 Subject: [PATCH 123/267] `vms/platformvm`: Remove `EnableAdding` and `DisableAdding` from `Mempool` interface (#2463) --- vms/platformvm/block/builder/builder.go | 2 -- vms/platformvm/txs/mempool/mempool.go | 21 ------------------- vms/platformvm/txs/mempool/mock_mempool.go | 24 ---------------------- 3 files changed, 47 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index dd46253aeb4e..140bc4fdb43e 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -192,9 +192,7 @@ func (b *builder) ShutdownBlockTimer() { // This method removes the transactions from the returned // blocks from the mempool. func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { - b.Mempool.DisableAdding() defer func() { - b.Mempool.EnableAdding() // If we need to advance the chain's timestamp in a standard block, but // we build an invalid block, then we need to re-trigger block building. // diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index bd219910bd9f..12c44e126555 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -45,11 +45,6 @@ var ( ) type Mempool interface { - // we may want to be able to stop valid transactions - // from entering the mempool, e.g. during blocks creation - EnableAdding() - DisableAdding() - Add(tx *txs.Tx) error Has(txID ids.ID) bool Get(txID ids.ID) *txs.Tx @@ -86,9 +81,6 @@ type Mempool interface { // Transactions from clients that have not yet been put into blocks and added to // consensus type mempool struct { - // If true, drop transactions added to the mempool via Add. - dropIncoming bool - bytesAvailableMetric prometheus.Gauge bytesAvailable int @@ -137,24 +129,11 @@ func New( droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, consumedUTXOs: set.NewSet[ids.ID](initialConsumedUTXOsSize), - dropIncoming: false, // enable tx adding by default toEngine: toEngine, }, nil } -func (m *mempool) EnableAdding() { - m.dropIncoming = false -} - -func (m *mempool) DisableAdding() { - m.dropIncoming = true -} - func (m *mempool) Add(tx *txs.Tx) error { - if m.dropIncoming { - return fmt.Errorf("tx %s not added because mempool is closed", tx.ID()) - } - switch tx.Unsigned.(type) { case *txs.AdvanceTimeTx: return errCantIssueAdvanceTimeTx diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index edc134a42ddf..26af31a83e03 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -53,18 +53,6 @@ func (mr *MockMempoolMockRecorder) Add(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockMempool)(nil).Add), arg0) } -// DisableAdding mocks base method. -func (m *MockMempool) DisableAdding() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DisableAdding") -} - -// DisableAdding indicates an expected call of DisableAdding. -func (mr *MockMempoolMockRecorder) DisableAdding() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableAdding", reflect.TypeOf((*MockMempool)(nil).DisableAdding)) -} - // DropExpiredStakerTxs mocks base method. func (m *MockMempool) DropExpiredStakerTxs(arg0 time.Time) []ids.ID { m.ctrl.T.Helper() @@ -79,18 +67,6 @@ func (mr *MockMempoolMockRecorder) DropExpiredStakerTxs(arg0 interface{}) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropExpiredStakerTxs", reflect.TypeOf((*MockMempool)(nil).DropExpiredStakerTxs), arg0) } -// EnableAdding mocks base method. -func (m *MockMempool) EnableAdding() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "EnableAdding") -} - -// EnableAdding indicates an expected call of EnableAdding. -func (mr *MockMempoolMockRecorder) EnableAdding() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableAdding", reflect.TypeOf((*MockMempool)(nil).EnableAdding)) -} - // Get mocks base method. func (m *MockMempool) Get(arg0 ids.ID) *txs.Tx { m.ctrl.T.Helper() From a36186898426e3b3845a3426919433991e65eaaa Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:00:58 -0500 Subject: [PATCH 124/267] `vms/avm`: Add `exists` bool to mempool `Peek` (#2465) --- vms/avm/block/builder/builder.go | 4 ++-- vms/avm/block/builder/builder_test.go | 26 +++++++++++++------------- vms/avm/txs/mempool/mempool.go | 8 ++++---- vms/avm/txs/mempool/mempool_test.go | 20 ++++++++++++++------ vms/avm/txs/mempool/mock_mempool.go | 5 +++-- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/vms/avm/block/builder/builder.go b/vms/avm/block/builder/builder.go index 093457c969fe..97610bb1ca2d 100644 --- a/vms/avm/block/builder/builder.go +++ b/vms/avm/block/builder/builder.go @@ -93,12 +93,12 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { remainingSize = targetBlockSize ) for { - tx := b.mempool.Peek() + tx, exists := b.mempool.Peek() // Invariant: [mempool.MaxTxSize] < [targetBlockSize]. This guarantees // that we will only stop building a block once there are no // transactions in the mempool or the block is at least // [targetBlockSize - mempool.MaxTxSize] bytes full. - if tx == nil || len(tx.Bytes()) > remainingSize { + if !exists || len(tx.Bytes()) > remainingSize { break } b.mempool.Remove([]*txs.Tx{tx}) diff --git a/vms/avm/block/builder/builder_test.go b/vms/avm/block/builder/builder_test.go index a6778a4564bc..d15a5f8d08f7 100644 --- a/vms/avm/block/builder/builder_test.go +++ b/vms/avm/block/builder/builder_test.go @@ -134,11 +134,11 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek().Return(tx) + mempool.EXPECT().Peek().Return(tx, true) mempool.EXPECT().Remove([]*txs.Tx{tx}) mempool.EXPECT().MarkDropped(tx.ID(), errTest) // Second loop iteration - mempool.EXPECT().Peek().Return(nil) + mempool.EXPECT().Peek().Return(nil, false) mempool.EXPECT().RequestBuildBlock() return New( @@ -179,11 +179,11 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek().Return(tx) + mempool.EXPECT().Peek().Return(tx, true) mempool.EXPECT().Remove([]*txs.Tx{tx}) mempool.EXPECT().MarkDropped(tx.ID(), errTest) // Second loop iteration - mempool.EXPECT().Peek().Return(nil) + mempool.EXPECT().Peek().Return(nil, false) mempool.EXPECT().RequestBuildBlock() return New( @@ -225,11 +225,11 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek().Return(tx) + mempool.EXPECT().Peek().Return(tx, true) mempool.EXPECT().Remove([]*txs.Tx{tx}) mempool.EXPECT().MarkDropped(tx.ID(), errTest) // Second loop iteration - mempool.EXPECT().Peek().Return(nil) + mempool.EXPECT().Peek().Return(nil, false) mempool.EXPECT().RequestBuildBlock() return New( @@ -309,14 +309,14 @@ func TestBuilderBuildBlock(t *testing.T) { ) mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek().Return(tx1) + mempool.EXPECT().Peek().Return(tx1, true) mempool.EXPECT().Remove([]*txs.Tx{tx1}) // Second loop iteration - mempool.EXPECT().Peek().Return(tx2) + mempool.EXPECT().Peek().Return(tx2, true) mempool.EXPECT().Remove([]*txs.Tx{tx2}) mempool.EXPECT().MarkDropped(tx2.ID(), blkexecutor.ErrConflictingBlockTxs) // Third loop iteration - mempool.EXPECT().Peek().Return(nil) + mempool.EXPECT().Peek().Return(nil, false) mempool.EXPECT().RequestBuildBlock() // To marshal the tx/block @@ -385,10 +385,10 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek().Return(tx) + mempool.EXPECT().Peek().Return(tx, true) mempool.EXPECT().Remove([]*txs.Tx{tx}) // Second loop iteration - mempool.EXPECT().Peek().Return(nil) + mempool.EXPECT().Peek().Return(nil, false) mempool.EXPECT().RequestBuildBlock() // To marshal the tx/block @@ -459,10 +459,10 @@ func TestBuilderBuildBlock(t *testing.T) { tx := &txs.Tx{Unsigned: unsignedTx} mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Peek().Return(tx) + mempool.EXPECT().Peek().Return(tx, true) mempool.EXPECT().Remove([]*txs.Tx{tx}) // Second loop iteration - mempool.EXPECT().Peek().Return(nil) + mempool.EXPECT().Peek().Return(nil, false) mempool.EXPECT().RequestBuildBlock() // To marshal the tx/block diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index 538f784b652b..6e22ee61407a 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -49,7 +49,7 @@ type Mempool interface { Remove(txs []*txs.Tx) // Peek returns the oldest tx in the mempool. - Peek() *txs.Tx + Peek() (tx *txs.Tx, exists bool) // RequestBuildBlock notifies the consensus engine that a block should be // built if there is at least one transaction in the mempool. @@ -182,9 +182,9 @@ func (m *mempool) Remove(txsToRemove []*txs.Tx) { } } -func (m *mempool) Peek() *txs.Tx { - _, tx, _ := m.unissuedTxs.Oldest() - return tx +func (m *mempool) Peek() (*txs.Tx, bool) { + _, tx, exists := m.unissuedTxs.Oldest() + return tx, exists } func (m *mempool) RequestBuildBlock() { diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index 86f3e0d5cf5f..2e009fc44520 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -181,20 +181,28 @@ func TestPeekTxs(t *testing.T) { testTxs := createTestTxs(2) - require.Nil(mempool.Peek()) + tx, exists := mempool.Peek() + require.False(exists) + require.Nil(tx) require.NoError(mempool.Add(testTxs[0])) require.NoError(mempool.Add(testTxs[1])) - require.Equal(mempool.Peek(), testTxs[0]) - require.NotEqual(mempool.Peek(), testTxs[1]) + tx, exists = mempool.Peek() + require.True(exists) + require.Equal(tx, testTxs[0]) + require.NotEqual(tx, testTxs[1]) mempool.Remove([]*txs.Tx{testTxs[0]}) - require.NotEqual(mempool.Peek(), testTxs[0]) - require.Equal(mempool.Peek(), testTxs[1]) + tx, exists = mempool.Peek() + require.True(exists) + require.NotEqual(tx, testTxs[0]) + require.Equal(tx, testTxs[1]) mempool.Remove([]*txs.Tx{testTxs[1]}) - require.Nil(mempool.Peek()) + tx, exists = mempool.Peek() + require.False(exists) + require.Nil(tx) } diff --git a/vms/avm/txs/mempool/mock_mempool.go b/vms/avm/txs/mempool/mock_mempool.go index ada05b2c6501..8660976dde0d 100644 --- a/vms/avm/txs/mempool/mock_mempool.go +++ b/vms/avm/txs/mempool/mock_mempool.go @@ -107,11 +107,12 @@ func (mr *MockMempoolMockRecorder) MarkDropped(arg0, arg1 interface{}) *gomock.C } // Peek mocks base method. -func (m *MockMempool) Peek() *txs.Tx { +func (m *MockMempool) Peek() (*txs.Tx, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Peek") ret0, _ := ret[0].(*txs.Tx) - return ret0 + ret1, _ := ret[1].(bool) + return ret0, ret1 } // Peek indicates an expected call of Peek. From 4be52185e6c5fb38e0d88fd184f42e4c56a4ccce Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:46:25 -0500 Subject: [PATCH 125/267] `vms/platformvm`: Remove `PeekTxs` from `Mempool` interface (#2378) --- vms/platformvm/block/builder/builder.go | 24 ++++-- vms/platformvm/block/builder/builder_test.go | 34 ++++++--- vms/platformvm/txs/mempool/mempool.go | 31 ++------ vms/platformvm/txs/mempool/mempool_test.go | 77 +++++++++++--------- vms/platformvm/txs/mempool/mock_mempool.go | 31 +++----- 5 files changed, 98 insertions(+), 99 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 140bc4fdb43e..53602ef3ed93 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -234,10 +234,6 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { return nil, err } - // Remove selected txs from mempool now that we are returning the block to - // the consensus engine. - txs := statelessBlk.Txs() - b.Mempool.Remove(txs) return b.blkManager.NewBlock(statelessBlk), nil } @@ -281,8 +277,24 @@ func buildBlock( ) } + var ( + blockTxs []*txs.Tx + remainingSize = targetBlockSize + ) + + for { + tx, exists := builder.Mempool.Peek() + if !exists || len(tx.Bytes()) > remainingSize { + break + } + builder.Mempool.Remove([]*txs.Tx{tx}) + + remainingSize -= len(tx.Bytes()) + blockTxs = append(blockTxs, tx) + } + // If there is no reason to build a block, don't. - if !builder.Mempool.HasTxs() && !forceAdvanceTime { + if len(blockTxs) == 0 && !forceAdvanceTime { builder.txExecutorBackend.Ctx.Log.Debug("no pending txs to issue into a block") return nil, ErrNoPendingBlocks } @@ -292,7 +304,7 @@ func buildBlock( timestamp, parentID, height, - builder.Mempool.PeekTxs(targetBlockSize), + blockTxs, ) } diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 3a030cdedcce..aaff6f1f008d 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -414,10 +414,15 @@ func TestBuildBlock(t *testing.T) { builderF: func(ctrl *gomock.Controller) *builder { mempool := mempool.NewMockMempool(ctrl) - // There are txs. mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - mempool.EXPECT().HasTxs().Return(true) - mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{tx}) + + gomock.InOrder( + mempool.EXPECT().Peek().Return(tx, true), + mempool.EXPECT().Remove([]*txs.Tx{tx}), + // Second loop iteration + mempool.EXPECT().Peek().Return(nil, false), + ) + return &builder{ Mempool: mempool, } @@ -463,7 +468,7 @@ func TestBuildBlock(t *testing.T) { // There are no txs. mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - mempool.EXPECT().HasTxs().Return(false) + mempool.EXPECT().Peek().Return(nil, false) clk := &mockable.Clock{} clk.Set(now) @@ -511,8 +516,7 @@ func TestBuildBlock(t *testing.T) { // There are no txs. mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - mempool.EXPECT().HasTxs().Return(false) - mempool.EXPECT().PeekTxs(targetBlockSize).Return(nil) + mempool.EXPECT().Peek().Return(nil, false) clk := &mockable.Clock{} clk.Set(now) @@ -566,8 +570,13 @@ func TestBuildBlock(t *testing.T) { // There is a tx. mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - mempool.EXPECT().HasTxs().Return(true) - mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{tx}) + + gomock.InOrder( + mempool.EXPECT().Peek().Return(tx, true), + mempool.EXPECT().Remove([]*txs.Tx{tx}), + // Second loop iteration + mempool.EXPECT().Peek().Return(nil, false), + ) clk := &mockable.Clock{} clk.Set(now) @@ -620,8 +629,13 @@ func TestBuildBlock(t *testing.T) { // There are no decision txs // There is a staker tx. mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - mempool.EXPECT().HasTxs().Return(true) - mempool.EXPECT().PeekTxs(targetBlockSize).Return([]*txs.Tx{tx}) + + gomock.InOrder( + mempool.EXPECT().Peek().Return(tx, true), + mempool.EXPECT().Remove([]*txs.Tx{tx}), + // Second loop iteration + mempool.EXPECT().Peek().Return(nil, false), + ) clk := &mockable.Clock{} clk.Set(now) diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 12c44e126555..d4783adf5a4c 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -50,13 +50,8 @@ type Mempool interface { Get(txID ids.ID) *txs.Tx Remove(txs []*txs.Tx) - // Following Banff activation, all mempool transactions, - // (both decision and staker) are included into Standard blocks. - // HasTxs allow to check for availability of any mempool transaction. - HasTxs() bool - // PeekTxs returns the next txs for Banff blocks - // up to maxTxsBytes without removing them from the mempool. - PeekTxs(maxTxsBytes int) []*txs.Tx + // Peek returns the oldest tx in the mempool. + Peek() (tx *txs.Tx, exists bool) // Drops all [txs.Staker] transactions whose [StartTime] is before // [minStartTime] from [mempool]. The dropped tx ids are returned. @@ -210,23 +205,9 @@ func (m *mempool) Remove(txsToRemove []*txs.Tx) { } } -func (m *mempool) HasTxs() bool { - return m.unissuedTxs.Len() > 0 -} - -func (m *mempool) PeekTxs(maxTxsBytes int) []*txs.Tx { - var txs []*txs.Tx - txIter := m.unissuedTxs.NewIterator() - size := 0 - for txIter.Next() { - tx := txIter.Value() - size += len(tx.Bytes()) - if size > maxTxsBytes { - return txs - } - txs = append(txs, tx) - } - return txs +func (m *mempool) Peek() (*txs.Tx, bool) { + _, tx, exists := m.unissuedTxs.Oldest() + return tx, exists } func (m *mempool) MarkDropped(txID ids.ID, reason error) { @@ -239,7 +220,7 @@ func (m *mempool) GetDropReason(txID ids.ID) error { } func (m *mempool) RequestBuildBlock(emptyBlockPermitted bool) { - if !emptyBlockPermitted && !m.HasTxs() { + if !emptyBlockPermitted && m.unissuedTxs.Len() == 0 { return } diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index 1d92132ebbcd..9877b0384288 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -5,7 +5,6 @@ package mempool import ( "errors" - "math" "testing" "time" @@ -14,6 +13,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -58,9 +58,6 @@ func TestDecisionTxsInMempool(t *testing.T) { decisionTxs, err := createTestDecisionTxs(2) require.NoError(err) - // txs must not already there before we start - require.False(mpool.HasTxs()) - for _, tx := range decisionTxs { // tx not already there require.False(mpool.Has(tx.ID())) @@ -75,20 +72,6 @@ func TestDecisionTxsInMempool(t *testing.T) { require.NotNil(retrieved) require.Equal(tx, retrieved) - // we can peek it - peeked := mpool.PeekTxs(math.MaxInt) - - // tx will be among those peeked, - // in NO PARTICULAR ORDER - found := false - for _, pk := range peeked { - if pk.ID() == tx.ID() { - found = true - break - } - } - require.True(found) - // once removed it cannot be there mpool.Remove([]*txs.Tx{tx}) @@ -113,7 +96,7 @@ func TestProposalTxsInMempool(t *testing.T) { proposalTxs, err := createTestProposalTxs(2) require.NoError(err) - for i, tx := range proposalTxs { + for _, tx := range proposalTxs { require.False(mpool.Has(tx.ID())) // we can insert @@ -126,23 +109,6 @@ func TestProposalTxsInMempool(t *testing.T) { require.NotNil(retrieved) require.Equal(tx, retrieved) - { - // we can peek it - peeked := mpool.PeekTxs(math.MaxInt) - require.Len(peeked, i+1) - - // tx will be among those peeked, - // in NO PARTICULAR ORDER - found := false - for _, pk := range peeked { - if pk.ID() == tx.ID() { - found = true - break - } - } - require.True(found) - } - // once removed it cannot be there mpool.Remove([]*txs.Tx{tx}) @@ -255,3 +221,42 @@ func TestDropExpiredStakerTxs(t *testing.T) { minStartTime := time.Unix(9, 0) require.Len(mempool.DropExpiredStakerTxs(minStartTime), 1) } + +func TestPeekTxs(t *testing.T) { + require := require.New(t) + + registerer := prometheus.NewRegistry() + toEngine := make(chan common.Message, 100) + mempool, err := New("mempool", registerer, toEngine) + require.NoError(err) + + testDecisionTxs, err := createTestDecisionTxs(1) + require.NoError(err) + testProposalTxs, err := createTestProposalTxs(1) + require.NoError(err) + + tx, exists := mempool.Peek() + require.False(exists) + require.Nil(tx) + + require.NoError(mempool.Add(testDecisionTxs[0])) + require.NoError(mempool.Add(testProposalTxs[0])) + + tx, exists = mempool.Peek() + require.True(exists) + require.Equal(tx, testDecisionTxs[0]) + require.NotEqual(tx, testProposalTxs[0]) + + mempool.Remove([]*txs.Tx{testDecisionTxs[0]}) + + tx, exists = mempool.Peek() + require.True(exists) + require.NotEqual(tx, testDecisionTxs[0]) + require.Equal(tx, testProposalTxs[0]) + + mempool.Remove([]*txs.Tx{testProposalTxs[0]}) + + tx, exists = mempool.Peek() + require.False(exists) + require.Nil(tx) +} diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index 26af31a83e03..5ccb1ec1820f 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -109,20 +109,6 @@ func (mr *MockMempoolMockRecorder) Has(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMempool)(nil).Has), arg0) } -// HasTxs mocks base method. -func (m *MockMempool) HasTxs() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HasTxs") - ret0, _ := ret[0].(bool) - return ret0 -} - -// HasTxs indicates an expected call of HasTxs. -func (mr *MockMempoolMockRecorder) HasTxs() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasTxs", reflect.TypeOf((*MockMempool)(nil).HasTxs)) -} - // MarkDropped mocks base method. func (m *MockMempool) MarkDropped(arg0 ids.ID, arg1 error) { m.ctrl.T.Helper() @@ -135,18 +121,19 @@ func (mr *MockMempoolMockRecorder) MarkDropped(arg0, arg1 interface{}) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkDropped", reflect.TypeOf((*MockMempool)(nil).MarkDropped), arg0, arg1) } -// PeekTxs mocks base method. -func (m *MockMempool) PeekTxs(arg0 int) []*txs.Tx { +// Peek mocks base method. +func (m *MockMempool) Peek() (*txs.Tx, bool) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PeekTxs", arg0) - ret0, _ := ret[0].([]*txs.Tx) - return ret0 + ret := m.ctrl.Call(m, "Peek") + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(bool) + return ret0, ret1 } -// PeekTxs indicates an expected call of PeekTxs. -func (mr *MockMempoolMockRecorder) PeekTxs(arg0 interface{}) *gomock.Call { +// Peek indicates an expected call of Peek. +func (mr *MockMempoolMockRecorder) Peek() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeekTxs", reflect.TypeOf((*MockMempool)(nil).PeekTxs), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peek", reflect.TypeOf((*MockMempool)(nil).Peek)) } // Remove mocks base method. From 2fd893100a9634474ce22be9c97da7be213178a7 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 11 Dec 2023 13:03:16 -0500 Subject: [PATCH 126/267] `vms/platformvm`: Add `processStandardTxs` helper (#2461) --- vms/platformvm/block/executor/verifier.go | 75 +++++++++++++++-------- 1 file changed, 48 insertions(+), 27 deletions(-) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 2982c29a2f08..9d754eec20fb 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/status" @@ -205,6 +206,8 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { return err } + v.Mempool.Remove([]*txs.Tx{b.Tx}) + blkID := b.ID() v.blkIDToState[blkID] = &blockState{ statelessBlock: b, @@ -215,8 +218,6 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { timestamp: atomicExecutor.OnAccept.GetTimestamp(), atomicRequests: atomicExecutor.AtomicRequests, } - - v.Mempool.Remove([]*txs.Tx{b.Tx}) return nil } @@ -371,6 +372,8 @@ func (v *verifier) proposalBlock( onCommitState.AddTx(b.Tx, status.Committed) onAbortState.AddTx(b.Tx, status.Aborted) + v.Mempool.Remove([]*txs.Tx{b.Tx}) + blkID := b.ID() v.blkIDToState[blkID] = &blockState{ proposalBlockState: proposalBlockState{ @@ -384,8 +387,6 @@ func (v *verifier) proposalBlock( // always be the same as the Banff Proposal Block. timestamp: onAbortState.GetTimestamp(), } - - v.Mempool.Remove([]*txs.Tx{b.Tx}) return nil } @@ -394,43 +395,67 @@ func (v *verifier) standardBlock( b *block.ApricotStandardBlock, onAcceptState state.Diff, ) error { - blkState := &blockState{ + inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onAcceptState, b.Parent()) + if err != nil { + return err + } + + v.Mempool.Remove(b.Transactions) + + blkID := b.ID() + v.blkIDToState[blkID] = &blockState{ statelessBlock: b, - onAcceptState: onAcceptState, + + onAcceptState: onAcceptState, + onAcceptFunc: onAcceptFunc, + timestamp: onAcceptState.GetTimestamp(), - atomicRequests: make(map[ids.ID]*atomic.Requests), + inputs: inputs, + atomicRequests: atomicRequests, } + return nil +} - // Finally we process the transactions - funcs := make([]func(), 0, len(b.Transactions)) - for _, tx := range b.Transactions { +func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID ids.ID) ( + set.Set[ids.ID], + map[ids.ID]*atomic.Requests, + func(), + error, +) { + var ( + onAcceptFunc func() + inputs set.Set[ids.ID] + funcs = make([]func(), 0, len(txs)) + atomicRequests = make(map[ids.ID]*atomic.Requests) + ) + for _, tx := range txs { txExecutor := executor.StandardTxExecutor{ Backend: v.txExecutorBackend, - State: onAcceptState, + State: state, Tx: tx, } if err := tx.Unsigned.Visit(&txExecutor); err != nil { txID := tx.ID() v.MarkDropped(txID, err) // cache tx as dropped - return err + return nil, nil, nil, err } // ensure it doesn't overlap with current input batch - if blkState.inputs.Overlaps(txExecutor.Inputs) { - return errConflictingBatchTxs + if inputs.Overlaps(txExecutor.Inputs) { + return nil, nil, nil, errConflictingBatchTxs } // Add UTXOs to batch - blkState.inputs.Union(txExecutor.Inputs) + inputs.Union(txExecutor.Inputs) - onAcceptState.AddTx(tx, status.Committed) + state.AddTx(tx, status.Committed) if txExecutor.OnAccept != nil { funcs = append(funcs, txExecutor.OnAccept) } for chainID, txRequests := range txExecutor.AtomicRequests { // Add/merge in the atomic requests represented by [tx] - chainRequests, exists := blkState.atomicRequests[chainID] + chainRequests, exists := atomicRequests[chainID] if !exists { - blkState.atomicRequests[chainID] = txRequests + atomicRequests[chainID] = txRequests continue } @@ -439,23 +464,19 @@ func (v *verifier) standardBlock( } } - if err := v.verifyUniqueInputs(b.Parent(), blkState.inputs); err != nil { - return err + if err := v.verifyUniqueInputs(parentID, inputs); err != nil { + return nil, nil, nil, err } if numFuncs := len(funcs); numFuncs == 1 { - blkState.onAcceptFunc = funcs[0] + onAcceptFunc = funcs[0] } else if numFuncs > 1 { - blkState.onAcceptFunc = func() { + onAcceptFunc = func() { for _, f := range funcs { f() } } } - blkID := b.ID() - v.blkIDToState[blkID] = blkState - - v.Mempool.Remove(b.Transactions) - return nil + return inputs, atomicRequests, onAcceptFunc, nil } From f5266fb8ef27505caff6faf4fbd56cf4184ff78e Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 11 Dec 2023 13:07:31 -0500 Subject: [PATCH 127/267] `vms/platformvm`: Process `atomicRequests` and `onAcceptFunc` in option blocks (#2459) Co-authored-by: Stephen Buttolph --- vms/platformvm/block/executor/acceptor.go | 19 +++++- .../block/executor/acceptor_test.go | 68 +++++++++++++++---- vms/platformvm/block/executor/backend.go | 8 +-- vms/platformvm/block/executor/verifier.go | 22 ++++-- vms/platformvm/vm_test.go | 8 +++ 5 files changed, 98 insertions(+), 27 deletions(-) diff --git a/vms/platformvm/block/executor/acceptor.go b/vms/platformvm/block/executor/acceptor.go index c66440aa83fe..ff5542f65157 100644 --- a/vms/platformvm/block/executor/acceptor.go +++ b/vms/platformvm/block/executor/acceptor.go @@ -180,8 +180,23 @@ func (a *acceptor) optionBlock(b, parent block.Block, blockType string) error { return err } - if err := a.state.Commit(); err != nil { - return err + defer a.state.Abort() + batch, err := a.state.CommitBatch() + if err != nil { + return fmt.Errorf( + "failed to commit VM's database for block %s: %w", + blkID, + err, + ) + } + + // Note that this method writes [batch] to the database. + if err := a.ctx.SharedMemory.Apply(blkState.atomicRequests, batch); err != nil { + return fmt.Errorf("failed to apply vm's state to shared memory: %w", err) + } + + if onAcceptFunc := blkState.onAcceptFunc; onAcceptFunc != nil { + onAcceptFunc() } a.ctx.Log.Trace( diff --git a/vms/platformvm/block/executor/acceptor_test.go b/vms/platformvm/block/executor/acceptor_test.go index 7b3ec462c556..210d5d810577 100644 --- a/vms/platformvm/block/executor/acceptor_test.go +++ b/vms/platformvm/block/executor/acceptor_test.go @@ -5,6 +5,7 @@ package executor import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -124,7 +125,7 @@ func TestAcceptorVisitAtomicBlock(t *testing.T) { // Set [blk]'s state in the map as though it had been verified. onAcceptState := state.NewMockDiff(ctrl) childID := ids.GenerateTestID() - atomicRequests := map[ids.ID]*atomic.Requests{ids.GenerateTestID(): nil} + atomicRequests := make(map[ids.ID]*atomic.Requests) acceptor.backend.blkIDToState[blk.ID()] = &blockState{ onAcceptState: onAcceptState, atomicRequests: atomicRequests, @@ -207,7 +208,7 @@ func TestAcceptorVisitStandardBlock(t *testing.T) { // Set [blk]'s state in the map as though it had been verified. onAcceptState := state.NewMockDiff(ctrl) childID := ids.GenerateTestID() - atomicRequests := map[ids.ID]*atomic.Requests{ids.GenerateTestID(): nil} + atomicRequests := make(map[ids.ID]*atomic.Requests) calledOnAcceptFunc := false acceptor.backend.blkIDToState[blk.ID()] = &blockState{ onAcceptState: onAcceptState, @@ -280,13 +281,21 @@ func TestAcceptorVisitCommitBlock(t *testing.T) { parentOnAbortState := state.NewMockDiff(ctrl) parentOnCommitState := state.NewMockDiff(ctrl) parentStatelessBlk := block.NewMockBlock(ctrl) + calledOnAcceptFunc := false + atomicRequests := make(map[ids.ID]*atomic.Requests) parentState := &blockState{ - statelessBlock: parentStatelessBlk, - onAcceptState: parentOnAcceptState, proposalBlockState: proposalBlockState{ onAbortState: parentOnAbortState, onCommitState: parentOnCommitState, }, + statelessBlock: parentStatelessBlk, + + onAcceptState: parentOnAcceptState, + onAcceptFunc: func() { + calledOnAcceptFunc = true + }, + + atomicRequests: atomicRequests, } acceptor.backend.blkIDToState[parentID] = parentState @@ -308,13 +317,21 @@ func TestAcceptorVisitCommitBlock(t *testing.T) { err = acceptor.ApricotCommitBlock(blk) require.ErrorIs(err, errMissingBlockState) + parentOnCommitState.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + // Set [blk]'s state in the map as though it had been verified. acceptor.backend.blkIDToState[parentID] = parentState - onAcceptState := state.NewMockDiff(ctrl) acceptor.backend.blkIDToState[blkID] = &blockState{ - onAcceptState: onAcceptState, + onAcceptState: parentState.onCommitState, + onAcceptFunc: parentState.onAcceptFunc, + + inputs: parentState.inputs, + timestamp: parentOnCommitState.GetTimestamp(), + atomicRequests: parentState.atomicRequests, } + batch := database.NewMockBatch(ctrl) + // Set expected calls on dependencies. // Make sure the parent is accepted first. gomock.InOrder( @@ -328,12 +345,15 @@ func TestAcceptorVisitCommitBlock(t *testing.T) { s.EXPECT().SetHeight(blk.Height()).Times(1), s.EXPECT().AddStatelessBlock(blk).Times(1), - onAcceptState.EXPECT().Apply(s).Times(1), - s.EXPECT().Commit().Return(nil).Times(1), + parentOnCommitState.EXPECT().Apply(s).Times(1), + s.EXPECT().CommitBatch().Return(batch, nil).Times(1), + sharedMemory.EXPECT().Apply(atomicRequests, batch).Return(nil).Times(1), s.EXPECT().Checksum().Return(ids.Empty).Times(1), + s.EXPECT().Abort().Times(1), ) require.NoError(acceptor.ApricotCommitBlock(blk)) + require.True(calledOnAcceptFunc) require.Equal(blk.ID(), acceptor.backend.lastAccepted) } @@ -371,13 +391,21 @@ func TestAcceptorVisitAbortBlock(t *testing.T) { parentOnAbortState := state.NewMockDiff(ctrl) parentOnCommitState := state.NewMockDiff(ctrl) parentStatelessBlk := block.NewMockBlock(ctrl) + calledOnAcceptFunc := false + atomicRequests := make(map[ids.ID]*atomic.Requests) parentState := &blockState{ - statelessBlock: parentStatelessBlk, - onAcceptState: parentOnAcceptState, proposalBlockState: proposalBlockState{ onAbortState: parentOnAbortState, onCommitState: parentOnCommitState, }, + statelessBlock: parentStatelessBlk, + + onAcceptState: parentOnAcceptState, + onAcceptFunc: func() { + calledOnAcceptFunc = true + }, + + atomicRequests: atomicRequests, } acceptor.backend.blkIDToState[parentID] = parentState @@ -399,14 +427,21 @@ func TestAcceptorVisitAbortBlock(t *testing.T) { err = acceptor.ApricotAbortBlock(blk) require.ErrorIs(err, errMissingBlockState) + parentOnAbortState.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + // Set [blk]'s state in the map as though it had been verified. acceptor.backend.blkIDToState[parentID] = parentState - - onAcceptState := state.NewMockDiff(ctrl) acceptor.backend.blkIDToState[blkID] = &blockState{ - onAcceptState: onAcceptState, + onAcceptState: parentState.onAbortState, + onAcceptFunc: parentState.onAcceptFunc, + + inputs: parentState.inputs, + timestamp: parentOnAbortState.GetTimestamp(), + atomicRequests: parentState.atomicRequests, } + batch := database.NewMockBatch(ctrl) + // Set expected calls on dependencies. // Make sure the parent is accepted first. gomock.InOrder( @@ -420,11 +455,14 @@ func TestAcceptorVisitAbortBlock(t *testing.T) { s.EXPECT().SetHeight(blk.Height()).Times(1), s.EXPECT().AddStatelessBlock(blk).Times(1), - onAcceptState.EXPECT().Apply(s).Times(1), - s.EXPECT().Commit().Return(nil).Times(1), + parentOnAbortState.EXPECT().Apply(s).Times(1), + s.EXPECT().CommitBatch().Return(batch, nil).Times(1), + sharedMemory.EXPECT().Apply(atomicRequests, batch).Return(nil).Times(1), s.EXPECT().Checksum().Return(ids.Empty).Times(1), + s.EXPECT().Abort().Times(1), ) require.NoError(acceptor.ApricotAbortBlock(blk)) + require.True(calledOnAcceptFunc) require.Equal(blk.ID(), acceptor.backend.lastAccepted) } diff --git a/vms/platformvm/block/executor/backend.go b/vms/platformvm/block/executor/backend.go index 4d915047f560..94b301c89ddb 100644 --- a/vms/platformvm/block/executor/backend.go +++ b/vms/platformvm/block/executor/backend.go @@ -51,20 +51,20 @@ func (b *backend) GetState(blkID ids.ID) (state.Chain, bool) { return b.state, blkID == b.state.GetLastAccepted() } -func (b *backend) getOnAbortState(blkID ids.ID) (state.Diff, bool) { +func (b *backend) getBlkWithOnAbortState(blkID ids.ID) (*blockState, bool) { state, ok := b.blkIDToState[blkID] if !ok || state.onAbortState == nil { return nil, false } - return state.onAbortState, true + return state, true } -func (b *backend) getOnCommitState(blkID ids.ID) (state.Diff, bool) { +func (b *backend) getBlkWithOnCommitState(blkID ids.ID) (*blockState, bool) { state, ok := b.blkIDToState[blkID] if !ok || state.onCommitState == nil { return nil, false } - return state.onCommitState, true + return state, true } func (b *backend) GetBlock(blkID ids.ID) (block.Block, error) { diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 9d754eec20fb..fd2ce999bd5f 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -319,7 +319,7 @@ func (v *verifier) commonBlock(b block.Block) error { // abortBlock populates the state of this block if [nil] is returned func (v *verifier) abortBlock(b block.Block) error { parentID := b.Parent() - onAcceptState, ok := v.getOnAbortState(parentID) + parentState, ok := v.getBlkWithOnAbortState(parentID) if !ok { return fmt.Errorf("%w: %s", state.ErrMissingParentState, parentID) } @@ -327,8 +327,13 @@ func (v *verifier) abortBlock(b block.Block) error { blkID := b.ID() v.blkIDToState[blkID] = &blockState{ statelessBlock: b, - onAcceptState: onAcceptState, - timestamp: onAcceptState.GetTimestamp(), + + onAcceptState: parentState.onAbortState, + onAcceptFunc: parentState.onAcceptFunc, + + inputs: parentState.inputs, + timestamp: parentState.onAbortState.GetTimestamp(), + atomicRequests: parentState.atomicRequests, } return nil } @@ -336,7 +341,7 @@ func (v *verifier) abortBlock(b block.Block) error { // commitBlock populates the state of this block if [nil] is returned func (v *verifier) commitBlock(b block.Block) error { parentID := b.Parent() - onAcceptState, ok := v.getOnCommitState(parentID) + parentState, ok := v.getBlkWithOnCommitState(parentID) if !ok { return fmt.Errorf("%w: %s", state.ErrMissingParentState, parentID) } @@ -344,8 +349,13 @@ func (v *verifier) commitBlock(b block.Block) error { blkID := b.ID() v.blkIDToState[blkID] = &blockState{ statelessBlock: b, - onAcceptState: onAcceptState, - timestamp: onAcceptState.GetTimestamp(), + + onAcceptState: parentState.onCommitState, + onAcceptFunc: parentState.onAcceptFunc, + + inputs: parentState.inputs, + timestamp: parentState.onCommitState.GetTimestamp(), + atomicRequests: parentState.atomicRequests, } return nil } diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 045ccf85b6ac..a74e6266bd07 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1873,6 +1873,10 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { secondCtx.Lock.Unlock() }() + atomicDB := prefixdb.New([]byte{1}, db) + m := atomic.NewMemory(atomicDB) + secondCtx.SharedMemory = m.NewSharedMemory(secondCtx.ChainID) + secondMsgChan := make(chan common.Message, 1) require.NoError(secondVM.Initialize( context.Background(), @@ -1962,6 +1966,10 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { ctx := defaultContext(t) ctx.Lock.Lock() + atomicDB := prefixdb.New([]byte{1}, db) + m := atomic.NewMemory(atomicDB) + ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) + msgChan := make(chan common.Message, 1) appSender := &common.SenderTest{T: t} require.NoError(vm.Initialize( From e3d02781f49e3b7406ede788dcc459a9a00224a2 Mon Sep 17 00:00:00 2001 From: marun Date: Mon, 11 Dec 2023 10:08:03 -0800 Subject: [PATCH 128/267] `e2e`: Rename 'funded key' to 'pre-funded key' for consistency (#2455) --- tests/e2e/c/dynamic_fees.go | 2 +- tests/e2e/c/interchain_workflow.go | 2 +- tests/e2e/p/staking_rewards.go | 2 +- tests/e2e/x/transfer/virtuous.go | 2 +- tests/fixture/e2e/env.go | 14 +++++------ tests/fixture/e2e/helpers.go | 2 +- tests/fixture/test_data_server.go | 20 ++++++++-------- tests/fixture/test_data_server_test.go | 6 ++--- tests/fixture/tmpnet/cmd/main.go | 12 +++++----- tests/fixture/tmpnet/config.go | 28 +++++++++++----------- tests/fixture/tmpnet/local/network.go | 18 +++++++------- tests/fixture/tmpnet/local/network_test.go | 2 +- 12 files changed, 55 insertions(+), 55 deletions(-) diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 38bbd668079b..6d106dc77fed 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -42,7 +42,7 @@ var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { privateNetwork := e2e.Env.NewPrivateNetwork() ginkgo.By("allocating a pre-funded key") - key := privateNetwork.GetConfig().FundedKeys[0] + key := privateNetwork.GetConfig().PreFundedKeys[0] ethAddress := evm.GetEthAddress(key) ginkgo.By("initializing a coreth client") diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index 2c9bd198ec39..e959418e878a 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -37,7 +37,7 @@ var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { ethClient := e2e.NewEthClient(nodeURI) ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") - senderKey := e2e.Env.AllocateFundedKey() + senderKey := e2e.Env.AllocatePreFundedKey() senderEthAddress := evm.GetEthAddress(senderKey) recipientKey, err := secp256k1.NewPrivateKey() require.NoError(err) diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index 475c3de261dd..ce6990b236a1 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -87,7 +87,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { ginkgo.By("creating keychain and P-Chain wallet") keychain := secp256k1fx.NewKeychain(rewardKeys...) - fundedKey := e2e.Env.AllocateFundedKey() + fundedKey := e2e.Env.AllocatePreFundedKey() keychain.Add(fundedKey) nodeURI := e2e.Env.GetRandomNodeURI() baseWallet := e2e.NewWallet(keychain, nodeURI) diff --git a/tests/e2e/x/transfer/virtuous.go b/tests/e2e/x/transfer/virtuous.go index 7a1eb1bb6b91..b409f7e5e555 100644 --- a/tests/e2e/x/transfer/virtuous.go +++ b/tests/e2e/x/transfer/virtuous.go @@ -69,7 +69,7 @@ var _ = e2e.DescribeXChainSerial("[Virtuous Transfer Tx AVAX]", func() { // Ensure the same set of 10 keys is used for all tests // by retrieving them outside of runFunc. - testKeys := e2e.Env.AllocateFundedKeys(10) + testKeys := e2e.Env.AllocatePreFundedKeys(10) runFunc := func(round int) { tests.Outf("{{green}}\n\n\n\n\n\n---\n[ROUND #%02d]:{{/}}\n", round) diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index 07c24866a9f0..3cd77ecb5c4c 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -75,7 +75,7 @@ func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { tests.Outf("{{green}}network URIs: {{/}} %+v\n", uris) testDataServerURI, err := fixture.ServeTestData(fixture.TestData{ - FundedKeys: network.FundedKeys, + PreFundedKeys: network.PreFundedKeys, }) tests.Outf("{{green}}test data server URI: {{/}} %+v\n", testDataServerURI) require.NoError(err) @@ -104,21 +104,21 @@ func (te *TestEnvironment) GetNetwork() tmpnet.Network { } // Retrieve the specified number of funded keys allocated for the caller's exclusive use. -func (te *TestEnvironment) AllocateFundedKeys(count int) []*secp256k1.PrivateKey { - keys, err := fixture.AllocateFundedKeys(te.TestDataServerURI, count) +func (te *TestEnvironment) AllocatePreFundedKeys(count int) []*secp256k1.PrivateKey { + keys, err := fixture.AllocatePreFundedKeys(te.TestDataServerURI, count) te.require.NoError(err) - tests.Outf("{{blue}} allocated funded key(s): %+v{{/}}\n", keys) + tests.Outf("{{blue}} allocated pre-funded key(s): %+v{{/}}\n", keys) return keys } // Retrieve a funded key allocated for the caller's exclusive use. -func (te *TestEnvironment) AllocateFundedKey() *secp256k1.PrivateKey { - return te.AllocateFundedKeys(1)[0] +func (te *TestEnvironment) AllocatePreFundedKey() *secp256k1.PrivateKey { + return te.AllocatePreFundedKeys(1)[0] } // Create a new keychain with the specified number of test keys. func (te *TestEnvironment) NewKeychain(count int) *secp256k1fx.Keychain { - keys := te.AllocateFundedKeys(count) + keys := te.AllocatePreFundedKeys(count) return secp256k1fx.NewKeychain(keys...) } diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 8b7eb5260b8c..c5776e546389 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -235,7 +235,7 @@ func StartLocalNetwork(avalancheGoExecPath string, networkDir string) *local.Loc }, }, tmpnet.DefaultNodeCount, - tmpnet.DefaultFundedKeyCount, + tmpnet.DefaultPreFundedKeyCount, ) require.NoError(err) ginkgo.DeferCleanup(func() { diff --git a/tests/fixture/test_data_server.go b/tests/fixture/test_data_server.go index 5a39baab8c9c..77e79b278b13 100644 --- a/tests/fixture/test_data_server.go +++ b/tests/fixture/test_data_server.go @@ -33,7 +33,7 @@ var ( ) type TestData struct { - FundedKeys []*secp256k1.PrivateKey + PreFundedKeys []*secp256k1.PrivateKey } // http server allocating resources to tests potentially executing in parallel @@ -68,14 +68,14 @@ func (s *testDataServer) allocateKeys(w http.ResponseWriter, r *http.Request) { defer s.lock.Unlock() // Only fulfill requests for available keys - if keyCount > len(s.FundedKeys) { + if keyCount > len(s.PreFundedKeys) { http.Error(w, requestedKeyCountExceedsAvailable, http.StatusInternalServerError) return } // Allocate the requested number of keys - remainingKeys := len(s.FundedKeys) - keyCount - allocatedKeys := s.FundedKeys[remainingKeys:] + remainingKeys := len(s.PreFundedKeys) - keyCount + allocatedKeys := s.PreFundedKeys[remainingKeys:] keysDoc := &keysDocument{ Keys: allocatedKeys, @@ -88,7 +88,7 @@ func (s *testDataServer) allocateKeys(w http.ResponseWriter, r *http.Request) { // Forget the allocated keys utils.ZeroSlice(allocatedKeys) - s.FundedKeys = s.FundedKeys[:remainingKeys] + s.PreFundedKeys = s.PreFundedKeys[:remainingKeys] } // Serve test data via http to ensure allocation is synchronized even when @@ -122,9 +122,9 @@ func ServeTestData(testData TestData) (string, error) { return address, nil } -// Retrieve the specified number of funded test keys from the provided URI. A given +// Retrieve the specified number of pre-funded test keys from the provided URI. A given // key is allocated at most once during the life of the test data server. -func AllocateFundedKeys(baseURI string, count int) ([]*secp256k1.PrivateKey, error) { +func AllocatePreFundedKeys(baseURI string, count int) ([]*secp256k1.PrivateKey, error) { if count <= 0 { return nil, errInvalidKeyCount } @@ -144,13 +144,13 @@ func AllocateFundedKeys(baseURI string, count int) ([]*secp256k1.PrivateKey, err resp, err := http.DefaultClient.Do(req) if err != nil { - return nil, fmt.Errorf("failed to request funded keys: %w", err) + return nil, fmt.Errorf("failed to request pre-funded keys: %w", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("failed to read response for funded keys: %w", err) + return nil, fmt.Errorf("failed to read response for pre-funded keys: %w", err) } if resp.StatusCode != http.StatusOK { if strings.TrimSpace(string(body)) == requestedKeyCountExceedsAvailable { @@ -161,7 +161,7 @@ func AllocateFundedKeys(baseURI string, count int) ([]*secp256k1.PrivateKey, err keysDoc := &keysDocument{} if err := json.Unmarshal(body, keysDoc); err != nil { - return nil, fmt.Errorf("failed to unmarshal funded keys: %w", err) + return nil, fmt.Errorf("failed to unmarshal pre-funded keys: %w", err) } return keysDoc.Keys, nil } diff --git a/tests/fixture/test_data_server_test.go b/tests/fixture/test_data_server_test.go index 979c927fea7f..7f68a6935da3 100644 --- a/tests/fixture/test_data_server_test.go +++ b/tests/fixture/test_data_server_test.go @@ -14,7 +14,7 @@ import ( // Check that funded test keys can be served from an http server to // ensure at-most-once allocation when tests are executed in parallel. -func TestAllocateFundedKeys(t *testing.T) { +func TestAllocatePreFundedKeys(t *testing.T) { require := require.New(t) keys := make([]*secp256k1.PrivateKey, 5) @@ -25,7 +25,7 @@ func TestAllocateFundedKeys(t *testing.T) { } uri, err := ServeTestData(TestData{ - FundedKeys: keys, + PreFundedKeys: keys, }) require.NoError(err) @@ -63,7 +63,7 @@ func TestAllocateFundedKeys(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - keys, err := AllocateFundedKeys(uri, tc.count) + keys, err := AllocatePreFundedKeys(uri, tc.count) require.ErrorIs(err, tc.expectedError) addresses := make([]ids.ShortID, len(keys)) diff --git a/tests/fixture/tmpnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go index a9f5c1865291..e58bb7213b36 100644 --- a/tests/fixture/tmpnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -46,10 +46,10 @@ func main() { rootCmd.AddCommand(versionCmd) var ( - rootDir string - execPath string - nodeCount uint8 - fundedKeyCount uint8 + rootDir string + execPath string + nodeCount uint8 + preFundedKeyCount uint8 ) startNetworkCmd := &cobra.Command{ Use: "start-network", @@ -68,7 +68,7 @@ func main() { } ctx, cancel := context.WithTimeout(context.Background(), local.DefaultNetworkStartTimeout) defer cancel() - network, err := local.StartNetwork(ctx, os.Stdout, rootDir, network, int(nodeCount), int(fundedKeyCount)) + network, err := local.StartNetwork(ctx, os.Stdout, rootDir, network, int(nodeCount), int(preFundedKeyCount)) if err != nil { return err } @@ -95,7 +95,7 @@ func main() { startNetworkCmd.PersistentFlags().StringVar(&rootDir, "root-dir", os.Getenv(local.RootDirEnvName), "The path to the root directory for local networks") startNetworkCmd.PersistentFlags().StringVar(&execPath, "avalanchego-path", os.Getenv(local.AvalancheGoPathEnvName), "The path to an avalanchego binary") startNetworkCmd.PersistentFlags().Uint8Var(&nodeCount, "node-count", tmpnet.DefaultNodeCount, "Number of nodes the network should initially consist of") - startNetworkCmd.PersistentFlags().Uint8Var(&fundedKeyCount, "funded-key-count", tmpnet.DefaultFundedKeyCount, "Number of funded keys the network should start with") + startNetworkCmd.PersistentFlags().Uint8Var(&preFundedKeyCount, "pre-funded-key-count", tmpnet.DefaultPreFundedKeyCount, "Number of pre-funded keys the network should start with") rootCmd.AddCommand(startNetworkCmd) var networkDir string diff --git a/tests/fixture/tmpnet/config.go b/tests/fixture/tmpnet/config.go index a86b2f26c51a..03a8487f67cc 100644 --- a/tests/fixture/tmpnet/config.go +++ b/tests/fixture/tmpnet/config.go @@ -33,13 +33,13 @@ import ( ) const ( - DefaultNodeCount = 2 // Minimum required to ensure connectivity-based health checks will pass - DefaultFundedKeyCount = 50 + DefaultNodeCount = 2 // Minimum required to ensure connectivity-based health checks will pass + DefaultPreFundedKeyCount = 50 DefaultGasLimit = uint64(100_000_000) // Gas limit is arbitrary // Arbitrarily large amount of AVAX to fund keys on the X-Chain for testing - DefaultFundedKeyXChainAmount = 30 * units.MegaAvax + DefaultPreFundedKeyXChainAmount = 30 * units.MegaAvax // A short min stake duration enables testing of staking logic. DefaultMinStakeDuration = time.Second @@ -47,7 +47,7 @@ const ( var ( // Arbitrarily large amount of AVAX (10^12) to fund keys on the C-Chain for testing - DefaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) + DefaultPreFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) errNoKeysForGenesis = errors.New("failed to generate genesis: no keys to fund") errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID") @@ -121,10 +121,10 @@ func DefaultJSONMarshal(v interface{}) ([]byte, error) { // NetworkConfig defines configuration shared or // common to all nodes in a given network. type NetworkConfig struct { - Genesis *genesis.UnparsedConfig - CChainConfig FlagsMap - DefaultFlags FlagsMap - FundedKeys []*secp256k1.PrivateKey + Genesis *genesis.UnparsedConfig + CChainConfig FlagsMap + DefaultFlags FlagsMap + PreFundedKeys []*secp256k1.PrivateKey } // Ensure genesis is generated if not already present. @@ -133,17 +133,17 @@ func (c *NetworkConfig) EnsureGenesis(networkID uint32, initialStakers []genesis return nil } - if len(c.FundedKeys) == 0 { + if len(c.PreFundedKeys) == 0 { return errNoKeysForGenesis } // Ensure pre-funded keys have arbitrary large balances on both chains to support testing - xChainBalances := make(XChainBalanceMap, len(c.FundedKeys)) - cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) - for _, key := range c.FundedKeys { - xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount + xChainBalances := make(XChainBalanceMap, len(c.PreFundedKeys)) + cChainBalances := make(core.GenesisAlloc, len(c.PreFundedKeys)) + for _, key := range c.PreFundedKeys { + xChainBalances[key.Address()] = DefaultPreFundedKeyXChainAmount cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - Balance: DefaultFundedKeyCChainAmount, + Balance: DefaultPreFundedKeyCChainAmount, } } diff --git a/tests/fixture/tmpnet/local/network.go b/tests/fixture/tmpnet/local/network.go index ea55f5f5968c..4d0fd4ed8a4d 100644 --- a/tests/fixture/tmpnet/local/network.go +++ b/tests/fixture/tmpnet/local/network.go @@ -226,7 +226,7 @@ func (ln *LocalNetwork) PopulateLocalNetworkConfig(networkID uint32, nodeCount i if len(ln.Nodes) > 0 && nodeCount > 0 { return errInvalidNodeCount } - if len(ln.FundedKeys) > 0 && keyCount > 0 { + if len(ln.PreFundedKeys) > 0 && keyCount > 0 { return errInvalidKeyCount } @@ -264,7 +264,7 @@ func (ln *LocalNetwork) PopulateLocalNetworkConfig(networkID uint32, nodeCount i } keys = append(keys, key) } - ln.FundedKeys = keys + ln.PreFundedKeys = keys } if err := ln.EnsureGenesis(networkID, initialStakers); err != nil { @@ -498,9 +498,9 @@ func (ln *LocalNetwork) WriteCChainConfig() error { // Used to marshal/unmarshal persistent local network defaults. type localDefaults struct { - Flags tmpnet.FlagsMap - ExecPath string - FundedKeys []*secp256k1.PrivateKey + Flags tmpnet.FlagsMap + ExecPath string + PreFundedKeys []*secp256k1.PrivateKey } func (ln *LocalNetwork) GetDefaultsPath() string { @@ -518,15 +518,15 @@ func (ln *LocalNetwork) ReadDefaults() error { } ln.DefaultFlags = defaults.Flags ln.ExecPath = defaults.ExecPath - ln.FundedKeys = defaults.FundedKeys + ln.PreFundedKeys = defaults.PreFundedKeys return nil } func (ln *LocalNetwork) WriteDefaults() error { defaults := localDefaults{ - Flags: ln.DefaultFlags, - ExecPath: ln.ExecPath, - FundedKeys: ln.FundedKeys, + Flags: ln.DefaultFlags, + ExecPath: ln.ExecPath, + PreFundedKeys: ln.PreFundedKeys, } bytes, err := tmpnet.DefaultJSONMarshal(defaults) if err != nil { diff --git a/tests/fixture/tmpnet/local/network_test.go b/tests/fixture/tmpnet/local/network_test.go index 8f7e66d37d5b..3893c9e51db4 100644 --- a/tests/fixture/tmpnet/local/network_test.go +++ b/tests/fixture/tmpnet/local/network_test.go @@ -20,7 +20,7 @@ func TestNetworkSerialization(t *testing.T) { loadedNetwork, err := ReadNetwork(tmpDir) require.NoError(err) - for _, key := range loadedNetwork.FundedKeys { + for _, key := range loadedNetwork.PreFundedKeys { // Address() enables comparison with the original network by // ensuring full population of a key's in-memory representation. _ = key.Address() From 8e55f7d8c5430eeb55c18fc9478338ed340321e8 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:00:45 -0500 Subject: [PATCH 129/267] `vms/platformvm`: Surface `VerifyUniqueInputs` in the `Manager` (#2467) --- scripts/mocks.mockgen.txt | 1 - vms/platformvm/block/executor/manager.go | 9 +++ vms/platformvm/block/executor/mock_manager.go | 57 ++++++++++++------- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 76add90f3f7f..0e32a76aec26 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -31,7 +31,6 @@ github.com/ava-labs/avalanchego/vms/avm/state=Chain,State,Diff=vms/avm/state/moc github.com/ava-labs/avalanchego/vms/avm/txs/mempool=Mempool=vms/avm/txs/mempool/mock_mempool.go github.com/ava-labs/avalanchego/vms/components/avax=TransferableIn=vms/components/avax/mock_transferable_in.go github.com/ava-labs/avalanchego/vms/components/verify=Verifiable=vms/components/verify/mock_verifiable.go -github.com/ava-labs/avalanchego/vms/platformvm/block/executor=Manager=vms/platformvm/block/executor/mock_manager.go github.com/ava-labs/avalanchego/vms/platformvm/block=Block=vms/platformvm/block/mock_block.go github.com/ava-labs/avalanchego/vms/platformvm/state=Chain,Diff,State,Versions=vms/platformvm/state/mock_state.go github.com/ava-labs/avalanchego/vms/platformvm/state=StakerIterator=vms/platformvm/state/mock_staker_iterator.go diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index ebecbf968e5f..0f8309020f6d 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "github.com/ava-labs/avalanchego/vms/platformvm/state" @@ -39,6 +40,10 @@ type Manager interface { // VerifyTx verifies that the transaction can be issued based on the currently // preferred state. This should *not* be used to verify transactions in a block. VerifyTx(tx *txs.Tx) error + + // VerifyUniqueInputs verifies that the inputs are not duplicated in the + // provided blk or any of its ancestors pinned in memory. + VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error } func NewManager( @@ -129,3 +134,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { Tx: tx, }) } + +func (m *manager) VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error { + return m.backend.verifyUniqueInputs(blkID, inputs) +} diff --git a/vms/platformvm/block/executor/mock_manager.go b/vms/platformvm/block/executor/mock_manager.go index f5b2bcb3608c..a6a7a9c95bcf 100644 --- a/vms/platformvm/block/executor/mock_manager.go +++ b/vms/platformvm/block/executor/mock_manager.go @@ -2,7 +2,7 @@ // See the file LICENSE for licensing terms. // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/block/executor (interfaces: Manager) +// Source: vms/platformvm/block/executor/manager.go // Package executor is a generated GoMock package. package executor @@ -12,6 +12,7 @@ import ( ids "github.com/ava-labs/avalanchego/ids" snowman "github.com/ava-labs/avalanchego/snow/consensus/snowman" + set "github.com/ava-labs/avalanchego/utils/set" block "github.com/ava-labs/avalanchego/vms/platformvm/block" state "github.com/ava-labs/avalanchego/vms/platformvm/state" txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -42,48 +43,48 @@ func (m *MockManager) EXPECT() *MockManagerMockRecorder { } // GetBlock mocks base method. -func (m *MockManager) GetBlock(arg0 ids.ID) (snowman.Block, error) { +func (m *MockManager) GetBlock(blkID ids.ID) (snowman.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlock", arg0) + ret := m.ctrl.Call(m, "GetBlock", blkID) ret0, _ := ret[0].(snowman.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlock indicates an expected call of GetBlock. -func (mr *MockManagerMockRecorder) GetBlock(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetBlock(blkID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockManager)(nil).GetBlock), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockManager)(nil).GetBlock), blkID) } // GetState mocks base method. -func (m *MockManager) GetState(arg0 ids.ID) (state.Chain, bool) { +func (m *MockManager) GetState(blkID ids.ID) (state.Chain, bool) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetState", arg0) + ret := m.ctrl.Call(m, "GetState", blkID) ret0, _ := ret[0].(state.Chain) ret1, _ := ret[1].(bool) return ret0, ret1 } // GetState indicates an expected call of GetState. -func (mr *MockManagerMockRecorder) GetState(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetState(blkID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockManager)(nil).GetState), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockManager)(nil).GetState), blkID) } // GetStatelessBlock mocks base method. -func (m *MockManager) GetStatelessBlock(arg0 ids.ID) (block.Block, error) { +func (m *MockManager) GetStatelessBlock(blkID ids.ID) (block.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStatelessBlock", arg0) + ret := m.ctrl.Call(m, "GetStatelessBlock", blkID) ret0, _ := ret[0].(block.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStatelessBlock indicates an expected call of GetStatelessBlock. -func (mr *MockManagerMockRecorder) GetStatelessBlock(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetStatelessBlock(blkID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessBlock", reflect.TypeOf((*MockManager)(nil).GetStatelessBlock), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessBlock", reflect.TypeOf((*MockManager)(nil).GetStatelessBlock), blkID) } // LastAccepted mocks base method. @@ -129,29 +130,43 @@ func (mr *MockManagerMockRecorder) Preferred() *gomock.Call { } // SetPreference mocks base method. -func (m *MockManager) SetPreference(arg0 ids.ID) bool { +func (m *MockManager) SetPreference(blkID ids.ID) bool { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetPreference", arg0) + ret := m.ctrl.Call(m, "SetPreference", blkID) ret0, _ := ret[0].(bool) return ret0 } // SetPreference indicates an expected call of SetPreference. -func (mr *MockManagerMockRecorder) SetPreference(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) SetPreference(blkID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockManager)(nil).SetPreference), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockManager)(nil).SetPreference), blkID) } // VerifyTx mocks base method. -func (m *MockManager) VerifyTx(arg0 *txs.Tx) error { +func (m *MockManager) VerifyTx(tx *txs.Tx) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VerifyTx", arg0) + ret := m.ctrl.Call(m, "VerifyTx", tx) ret0, _ := ret[0].(error) return ret0 } // VerifyTx indicates an expected call of VerifyTx. -func (mr *MockManagerMockRecorder) VerifyTx(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) VerifyTx(tx interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyTx", reflect.TypeOf((*MockManager)(nil).VerifyTx), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyTx", reflect.TypeOf((*MockManager)(nil).VerifyTx), tx) +} + +// VerifyUniqueInputs mocks base method. +func (m *MockManager) VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VerifyUniqueInputs", blkID, inputs) + ret0, _ := ret[0].(error) + return ret0 +} + +// VerifyUniqueInputs indicates an expected call of VerifyUniqueInputs. +func (mr *MockManagerMockRecorder) VerifyUniqueInputs(blkID, inputs interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyUniqueInputs", reflect.TypeOf((*MockManager)(nil).VerifyUniqueInputs), blkID, inputs) } From dd3759aa7bb7d1764b05f95c71420e25d6b45c4a Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:04:37 -0500 Subject: [PATCH 130/267] `vms/platformvm`: Add `TestBuildBlockShouldReward` test (#2466) --- vms/platformvm/block/builder/builder_test.go | 210 ++++++++++--------- 1 file changed, 110 insertions(+), 100 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index aaff6f1f008d..c536e10c6375 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -15,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/logging" @@ -27,7 +28,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" - txbuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" ) @@ -72,6 +72,115 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { require.NoError(env.mempool.GetDropReason(txID)) } +func TestBuildBlockShouldReward(t *testing.T) { + require := require.New(t) + + env := newEnvironment(t) + env.ctx.Lock.Lock() + defer func() { + require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() + }() + + var ( + now = env.backend.Clk.Time() + nodeID = ids.GenerateTestNodeID() + + defaultValidatorStake = 100 * units.MilliAvax + validatorStartTime = now.Add(2 * txexecutor.SyncBound) + validatorEndTime = validatorStartTime.Add(360 * 24 * time.Hour) + ) + + // Create a valid [AddValidatorTx] + tx, err := env.txBuilder.NewAddValidatorTx( + defaultValidatorStake, + uint64(validatorStartTime.Unix()), + uint64(validatorEndTime.Unix()), + nodeID, + preFundedKeys[0].PublicKey().Address(), + reward.PercentDenominator, + []*secp256k1.PrivateKey{preFundedKeys[0]}, + preFundedKeys[0].PublicKey().Address(), + ) + require.NoError(err) + txID := tx.ID() + + // Issue the transaction + require.NoError(env.network.IssueTx(context.Background(), tx)) + require.True(env.mempool.Has(txID)) + + // Build and accept a block with the tx + blk, err := env.Builder.BuildBlock(context.Background()) + require.NoError(err) + require.IsType(&block.BanffStandardBlock{}, blk.(*blockexecutor.Block).Block) + require.Equal([]*txs.Tx{tx}, blk.(*blockexecutor.Block).Block.Txs()) + require.NoError(blk.Verify(context.Background())) + require.NoError(blk.Accept(context.Background())) + require.True(env.blkManager.SetPreference(blk.ID())) + + // Validator should now be pending + staker, err := env.state.GetPendingValidator(constants.PrimaryNetworkID, nodeID) + require.NoError(err) + require.Equal(txID, staker.TxID) + + // Move it from pending to current + env.backend.Clk.Set(validatorStartTime) + blk, err = env.Builder.BuildBlock(context.Background()) + require.NoError(err) + require.NoError(blk.Verify(context.Background())) + require.NoError(blk.Accept(context.Background())) + require.True(env.blkManager.SetPreference(blk.ID())) + + staker, err = env.state.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) + require.NoError(err) + require.Equal(txID, staker.TxID) + + // Should be rewarded at the end of staking period + env.backend.Clk.Set(validatorEndTime) + + for { + iter, err := env.state.GetCurrentStakerIterator() + require.NoError(err) + require.True(iter.Next()) + staker := iter.Value() + iter.Release() + + // Check that the right block was built + blk, err := env.Builder.BuildBlock(context.Background()) + require.NoError(err) + require.NoError(blk.Verify(context.Background())) + require.IsType(&block.BanffProposalBlock{}, blk.(*blockexecutor.Block).Block) + + expectedTx, err := env.txBuilder.NewRewardValidatorTx(staker.TxID) + require.NoError(err) + require.Equal([]*txs.Tx{expectedTx}, blk.(*blockexecutor.Block).Block.Txs()) + + // Commit the [ProposalBlock] with a [CommitBlock] + proposalBlk, ok := blk.(snowman.OracleBlock) + require.True(ok) + options, err := proposalBlk.Options(context.Background()) + require.NoError(err) + + commit := options[0].(*blockexecutor.Block) + require.IsType(&block.BanffCommitBlock{}, commit.Block) + + require.NoError(blk.Accept(context.Background())) + require.NoError(commit.Verify(context.Background())) + require.NoError(commit.Accept(context.Background())) + require.True(env.blkManager.SetPreference(commit.ID())) + + // Stop rewarding once our staker is rewarded + if staker.TxID == txID { + break + } + } + + // Staking rewards should have been issued + rewardUTXOs, err := env.state.GetRewardUTXOs(txID) + require.NoError(err) + require.NotEmpty(rewardUTXOs) +} + func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { require := require.New(t) @@ -333,7 +442,6 @@ func TestBuildBlock(t *testing.T) { parentID = ids.GenerateTestID() height = uint64(1337) parentTimestamp = now.Add(-2 * time.Second) - stakerTxID = ids.GenerateTestID() defaultValidatorStake = 100 * units.MilliAvax validatorStartTime = now.Add(2 * txexecutor.SyncBound) @@ -363,104 +471,6 @@ func TestBuildBlock(t *testing.T) { } tests := []test{ - { - name: "should reward", - builderF: func(ctrl *gomock.Controller) *builder { - mempool := mempool.NewMockMempool(ctrl) - - // The tx builder should be asked to build a reward tx - txBuilder := txbuilder.NewMockBuilder(ctrl) - txBuilder.EXPECT().NewRewardValidatorTx(stakerTxID).Return(tx, nil) - - return &builder{ - Mempool: mempool, - txBuilder: txBuilder, - } - }, - timestamp: parentTimestamp, - forceAdvanceTime: false, - parentStateF: func(ctrl *gomock.Controller) state.Chain { - s := state.NewMockChain(ctrl) - - // add current validator that ends at [parentTimestamp] - // i.e. it should be rewarded - currentStakerIter := state.NewMockStakerIterator(ctrl) - currentStakerIter.EXPECT().Next().Return(true) - currentStakerIter.EXPECT().Value().Return(&state.Staker{ - TxID: stakerTxID, - Priority: txs.PrimaryNetworkDelegatorCurrentPriority, - EndTime: parentTimestamp, - }) - currentStakerIter.EXPECT().Release() - - s.EXPECT().GetCurrentStakerIterator().Return(currentStakerIter, nil) - return s - }, - expectedBlkF: func(require *require.Assertions) block.Block { - expectedBlk, err := block.NewBanffProposalBlock( - parentTimestamp, - parentID, - height, - tx, - []*txs.Tx{}, - ) - require.NoError(err) - return expectedBlk - }, - expectedErr: nil, - }, - { - name: "has decision txs", - builderF: func(ctrl *gomock.Controller) *builder { - mempool := mempool.NewMockMempool(ctrl) - - mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - - gomock.InOrder( - mempool.EXPECT().Peek().Return(tx, true), - mempool.EXPECT().Remove([]*txs.Tx{tx}), - // Second loop iteration - mempool.EXPECT().Peek().Return(nil, false), - ) - - return &builder{ - Mempool: mempool, - } - }, - timestamp: parentTimestamp, - forceAdvanceTime: false, - parentStateF: func(ctrl *gomock.Controller) state.Chain { - s := state.NewMockChain(ctrl) - - // Handle calls in [getNextStakerToReward] - // and [GetNextStakerChangeTime]. - // Next validator change time is in the future. - currentStakerIter := state.NewMockStakerIterator(ctrl) - gomock.InOrder( - // expect calls from [getNextStakerToReward] - currentStakerIter.EXPECT().Next().Return(true), - currentStakerIter.EXPECT().Value().Return(&state.Staker{ - NextTime: now.Add(time.Second), - Priority: txs.PrimaryNetworkDelegatorCurrentPriority, - }), - currentStakerIter.EXPECT().Release(), - ) - - s.EXPECT().GetCurrentStakerIterator().Return(currentStakerIter, nil).Times(1) - return s - }, - expectedBlkF: func(require *require.Assertions) block.Block { - expectedBlk, err := block.NewBanffStandardBlock( - parentTimestamp, - parentID, - height, - []*txs.Tx{tx}, - ) - require.NoError(err) - return expectedBlk - }, - expectedErr: nil, - }, { name: "no stakers tx", builderF: func(ctrl *gomock.Controller) *builder { From de89d1eb5bf376eeaa4395b9b896379e88cc3d6b Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 01:23:49 -0500 Subject: [PATCH 131/267] Switch client version to a proto type from a string (#2188) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- message/mock_outbound_message_builder.go | 8 +- message/outbound_msg_builder.go | 14 + network/peer/peer.go | 52 +- proto/p2p/p2p.proto | 11 + proto/pb/p2p/p2p.pb.go | 784 +++++++++++++---------- proto/pb/vm/vm.pb.go | 578 +++++++++-------- proto/vm/vm.proto | 7 +- version/application.go | 31 +- version/application_test.go | 15 + version/compatibility_test.go | 18 + version/constants.go | 12 +- version/parser.go | 9 +- version/parser_test.go | 13 +- version/version.go | 2 +- vms/rpcchainvm/vm_client.go | 7 +- vms/rpcchainvm/vm_server.go | 9 +- 16 files changed, 905 insertions(+), 665 deletions(-) diff --git a/message/mock_outbound_message_builder.go b/message/mock_outbound_message_builder.go index 6c128123cc3c..5f224e90da45 100644 --- a/message/mock_outbound_message_builder.go +++ b/message/mock_outbound_message_builder.go @@ -371,16 +371,16 @@ func (mr *MockOutboundMsgBuilderMockRecorder) StateSummaryFrontier(arg0, arg1, a } // Version mocks base method. -func (m *MockOutboundMsgBuilder) Version(arg0 uint32, arg1 uint64, arg2 ips.IPPort, arg3 string, arg4 uint64, arg5 []byte, arg6 []ids.ID) (OutboundMessage, error) { +func (m *MockOutboundMsgBuilder) Version(arg0 uint32, arg1 uint64, arg2 ips.IPPort, arg3, arg4 string, arg5, arg6, arg7 uint32, arg8 uint64, arg9 []byte, arg10 []ids.ID) (OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Version", arg0, arg1, arg2, arg3, arg4, arg5, arg6) + ret := m.ctrl.Call(m, "Version", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) ret0, _ := ret[0].(OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Version indicates an expected call of Version. -func (mr *MockOutboundMsgBuilderMockRecorder) Version(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Version(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Version), arg0, arg1, arg2, arg3, arg4, arg5, arg6) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Version), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) } diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index f38a1d98ffed..dc2cb4f7d6ba 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -23,6 +23,10 @@ type OutboundMsgBuilder interface { myTime uint64, ip ips.IPPort, myVersion string, + client string, + major uint32, + minor uint32, + patch uint32, myVersionTime uint64, sig []byte, trackedSubnets []ids.ID, @@ -229,6 +233,10 @@ func (b *outMsgBuilder) Version( myTime uint64, ip ips.IPPort, myVersion string, + client string, + major uint32, + minor uint32, + patch uint32, myVersionTime uint64, sig []byte, trackedSubnets []ids.ID, @@ -247,6 +255,12 @@ func (b *outMsgBuilder) Version( MyVersionTime: myVersionTime, Sig: sig, TrackedSubnets: subnetIDBytes, + Client: &p2p.Client{ + Name: client, + Major: major, + Minor: minor, + Patch: patch, + }, }, }, }, diff --git a/network/peer/peer.go b/network/peer/peer.go index 503f97262882..e35d1ba027f0 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -497,11 +497,23 @@ func (p *peer) writeMessages() { return } + myVersion := p.VersionCompatibility.Version() + legacyApplication := &version.Application{ + Name: version.LegacyAppName, + Major: myVersion.Major, + Minor: myVersion.Minor, + Patch: myVersion.Patch, + } + msg, err := p.MessageCreator.Version( p.NetworkID, p.Clock.Unix(), mySignedIP.IPPort, - p.VersionCompatibility.Version().String(), + legacyApplication.String(), + myVersion.Name, + uint32(myVersion.Major), + uint32(myVersion.Minor), + uint32(myVersion.Patch), mySignedIP.Timestamp, mySignedIP.Signature, p.MySubnets.List(), @@ -870,35 +882,45 @@ func (p *peer) handleVersion(msg *p2p.Version) { return } - peerVersion, err := version.ParseApplication(msg.MyVersion) - if err != nil { - p.Log.Debug("failed to parse peer version", - zap.Stringer("nodeID", p.id), - zap.Error(err), - ) - p.StartClose() - return + if msg.Client != nil { + p.version = &version.Application{ + Name: msg.Client.Name, + Major: int(msg.Client.Major), + Minor: int(msg.Client.Minor), + Patch: int(msg.Client.Patch), + } + } else { + // Handle legacy version field + peerVersion, err := version.ParseLegacyApplication(msg.MyVersion) + if err != nil { + p.Log.Debug("failed to parse peer version", + zap.Stringer("nodeID", p.id), + zap.Error(err), + ) + p.StartClose() + return + } + p.version = peerVersion } - p.version = peerVersion - if p.VersionCompatibility.Version().Before(peerVersion) { + if p.VersionCompatibility.Version().Before(p.version) { if _, ok := p.Beacons.GetValidator(constants.PrimaryNetworkID, p.id); ok { p.Log.Info("beacon attempting to connect with newer version. You may want to update your client", zap.Stringer("nodeID", p.id), - zap.Stringer("beaconVersion", peerVersion), + zap.Stringer("beaconVersion", p.version), ) } else { p.Log.Debug("peer attempting to connect with newer version. You may want to update your client", zap.Stringer("nodeID", p.id), - zap.Stringer("peerVersion", peerVersion), + zap.Stringer("peerVersion", p.version), ) } } - if err := p.VersionCompatibility.Compatible(peerVersion); err != nil { + if err := p.VersionCompatibility.Compatible(p.version); err != nil { p.Log.Verbo("peer version not compatible", zap.Stringer("nodeID", p.id), - zap.Stringer("peerVersion", peerVersion), + zap.Stringer("peerVersion", p.version), zap.Error(err), ) p.StartClose() diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 9b45148e3344..4f37af848fdb 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -115,6 +115,17 @@ message Version { bytes sig = 7; // Subnets the peer is tracking repeated bytes tracked_subnets = 8; + Client client = 9; +} + +// Metadata about a peer's P2P client used to determine compatibility +message Client { + // Client name (e.g avalanchego) + string name = 1; + // Client semantic version + uint32 major = 2; + uint32 minor = 3; + uint32 patch = 4; } // ClaimedIpPort contains metadata needed to connect to a peer diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index 8b804d1ceb02..235637d1dd0c 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -712,6 +712,7 @@ type Version struct { Sig []byte `protobuf:"bytes,7,opt,name=sig,proto3" json:"sig,omitempty"` // Subnets the peer is tracking TrackedSubnets [][]byte `protobuf:"bytes,8,rep,name=tracked_subnets,json=trackedSubnets,proto3" json:"tracked_subnets,omitempty"` + Client *Client `protobuf:"bytes,9,opt,name=client,proto3" json:"client,omitempty"` } func (x *Version) Reset() { @@ -802,6 +803,87 @@ func (x *Version) GetTrackedSubnets() [][]byte { return nil } +func (x *Version) GetClient() *Client { + if x != nil { + return x.Client + } + return nil +} + +// Metadata about a peer's P2P client used to determine compatibility +type Client struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Client name (e.g avalanchego) + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Client semantic version + Major uint32 `protobuf:"varint,2,opt,name=major,proto3" json:"major,omitempty"` + Minor uint32 `protobuf:"varint,3,opt,name=minor,proto3" json:"minor,omitempty"` + Patch uint32 `protobuf:"varint,4,opt,name=patch,proto3" json:"patch,omitempty"` +} + +func (x *Client) Reset() { + *x = Client{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Client) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Client) ProtoMessage() {} + +func (x *Client) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Client.ProtoReflect.Descriptor instead. +func (*Client) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{5} +} + +func (x *Client) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Client) GetMajor() uint32 { + if x != nil { + return x.Major + } + return 0 +} + +func (x *Client) GetMinor() uint32 { + if x != nil { + return x.Minor + } + return 0 +} + +func (x *Client) GetPatch() uint32 { + if x != nil { + return x.Patch + } + return 0 +} + // ClaimedIpPort contains metadata needed to connect to a peer type ClaimedIpPort struct { state protoimpl.MessageState @@ -825,7 +907,7 @@ type ClaimedIpPort struct { func (x *ClaimedIpPort) Reset() { *x = ClaimedIpPort{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[5] + mi := &file_p2p_p2p_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -838,7 +920,7 @@ func (x *ClaimedIpPort) String() string { func (*ClaimedIpPort) ProtoMessage() {} func (x *ClaimedIpPort) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[5] + mi := &file_p2p_p2p_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -851,7 +933,7 @@ func (x *ClaimedIpPort) ProtoReflect() protoreflect.Message { // Deprecated: Use ClaimedIpPort.ProtoReflect.Descriptor instead. func (*ClaimedIpPort) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{5} + return file_p2p_p2p_proto_rawDescGZIP(), []int{6} } func (x *ClaimedIpPort) GetX509Certificate() []byte { @@ -911,7 +993,7 @@ type PeerList struct { func (x *PeerList) Reset() { *x = PeerList{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[6] + mi := &file_p2p_p2p_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -924,7 +1006,7 @@ func (x *PeerList) String() string { func (*PeerList) ProtoMessage() {} func (x *PeerList) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[6] + mi := &file_p2p_p2p_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -937,7 +1019,7 @@ func (x *PeerList) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerList.ProtoReflect.Descriptor instead. func (*PeerList) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{6} + return file_p2p_p2p_proto_rawDescGZIP(), []int{7} } func (x *PeerList) GetClaimedIpPorts() []*ClaimedIpPort { @@ -964,7 +1046,7 @@ type PeerAck struct { func (x *PeerAck) Reset() { *x = PeerAck{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[7] + mi := &file_p2p_p2p_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -977,7 +1059,7 @@ func (x *PeerAck) String() string { func (*PeerAck) ProtoMessage() {} func (x *PeerAck) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[7] + mi := &file_p2p_p2p_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -990,7 +1072,7 @@ func (x *PeerAck) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerAck.ProtoReflect.Descriptor instead. func (*PeerAck) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{7} + return file_p2p_p2p_proto_rawDescGZIP(), []int{8} } func (x *PeerAck) GetTxId() []byte { @@ -1020,7 +1102,7 @@ type PeerListAck struct { func (x *PeerListAck) Reset() { *x = PeerListAck{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[8] + mi := &file_p2p_p2p_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1033,7 +1115,7 @@ func (x *PeerListAck) String() string { func (*PeerListAck) ProtoMessage() {} func (x *PeerListAck) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[8] + mi := &file_p2p_p2p_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1046,7 +1128,7 @@ func (x *PeerListAck) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerListAck.ProtoReflect.Descriptor instead. func (*PeerListAck) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{8} + return file_p2p_p2p_proto_rawDescGZIP(), []int{9} } func (x *PeerListAck) GetPeerAcks() []*PeerAck { @@ -1074,7 +1156,7 @@ type GetStateSummaryFrontier struct { func (x *GetStateSummaryFrontier) Reset() { *x = GetStateSummaryFrontier{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[9] + mi := &file_p2p_p2p_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1087,7 +1169,7 @@ func (x *GetStateSummaryFrontier) String() string { func (*GetStateSummaryFrontier) ProtoMessage() {} func (x *GetStateSummaryFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[9] + mi := &file_p2p_p2p_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1100,7 +1182,7 @@ func (x *GetStateSummaryFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateSummaryFrontier.ProtoReflect.Descriptor instead. func (*GetStateSummaryFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{9} + return file_p2p_p2p_proto_rawDescGZIP(), []int{10} } func (x *GetStateSummaryFrontier) GetChainId() []byte { @@ -1141,7 +1223,7 @@ type StateSummaryFrontier struct { func (x *StateSummaryFrontier) Reset() { *x = StateSummaryFrontier{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[10] + mi := &file_p2p_p2p_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1154,7 +1236,7 @@ func (x *StateSummaryFrontier) String() string { func (*StateSummaryFrontier) ProtoMessage() {} func (x *StateSummaryFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[10] + mi := &file_p2p_p2p_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1167,7 +1249,7 @@ func (x *StateSummaryFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryFrontier.ProtoReflect.Descriptor instead. func (*StateSummaryFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{10} + return file_p2p_p2p_proto_rawDescGZIP(), []int{11} } func (x *StateSummaryFrontier) GetChainId() []byte { @@ -1211,7 +1293,7 @@ type GetAcceptedStateSummary struct { func (x *GetAcceptedStateSummary) Reset() { *x = GetAcceptedStateSummary{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[11] + mi := &file_p2p_p2p_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1224,7 +1306,7 @@ func (x *GetAcceptedStateSummary) String() string { func (*GetAcceptedStateSummary) ProtoMessage() {} func (x *GetAcceptedStateSummary) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[11] + mi := &file_p2p_p2p_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1237,7 +1319,7 @@ func (x *GetAcceptedStateSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAcceptedStateSummary.ProtoReflect.Descriptor instead. func (*GetAcceptedStateSummary) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{11} + return file_p2p_p2p_proto_rawDescGZIP(), []int{12} } func (x *GetAcceptedStateSummary) GetChainId() []byte { @@ -1285,7 +1367,7 @@ type AcceptedStateSummary struct { func (x *AcceptedStateSummary) Reset() { *x = AcceptedStateSummary{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[12] + mi := &file_p2p_p2p_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1298,7 +1380,7 @@ func (x *AcceptedStateSummary) String() string { func (*AcceptedStateSummary) ProtoMessage() {} func (x *AcceptedStateSummary) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[12] + mi := &file_p2p_p2p_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1311,7 +1393,7 @@ func (x *AcceptedStateSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptedStateSummary.ProtoReflect.Descriptor instead. func (*AcceptedStateSummary) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{12} + return file_p2p_p2p_proto_rawDescGZIP(), []int{13} } func (x *AcceptedStateSummary) GetChainId() []byte { @@ -1356,7 +1438,7 @@ type GetAcceptedFrontier struct { func (x *GetAcceptedFrontier) Reset() { *x = GetAcceptedFrontier{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[13] + mi := &file_p2p_p2p_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1369,7 +1451,7 @@ func (x *GetAcceptedFrontier) String() string { func (*GetAcceptedFrontier) ProtoMessage() {} func (x *GetAcceptedFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[13] + mi := &file_p2p_p2p_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1382,7 +1464,7 @@ func (x *GetAcceptedFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAcceptedFrontier.ProtoReflect.Descriptor instead. func (*GetAcceptedFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{13} + return file_p2p_p2p_proto_rawDescGZIP(), []int{14} } func (x *GetAcceptedFrontier) GetChainId() []byte { @@ -1432,7 +1514,7 @@ type AcceptedFrontier struct { func (x *AcceptedFrontier) Reset() { *x = AcceptedFrontier{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[14] + mi := &file_p2p_p2p_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1445,7 +1527,7 @@ func (x *AcceptedFrontier) String() string { func (*AcceptedFrontier) ProtoMessage() {} func (x *AcceptedFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[14] + mi := &file_p2p_p2p_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1458,7 +1540,7 @@ func (x *AcceptedFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptedFrontier.ProtoReflect.Descriptor instead. func (*AcceptedFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{14} + return file_p2p_p2p_proto_rawDescGZIP(), []int{15} } func (x *AcceptedFrontier) GetChainId() []byte { @@ -1506,7 +1588,7 @@ type GetAccepted struct { func (x *GetAccepted) Reset() { *x = GetAccepted{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[15] + mi := &file_p2p_p2p_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1519,7 +1601,7 @@ func (x *GetAccepted) String() string { func (*GetAccepted) ProtoMessage() {} func (x *GetAccepted) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[15] + mi := &file_p2p_p2p_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1532,7 +1614,7 @@ func (x *GetAccepted) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAccepted.ProtoReflect.Descriptor instead. func (*GetAccepted) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{15} + return file_p2p_p2p_proto_rawDescGZIP(), []int{16} } func (x *GetAccepted) GetChainId() []byte { @@ -1590,7 +1672,7 @@ type Accepted struct { func (x *Accepted) Reset() { *x = Accepted{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[16] + mi := &file_p2p_p2p_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1603,7 +1685,7 @@ func (x *Accepted) String() string { func (*Accepted) ProtoMessage() {} func (x *Accepted) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[16] + mi := &file_p2p_p2p_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1616,7 +1698,7 @@ func (x *Accepted) ProtoReflect() protoreflect.Message { // Deprecated: Use Accepted.ProtoReflect.Descriptor instead. func (*Accepted) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{16} + return file_p2p_p2p_proto_rawDescGZIP(), []int{17} } func (x *Accepted) GetChainId() []byte { @@ -1663,7 +1745,7 @@ type GetAncestors struct { func (x *GetAncestors) Reset() { *x = GetAncestors{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[17] + mi := &file_p2p_p2p_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1676,7 +1758,7 @@ func (x *GetAncestors) String() string { func (*GetAncestors) ProtoMessage() {} func (x *GetAncestors) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[17] + mi := &file_p2p_p2p_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1689,7 +1771,7 @@ func (x *GetAncestors) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAncestors.ProtoReflect.Descriptor instead. func (*GetAncestors) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{17} + return file_p2p_p2p_proto_rawDescGZIP(), []int{18} } func (x *GetAncestors) GetChainId() []byte { @@ -1747,7 +1829,7 @@ type Ancestors struct { func (x *Ancestors) Reset() { *x = Ancestors{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[18] + mi := &file_p2p_p2p_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1760,7 +1842,7 @@ func (x *Ancestors) String() string { func (*Ancestors) ProtoMessage() {} func (x *Ancestors) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[18] + mi := &file_p2p_p2p_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1773,7 +1855,7 @@ func (x *Ancestors) ProtoReflect() protoreflect.Message { // Deprecated: Use Ancestors.ProtoReflect.Descriptor instead. func (*Ancestors) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{18} + return file_p2p_p2p_proto_rawDescGZIP(), []int{19} } func (x *Ancestors) GetChainId() []byte { @@ -1820,7 +1902,7 @@ type Get struct { func (x *Get) Reset() { *x = Get{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[19] + mi := &file_p2p_p2p_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1833,7 +1915,7 @@ func (x *Get) String() string { func (*Get) ProtoMessage() {} func (x *Get) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[19] + mi := &file_p2p_p2p_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1846,7 +1928,7 @@ func (x *Get) ProtoReflect() protoreflect.Message { // Deprecated: Use Get.ProtoReflect.Descriptor instead. func (*Get) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{19} + return file_p2p_p2p_proto_rawDescGZIP(), []int{20} } func (x *Get) GetChainId() []byte { @@ -1903,7 +1985,7 @@ type Put struct { func (x *Put) Reset() { *x = Put{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[20] + mi := &file_p2p_p2p_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1916,7 +1998,7 @@ func (x *Put) String() string { func (*Put) ProtoMessage() {} func (x *Put) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[20] + mi := &file_p2p_p2p_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1929,7 +2011,7 @@ func (x *Put) ProtoReflect() protoreflect.Message { // Deprecated: Use Put.ProtoReflect.Descriptor instead. func (*Put) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{20} + return file_p2p_p2p_proto_rawDescGZIP(), []int{21} } func (x *Put) GetChainId() []byte { @@ -1985,7 +2067,7 @@ type PushQuery struct { func (x *PushQuery) Reset() { *x = PushQuery{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[21] + mi := &file_p2p_p2p_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1998,7 +2080,7 @@ func (x *PushQuery) String() string { func (*PushQuery) ProtoMessage() {} func (x *PushQuery) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[21] + mi := &file_p2p_p2p_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2011,7 +2093,7 @@ func (x *PushQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PushQuery.ProtoReflect.Descriptor instead. func (*PushQuery) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{21} + return file_p2p_p2p_proto_rawDescGZIP(), []int{22} } func (x *PushQuery) GetChainId() []byte { @@ -2081,7 +2163,7 @@ type PullQuery struct { func (x *PullQuery) Reset() { *x = PullQuery{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[22] + mi := &file_p2p_p2p_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2094,7 +2176,7 @@ func (x *PullQuery) String() string { func (*PullQuery) ProtoMessage() {} func (x *PullQuery) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[22] + mi := &file_p2p_p2p_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2107,7 +2189,7 @@ func (x *PullQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PullQuery.ProtoReflect.Descriptor instead. func (*PullQuery) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{22} + return file_p2p_p2p_proto_rawDescGZIP(), []int{23} } func (x *PullQuery) GetChainId() []byte { @@ -2174,7 +2256,7 @@ type Chits struct { func (x *Chits) Reset() { *x = Chits{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[23] + mi := &file_p2p_p2p_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2187,7 +2269,7 @@ func (x *Chits) String() string { func (*Chits) ProtoMessage() {} func (x *Chits) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[23] + mi := &file_p2p_p2p_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2200,7 +2282,7 @@ func (x *Chits) ProtoReflect() protoreflect.Message { // Deprecated: Use Chits.ProtoReflect.Descriptor instead. func (*Chits) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{23} + return file_p2p_p2p_proto_rawDescGZIP(), []int{24} } func (x *Chits) GetChainId() []byte { @@ -2260,7 +2342,7 @@ type AppRequest struct { func (x *AppRequest) Reset() { *x = AppRequest{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[24] + mi := &file_p2p_p2p_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2273,7 +2355,7 @@ func (x *AppRequest) String() string { func (*AppRequest) ProtoMessage() {} func (x *AppRequest) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[24] + mi := &file_p2p_p2p_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2286,7 +2368,7 @@ func (x *AppRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AppRequest.ProtoReflect.Descriptor instead. func (*AppRequest) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{24} + return file_p2p_p2p_proto_rawDescGZIP(), []int{25} } func (x *AppRequest) GetChainId() []byte { @@ -2334,7 +2416,7 @@ type AppResponse struct { func (x *AppResponse) Reset() { *x = AppResponse{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[25] + mi := &file_p2p_p2p_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2347,7 +2429,7 @@ func (x *AppResponse) String() string { func (*AppResponse) ProtoMessage() {} func (x *AppResponse) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[25] + mi := &file_p2p_p2p_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2360,7 +2442,7 @@ func (x *AppResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AppResponse.ProtoReflect.Descriptor instead. func (*AppResponse) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{25} + return file_p2p_p2p_proto_rawDescGZIP(), []int{26} } func (x *AppResponse) GetChainId() []byte { @@ -2403,7 +2485,7 @@ type AppError struct { func (x *AppError) Reset() { *x = AppError{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[26] + mi := &file_p2p_p2p_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2416,7 +2498,7 @@ func (x *AppError) String() string { func (*AppError) ProtoMessage() {} func (x *AppError) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[26] + mi := &file_p2p_p2p_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2429,7 +2511,7 @@ func (x *AppError) ProtoReflect() protoreflect.Message { // Deprecated: Use AppError.ProtoReflect.Descriptor instead. func (*AppError) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{26} + return file_p2p_p2p_proto_rawDescGZIP(), []int{27} } func (x *AppError) GetChainId() []byte { @@ -2475,7 +2557,7 @@ type AppGossip struct { func (x *AppGossip) Reset() { *x = AppGossip{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[27] + mi := &file_p2p_p2p_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2488,7 +2570,7 @@ func (x *AppGossip) String() string { func (*AppGossip) ProtoMessage() {} func (x *AppGossip) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[27] + mi := &file_p2p_p2p_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2501,7 +2583,7 @@ func (x *AppGossip) ProtoReflect() protoreflect.Message { // Deprecated: Use AppGossip.ProtoReflect.Descriptor instead. func (*AppGossip) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{27} + return file_p2p_p2p_proto_rawDescGZIP(), []int{28} } func (x *AppGossip) GetChainId() []byte { @@ -2626,7 +2708,7 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0xf5, 0x01, 0x0a, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, @@ -2642,213 +2724,221 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, - 0x6e, 0x65, 0x74, 0x73, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, - 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, - 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, - 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, - 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, 0x70, - 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0e, - 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x3c, - 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x1c, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3e, 0x0a, 0x0b, - 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x09, 0x70, - 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, - 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x52, 0x08, 0x70, 0x65, - 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6f, 0x0a, 0x17, - 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, - 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, + 0x6e, 0x65, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x5e, 0x0a, 0x06, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, + 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, + 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, + 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, + 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, + 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, + 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, + 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, + 0x72, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x12, 0x13, + 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, + 0x78, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x22, 0x3e, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, + 0x12, 0x29, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, + 0x6b, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, + 0x02, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, + 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, + 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x9d, 0x01, + 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, - 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, + 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x75, 0x0a, + 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, + 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x4a, 0x04, + 0x08, 0x04, 0x10, 0x05, 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, + 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x6f, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x75, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, - 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, - 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6f, 0x0a, 0x08, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb9, 0x01, - 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x04, + 0x10, 0x05, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, + 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6b, + 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x01, 0x0a, 0x03, + 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, + 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8f, + 0x01, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, + 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x22, 0xdc, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, - 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x6e, 0x63, - 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, - 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, + 0xe1, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, + 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, + 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, - 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, 0x75, - 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, - 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x09, - 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, - 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x09, 0x50, - 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xba, - 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, - 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, - 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, + 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, + 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, - 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, - 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, - 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, - 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, - 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, - 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, + 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, + 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, + 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, + 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2864,7 +2954,7 @@ func file_p2p_p2p_proto_rawDescGZIP() []byte { } var file_p2p_p2p_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_p2p_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 28) +var file_p2p_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 29) var file_p2p_p2p_proto_goTypes = []interface{}{ (EngineType)(0), // 0: p2p.EngineType (*Message)(nil), // 1: p2p.Message @@ -2872,71 +2962,73 @@ var file_p2p_p2p_proto_goTypes = []interface{}{ (*SubnetUptime)(nil), // 3: p2p.SubnetUptime (*Pong)(nil), // 4: p2p.Pong (*Version)(nil), // 5: p2p.Version - (*ClaimedIpPort)(nil), // 6: p2p.ClaimedIpPort - (*PeerList)(nil), // 7: p2p.PeerList - (*PeerAck)(nil), // 8: p2p.PeerAck - (*PeerListAck)(nil), // 9: p2p.PeerListAck - (*GetStateSummaryFrontier)(nil), // 10: p2p.GetStateSummaryFrontier - (*StateSummaryFrontier)(nil), // 11: p2p.StateSummaryFrontier - (*GetAcceptedStateSummary)(nil), // 12: p2p.GetAcceptedStateSummary - (*AcceptedStateSummary)(nil), // 13: p2p.AcceptedStateSummary - (*GetAcceptedFrontier)(nil), // 14: p2p.GetAcceptedFrontier - (*AcceptedFrontier)(nil), // 15: p2p.AcceptedFrontier - (*GetAccepted)(nil), // 16: p2p.GetAccepted - (*Accepted)(nil), // 17: p2p.Accepted - (*GetAncestors)(nil), // 18: p2p.GetAncestors - (*Ancestors)(nil), // 19: p2p.Ancestors - (*Get)(nil), // 20: p2p.Get - (*Put)(nil), // 21: p2p.Put - (*PushQuery)(nil), // 22: p2p.PushQuery - (*PullQuery)(nil), // 23: p2p.PullQuery - (*Chits)(nil), // 24: p2p.Chits - (*AppRequest)(nil), // 25: p2p.AppRequest - (*AppResponse)(nil), // 26: p2p.AppResponse - (*AppError)(nil), // 27: p2p.AppError - (*AppGossip)(nil), // 28: p2p.AppGossip + (*Client)(nil), // 6: p2p.Client + (*ClaimedIpPort)(nil), // 7: p2p.ClaimedIpPort + (*PeerList)(nil), // 8: p2p.PeerList + (*PeerAck)(nil), // 9: p2p.PeerAck + (*PeerListAck)(nil), // 10: p2p.PeerListAck + (*GetStateSummaryFrontier)(nil), // 11: p2p.GetStateSummaryFrontier + (*StateSummaryFrontier)(nil), // 12: p2p.StateSummaryFrontier + (*GetAcceptedStateSummary)(nil), // 13: p2p.GetAcceptedStateSummary + (*AcceptedStateSummary)(nil), // 14: p2p.AcceptedStateSummary + (*GetAcceptedFrontier)(nil), // 15: p2p.GetAcceptedFrontier + (*AcceptedFrontier)(nil), // 16: p2p.AcceptedFrontier + (*GetAccepted)(nil), // 17: p2p.GetAccepted + (*Accepted)(nil), // 18: p2p.Accepted + (*GetAncestors)(nil), // 19: p2p.GetAncestors + (*Ancestors)(nil), // 20: p2p.Ancestors + (*Get)(nil), // 21: p2p.Get + (*Put)(nil), // 22: p2p.Put + (*PushQuery)(nil), // 23: p2p.PushQuery + (*PullQuery)(nil), // 24: p2p.PullQuery + (*Chits)(nil), // 25: p2p.Chits + (*AppRequest)(nil), // 26: p2p.AppRequest + (*AppResponse)(nil), // 27: p2p.AppResponse + (*AppError)(nil), // 28: p2p.AppError + (*AppGossip)(nil), // 29: p2p.AppGossip } var file_p2p_p2p_proto_depIdxs = []int32{ 2, // 0: p2p.Message.ping:type_name -> p2p.Ping 4, // 1: p2p.Message.pong:type_name -> p2p.Pong 5, // 2: p2p.Message.version:type_name -> p2p.Version - 7, // 3: p2p.Message.peer_list:type_name -> p2p.PeerList - 10, // 4: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier - 11, // 5: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier - 12, // 6: p2p.Message.get_accepted_state_summary:type_name -> p2p.GetAcceptedStateSummary - 13, // 7: p2p.Message.accepted_state_summary:type_name -> p2p.AcceptedStateSummary - 14, // 8: p2p.Message.get_accepted_frontier:type_name -> p2p.GetAcceptedFrontier - 15, // 9: p2p.Message.accepted_frontier:type_name -> p2p.AcceptedFrontier - 16, // 10: p2p.Message.get_accepted:type_name -> p2p.GetAccepted - 17, // 11: p2p.Message.accepted:type_name -> p2p.Accepted - 18, // 12: p2p.Message.get_ancestors:type_name -> p2p.GetAncestors - 19, // 13: p2p.Message.ancestors:type_name -> p2p.Ancestors - 20, // 14: p2p.Message.get:type_name -> p2p.Get - 21, // 15: p2p.Message.put:type_name -> p2p.Put - 22, // 16: p2p.Message.push_query:type_name -> p2p.PushQuery - 23, // 17: p2p.Message.pull_query:type_name -> p2p.PullQuery - 24, // 18: p2p.Message.chits:type_name -> p2p.Chits - 25, // 19: p2p.Message.app_request:type_name -> p2p.AppRequest - 26, // 20: p2p.Message.app_response:type_name -> p2p.AppResponse - 28, // 21: p2p.Message.app_gossip:type_name -> p2p.AppGossip - 9, // 22: p2p.Message.peer_list_ack:type_name -> p2p.PeerListAck - 27, // 23: p2p.Message.app_error:type_name -> p2p.AppError + 8, // 3: p2p.Message.peer_list:type_name -> p2p.PeerList + 11, // 4: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier + 12, // 5: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier + 13, // 6: p2p.Message.get_accepted_state_summary:type_name -> p2p.GetAcceptedStateSummary + 14, // 7: p2p.Message.accepted_state_summary:type_name -> p2p.AcceptedStateSummary + 15, // 8: p2p.Message.get_accepted_frontier:type_name -> p2p.GetAcceptedFrontier + 16, // 9: p2p.Message.accepted_frontier:type_name -> p2p.AcceptedFrontier + 17, // 10: p2p.Message.get_accepted:type_name -> p2p.GetAccepted + 18, // 11: p2p.Message.accepted:type_name -> p2p.Accepted + 19, // 12: p2p.Message.get_ancestors:type_name -> p2p.GetAncestors + 20, // 13: p2p.Message.ancestors:type_name -> p2p.Ancestors + 21, // 14: p2p.Message.get:type_name -> p2p.Get + 22, // 15: p2p.Message.put:type_name -> p2p.Put + 23, // 16: p2p.Message.push_query:type_name -> p2p.PushQuery + 24, // 17: p2p.Message.pull_query:type_name -> p2p.PullQuery + 25, // 18: p2p.Message.chits:type_name -> p2p.Chits + 26, // 19: p2p.Message.app_request:type_name -> p2p.AppRequest + 27, // 20: p2p.Message.app_response:type_name -> p2p.AppResponse + 29, // 21: p2p.Message.app_gossip:type_name -> p2p.AppGossip + 10, // 22: p2p.Message.peer_list_ack:type_name -> p2p.PeerListAck + 28, // 23: p2p.Message.app_error:type_name -> p2p.AppError 3, // 24: p2p.Ping.subnet_uptimes:type_name -> p2p.SubnetUptime 3, // 25: p2p.Pong.subnet_uptimes:type_name -> p2p.SubnetUptime - 6, // 26: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort - 8, // 27: p2p.PeerListAck.peer_acks:type_name -> p2p.PeerAck - 0, // 28: p2p.GetAcceptedFrontier.engine_type:type_name -> p2p.EngineType - 0, // 29: p2p.GetAccepted.engine_type:type_name -> p2p.EngineType - 0, // 30: p2p.GetAncestors.engine_type:type_name -> p2p.EngineType - 0, // 31: p2p.Get.engine_type:type_name -> p2p.EngineType - 0, // 32: p2p.Put.engine_type:type_name -> p2p.EngineType - 0, // 33: p2p.PushQuery.engine_type:type_name -> p2p.EngineType - 0, // 34: p2p.PullQuery.engine_type:type_name -> p2p.EngineType - 35, // [35:35] is the sub-list for method output_type - 35, // [35:35] is the sub-list for method input_type - 35, // [35:35] is the sub-list for extension type_name - 35, // [35:35] is the sub-list for extension extendee - 0, // [0:35] is the sub-list for field type_name + 6, // 26: p2p.Version.client:type_name -> p2p.Client + 7, // 27: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort + 9, // 28: p2p.PeerListAck.peer_acks:type_name -> p2p.PeerAck + 0, // 29: p2p.GetAcceptedFrontier.engine_type:type_name -> p2p.EngineType + 0, // 30: p2p.GetAccepted.engine_type:type_name -> p2p.EngineType + 0, // 31: p2p.GetAncestors.engine_type:type_name -> p2p.EngineType + 0, // 32: p2p.Get.engine_type:type_name -> p2p.EngineType + 0, // 33: p2p.Put.engine_type:type_name -> p2p.EngineType + 0, // 34: p2p.PushQuery.engine_type:type_name -> p2p.EngineType + 0, // 35: p2p.PullQuery.engine_type:type_name -> p2p.EngineType + 36, // [36:36] is the sub-list for method output_type + 36, // [36:36] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name } func init() { file_p2p_p2p_proto_init() } @@ -3006,7 +3098,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClaimedIpPort); i { + switch v := v.(*Client); i { case 0: return &v.state case 1: @@ -3018,7 +3110,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerList); i { + switch v := v.(*ClaimedIpPort); i { case 0: return &v.state case 1: @@ -3030,7 +3122,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerAck); i { + switch v := v.(*PeerList); i { case 0: return &v.state case 1: @@ -3042,7 +3134,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerListAck); i { + switch v := v.(*PeerAck); i { case 0: return &v.state case 1: @@ -3054,7 +3146,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetStateSummaryFrontier); i { + switch v := v.(*PeerListAck); i { case 0: return &v.state case 1: @@ -3066,7 +3158,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StateSummaryFrontier); i { + switch v := v.(*GetStateSummaryFrontier); i { case 0: return &v.state case 1: @@ -3078,7 +3170,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetAcceptedStateSummary); i { + switch v := v.(*StateSummaryFrontier); i { case 0: return &v.state case 1: @@ -3090,7 +3182,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AcceptedStateSummary); i { + switch v := v.(*GetAcceptedStateSummary); i { case 0: return &v.state case 1: @@ -3102,7 +3194,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetAcceptedFrontier); i { + switch v := v.(*AcceptedStateSummary); i { case 0: return &v.state case 1: @@ -3114,7 +3206,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AcceptedFrontier); i { + switch v := v.(*GetAcceptedFrontier); i { case 0: return &v.state case 1: @@ -3126,7 +3218,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetAccepted); i { + switch v := v.(*AcceptedFrontier); i { case 0: return &v.state case 1: @@ -3138,7 +3230,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Accepted); i { + switch v := v.(*GetAccepted); i { case 0: return &v.state case 1: @@ -3150,7 +3242,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetAncestors); i { + switch v := v.(*Accepted); i { case 0: return &v.state case 1: @@ -3162,7 +3254,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Ancestors); i { + switch v := v.(*GetAncestors); i { case 0: return &v.state case 1: @@ -3174,7 +3266,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Get); i { + switch v := v.(*Ancestors); i { case 0: return &v.state case 1: @@ -3186,7 +3278,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Put); i { + switch v := v.(*Get); i { case 0: return &v.state case 1: @@ -3198,7 +3290,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PushQuery); i { + switch v := v.(*Put); i { case 0: return &v.state case 1: @@ -3210,7 +3302,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PullQuery); i { + switch v := v.(*PushQuery); i { case 0: return &v.state case 1: @@ -3222,7 +3314,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Chits); i { + switch v := v.(*PullQuery); i { case 0: return &v.state case 1: @@ -3234,7 +3326,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AppRequest); i { + switch v := v.(*Chits); i { case 0: return &v.state case 1: @@ -3246,7 +3338,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AppResponse); i { + switch v := v.(*AppRequest); i { case 0: return &v.state case 1: @@ -3258,7 +3350,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AppError); i { + switch v := v.(*AppResponse); i { case 0: return &v.state case 1: @@ -3270,6 +3362,18 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppGossip); i { case 0: return &v.state @@ -3316,7 +3420,7 @@ func file_p2p_p2p_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_p2p_p2p_proto_rawDesc, NumEnums: 1, - NumMessages: 28, + NumMessages: 29, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/pb/vm/vm.pb.go b/proto/pb/vm/vm.pb.go index ebc64f5c3a48..a68fbbca4bc6 100644 --- a/proto/pb/vm/vm.pb.go +++ b/proto/pb/vm/vm.pb.go @@ -1956,8 +1956,13 @@ type ConnectedRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - NodeId []byte `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + NodeId []byte `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` + // Client name (e.g avalanchego) + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Client semantic version + Major uint32 `protobuf:"varint,3,opt,name=major,proto3" json:"major,omitempty"` + Minor uint32 `protobuf:"varint,4,opt,name=minor,proto3" json:"minor,omitempty"` + Patch uint32 `protobuf:"varint,5,opt,name=patch,proto3" json:"patch,omitempty"` } func (x *ConnectedRequest) Reset() { @@ -1999,13 +2004,34 @@ func (x *ConnectedRequest) GetNodeId() []byte { return nil } -func (x *ConnectedRequest) GetVersion() string { +func (x *ConnectedRequest) GetName() string { if x != nil { - return x.Version + return x.Name } return "" } +func (x *ConnectedRequest) GetMajor() uint32 { + if x != nil { + return x.Major + } + return 0 +} + +func (x *ConnectedRequest) GetMinor() uint32 { + if x != nil { + return x.Minor + } + return 0 +} + +func (x *ConnectedRequest) GetPatch() uint32 { + if x != nil { + return x.Patch + } + return 0 +} + type DisconnectedRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3192,281 +3218,285 @@ var file_vm_vm_proto_rawDesc = []byte{ 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x45, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x2e, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, - 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, - 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, - 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, - 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4e, 0x75, 0x6d, 0x12, 0x26, 0x0a, 0x0f, 0x6d, - 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x53, - 0x69, 0x7a, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x73, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, - 0x52, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x14, - 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6b, 0x73, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4f, 0x0a, 0x19, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x0a, 0x19, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, - 0x03, 0x65, 0x72, 0x72, 0x22, 0x33, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x50, 0x0a, 0x1a, 0x47, 0x65, 0x74, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x1b, - 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, - 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x5d, 0x0a, 0x0e, 0x47, - 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, - 0x0f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, - 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, - 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x7f, 0x0a, - 0x22, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, - 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x78, - 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, - 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x73, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x60, 0x0a, 0x19, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, - 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x16, - 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5c, - 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, - 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, - 0xc5, 0x01, 0x0a, 0x1a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, - 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, - 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, - 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, - 0x03, 0x65, 0x72, 0x72, 0x22, 0x51, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, - 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, - 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x49, 0x43, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, - 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x10, 0x03, 0x2a, 0x65, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, - 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, - 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x61, - 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, - 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, - 0x03, 0x2a, 0x8e, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, - 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, - 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, - 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, - 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, - 0x10, 0x04, 0x32, 0xa4, 0x12, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, - 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, - 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x50, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, - 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x20, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x39, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, - 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, - 0x6d, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, - 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, - 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, - 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, - 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x37, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, - 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, - 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, - 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, - 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, - 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, - 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, - 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x34, 0x0a, 0x06, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x14, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, - 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x57, 0x0a, 0x1a, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x12, 0x21, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x43, - 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, - 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, - 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, - 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, - 0x11, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, - 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, - 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4a, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x76, - 0x6d, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, - 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, - 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, - 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x48, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, - 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, + 0x81, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, + 0x74, 0x63, 0x68, 0x22, 0x2e, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, + 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, + 0x65, 0x49, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x62, + 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, + 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, + 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4e, 0x75, 0x6d, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x69, 0x7a, 0x65, + 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x72, + 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x74, + 0x72, 0x69, 0x76, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, 0x74, + 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x22, 0x34, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4f, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x0a, 0x19, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, + 0x72, 0x22, 0x33, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, + 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, + 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x50, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, + 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x5d, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x68, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, + 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, + 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, + 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x7f, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, + 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, + 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x78, 0x0a, 0x1b, 0x47, + 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x60, 0x0a, 0x19, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x03, + 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5c, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, + 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc5, 0x01, 0x0a, + 0x1a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, 0x6d, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, + 0x72, 0x22, 0x51, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, + 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, + 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, + 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, + 0x49, 0x43, 0x10, 0x03, 0x2a, 0x65, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, + 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, + 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, + 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, + 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x61, 0x0a, 0x06, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, + 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, + 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, + 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x8e, + 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, + 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, + 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x49, 0x4e, 0x43, + 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4e, 0x4f, + 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x04, 0x32, + 0xa4, 0x12, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, + 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x53, 0x68, + 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x14, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x76, + 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, + 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, + 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, 0x2e, 0x76, 0x6d, + 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x44, + 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0a, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, + 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0d, 0x53, + 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x76, + 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, + 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x26, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, - 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, - 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, + 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, - 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, - 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, - 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, - 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, - 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, - 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x76, 0x6d, 0x2e, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, - 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x41, + 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, + 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x41, 0x70, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x41, + 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, + 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, + 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x06, + 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, + 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x14, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, + 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x57, 0x0a, 0x1a, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x2e, + 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x43, 0x72, 0x6f, 0x73, + 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, + 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, + 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x56, + 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, + 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, + 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, + 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4f, 0x6e, + 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, + 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, + 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x53, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, - 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, + 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, + 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x6d, 0x2e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, + 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x53, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x70, 0x62, 0x2f, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/vm/vm.proto b/proto/vm/vm.proto index 0eca74b46041..4a68c5e91810 100644 --- a/proto/vm/vm.proto +++ b/proto/vm/vm.proto @@ -306,7 +306,12 @@ message CrossChainAppResponseMsg { message ConnectedRequest { bytes node_id = 1; - string version = 2; + // Client name (e.g avalanchego) + string name = 2; + // Client semantic version + uint32 major = 3; + uint32 minor = 4; + uint32 patch = 5; } message DisconnectedRequest { diff --git a/version/application.go b/version/application.go index bc545e54fa4b..a4956dfd78d6 100644 --- a/version/application.go +++ b/version/application.go @@ -6,9 +6,11 @@ package version import ( "errors" "fmt" - "sync/atomic" + "sync" ) +const LegacyAppName = "avalanche" + var ( errDifferentMajor = errors.New("different major version") @@ -16,29 +18,30 @@ var ( ) type Application struct { - Major int `json:"major" yaml:"major"` - Minor int `json:"minor" yaml:"minor"` - Patch int `json:"patch" yaml:"patch"` + Name string `json:"name" yaml:"name"` + Major int `json:"major" yaml:"major"` + Minor int `json:"minor" yaml:"minor"` + Patch int `json:"patch" yaml:"patch"` - str atomic.Value + makeStrOnce sync.Once + str string } // The only difference here between Application and Semantic is that Application -// prepends "avalanche/" rather than "v". +// prepends the client name rather than "v". func (a *Application) String() string { - strIntf := a.str.Load() - if strIntf != nil { - return strIntf.(string) - } + a.makeStrOnce.Do(a.initString) + return a.str +} - str := fmt.Sprintf( - "avalanche/%d.%d.%d", +func (a *Application) initString() { + a.str = fmt.Sprintf( + "%s/%d.%d.%d", + a.Name, a.Major, a.Minor, a.Patch, ) - a.str.Store(str) - return str } func (a *Application) Compatible(o *Application) error { diff --git a/version/application_test.go b/version/application_test.go index 0423e91918e5..09d049edcb77 100644 --- a/version/application_test.go +++ b/version/application_test.go @@ -14,6 +14,7 @@ func TestNewDefaultApplication(t *testing.T) { require := require.New(t) v := &Application{ + Name: LegacyAppName, Major: 1, Minor: 2, Patch: 3, @@ -33,11 +34,13 @@ func TestComparingVersions(t *testing.T) { }{ { myVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 3, }, peerVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 3, @@ -47,11 +50,13 @@ func TestComparingVersions(t *testing.T) { }, { myVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 4, }, peerVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 3, @@ -61,11 +66,13 @@ func TestComparingVersions(t *testing.T) { }, { myVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 3, }, peerVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 4, @@ -75,11 +82,13 @@ func TestComparingVersions(t *testing.T) { }, { myVersion: &Application{ + Name: Client, Major: 1, Minor: 3, Patch: 3, }, peerVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 3, @@ -89,11 +98,13 @@ func TestComparingVersions(t *testing.T) { }, { myVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 3, }, peerVersion: &Application{ + Name: Client, Major: 1, Minor: 3, Patch: 3, @@ -103,11 +114,13 @@ func TestComparingVersions(t *testing.T) { }, { myVersion: &Application{ + Name: Client, Major: 2, Minor: 2, Patch: 3, }, peerVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 3, @@ -117,11 +130,13 @@ func TestComparingVersions(t *testing.T) { }, { myVersion: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 3, }, peerVersion: &Application{ + Name: Client, Major: 2, Minor: 2, Patch: 3, diff --git a/version/compatibility_test.go b/version/compatibility_test.go index a95a85af55dd..1e4cbd03315f 100644 --- a/version/compatibility_test.go +++ b/version/compatibility_test.go @@ -13,17 +13,20 @@ import ( func TestCompatibility(t *testing.T) { v := &Application{ + Name: Client, Major: 1, Minor: 4, Patch: 3, } minCompatable := &Application{ + Name: Client, Major: 1, Minor: 4, Patch: 0, } minCompatableTime := time.Unix(9000, 0) prevMinCompatable := &Application{ + Name: Client, Major: 1, Minor: 3, Patch: 0, @@ -44,6 +47,7 @@ func TestCompatibility(t *testing.T) { }{ { peer: &Application{ + Name: LegacyAppName, Major: 1, Minor: 5, Patch: 0, @@ -52,6 +56,16 @@ func TestCompatibility(t *testing.T) { }, { peer: &Application{ + Name: Client, + Major: 1, + Minor: 5, + Patch: 0, + }, + time: minCompatableTime, + }, + { + peer: &Application{ + Name: Client, Major: 1, Minor: 3, Patch: 5, @@ -60,6 +74,7 @@ func TestCompatibility(t *testing.T) { }, { peer: &Application{ + Name: Client, Major: 0, Minor: 1, Patch: 0, @@ -69,6 +84,7 @@ func TestCompatibility(t *testing.T) { }, { peer: &Application{ + Name: Client, Major: 1, Minor: 3, Patch: 5, @@ -78,6 +94,7 @@ func TestCompatibility(t *testing.T) { }, { peer: &Application{ + Name: Client, Major: 1, Minor: 2, Patch: 5, @@ -87,6 +104,7 @@ func TestCompatibility(t *testing.T) { }, { peer: &Application{ + Name: Client, Major: 1, Minor: 1, Patch: 5, diff --git a/version/constants.go b/version/constants.go index f7c27f641395..069868162094 100644 --- a/version/constants.go +++ b/version/constants.go @@ -13,9 +13,12 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" ) -// RPCChainVMProtocol should be bumped anytime changes are made which require -// the plugin vm to upgrade to latest avalanchego release to be compatible. -const RPCChainVMProtocol uint = 30 +const ( + Client = "avalanchego" + // RPCChainVMProtocol should be bumped anytime changes are made which require + // the plugin vm to upgrade to latest avalanchego release to be compatible. + RPCChainVMProtocol uint = 30 +) // These are globals that describe network upgrades and node versions var ( @@ -25,16 +28,19 @@ var ( Patch: 17, } CurrentApp = &Application{ + Name: Client, Major: Current.Major, Minor: Current.Minor, Patch: Current.Patch, } MinimumCompatibleVersion = &Application{ + Name: Client, Major: 1, Minor: 10, Patch: 0, } PrevMinimumCompatibleVersion = &Application{ + Name: Client, Major: 1, Minor: 9, Patch: 0, diff --git a/version/parser.go b/version/parser.go index debb636a92cb..be4bd1a54930 100644 --- a/version/parser.go +++ b/version/parser.go @@ -34,18 +34,21 @@ func Parse(s string) (*Semantic, error) { }, nil } -func ParseApplication(s string) (*Application, error) { - if !strings.HasPrefix(s, "avalanche/") { +// TODO: Remove after v1.11.x is activated +func ParseLegacyApplication(s string) (*Application, error) { + prefix := fmt.Sprintf("%s/", LegacyAppName) + if !strings.HasPrefix(s, prefix) { return nil, fmt.Errorf("%w: %q", errMissingApplicationPrefix, s) } - s = s[10:] + s = s[len(prefix):] major, minor, patch, err := parseVersions(s) if err != nil { return nil, err } return &Application{ + Name: Client, // Convert the legacy name to the current client name Major: major, Minor: minor, Patch: patch, diff --git a/version/parser_test.go b/version/parser_test.go index 3bc8b5e30589..9a1175ea11b8 100644 --- a/version/parser_test.go +++ b/version/parser_test.go @@ -65,12 +65,13 @@ func TestParse(t *testing.T) { } } -func TestParseApplication(t *testing.T) { - v, err := ParseApplication("avalanche/1.2.3") +func TestParseLegacyApplication(t *testing.T) { + v, err := ParseLegacyApplication("avalanche/1.2.3") require.NoError(t, err) require.NotNil(t, v) - require.Equal(t, "avalanche/1.2.3", v.String()) + require.Equal(t, "avalanchego/1.2.3", v.String()) + require.Equal(t, "avalanchego", v.Name) require.Equal(t, 1, v.Major) require.Equal(t, 2, v.Minor) require.Equal(t, 3, v.Patch) @@ -85,6 +86,10 @@ func TestParseApplication(t *testing.T) { version: "", expectedErr: errMissingApplicationPrefix, }, + { + version: "avalanchego/v1.2.3", + expectedErr: errMissingApplicationPrefix, + }, { version: "avalanche/", expectedErr: errMissingVersions, @@ -108,7 +113,7 @@ func TestParseApplication(t *testing.T) { } for _, test := range tests { t.Run(test.version, func(t *testing.T) { - _, err := ParseApplication(test.version) + _, err := ParseLegacyApplication(test.version) require.ErrorIs(t, err, test.expectedErr) }) } diff --git a/version/version.go b/version/version.go index 81acdc42e77b..59fb9b937883 100644 --- a/version/version.go +++ b/version/version.go @@ -28,7 +28,7 @@ type Semantic struct { } // The only difference here between Semantic and Application is that Semantic -// prepends "v" rather than "avalanche/". +// prepends "v" rather than the client name. func (s *Semantic) String() string { strIntf := s.str.Load() if strIntf != nil { diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go index d9915bfbfcd6..8f6c82e3d77d 100644 --- a/vms/rpcchainvm/vm_client.go +++ b/vms/rpcchainvm/vm_client.go @@ -396,8 +396,11 @@ func (vm *VMClient) CreateStaticHandlers(ctx context.Context) (map[string]http.H func (vm *VMClient) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { _, err := vm.client.Connected(ctx, &vmpb.ConnectedRequest{ - NodeId: nodeID.Bytes(), - Version: nodeVersion.String(), + NodeId: nodeID.Bytes(), + Name: nodeVersion.Name, + Major: uint32(nodeVersion.Major), + Minor: uint32(nodeVersion.Minor), + Patch: uint32(nodeVersion.Patch), }) return err } diff --git a/vms/rpcchainvm/vm_server.go b/vms/rpcchainvm/vm_server.go index 7ee82a241506..e35e7a950e9b 100644 --- a/vms/rpcchainvm/vm_server.go +++ b/vms/rpcchainvm/vm_server.go @@ -369,11 +369,12 @@ func (vm *VMServer) Connected(ctx context.Context, req *vmpb.ConnectedRequest) ( return nil, err } - peerVersion, err := version.ParseApplication(req.Version) - if err != nil { - return nil, err + peerVersion := &version.Application{ + Name: req.Name, + Major: int(req.Major), + Minor: int(req.Minor), + Patch: int(req.Patch), } - return &emptypb.Empty{}, vm.vm.Connected(ctx, nodeID, peerVersion) } From baf0fbd56fad8757d72146ec966446455bdd4b1c Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 12 Dec 2023 10:59:58 -0500 Subject: [PATCH 132/267] Remove stale TODO (#2468) --- x/merkledb/history.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x/merkledb/history.go b/x/merkledb/history.go index dd4ff4f93c8c..3717f9ef9b96 100644 --- a/x/merkledb/history.go +++ b/x/merkledb/history.go @@ -98,10 +98,6 @@ func (th *trieHistory) getValueChanges( } // [endRootChanges] is the last change in the history resulting in [endRoot]. - // TODO when we update to minimum go version 1.20.X, make this return another - // wrapped error ErrNoEndRoot. In NetworkServer.HandleChangeProofRequest, if we return - // that error, we know we shouldn't try to generate a range proof since we - // lack the necessary history. endRootChanges, ok := th.lastChanges[endRoot] if !ok { return nil, fmt.Errorf("%w: %s", ErrNoEndRoot, endRoot) From 054b5e915a82fa367330eec63942ae613f5d73b0 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:19:15 -0500 Subject: [PATCH 133/267] `vms/platformvm`: Add `TestBuildBlockDoesNotBuildWithEmptyMempool` test (#2469) --- vms/platformvm/block/builder/builder_test.go | 72 ++++++-------------- 1 file changed, 21 insertions(+), 51 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index c536e10c6375..97018ee9839c 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -14,11 +14,9 @@ import ( "go.uber.org/mock/gomock" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/block" @@ -31,7 +29,7 @@ import ( txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" ) -func TestBlockBuilderAddLocalTx(t *testing.T) { +func TestBuildBlockBasic(t *testing.T) { require := require.New(t) env := newEnvironment(t) @@ -72,6 +70,26 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { require.NoError(env.mempool.GetDropReason(txID)) } +func TestBuildBlockDoesNotBuildWithEmptyMempool(t *testing.T) { + require := require.New(t) + + env := newEnvironment(t) + env.ctx.Lock.Lock() + defer func() { + require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() + }() + + tx, exists := env.mempool.Peek() + require.False(exists) + require.Nil(tx) + + // [BuildBlock] should not build an empty block + blk, err := env.Builder.BuildBlock(context.Background()) + require.ErrorIs(err, ErrNoPendingBlocks) + require.Nil(blk) +} + func TestBuildBlockShouldReward(t *testing.T) { require := require.New(t) @@ -471,54 +489,6 @@ func TestBuildBlock(t *testing.T) { } tests := []test{ - { - name: "no stakers tx", - builderF: func(ctrl *gomock.Controller) *builder { - mempool := mempool.NewMockMempool(ctrl) - - // There are no txs. - mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - mempool.EXPECT().Peek().Return(nil, false) - - clk := &mockable.Clock{} - clk.Set(now) - return &builder{ - Mempool: mempool, - txExecutorBackend: &txexecutor.Backend{ - Ctx: &snow.Context{ - Log: logging.NoLog{}, - }, - Clk: clk, - }, - } - }, - timestamp: parentTimestamp, - forceAdvanceTime: false, - parentStateF: func(ctrl *gomock.Controller) state.Chain { - s := state.NewMockChain(ctrl) - - // Handle calls in [getNextStakerToReward] - // and [GetNextStakerChangeTime]. - // Next validator change time is in the future. - currentStakerIter := state.NewMockStakerIterator(ctrl) - gomock.InOrder( - // expect calls from [getNextStakerToReward] - currentStakerIter.EXPECT().Next().Return(true), - currentStakerIter.EXPECT().Value().Return(&state.Staker{ - NextTime: now.Add(time.Second), - Priority: txs.PrimaryNetworkDelegatorCurrentPriority, - }), - currentStakerIter.EXPECT().Release(), - ) - - s.EXPECT().GetCurrentStakerIterator().Return(currentStakerIter, nil).Times(1) - return s - }, - expectedBlkF: func(*require.Assertions) block.Block { - return nil - }, - expectedErr: ErrNoPendingBlocks, - }, { name: "should advance time", builderF: func(ctrl *gomock.Controller) *builder { From 54abd9a5a61ec701954b791fbd6d3ecca18704b3 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:12:46 -0500 Subject: [PATCH 134/267] `vms/platformvm`: Add `TestBuildBlockShouldAdvanceTime` test (#2471) Co-authored-by: Stephen Buttolph --- vms/platformvm/block/builder/builder_test.go | 90 ++++++++------------ 1 file changed, 36 insertions(+), 54 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 97018ee9839c..fcfba8998e2c 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -199,6 +199,42 @@ func TestBuildBlockShouldReward(t *testing.T) { require.NotEmpty(rewardUTXOs) } +func TestBuildBlockAdvanceTime(t *testing.T) { + require := require.New(t) + + env := newEnvironment(t) + env.ctx.Lock.Lock() + defer func() { + require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() + }() + + var ( + now = env.backend.Clk.Time() + nextTime = now.Add(2 * txexecutor.SyncBound) + ) + + // Add a staker to [env.state] + env.state.PutCurrentValidator(&state.Staker{ + NextTime: nextTime, + Priority: txs.PrimaryNetworkValidatorCurrentPriority, + }) + + // Advance wall clock to [nextTime] + env.backend.Clk.Set(nextTime) + + // [BuildBlock] should build a block advancing the time to [NextTime] + blkIntf, err := env.Builder.BuildBlock(context.Background()) + require.NoError(err) + + require.IsType(&blockexecutor.Block{}, blkIntf) + blk := blkIntf.(*blockexecutor.Block) + require.Empty(blk.Txs()) + require.IsType(&block.BanffStandardBlock{}, blk.Block) + standardBlk := blk.Block.(*block.BanffStandardBlock) + require.Equal(nextTime.Unix(), standardBlk.Timestamp().Unix()) +} + func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { require := require.New(t) @@ -489,60 +525,6 @@ func TestBuildBlock(t *testing.T) { } tests := []test{ - { - name: "should advance time", - builderF: func(ctrl *gomock.Controller) *builder { - mempool := mempool.NewMockMempool(ctrl) - - // There are no txs. - mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - mempool.EXPECT().Peek().Return(nil, false) - - clk := &mockable.Clock{} - clk.Set(now) - return &builder{ - Mempool: mempool, - txExecutorBackend: &txexecutor.Backend{ - Clk: clk, - }, - } - }, - timestamp: now.Add(-1 * time.Second), - forceAdvanceTime: true, - parentStateF: func(ctrl *gomock.Controller) state.Chain { - s := state.NewMockChain(ctrl) - - // add current validator that ends at [now] - 1 second. - // That is, it ends in the past but after the current chain time. - // Handle calls in [getNextStakerToReward] - // and [GetNextStakerChangeTime] - // when determining whether to issue a reward tx. - currentStakerIter := state.NewMockStakerIterator(ctrl) - gomock.InOrder( - // expect calls from [getNextStakerToReward] - currentStakerIter.EXPECT().Next().Return(true), - currentStakerIter.EXPECT().Value().Return(&state.Staker{ - NextTime: now.Add(-1 * time.Second), - Priority: txs.PrimaryNetworkDelegatorCurrentPriority, - }), - currentStakerIter.EXPECT().Release(), - ) - - s.EXPECT().GetCurrentStakerIterator().Return(currentStakerIter, nil).Times(1) - return s - }, - expectedBlkF: func(require *require.Assertions) block.Block { - expectedBlk, err := block.NewBanffStandardBlock( - now.Add(-1*time.Second), // note the advanced time - parentID, - height, - nil, // empty block to advance time - ) - require.NoError(err) - return expectedBlk - }, - expectedErr: nil, - }, { name: "has a staker tx no force", builderF: func(ctrl *gomock.Controller) *builder { From dc472ec2b27ba4bd2daae596c317219efd04b852 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 12 Dec 2023 14:37:43 -0500 Subject: [PATCH 135/267] `vms/platformvm`: Permit usage of the `Transactions` field in `BanffProposalBlock` (#2451) Co-authored-by: Stephen Buttolph --- vms/avm/block/builder/builder.go | 16 +- vms/avm/state/diff.go | 17 +- vms/platformvm/block/executor/acceptor.go | 14 +- vms/platformvm/block/executor/backend.go | 8 +- vms/platformvm/block/executor/block_state.go | 1 + .../block/executor/proposal_block_test.go | 171 +++++++++++++++++- vms/platformvm/block/executor/verifier.go | 77 +++++--- .../block/executor/verifier_test.go | 34 ++-- vms/platformvm/state/diff.go | 17 +- vms/platformvm/state/diff_test.go | 16 +- 10 files changed, 290 insertions(+), 81 deletions(-) diff --git a/vms/avm/block/builder/builder.go b/vms/avm/block/builder/builder.go index 97610bb1ca2d..6b7a643d19c9 100644 --- a/vms/avm/block/builder/builder.go +++ b/vms/avm/block/builder/builder.go @@ -105,7 +105,7 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { // Invariant: [tx] has already been syntactically verified. - txDiff, err := wrapState(stateDiff) + txDiff, err := state.NewDiffOn(stateDiff) if err != nil { return nil, err } @@ -170,17 +170,3 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { return b.manager.NewBlock(statelessBlk), nil } - -type stateGetter struct { - state state.Chain -} - -func (s stateGetter) GetState(ids.ID) (state.Chain, bool) { - return s.state, true -} - -func wrapState(parentState state.Chain) (state.Diff, error) { - return state.NewDiff(ids.Empty, stateGetter{ - state: parentState, - }) -} diff --git a/vms/avm/state/diff.go b/vms/avm/state/diff.go index 1d53fa37da3e..1f1a98d38a96 100644 --- a/vms/avm/state/diff.go +++ b/vms/avm/state/diff.go @@ -16,7 +16,8 @@ import ( ) var ( - _ Diff = (*diff)(nil) + _ Diff = (*diff)(nil) + _ Versions = stateGetter{} ErrMissingParentState = errors.New("missing parent state") ) @@ -61,6 +62,20 @@ func NewDiff( }, nil } +type stateGetter struct { + state Chain +} + +func (s stateGetter) GetState(ids.ID) (Chain, bool) { + return s.state, true +} + +func NewDiffOn(parentState Chain) (Diff, error) { + return NewDiff(ids.Empty, stateGetter{ + state: parentState, + }) +} + func (d *diff) GetUTXO(utxoID ids.ID) (*avax.UTXO, error) { if utxo, modified := d.modifiedUTXOs[utxoID]; modified { if utxo == nil { diff --git a/vms/platformvm/block/executor/acceptor.go b/vms/platformvm/block/executor/acceptor.go index ff5542f65157..af26c931d088 100644 --- a/vms/platformvm/block/executor/acceptor.go +++ b/vms/platformvm/block/executor/acceptor.go @@ -172,6 +172,16 @@ func (a *acceptor) optionBlock(b, parent block.Block, blockType string) error { return err } + parentState, ok := a.blkIDToState[parentID] + if !ok { + return fmt.Errorf("%w %s", errMissingBlockState, parentID) + } + if parentState.onDecisionState != nil { + if err := parentState.onDecisionState.Apply(a.state); err != nil { + return err + } + } + blkState, ok := a.blkIDToState[blkID] if !ok { return fmt.Errorf("%w %s", errMissingBlockState, blkID) @@ -191,11 +201,11 @@ func (a *acceptor) optionBlock(b, parent block.Block, blockType string) error { } // Note that this method writes [batch] to the database. - if err := a.ctx.SharedMemory.Apply(blkState.atomicRequests, batch); err != nil { + if err := a.ctx.SharedMemory.Apply(parentState.atomicRequests, batch); err != nil { return fmt.Errorf("failed to apply vm's state to shared memory: %w", err) } - if onAcceptFunc := blkState.onAcceptFunc; onAcceptFunc != nil { + if onAcceptFunc := parentState.onAcceptFunc; onAcceptFunc != nil { onAcceptFunc() } diff --git a/vms/platformvm/block/executor/backend.go b/vms/platformvm/block/executor/backend.go index 94b301c89ddb..4d915047f560 100644 --- a/vms/platformvm/block/executor/backend.go +++ b/vms/platformvm/block/executor/backend.go @@ -51,20 +51,20 @@ func (b *backend) GetState(blkID ids.ID) (state.Chain, bool) { return b.state, blkID == b.state.GetLastAccepted() } -func (b *backend) getBlkWithOnAbortState(blkID ids.ID) (*blockState, bool) { +func (b *backend) getOnAbortState(blkID ids.ID) (state.Diff, bool) { state, ok := b.blkIDToState[blkID] if !ok || state.onAbortState == nil { return nil, false } - return state, true + return state.onAbortState, true } -func (b *backend) getBlkWithOnCommitState(blkID ids.ID) (*blockState, bool) { +func (b *backend) getOnCommitState(blkID ids.ID) (state.Diff, bool) { state, ok := b.blkIDToState[blkID] if !ok || state.onCommitState == nil { return nil, false } - return state, true + return state.onCommitState, true } func (b *backend) GetBlock(blkID ids.ID) (block.Block, error) { diff --git a/vms/platformvm/block/executor/block_state.go b/vms/platformvm/block/executor/block_state.go index 1386abd58bd4..abec214ae244 100644 --- a/vms/platformvm/block/executor/block_state.go +++ b/vms/platformvm/block/executor/block_state.go @@ -15,6 +15,7 @@ import ( type proposalBlockState struct { initiallyPreferCommit bool + onDecisionState state.Diff onCommitState state.Diff onAbortState state.Diff } diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 18a1131b6126..610fdef0cc87 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/reward" @@ -151,7 +152,8 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { require.NoError(shutdownEnvironment(env)) }() env.clk.Set(defaultGenesisTime) - env.config.BanffTime = time.Time{} // activate Banff + env.config.BanffTime = time.Time{} // activate Banff + env.config.DurangoTime = mockable.MaxTime // deactivate Durango // create parentBlock. It's a standard one for simplicity parentTime := defaultGenesisTime @@ -1335,3 +1337,170 @@ func TestBanffProposalBlockDelegatorStakers(t *testing.T) { vdrWeight = env.config.Validators.GetWeight(constants.PrimaryNetworkID, nodeID) require.Equal(env.config.MinDelegatorStake+env.config.MinValidatorStake, vdrWeight) } + +func TestAddValidatorProposalBlock(t *testing.T) { + require := require.New(t) + env := newEnvironment(t, nil) + defer func() { + require.NoError(shutdownEnvironment(env)) + }() + env.config.BanffTime = time.Time{} // activate Banff + env.config.DurangoTime = time.Time{} // activate Durango + + now := env.clk.Time() + + // Create validator tx + var ( + validatorStartTime = now.Add(2 * executor.SyncBound) + validatorEndTime = validatorStartTime.Add(env.config.MinStakeDuration) + nodeID = ids.GenerateTestNodeID() + ) + + addValidatorTx, err := env.txBuilder.NewAddValidatorTx( + env.config.MinValidatorStake, + uint64(validatorStartTime.Unix()), + uint64(validatorEndTime.Unix()), + nodeID, + preFundedKeys[0].PublicKey().Address(), + 10000, + []*secp256k1.PrivateKey{ + preFundedKeys[0], + preFundedKeys[1], + preFundedKeys[4], + }, + ids.ShortEmpty, + ) + require.NoError(err) + + // Add validator through a [StandardBlock] + preferredID := env.blkManager.Preferred() + preferred, err := env.blkManager.GetStatelessBlock(preferredID) + require.NoError(err) + + statelessBlk, err := block.NewBanffStandardBlock( + now.Add(executor.SyncBound), + preferredID, + preferred.Height()+1, + []*txs.Tx{addValidatorTx}, + ) + require.NoError(err) + blk := env.blkManager.NewBlock(statelessBlk) + require.NoError(blk.Verify(context.Background())) + require.NoError(blk.Accept(context.Background())) + require.True(env.blkManager.SetPreference(statelessBlk.ID())) + + // Should be pending + staker, err := env.state.GetPendingValidator(constants.PrimaryNetworkID, nodeID) + require.NoError(err) + require.NotNil(staker) + + // Promote validator from pending to current + env.clk.Set(validatorStartTime) + now = env.clk.Time() + + preferredID = env.blkManager.Preferred() + preferred, err = env.blkManager.GetStatelessBlock(preferredID) + require.NoError(err) + + statelessBlk, err = block.NewBanffStandardBlock( + now, + preferredID, + preferred.Height()+1, + nil, + ) + require.NoError(err) + blk = env.blkManager.NewBlock(statelessBlk) + require.NoError(blk.Verify(context.Background())) + require.NoError(blk.Accept(context.Background())) + require.True(env.blkManager.SetPreference(statelessBlk.ID())) + + // Should be current + staker, err = env.state.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) + require.NoError(err) + require.NotNil(staker) + + // Advance time until next staker change time is [validatorEndTime] + for { + nextStakerChangeTime, err := executor.GetNextStakerChangeTime(env.state) + require.NoError(err) + if nextStakerChangeTime.Equal(validatorEndTime) { + break + } + + preferredID = env.blkManager.Preferred() + preferred, err = env.blkManager.GetStatelessBlock(preferredID) + require.NoError(err) + + statelessBlk, err = block.NewBanffStandardBlock( + nextStakerChangeTime, + preferredID, + preferred.Height()+1, + nil, + ) + require.NoError(err) + blk = env.blkManager.NewBlock(statelessBlk) + require.NoError(blk.Verify(context.Background())) + require.NoError(blk.Accept(context.Background())) + require.True(env.blkManager.SetPreference(statelessBlk.ID())) + } + + env.clk.Set(validatorEndTime) + now = env.clk.Time() + + // Create another validator tx + validatorStartTime = now.Add(2 * executor.SyncBound) + validatorEndTime = validatorStartTime.Add(env.config.MinStakeDuration) + nodeID = ids.GenerateTestNodeID() + + addValidatorTx2, err := env.txBuilder.NewAddValidatorTx( + env.config.MinValidatorStake, + uint64(validatorStartTime.Unix()), + uint64(validatorEndTime.Unix()), + nodeID, + preFundedKeys[0].PublicKey().Address(), + 10000, + []*secp256k1.PrivateKey{ + preFundedKeys[0], + preFundedKeys[1], + preFundedKeys[4], + }, + ids.ShortEmpty, + ) + require.NoError(err) + + // Add validator through a [ProposalBlock] and reward the last one + preferredID = env.blkManager.Preferred() + preferred, err = env.blkManager.GetStatelessBlock(preferredID) + require.NoError(err) + + rewardValidatorTx, err := env.txBuilder.NewRewardValidatorTx(addValidatorTx.ID()) + require.NoError(err) + + statelessProposalBlk, err := block.NewBanffProposalBlock( + now, + preferredID, + preferred.Height()+1, + rewardValidatorTx, + []*txs.Tx{addValidatorTx2}, + ) + require.NoError(err) + blk = env.blkManager.NewBlock(statelessProposalBlk) + require.NoError(blk.Verify(context.Background())) + + options, err := blk.(snowman.OracleBlock).Options(context.Background()) + require.NoError(err) + commitBlk := options[0] + require.NoError(commitBlk.Verify(context.Background())) + + require.NoError(blk.Accept(context.Background())) + require.NoError(commitBlk.Accept(context.Background())) + + // Should be pending + staker, err = env.state.GetPendingValidator(constants.PrimaryNetworkID, nodeID) + require.NoError(err) + require.NotNil(staker) + + rewardUTXOs, err := env.state.GetRewardUTXOs(addValidatorTx.ID()) + require.NoError(err) + require.NotEmpty(rewardUTXOs) +} diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index fd2ce999bd5f..4e81c8470ba3 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -50,7 +50,7 @@ func (v *verifier) BanffCommitBlock(b *block.BanffCommitBlock) error { } func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { - if len(b.Transactions) != 0 { + if !v.txExecutorBackend.Config.IsDurangoActivated(b.Timestamp()) && len(b.Transactions) != 0 { return errBanffProposalBlockWithMultipleTransactions } @@ -59,11 +59,7 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { } parentID := b.Parent() - onCommitState, err := state.NewDiff(parentID, v.backend) - if err != nil { - return err - } - onAbortState, err := state.NewDiff(parentID, v.backend) + onDecisionState, err := state.NewDiff(parentID, v.backend) if err != nil { return err } @@ -72,20 +68,40 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { nextChainTime := b.Timestamp() changes, err := executor.AdvanceTimeTo( v.txExecutorBackend, - onCommitState, + onDecisionState, nextChainTime, ) if err != nil { return err } - onCommitState.SetTimestamp(nextChainTime) - changes.Apply(onCommitState) + onDecisionState.SetTimestamp(nextChainTime) + changes.Apply(onDecisionState) + + inputs, atomicRequests, onAcceptFunc, err := v.processStandardTxs(b.Transactions, onDecisionState, b.Parent()) + if err != nil { + return err + } - onAbortState.SetTimestamp(nextChainTime) - changes.Apply(onAbortState) + onCommitState, err := state.NewDiffOn(onDecisionState) + if err != nil { + return err + } - return v.proposalBlock(&b.ApricotProposalBlock, onCommitState, onAbortState) + onAbortState, err := state.NewDiffOn(onDecisionState) + if err != nil { + return err + } + + return v.proposalBlock( + &b.ApricotProposalBlock, + onDecisionState, + onCommitState, + onAbortState, + inputs, + atomicRequests, + onAcceptFunc, + ) } func (v *verifier) BanffStandardBlock(b *block.BanffStandardBlock) error { @@ -151,7 +167,7 @@ func (v *verifier) ApricotProposalBlock(b *block.ApricotProposalBlock) error { return err } - return v.proposalBlock(b, onCommitState, onAbortState) + return v.proposalBlock(b, nil, onCommitState, onAbortState, nil, nil, nil) } func (v *verifier) ApricotStandardBlock(b *block.ApricotStandardBlock) error { @@ -319,7 +335,7 @@ func (v *verifier) commonBlock(b block.Block) error { // abortBlock populates the state of this block if [nil] is returned func (v *verifier) abortBlock(b block.Block) error { parentID := b.Parent() - parentState, ok := v.getBlkWithOnAbortState(parentID) + onAbortState, ok := v.getOnAbortState(parentID) if !ok { return fmt.Errorf("%w: %s", state.ErrMissingParentState, parentID) } @@ -327,13 +343,8 @@ func (v *verifier) abortBlock(b block.Block) error { blkID := b.ID() v.blkIDToState[blkID] = &blockState{ statelessBlock: b, - - onAcceptState: parentState.onAbortState, - onAcceptFunc: parentState.onAcceptFunc, - - inputs: parentState.inputs, - timestamp: parentState.onAbortState.GetTimestamp(), - atomicRequests: parentState.atomicRequests, + onAcceptState: onAbortState, + timestamp: onAbortState.GetTimestamp(), } return nil } @@ -341,7 +352,7 @@ func (v *verifier) abortBlock(b block.Block) error { // commitBlock populates the state of this block if [nil] is returned func (v *verifier) commitBlock(b block.Block) error { parentID := b.Parent() - parentState, ok := v.getBlkWithOnCommitState(parentID) + onCommitState, ok := v.getOnCommitState(parentID) if !ok { return fmt.Errorf("%w: %s", state.ErrMissingParentState, parentID) } @@ -349,13 +360,8 @@ func (v *verifier) commitBlock(b block.Block) error { blkID := b.ID() v.blkIDToState[blkID] = &blockState{ statelessBlock: b, - - onAcceptState: parentState.onCommitState, - onAcceptFunc: parentState.onAcceptFunc, - - inputs: parentState.inputs, - timestamp: parentState.onCommitState.GetTimestamp(), - atomicRequests: parentState.atomicRequests, + onAcceptState: onCommitState, + timestamp: onCommitState.GetTimestamp(), } return nil } @@ -363,8 +369,12 @@ func (v *verifier) commitBlock(b block.Block) error { // proposalBlock populates the state of this block if [nil] is returned func (v *verifier) proposalBlock( b *block.ApricotProposalBlock, + onDecisionState state.Diff, onCommitState state.Diff, onAbortState state.Diff, + inputs set.Set[ids.ID], + atomicRequests map[ids.ID]*atomic.Requests, + onAcceptFunc func(), ) error { txExecutor := executor.ProposalTxExecutor{ OnCommitState: onCommitState, @@ -387,15 +397,22 @@ func (v *verifier) proposalBlock( blkID := b.ID() v.blkIDToState[blkID] = &blockState{ proposalBlockState: proposalBlockState{ + onDecisionState: onDecisionState, onCommitState: onCommitState, onAbortState: onAbortState, initiallyPreferCommit: txExecutor.PrefersCommit, }, + statelessBlock: b, + + onAcceptFunc: onAcceptFunc, + + inputs: inputs, // It is safe to use [b.onAbortState] here because the timestamp will // never be modified by an Apricot Abort block and the timestamp will // always be the same as the Banff Proposal Block. - timestamp: onAbortState.GetTimestamp(), + timestamp: onAbortState.GetTimestamp(), + atomicRequests: atomicRequests, } return nil } diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index e4095f6b4f77..6d4e32e0bee5 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -311,6 +311,7 @@ func TestVerifierVisitCommitBlock(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) parentID := ids.GenerateTestID() parentStatelessBlk := block.NewMockBlock(ctrl) + parentOnDecisionState := state.NewMockDiff(ctrl) parentOnCommitState := state.NewMockDiff(ctrl) parentOnAbortState := state.NewMockDiff(ctrl) @@ -319,8 +320,9 @@ func TestVerifierVisitCommitBlock(t *testing.T) { parentID: { statelessBlock: parentStatelessBlk, proposalBlockState: proposalBlockState{ - onCommitState: parentOnCommitState, - onAbortState: parentOnAbortState, + onDecisionState: parentOnDecisionState, + onCommitState: parentOnCommitState, + onAbortState: parentOnAbortState, }, }, }, @@ -380,6 +382,7 @@ func TestVerifierVisitAbortBlock(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) parentID := ids.GenerateTestID() parentStatelessBlk := block.NewMockBlock(ctrl) + parentOnDecisionState := state.NewMockDiff(ctrl) parentOnCommitState := state.NewMockDiff(ctrl) parentOnAbortState := state.NewMockDiff(ctrl) @@ -388,8 +391,9 @@ func TestVerifierVisitAbortBlock(t *testing.T) { parentID: { statelessBlock: parentStatelessBlk, proposalBlockState: proposalBlockState{ - onCommitState: parentOnCommitState, - onAbortState: parentOnAbortState, + onDecisionState: parentOnDecisionState, + onCommitState: parentOnCommitState, + onAbortState: parentOnAbortState, }, }, }, @@ -547,9 +551,11 @@ func TestBanffAbortBlockTimestampChecks(t *testing.T) { // setup parent state parentTime := defaultGenesisTime - s.EXPECT().GetLastAccepted().Return(parentID).Times(2) - s.EXPECT().GetTimestamp().Return(parentTime).Times(2) + s.EXPECT().GetLastAccepted().Return(parentID).Times(3) + s.EXPECT().GetTimestamp().Return(parentTime).Times(3) + onDecisionState, err := state.NewDiff(parentID, backend) + require.NoError(err) onCommitState, err := state.NewDiff(parentID, backend) require.NoError(err) onAbortState, err := state.NewDiff(parentID, backend) @@ -558,8 +564,9 @@ func TestBanffAbortBlockTimestampChecks(t *testing.T) { timestamp: test.parentTime, statelessBlock: parentStatelessBlk, proposalBlockState: proposalBlockState{ - onCommitState: onCommitState, - onAbortState: onAbortState, + onDecisionState: onDecisionState, + onCommitState: onCommitState, + onAbortState: onAbortState, }, } @@ -640,9 +647,11 @@ func TestBanffCommitBlockTimestampChecks(t *testing.T) { // setup parent state parentTime := defaultGenesisTime - s.EXPECT().GetLastAccepted().Return(parentID).Times(2) - s.EXPECT().GetTimestamp().Return(parentTime).Times(2) + s.EXPECT().GetLastAccepted().Return(parentID).Times(3) + s.EXPECT().GetTimestamp().Return(parentTime).Times(3) + onDecisionState, err := state.NewDiff(parentID, backend) + require.NoError(err) onCommitState, err := state.NewDiff(parentID, backend) require.NoError(err) onAbortState, err := state.NewDiff(parentID, backend) @@ -651,8 +660,9 @@ func TestBanffCommitBlockTimestampChecks(t *testing.T) { timestamp: test.parentTime, statelessBlock: parentStatelessBlk, proposalBlockState: proposalBlockState{ - onCommitState: onCommitState, - onAbortState: onAbortState, + onDecisionState: onDecisionState, + onCommitState: onCommitState, + onAbortState: onAbortState, }, } diff --git a/vms/platformvm/state/diff.go b/vms/platformvm/state/diff.go index d509fa69e0dd..bb308c9c28e2 100644 --- a/vms/platformvm/state/diff.go +++ b/vms/platformvm/state/diff.go @@ -17,7 +17,8 @@ import ( ) var ( - _ Diff = (*diff)(nil) + _ Diff = (*diff)(nil) + _ Versions = stateGetter{} ErrMissingParentState = errors.New("missing parent state") ) @@ -74,6 +75,20 @@ func NewDiff( }, nil } +type stateGetter struct { + state Chain +} + +func (s stateGetter) GetState(ids.ID) (Chain, bool) { + return s.state, true +} + +func NewDiffOn(parentState Chain) (Diff, error) { + return NewDiff(ids.Empty, stateGetter{ + state: parentState, + }) +} + func (d *diff) GetTimestamp() time.Time { return d.timestamp } diff --git a/vms/platformvm/state/diff_test.go b/vms/platformvm/state/diff_test.go index 50c87b2d3a53..e9eecdb182cb 100644 --- a/vms/platformvm/state/diff_test.go +++ b/vms/platformvm/state/diff_test.go @@ -637,7 +637,7 @@ func TestDiffStacking(t *testing.T) { require.Equal(owner1, owner) // Create a second diff on first diff and verify that subnet owner returns correctly - stackedDiff, err := wrapState(statesDiff) + stackedDiff, err := NewDiffOn(statesDiff) require.NoError(err) owner, err = stackedDiff.GetSubnetOwner(subnetID) require.NoError(err) @@ -674,17 +674,3 @@ func TestDiffStacking(t *testing.T) { require.NoError(err) require.Equal(owner3, owner) } - -type stateGetter struct { - state Chain -} - -func (s stateGetter) GetState(ids.ID) (Chain, bool) { - return s.state, true -} - -func wrapState(parentState Chain) (Diff, error) { - return NewDiff(ids.Empty, stateGetter{ - state: parentState, - }) -} From 79631151a7a2c8e42a6c506926ce8fa3c2fe55d1 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 12 Dec 2023 14:37:59 -0500 Subject: [PATCH 136/267] `vms/platformvm`: Add `TestBuildBlockForceAdvanceTime` test (#2472) Co-authored-by: Stephen Buttolph --- vms/platformvm/block/builder/builder_test.go | 239 +++++-------------- 1 file changed, 54 insertions(+), 185 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index fcfba8998e2c..ee603c484622 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" @@ -235,6 +234,60 @@ func TestBuildBlockAdvanceTime(t *testing.T) { require.Equal(nextTime.Unix(), standardBlk.Timestamp().Unix()) } +func TestBuildBlockForceAdvanceTime(t *testing.T) { + require := require.New(t) + + env := newEnvironment(t) + env.ctx.Lock.Lock() + defer func() { + require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() + }() + + // Create a valid transaction + tx, err := env.txBuilder.NewCreateChainTx( + testSubnet1.ID(), + nil, + constants.AVMID, + nil, + "chain name", + []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, + ids.ShortEmpty, + ) + require.NoError(err) + txID := tx.ID() + + // Issue the transaction + require.NoError(env.network.IssueTx(context.Background(), tx)) + require.True(env.mempool.Has(txID)) + + var ( + now = env.backend.Clk.Time() + nextTime = now.Add(2 * txexecutor.SyncBound) + ) + + // Add a staker to [env.state] + env.state.PutCurrentValidator(&state.Staker{ + NextTime: nextTime, + Priority: txs.PrimaryNetworkValidatorCurrentPriority, + }) + + // Advance wall clock to [nextTime] + [txexecutor.SyncBound] + env.backend.Clk.Set(nextTime.Add(txexecutor.SyncBound)) + + // [BuildBlock] should build a block advancing the time to [nextTime], + // not the current wall clock. + blkIntf, err := env.Builder.BuildBlock(context.Background()) + require.NoError(err) + + require.IsType(&blockexecutor.Block{}, blkIntf) + blk := blkIntf.(*blockexecutor.Block) + require.Equal([]*txs.Tx{tx}, blk.Txs()) + require.IsType(&block.BanffStandardBlock{}, blk.Block) + standardBlk := blk.Block.(*block.BanffStandardBlock) + require.Equal(nextTime.Unix(), standardBlk.Timestamp().Unix()) +} + func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { require := require.New(t) @@ -482,187 +535,3 @@ func TestGetNextStakerToReward(t *testing.T) { }) } } - -func TestBuildBlock(t *testing.T) { - env := newEnvironment(t) - env.ctx.Lock.Lock() - defer func() { - require.NoError(t, shutdownEnvironment(env)) - env.ctx.Lock.Unlock() - }() - - var ( - now = env.backend.Clk.Time() - parentID = ids.GenerateTestID() - height = uint64(1337) - parentTimestamp = now.Add(-2 * time.Second) - - defaultValidatorStake = 100 * units.MilliAvax - validatorStartTime = now.Add(2 * txexecutor.SyncBound) - validatorEndTime = validatorStartTime.Add(360 * 24 * time.Hour) - ) - - tx, err := env.txBuilder.NewAddValidatorTx( - defaultValidatorStake, - uint64(validatorStartTime.Unix()), - uint64(validatorEndTime.Unix()), - ids.GenerateTestNodeID(), - preFundedKeys[0].PublicKey().Address(), - reward.PercentDenominator, - []*secp256k1.PrivateKey{preFundedKeys[0]}, - preFundedKeys[0].PublicKey().Address(), - ) - require.NoError(t, err) - - type test struct { - name string - builderF func(*gomock.Controller) *builder - timestamp time.Time - forceAdvanceTime bool - parentStateF func(*gomock.Controller) state.Chain - expectedBlkF func(*require.Assertions) block.Block - expectedErr error - } - - tests := []test{ - { - name: "has a staker tx no force", - builderF: func(ctrl *gomock.Controller) *builder { - mempool := mempool.NewMockMempool(ctrl) - - // There is a tx. - mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - - gomock.InOrder( - mempool.EXPECT().Peek().Return(tx, true), - mempool.EXPECT().Remove([]*txs.Tx{tx}), - // Second loop iteration - mempool.EXPECT().Peek().Return(nil, false), - ) - - clk := &mockable.Clock{} - clk.Set(now) - return &builder{ - Mempool: mempool, - txExecutorBackend: &txexecutor.Backend{ - Clk: clk, - }, - } - }, - timestamp: parentTimestamp, - forceAdvanceTime: false, - parentStateF: func(ctrl *gomock.Controller) state.Chain { - s := state.NewMockChain(ctrl) - - // Handle calls in [getNextStakerToReward] - // and [GetNextStakerChangeTime]. - // Next validator change time is in the future. - currentStakerIter := state.NewMockStakerIterator(ctrl) - gomock.InOrder( - // expect calls from [getNextStakerToReward] - currentStakerIter.EXPECT().Next().Return(true), - currentStakerIter.EXPECT().Value().Return(&state.Staker{ - NextTime: now.Add(time.Second), - Priority: txs.PrimaryNetworkDelegatorCurrentPriority, - }), - currentStakerIter.EXPECT().Release(), - ) - - s.EXPECT().GetCurrentStakerIterator().Return(currentStakerIter, nil).Times(1) - return s - }, - expectedBlkF: func(require *require.Assertions) block.Block { - expectedBlk, err := block.NewBanffStandardBlock( - parentTimestamp, - parentID, - height, - []*txs.Tx{tx}, - ) - require.NoError(err) - return expectedBlk - }, - expectedErr: nil, - }, - { - name: "has a staker tx with force", - builderF: func(ctrl *gomock.Controller) *builder { - mempool := mempool.NewMockMempool(ctrl) - - // There are no decision txs - // There is a staker tx. - mempool.EXPECT().DropExpiredStakerTxs(gomock.Any()).Return([]ids.ID{}) - - gomock.InOrder( - mempool.EXPECT().Peek().Return(tx, true), - mempool.EXPECT().Remove([]*txs.Tx{tx}), - // Second loop iteration - mempool.EXPECT().Peek().Return(nil, false), - ) - - clk := &mockable.Clock{} - clk.Set(now) - return &builder{ - Mempool: mempool, - txExecutorBackend: &txexecutor.Backend{ - Clk: clk, - }, - } - }, - timestamp: parentTimestamp, - forceAdvanceTime: true, - parentStateF: func(ctrl *gomock.Controller) state.Chain { - s := state.NewMockChain(ctrl) - - // Handle calls in [getNextStakerToReward] - // and [GetNextStakerChangeTime]. - // Next validator change time is in the future. - currentStakerIter := state.NewMockStakerIterator(ctrl) - gomock.InOrder( - // expect calls from [getNextStakerToReward] - currentStakerIter.EXPECT().Next().Return(true), - currentStakerIter.EXPECT().Value().Return(&state.Staker{ - NextTime: now.Add(time.Second), - Priority: txs.PrimaryNetworkDelegatorCurrentPriority, - }), - currentStakerIter.EXPECT().Release(), - ) - - s.EXPECT().GetCurrentStakerIterator().Return(currentStakerIter, nil).Times(1) - return s - }, - expectedBlkF: func(require *require.Assertions) block.Block { - expectedBlk, err := block.NewBanffStandardBlock( - parentTimestamp, - parentID, - height, - []*txs.Tx{tx}, - ) - require.NoError(err) - return expectedBlk - }, - expectedErr: nil, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) - - gotBlk, err := buildBlock( - tt.builderF(ctrl), - parentID, - height, - tt.timestamp, - tt.forceAdvanceTime, - tt.parentStateF(ctrl), - ) - if tt.expectedErr != nil { - require.ErrorIs(err, tt.expectedErr) - return - } - require.NoError(err) - require.Equal(tt.expectedBlkF(require), gotBlk) - }) - } -} From 4be744e5ec214a0cdb0c93e949d2e9d70bbcfc96 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:08:48 -0500 Subject: [PATCH 137/267] P2P AppError handling (#2248) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- go.mod | 2 +- go.sum | 4 +- message/inbound_msg_builder.go | 20 + message/inbound_msg_builder_test.go | 44 ++ message/internal_msg_builder.go | 50 +- message/ops.go | 28 +- network/p2p/client.go | 5 +- network/p2p/network.go | 8 +- network/p2p/network_test.go | 17 +- network/p2p/router.go | 8 +- proto/pb/vm/vm.pb.go | 641 ++++++++-------- proto/vm/vm.proto | 8 + snow/engine/avalanche/vertex/mock_vm.go | 16 +- snow/engine/common/engine.go | 2 + snow/engine/common/error.go | 43 ++ snow/engine/common/error_test.go | 92 +++ snow/engine/common/no_ops_handlers.go | 10 +- snow/engine/common/test_engine.go | 12 +- snow/engine/common/test_vm.go | 12 +- snow/engine/common/traced_engine.go | 8 +- snow/engine/snowman/block/mocks/chain_vm.go | 16 +- snow/networking/handler/handler.go | 24 +- snow/networking/router/chain_router_test.go | 804 +++++++++----------- snow/networking/sender/sender.go | 16 +- snow/networking/sender/sender_test.go | 14 +- vms/avm/network/atomic.go | 4 + vms/rpcchainvm/vm_client.go | 34 +- vms/rpcchainvm/vm_server.go | 14 +- 28 files changed, 1070 insertions(+), 886 deletions(-) create mode 100644 snow/engine/common/error.go create mode 100644 snow/engine/common/error_test.go diff --git a/go.mod b/go.mod index b793394d8d24..5bbdeab03311 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.10-rc.0 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231206202846-fc088a944e76 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 7b9a76de9663..b0bec442701d 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.10-rc.0 h1:qmuom7rtH5hc1E3lnqrMFNLFL1TMnEVa/2O8poB1YLU= -github.com/ava-labs/coreth v0.12.10-rc.0/go.mod h1:plFm/xzvWmx1+qJ3JQSTzF8+FdaA2xu7GgY/AdaZDfk= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231206202846-fc088a944e76 h1:0hYwcuOfndE1I61SvWv2dEa7N3QRJL3RpB9fmJy0sr0= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231206202846-fc088a944e76/go.mod h1:dH0LOVIEm1uHKozwhDV223BOyP0ElVsYclizRJzEY4s= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/message/inbound_msg_builder.go b/message/inbound_msg_builder.go index a287ade2d8cb..e6822bc329d1 100644 --- a/message/inbound_msg_builder.go +++ b/message/inbound_msg_builder.go @@ -284,6 +284,26 @@ func InboundAppRequest( } } +func InboundAppError( + nodeID ids.NodeID, + chainID ids.ID, + requestID uint32, + errorCode int32, + errorMessage string, +) InboundMessage { + return &inboundMessage{ + nodeID: nodeID, + op: AppErrorOp, + message: &p2p.AppError{ + ChainId: chainID[:], + RequestId: requestID, + ErrorCode: errorCode, + ErrorMessage: errorMessage, + }, + expiration: mockable.MaxTime, + } +} + func InboundAppResponse( chainID ids.ID, requestID uint32, diff --git a/message/inbound_msg_builder_test.go b/message/inbound_msg_builder_test.go index c9642c57250c..08234b58fd88 100644 --- a/message/inbound_msg_builder_test.go +++ b/message/inbound_msg_builder_test.go @@ -13,6 +13,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" ) @@ -396,3 +397,46 @@ func TestInboundMsgBuilder(t *testing.T) { }, ) } + +func TestAppError(t *testing.T) { + require := require.New(t) + + mb, err := newMsgBuilder( + logging.NoLog{}, + "", + prometheus.NewRegistry(), + time.Second, + ) + require.NoError(err) + + nodeID := ids.GenerateTestNodeID() + chainID := ids.GenerateTestID() + requestID := uint32(1) + errorCode := int32(2) + errorMessage := "hello world" + + want := &p2p.Message{ + Message: &p2p.Message_AppError{ + AppError: &p2p.AppError{ + ChainId: chainID[:], + RequestId: requestID, + ErrorCode: errorCode, + ErrorMessage: errorMessage, + }, + }, + } + + outMsg, err := mb.createOutbound(want, compression.TypeNone, false) + require.NoError(err) + + got, err := mb.parseInbound(outMsg.Bytes(), nodeID, func() {}) + require.NoError(err) + + require.Equal(nodeID, got.NodeID()) + require.Equal(AppErrorOp, got.Op()) + + msg, ok := got.Message().(*p2p.AppError) + require.True(ok) + require.Equal(errorCode, msg.ErrorCode) + require.Equal(errorMessage, msg.ErrorMessage) +} diff --git a/message/internal_msg_builder.go b/message/internal_msg_builder.go index 46e7b7e78405..9b1780b42571 100644 --- a/message/internal_msg_builder.go +++ b/message/internal_msg_builder.go @@ -52,10 +52,6 @@ var ( _ requestIDGetter = (*QueryFailed)(nil) _ engineTypeGetter = (*QueryFailed)(nil) - _ fmt.Stringer = (*AppRequestFailed)(nil) - _ chainIDGetter = (*AppRequestFailed)(nil) - _ requestIDGetter = (*AppRequestFailed)(nil) - _ fmt.Stringer = (*CrossChainAppRequest)(nil) _ sourceChainIDGetter = (*CrossChainAppRequest)(nil) _ chainIDGetter = (*CrossChainAppRequest)(nil) @@ -365,42 +361,6 @@ func InternalQueryFailed( } } -type AppRequestFailed struct { - ChainID ids.ID `json:"chain_id,omitempty"` - RequestID uint32 `json:"request_id,omitempty"` -} - -func (m *AppRequestFailed) String() string { - return fmt.Sprintf( - "ChainID: %s RequestID: %d", - m.ChainID, m.RequestID, - ) -} - -func (m *AppRequestFailed) GetChainId() []byte { - return m.ChainID[:] -} - -func (m *AppRequestFailed) GetRequestId() uint32 { - return m.RequestID -} - -func InternalAppRequestFailed( - nodeID ids.NodeID, - chainID ids.ID, - requestID uint32, -) InboundMessage { - return &inboundMessage{ - nodeID: nodeID, - op: AppRequestFailedOp, - message: &AppRequestFailed{ - ChainID: chainID, - RequestID: requestID, - }, - expiration: mockable.MaxTime, - } -} - type CrossChainAppRequest struct { SourceChainID ids.ID `json:"source_chain_id,omitempty"` DestinationChainID ids.ID `json:"destination_chain_id,omitempty"` @@ -452,6 +412,8 @@ type CrossChainAppRequestFailed struct { SourceChainID ids.ID `json:"source_chain_id,omitempty"` DestinationChainID ids.ID `json:"destination_chain_id,omitempty"` RequestID uint32 `json:"request_id,omitempty"` + ErrorCode int32 `json:"error_code,omitempty"` + ErrorMessage string `json:"error_message,omitempty"` } func (m *CrossChainAppRequestFailed) String() string { @@ -473,19 +435,23 @@ func (m *CrossChainAppRequestFailed) GetRequestId() uint32 { return m.RequestID } -func InternalCrossChainAppRequestFailed( +func InternalCrossChainAppError( nodeID ids.NodeID, sourceChainID ids.ID, destinationChainID ids.ID, requestID uint32, + errorCode int32, + errorMessage string, ) InboundMessage { return &inboundMessage{ nodeID: nodeID, - op: CrossChainAppRequestFailedOp, + op: CrossChainAppErrorOp, message: &CrossChainAppRequestFailed{ SourceChainID: sourceChainID, DestinationChainID: destinationChainID, RequestID: requestID, + ErrorCode: errorCode, + ErrorMessage: errorMessage, }, expiration: mockable.MaxTime, } diff --git a/message/ops.go b/message/ops.go index e069553abd42..f511ebacac36 100644 --- a/message/ops.go +++ b/message/ops.go @@ -51,12 +51,12 @@ const ( ChitsOp // Application: AppRequestOp - AppRequestFailedOp + AppErrorOp AppResponseOp AppGossipOp // Cross chain: CrossChainAppRequestOp - CrossChainAppRequestFailedOp + CrossChainAppErrorOp CrossChainAppResponseOp // Internal: ConnectedOp @@ -115,9 +115,9 @@ var ( GetAncestorsFailedOp, GetFailedOp, QueryFailedOp, - AppRequestFailedOp, + AppErrorOp, CrossChainAppRequestOp, - CrossChainAppRequestFailedOp, + CrossChainAppErrorOp, CrossChainAppResponseOp, ConnectedOp, ConnectedSubnetOp, @@ -165,12 +165,12 @@ var ( AsynchronousOps = []Op{ // Application AppRequestOp, - AppRequestFailedOp, + AppErrorOp, AppGossipOp, AppResponseOp, // Cross chain CrossChainAppRequestOp, - CrossChainAppRequestFailedOp, + CrossChainAppErrorOp, CrossChainAppResponseOp, } @@ -182,8 +182,8 @@ var ( GetAncestorsFailedOp: AncestorsOp, GetFailedOp: PutOp, QueryFailedOp: ChitsOp, - AppRequestFailedOp: AppResponseOp, - CrossChainAppRequestFailedOp: CrossChainAppResponseOp, + AppErrorOp: AppResponseOp, + CrossChainAppErrorOp: CrossChainAppResponseOp, } UnrequestedOps = set.Of( GetAcceptedFrontierOp, @@ -265,8 +265,8 @@ func (op Op) String() string { // Application case AppRequestOp: return "app_request" - case AppRequestFailedOp: - return "app_request_failed" + case AppErrorOp: + return "app_error" case AppResponseOp: return "app_response" case AppGossipOp: @@ -274,8 +274,8 @@ func (op Op) String() string { // Cross chain case CrossChainAppRequestOp: return "cross_chain_app_request" - case CrossChainAppRequestFailedOp: - return "cross_chain_app_request_failed" + case CrossChainAppErrorOp: + return "cross_chain_app_error" case CrossChainAppResponseOp: return "cross_chain_app_response" // Internal @@ -347,6 +347,8 @@ func Unwrap(m *p2p.Message) (fmt.Stringer, error) { return msg.AppRequest, nil case *p2p.Message_AppResponse: return msg.AppResponse, nil + case *p2p.Message_AppError: + return msg.AppError, nil case *p2p.Message_AppGossip: return msg.AppGossip, nil default: @@ -400,6 +402,8 @@ func ToOp(m *p2p.Message) (Op, error) { return AppRequestOp, nil case *p2p.Message_AppResponse: return AppResponseOp, nil + case *p2p.Message_AppError: + return AppErrorOp, nil case *p2p.Message_AppGossip: return AppGossipOp, nil default: diff --git a/network/p2p/client.go b/network/p2p/client.go index 1c3c9bee01da..6f2e35c26896 100644 --- a/network/p2p/client.go +++ b/network/p2p/client.go @@ -14,9 +14,8 @@ import ( ) var ( - ErrAppRequestFailed = errors.New("app request failed") - ErrRequestPending = errors.New("request pending") - ErrNoPeers = errors.New("no peers") + ErrRequestPending = errors.New("request pending") + ErrNoPeers = errors.New("no peers") ) // AppResponseCallback is called upon receiving an AppResponse for an AppRequest diff --git a/network/p2p/network.go b/network/p2p/network.go index 444c2e4b9408..bed562b1204d 100644 --- a/network/p2p/network.go +++ b/network/p2p/network.go @@ -87,8 +87,8 @@ func (n *Network) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID return n.router.AppResponse(ctx, nodeID, requestID, response) } -func (n *Network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - return n.router.AppRequestFailed(ctx, nodeID, requestID) +func (n *Network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error { + return n.router.AppRequestFailed(ctx, nodeID, requestID, appErr) } func (n *Network) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error { @@ -103,8 +103,8 @@ func (n *Network) CrossChainAppResponse(ctx context.Context, chainID ids.ID, req return n.router.CrossChainAppResponse(ctx, chainID, requestID, response) } -func (n *Network) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { - return n.router.CrossChainAppRequestFailed(ctx, chainID, requestID) +func (n *Network) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *common.AppError) error { + return n.router.CrossChainAppRequestFailed(ctx, chainID, requestID, appErr) } func (n *Network) Connected(_ context.Context, nodeID ids.NodeID, _ *version.Application) error { diff --git a/network/p2p/network_test.go b/network/p2p/network_test.go index 590858a0c467..17b02a3fa0a2 100644 --- a/network/p2p/network_test.go +++ b/network/p2p/network_test.go @@ -25,6 +25,11 @@ import ( "github.com/ava-labs/avalanchego/version" ) +var errFoo = &common.AppError{ + Code: 123, + Message: "foo", +} + func TestAppRequestResponse(t *testing.T) { handlerID := uint64(0x0) request := []byte("request") @@ -85,7 +90,7 @@ func TestAppRequestResponse(t *testing.T) { sender.SendAppRequestF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { for range nodeIDs { go func() { - require.NoError(t, network.AppRequestFailed(ctx, nodeID, requestID)) + require.NoError(t, network.AppRequestFailed(ctx, nodeID, requestID, errFoo)) }() } @@ -95,7 +100,7 @@ func TestAppRequestResponse(t *testing.T) { callback := func(_ context.Context, actualNodeID ids.NodeID, actualResponse []byte, err error) { defer wg.Done() - require.ErrorIs(t, err, ErrAppRequestFailed) + require.ErrorIs(t, err, errFoo) require.Equal(t, nodeID, actualNodeID) require.Nil(t, actualResponse) } @@ -140,14 +145,14 @@ func TestAppRequestResponse(t *testing.T) { requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { sender.SendCrossChainAppRequestF = func(ctx context.Context, chainID ids.ID, requestID uint32, request []byte) { go func() { - require.NoError(t, network.CrossChainAppRequestFailed(ctx, chainID, requestID)) + require.NoError(t, network.CrossChainAppRequestFailed(ctx, chainID, requestID, errFoo)) }() } callback := func(_ context.Context, actualChainID ids.ID, actualResponse []byte, err error) { defer wg.Done() - require.ErrorIs(t, err, ErrAppRequestFailed) + require.ErrorIs(t, err, errFoo) require.Equal(t, chainID, actualChainID) require.Nil(t, actualResponse) } @@ -273,7 +278,7 @@ func TestNetworkDropMessage(t *testing.T) { { name: "drop unrequested app request failed", requestFunc: func(network *Network) error { - return network.AppRequestFailed(context.Background(), ids.GenerateTestNodeID(), 0) + return network.AppRequestFailed(context.Background(), ids.GenerateTestNodeID(), 0, errFoo) }, err: ErrUnrequestedResponse, }, @@ -287,7 +292,7 @@ func TestNetworkDropMessage(t *testing.T) { { name: "drop unrequested cross-chain request failed", requestFunc: func(network *Network) error { - return network.CrossChainAppRequestFailed(context.Background(), ids.GenerateTestID(), 0) + return network.CrossChainAppRequestFailed(context.Background(), ids.GenerateTestID(), 0, errFoo) }, err: ErrUnrequestedResponse, }, diff --git a/network/p2p/router.go b/network/p2p/router.go index 110e9b6de627..0b4eff4eb576 100644 --- a/network/p2p/router.go +++ b/network/p2p/router.go @@ -223,7 +223,7 @@ func (r *router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID ui // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { +func (r *router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error { start := time.Now() pending, ok := r.clearAppRequest(requestID) if !ok { @@ -231,7 +231,7 @@ func (r *router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, reques return ErrUnrequestedResponse } - pending.AppResponseCallback(ctx, nodeID, nil, ErrAppRequestFailed) + pending.AppResponseCallback(ctx, nodeID, nil, appErr) pending.appRequestFailedTime.Observe(float64(time.Since(start))) return nil } @@ -316,7 +316,7 @@ func (r *router) CrossChainAppRequest( // // Any error condition propagated outside Handler application logic is // considered fatal -func (r *router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { +func (r *router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *common.AppError) error { start := time.Now() pending, ok := r.clearCrossChainAppRequest(requestID) if !ok { @@ -324,7 +324,7 @@ func (r *router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, return ErrUnrequestedResponse } - pending.CrossChainAppResponseCallback(ctx, chainID, nil, ErrAppRequestFailed) + pending.CrossChainAppResponseCallback(ctx, chainID, nil, appErr) pending.crossChainAppRequestFailedTime.Observe(float64(time.Since(start))) return nil } diff --git a/proto/pb/vm/vm.pb.go b/proto/pb/vm/vm.pb.go index a68fbbca4bc6..f7d48de642d7 100644 --- a/proto/pb/vm/vm.pb.go +++ b/proto/pb/vm/vm.pb.go @@ -1582,6 +1582,10 @@ type AppRequestFailedMsg struct { NodeId []byte `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` // The ID of the request we sent and didn't get a response to RequestId uint32 `protobuf:"varint,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // Application-defined error code + ErrorCode int32 `protobuf:"zigzag32,3,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` + // Application-defined error message + ErrorMessage string `protobuf:"bytes,4,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` } func (x *AppRequestFailedMsg) Reset() { @@ -1630,6 +1634,20 @@ func (x *AppRequestFailedMsg) GetRequestId() uint32 { return 0 } +func (x *AppRequestFailedMsg) GetErrorCode() int32 { + if x != nil { + return x.ErrorCode + } + return 0 +} + +func (x *AppRequestFailedMsg) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + type AppResponseMsg struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1837,6 +1855,10 @@ type CrossChainAppRequestFailedMsg struct { ChainId []byte `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` // The ID of the request we sent and didn't get a response to RequestId uint32 `protobuf:"varint,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // Application-defined error code + ErrorCode int32 `protobuf:"zigzag32,3,opt,name=error_code,json=errorCode,proto3" json:"error_code,omitempty"` + // Application-defined error message + ErrorMessage string `protobuf:"bytes,4,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` } func (x *CrossChainAppRequestFailedMsg) Reset() { @@ -1885,6 +1907,20 @@ func (x *CrossChainAppRequestFailedMsg) GetRequestId() uint32 { return 0 } +func (x *CrossChainAppRequestFailedMsg) GetErrorCode() int32 { + if x != nil { + return x.ErrorCode + } + return 0 +} + +func (x *CrossChainAppRequestFailedMsg) GetErrorMessage() string { + if x != nil { + return x.ErrorMessage + } + return "" +} + type CrossChainAppResponseMsg struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3179,324 +3215,333 @@ var file_vm_vm_proto_rawDesc = []byte{ 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4d, 0x0a, 0x13, 0x41, 0x70, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, - 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0x64, 0x0a, 0x0e, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, - 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, - 0x64, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x91, 0x01, 0x0a, 0x13, 0x41, + 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, + 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x64, + 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, + 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, + 0x70, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, + 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, + 0xa5, 0x01, 0x0a, 0x17, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9d, 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x6f, 0x73, + 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x39, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x12, - 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0xa5, 0x01, 0x0a, 0x17, 0x43, - 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x36, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x59, 0x0a, 0x1d, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, + 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, + 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x70, 0x0a, 0x18, 0x43, 0x72, 0x6f, 0x73, 0x73, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0x70, 0x0a, - 0x18, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x81, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x10, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, + 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, + 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, + 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x2e, 0x0a, + 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, - 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, - 0x74, 0x63, 0x68, 0x22, 0x2e, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, - 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, - 0x65, 0x49, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x62, - 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, - 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, - 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4e, 0x75, 0x6d, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x69, 0x7a, 0x65, - 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x72, - 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x74, - 0x72, 0x69, 0x76, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, 0x74, - 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, - 0x22, 0x34, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4f, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x0a, 0x19, 0x56, 0x65, 0x72, 0x69, 0x66, - 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, - 0x72, 0x22, 0x33, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, - 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x50, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, - 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x5d, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x68, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, - 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, - 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, - 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x7f, 0x0a, 0x22, 0x47, 0x65, - 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, - 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, - 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x78, 0x0a, 0x1b, 0x47, - 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0xb3, 0x01, + 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, + 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4e, + 0x75, 0x6d, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, + 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, + 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, + 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x54, + 0x69, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, + 0x6c, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x09, 0x62, 0x6c, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x18, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x4f, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x38, 0x0a, 0x19, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, + 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, + 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x33, 0x0a, 0x19, 0x47, + 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x22, 0x50, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, + 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, + 0x72, 0x72, 0x22, 0x5d, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x66, + 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, + 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, + 0x73, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, + 0x03, 0x65, 0x72, 0x72, 0x22, 0x7f, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, + 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x60, 0x0a, 0x19, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x78, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x03, - 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5c, 0x0a, 0x17, 0x47, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, - 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc5, 0x01, 0x0a, - 0x1a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, - 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, 0x6d, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, - 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, - 0x72, 0x22, 0x51, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, - 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, - 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, - 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, - 0x49, 0x43, 0x10, 0x03, 0x2a, 0x65, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, - 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, - 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, - 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, - 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, - 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x61, 0x0a, 0x06, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, - 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, - 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, - 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x8e, - 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, - 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, - 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x49, 0x4e, 0x43, - 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4e, 0x4f, - 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x04, 0x32, - 0xa4, 0x12, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, - 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, - 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x53, 0x68, - 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, - 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x14, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, 0x6e, 0x64, - 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x76, - 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, - 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, - 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, 0x2e, 0x76, 0x6d, - 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x44, - 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0a, 0x42, 0x75, - 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, - 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, - 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0d, 0x53, - 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x76, - 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, - 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, + 0x30, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x22, 0x60, 0x0a, 0x19, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, + 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, + 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, + 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x1a, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1b, + 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, + 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x51, 0x0a, 0x04, 0x4d, + 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, + 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, + 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, + 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x10, 0x03, 0x2a, 0x65, + 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, + 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, + 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, + 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, + 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, + 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x61, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, + 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, + 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, + 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, + 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x8e, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, + 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, + 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, + 0x45, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, + 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x04, 0x32, 0xa4, 0x12, 0x0a, 0x02, 0x56, 0x4d, + 0x12, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, + 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, + 0x08, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, + 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x76, 0x6d, 0x2e, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x41, - 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, - 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x41, 0x70, - 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x41, - 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, - 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x06, - 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, - 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x14, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, - 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, + 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, + 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, + 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, + 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, + 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, + 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x57, 0x0a, 0x1a, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x2e, - 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x43, 0x72, 0x6f, 0x73, - 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, - 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, - 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, - 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, - 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, - 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, - 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, - 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, - 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, - 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4f, 0x6e, - 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, - 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, - 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, + 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, + 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, - 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, - 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, - 0x66, 0x79, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x6d, 0x2e, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, + 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x06, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, + 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x14, + 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, + 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, + 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x57, 0x0a, 0x1a, 0x43, 0x72, 0x6f, + 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, + 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, - 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x6d, + 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x53, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x70, 0x62, 0x2f, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6d, 0x2e, + 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, + 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, + 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, + 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, + 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, + 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, + 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, + 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x76, + 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, + 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, + 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x16, 0x2e, 0x76, + 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, + 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x53, 0x0a, 0x12, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, + 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x76, 0x6d, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/vm/vm.proto b/proto/vm/vm.proto index 4a68c5e91810..fb93455105df 100644 --- a/proto/vm/vm.proto +++ b/proto/vm/vm.proto @@ -259,6 +259,10 @@ message AppRequestFailedMsg { bytes node_id = 1; // The ID of the request we sent and didn't get a response to uint32 request_id = 2; + // Application-defined error code + sint32 error_code = 3; + // Application-defined error message + string error_message = 4; } message AppResponseMsg { @@ -293,6 +297,10 @@ message CrossChainAppRequestFailedMsg { bytes chain_id = 1; // The ID of the request we sent and didn't get a response to uint32 request_id = 2; + // Application-defined error code + sint32 error_code = 3; + // Application-defined error message + string error_message = 4; } message CrossChainAppResponseMsg { diff --git a/snow/engine/avalanche/vertex/mock_vm.go b/snow/engine/avalanche/vertex/mock_vm.go index b8d2637c7311..045b275586d0 100644 --- a/snow/engine/avalanche/vertex/mock_vm.go +++ b/snow/engine/avalanche/vertex/mock_vm.go @@ -75,17 +75,17 @@ func (mr *MockLinearizableVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg } // AppRequestFailed mocks base method. -func (m *MockLinearizableVM) AppRequestFailed(arg0 context.Context, arg1 ids.NodeID, arg2 uint32) error { +func (m *MockLinearizableVM) AppRequestFailed(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 *common.AppError) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppRequestFailed", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "AppRequestFailed", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // AppRequestFailed indicates an expected call of AppRequestFailed. -func (mr *MockLinearizableVMMockRecorder) AppRequestFailed(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*MockLinearizableVM)(nil).AppRequestFailed), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*MockLinearizableVM)(nil).AppRequestFailed), arg0, arg1, arg2, arg3) } // AppResponse mocks base method. @@ -176,17 +176,17 @@ func (mr *MockLinearizableVMMockRecorder) CrossChainAppRequest(arg0, arg1, arg2, } // CrossChainAppRequestFailed mocks base method. -func (m *MockLinearizableVM) CrossChainAppRequestFailed(arg0 context.Context, arg1 ids.ID, arg2 uint32) error { +func (m *MockLinearizableVM) CrossChainAppRequestFailed(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 *common.AppError) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CrossChainAppRequestFailed", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "CrossChainAppRequestFailed", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // CrossChainAppRequestFailed indicates an expected call of CrossChainAppRequestFailed. -func (mr *MockLinearizableVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequestFailed", reflect.TypeOf((*MockLinearizableVM)(nil).CrossChainAppRequestFailed), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequestFailed", reflect.TypeOf((*MockLinearizableVM)(nil).CrossChainAppRequestFailed), arg0, arg1, arg2, arg3) } // CrossChainAppResponse mocks base method. diff --git a/snow/engine/common/engine.go b/snow/engine/common/engine.go index e50d94327a30..aea725ccf8a1 100644 --- a/snow/engine/common/engine.go +++ b/snow/engine/common/engine.go @@ -396,6 +396,7 @@ type AppResponseHandler interface { ctx context.Context, nodeID ids.NodeID, requestID uint32, + appErr *AppError, ) error } @@ -465,6 +466,7 @@ type CrossChainAppResponseHandler interface { ctx context.Context, chainID ids.ID, requestID uint32, + appErr *AppError, ) error } diff --git a/snow/engine/common/error.go b/snow/engine/common/error.go new file mode 100644 index 000000000000..9e83325ddd4e --- /dev/null +++ b/snow/engine/common/error.go @@ -0,0 +1,43 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package common + +import "fmt" + +var ( + _ error = (*AppError)(nil) + + // ErrUndefined indicates an undefined error + ErrUndefined = &AppError{ + Code: 0, + Message: "undefined", + } + + // ErrTimeout is used to signal a response timeout + ErrTimeout = &AppError{ + Code: -1, + Message: "timed out", + } +) + +// AppError is an application-defined error +type AppError struct { + // Code is application-defined and should be used for error matching + Code int32 + // Message is a human-readable error message + Message string +} + +func (a *AppError) Error() string { + return fmt.Sprintf("%d: %s", a.Code, a.Message) +} + +func (a *AppError) Is(target error) bool { + appErr, ok := target.(*AppError) + if !ok { + return false + } + + return a.Code == appErr.Code +} diff --git a/snow/engine/common/error_test.go b/snow/engine/common/error_test.go new file mode 100644 index 000000000000..124eaad33870 --- /dev/null +++ b/snow/engine/common/error_test.go @@ -0,0 +1,92 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package common + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" +) + +// Tests the invariant that AppErrors are matched against their error codes +func TestAppErrorEqual(t *testing.T) { + tests := []struct { + name string + err1 *AppError + err2 error + expected bool + }{ + { + name: "is - equal", + err1: &AppError{ + Code: 1, + }, + err2: &AppError{ + Code: 1, + }, + expected: true, + }, + { + name: "is - same error code different messages", + err1: &AppError{ + Code: 1, + Message: "foo", + }, + err2: &AppError{ + Code: 1, + Message: "bar", + }, + expected: true, + }, + { + name: "not is - different error code", + err1: &AppError{ + Code: 1, + }, + err2: &AppError{ + Code: 2, + }, + }, + { + name: "not is - different type", + err1: &AppError{ + Code: 1, + }, + err2: errors.New("foobar"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.expected, errors.Is(tt.err1, tt.err2)) + }) + } +} + +// Tests reserved error types +func TestErrorCode(t *testing.T) { + tests := []struct { + name string + code int32 + expected *AppError + }{ + { + name: "undefined", + code: 0, + expected: ErrUndefined, + }, + { + name: "undefined", + code: -1, + expected: ErrTimeout, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.ErrorIs(t, tt.expected, &AppError{Code: tt.code}) + }) + } +} diff --git a/snow/engine/common/no_ops_handlers.go b/snow/engine/common/no_ops_handlers.go index 716d1d5111b3..15a3f2900ccb 100644 --- a/snow/engine/common/no_ops_handlers.go +++ b/snow/engine/common/no_ops_handlers.go @@ -288,12 +288,13 @@ func (nop *noOpAppHandler) CrossChainAppRequest(_ context.Context, chainID ids.I return nil } -func (nop *noOpAppHandler) CrossChainAppRequestFailed(_ context.Context, chainID ids.ID, requestID uint32) error { +func (nop *noOpAppHandler) CrossChainAppRequestFailed(_ context.Context, chainID ids.ID, requestID uint32, appErr *AppError) error { nop.log.Debug("dropping request", zap.String("reason", "unhandled by this gear"), - zap.Stringer("messageOp", message.CrossChainAppRequestFailedOp), + zap.Stringer("messageOp", message.CrossChainAppErrorOp), zap.Stringer("chainID", chainID), zap.Uint32("requestID", requestID), + zap.Error(appErr), ) return nil } @@ -318,12 +319,13 @@ func (nop *noOpAppHandler) AppRequest(_ context.Context, nodeID ids.NodeID, requ return nil } -func (nop *noOpAppHandler) AppRequestFailed(_ context.Context, nodeID ids.NodeID, requestID uint32) error { +func (nop *noOpAppHandler) AppRequestFailed(_ context.Context, nodeID ids.NodeID, requestID uint32, appErr *AppError) error { nop.log.Debug("dropping request", zap.String("reason", "unhandled by this gear"), - zap.Stringer("messageOp", message.AppRequestFailedOp), + zap.Stringer("messageOp", message.AppErrorOp), zap.Stringer("nodeID", nodeID), zap.Uint32("requestID", requestID), + zap.Error(appErr), ) return nil } diff --git a/snow/engine/common/test_engine.go b/snow/engine/common/test_engine.go index 0081d63b5753..414048366336 100644 --- a/snow/engine/common/test_engine.go +++ b/snow/engine/common/test_engine.go @@ -125,7 +125,7 @@ type EngineTest struct { GetStateSummaryFrontierF, GetStateSummaryFrontierFailedF, GetAcceptedStateSummaryFailedF, GetAcceptedFrontierF, GetFailedF, GetAncestorsFailedF, QueryFailedF, GetAcceptedFrontierFailedF, GetAcceptedFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32) error - AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32) error + AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *AppError) error StateSummaryFrontierF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, summary []byte) error GetAcceptedStateSummaryF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, keys set.Set[uint64]) error AcceptedStateSummaryF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs set.Set[ids.ID]) error @@ -138,7 +138,7 @@ type EngineTest struct { AppGossipF func(ctx context.Context, nodeID ids.NodeID, msg []byte) error CrossChainAppRequestF func(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, msg []byte) error CrossChainAppResponseF func(ctx context.Context, chainID ids.ID, requestID uint32, msg []byte) error - CrossChainAppRequestFailedF func(ctx context.Context, chainID ids.ID, requestID uint32) error + CrossChainAppRequestFailedF func(ctx context.Context, chainID ids.ID, requestID uint32, appErr *AppError) error } func (e *EngineTest) Default(cant bool) { @@ -562,9 +562,9 @@ func (e *EngineTest) CrossChainAppRequest(ctx context.Context, chainID ids.ID, r return errCrossChainAppRequest } -func (e *EngineTest) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { +func (e *EngineTest) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *AppError) error { if e.CrossChainAppRequestFailedF != nil { - return e.CrossChainAppRequestFailedF(ctx, chainID, requestID) + return e.CrossChainAppRequestFailedF(ctx, chainID, requestID, appErr) } if !e.CantCrossChainAppRequestFailed { return nil @@ -614,9 +614,9 @@ func (e *EngineTest) AppResponse(ctx context.Context, nodeID ids.NodeID, request return errAppResponse } -func (e *EngineTest) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { +func (e *EngineTest) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *AppError) error { if e.AppRequestFailedF != nil { - return e.AppRequestFailedF(ctx, nodeID, requestID) + return e.AppRequestFailedF(ctx, nodeID, requestID, appErr) } if !e.CantAppRequestFailed { return nil diff --git a/snow/engine/common/test_vm.go b/snow/engine/common/test_vm.go index 9d1a77ef2a9f..8146a5f6746b 100644 --- a/snow/engine/common/test_vm.go +++ b/snow/engine/common/test_vm.go @@ -60,11 +60,11 @@ type TestVM struct { AppRequestF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, msg []byte) error AppResponseF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, msg []byte) error AppGossipF func(ctx context.Context, nodeID ids.NodeID, msg []byte) error - AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32) error + AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *AppError) error VersionF func(context.Context) (string, error) CrossChainAppRequestF func(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, msg []byte) error CrossChainAppResponseF func(ctx context.Context, chainID ids.ID, requestID uint32, msg []byte) error - CrossChainAppRequestFailedF func(ctx context.Context, chainID ids.ID, requestID uint32) error + CrossChainAppRequestFailedF func(ctx context.Context, chainID ids.ID, requestID uint32, appErr *AppError) error } func (vm *TestVM) Default(cant bool) { @@ -185,9 +185,9 @@ func (vm *TestVM) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID u return errAppRequest } -func (vm *TestVM) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { +func (vm *TestVM) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *AppError) error { if vm.AppRequestFailedF != nil { - return vm.AppRequestFailedF(ctx, nodeID, requestID) + return vm.AppRequestFailedF(ctx, nodeID, requestID, appErr) } if !vm.CantAppRequestFailed { return nil @@ -237,9 +237,9 @@ func (vm *TestVM) CrossChainAppRequest(ctx context.Context, chainID ids.ID, requ return errCrossChainAppRequest } -func (vm *TestVM) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { +func (vm *TestVM) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *AppError) error { if vm.CrossChainAppRequestFailedF != nil { - return vm.CrossChainAppRequestFailedF(ctx, chainID, requestID) + return vm.CrossChainAppRequestFailedF(ctx, chainID, requestID, appErr) } if !vm.CantCrossChainAppRequestFailed { return nil diff --git a/snow/engine/common/traced_engine.go b/snow/engine/common/traced_engine.go index 28be03d6df7c..13ecc92a97ca 100644 --- a/snow/engine/common/traced_engine.go +++ b/snow/engine/common/traced_engine.go @@ -291,14 +291,14 @@ func (e *tracedEngine) AppResponse(ctx context.Context, nodeID ids.NodeID, reque return e.engine.AppResponse(ctx, nodeID, requestID, response) } -func (e *tracedEngine) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { +func (e *tracedEngine) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *AppError) error { ctx, span := e.tracer.Start(ctx, "tracedEngine.AppRequestFailed", oteltrace.WithAttributes( attribute.Stringer("nodeID", nodeID), attribute.Int64("requestID", int64(requestID)), )) defer span.End() - return e.engine.AppRequestFailed(ctx, nodeID, requestID) + return e.engine.AppRequestFailed(ctx, nodeID, requestID, appErr) } func (e *tracedEngine) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error { @@ -333,14 +333,14 @@ func (e *tracedEngine) CrossChainAppResponse(ctx context.Context, chainID ids.ID return e.engine.CrossChainAppResponse(ctx, chainID, requestID, response) } -func (e *tracedEngine) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { +func (e *tracedEngine) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *AppError) error { ctx, span := e.tracer.Start(ctx, "tracedEngine.CrossChainAppRequestFailed", oteltrace.WithAttributes( attribute.Stringer("chainID", chainID), attribute.Int64("requestID", int64(requestID)), )) defer span.End() - return e.engine.CrossChainAppRequestFailed(ctx, chainID, requestID) + return e.engine.CrossChainAppRequestFailed(ctx, chainID, requestID, appErr) } func (e *tracedEngine) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { diff --git a/snow/engine/snowman/block/mocks/chain_vm.go b/snow/engine/snowman/block/mocks/chain_vm.go index 2a2446a94ee5..fc75a0f344a8 100644 --- a/snow/engine/snowman/block/mocks/chain_vm.go +++ b/snow/engine/snowman/block/mocks/chain_vm.go @@ -74,17 +74,17 @@ func (mr *MockChainVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg4 inter } // AppRequestFailed mocks base method. -func (m *MockChainVM) AppRequestFailed(arg0 context.Context, arg1 ids.NodeID, arg2 uint32) error { +func (m *MockChainVM) AppRequestFailed(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 *common.AppError) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppRequestFailed", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "AppRequestFailed", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // AppRequestFailed indicates an expected call of AppRequestFailed. -func (mr *MockChainVMMockRecorder) AppRequestFailed(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*MockChainVM)(nil).AppRequestFailed), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*MockChainVM)(nil).AppRequestFailed), arg0, arg1, arg2, arg3) } // AppResponse mocks base method. @@ -175,17 +175,17 @@ func (mr *MockChainVMMockRecorder) CrossChainAppRequest(arg0, arg1, arg2, arg3, } // CrossChainAppRequestFailed mocks base method. -func (m *MockChainVM) CrossChainAppRequestFailed(arg0 context.Context, arg1 ids.ID, arg2 uint32) error { +func (m *MockChainVM) CrossChainAppRequestFailed(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 *common.AppError) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CrossChainAppRequestFailed", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "CrossChainAppRequestFailed", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // CrossChainAppRequestFailed indicates an expected call of CrossChainAppRequestFailed. -func (mr *MockChainVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequestFailed", reflect.TypeOf((*MockChainVM)(nil).CrossChainAppRequestFailed), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequestFailed", reflect.TypeOf((*MockChainVM)(nil).CrossChainAppRequestFailed), arg0, arg1, arg2, arg3) } // CrossChainAppResponse mocks base method. diff --git a/snow/networking/handler/handler.go b/snow/networking/handler/handler.go index 68ec1e5a0f36..b11f719cca13 100644 --- a/snow/networking/handler/handler.go +++ b/snow/networking/handler/handler.go @@ -271,8 +271,8 @@ func (h *handler) Start(ctx context.Context, recoverPanic bool) { // Push the message onto the handler's queue func (h *handler) Push(ctx context.Context, msg Message) { switch msg.Op() { - case message.AppRequestOp, message.AppRequestFailedOp, message.AppResponseOp, message.AppGossipOp, - message.CrossChainAppRequestOp, message.CrossChainAppRequestFailedOp, message.CrossChainAppResponseOp: + case message.AppRequestOp, message.AppErrorOp, message.AppResponseOp, message.AppGossipOp, + message.CrossChainAppRequestOp, message.CrossChainAppErrorOp, message.CrossChainAppResponseOp: h.asyncMessageQueue.Push(ctx, msg) default: h.syncMessageQueue.Push(ctx, msg) @@ -842,8 +842,18 @@ func (h *handler) executeAsyncMsg(ctx context.Context, msg Message) error { case *p2p.AppResponse: return engine.AppResponse(ctx, nodeID, m.RequestId, m.AppBytes) - case *message.AppRequestFailed: - return engine.AppRequestFailed(ctx, nodeID, m.RequestID) + case *p2p.AppError: + err := &common.AppError{ + Code: m.ErrorCode, + Message: m.ErrorMessage, + } + + return engine.AppRequestFailed( + ctx, + nodeID, + m.RequestId, + err, + ) case *p2p.AppGossip: return engine.AppGossip(ctx, nodeID, m.AppBytes) @@ -866,10 +876,16 @@ func (h *handler) executeAsyncMsg(ctx context.Context, msg Message) error { ) case *message.CrossChainAppRequestFailed: + err := &common.AppError{ + Code: m.ErrorCode, + Message: m.ErrorMessage, + } + return engine.CrossChainAppRequestFailed( ctx, m.SourceChainID, m.RequestID, + err, ) default: diff --git a/snow/networking/router/chain_router_test.go b/snow/networking/router/chain_router_test.go index 1e37c7c1d799..05e749ed7bcf 100644 --- a/snow/networking/router/chain_router_test.go +++ b/snow/networking/router/chain_router_test.go @@ -43,6 +43,8 @@ const ( testThreadPoolSize = 2 ) +// TODO refactor tests in this file + func TestShutdown(t *testing.T) { require := require.New(t) @@ -451,12 +453,12 @@ func TestRouterTimeout(t *testing.T) { calledQueryFailed = true return nil } - bootstrapper.AppRequestFailedF = func(context.Context, ids.NodeID, uint32) error { + bootstrapper.AppRequestFailedF = func(context.Context, ids.NodeID, uint32, *common.AppError) error { defer wg.Done() calledAppRequestFailed = true return nil } - bootstrapper.CrossChainAppRequestFailedF = func(context.Context, ids.ID, uint32) error { + bootstrapper.CrossChainAppRequestFailedF = func(context.Context, ids.ID, uint32, *common.AppError) error { defer wg.Done() calledCrossChainAppRequestFailed = true return nil @@ -634,10 +636,12 @@ func TestRouterTimeout(t *testing.T) { ctx.ChainID, requestID, message.AppResponseOp, - message.InternalAppRequestFailed( + message.InboundAppError( nodeID, ctx.ChainID, requestID, + common.ErrTimeout.Code, + common.ErrTimeout.Message, ), p2p.EngineType_ENGINE_TYPE_SNOWMAN, ) @@ -653,11 +657,13 @@ func TestRouterTimeout(t *testing.T) { ctx.ChainID, requestID, message.CrossChainAppResponseOp, - message.InternalCrossChainAppRequestFailed( + message.InternalCrossChainAppError( nodeID, ctx.ChainID, ctx.ChainID, requestID, + common.ErrTimeout.Code, + common.ErrTimeout.Message, ), p2p.EngineType_ENGINE_TYPE_SNOWMAN, ) @@ -814,291 +820,91 @@ func TestRouterHonorsRequestedEngine(t *testing.T) { } func TestRouterClearTimeouts(t *testing.T) { - require := require.New(t) - - // Create a timeout manager - tm, err := timeout.NewManager( - &timer.AdaptiveTimeoutConfig{ - InitialTimeout: 3 * time.Second, - MinimumTimeout: 3 * time.Second, - MaximumTimeout: 5 * time.Minute, - TimeoutCoefficient: 1, - TimeoutHalflife: 5 * time.Minute, + requestID := uint32(123) + + tests := []struct { + name string + responseOp message.Op + responseMsg message.InboundMessage + timeoutMsg message.InboundMessage + }{ + { + name: "StateSummaryFrontier", + responseOp: message.StateSummaryFrontierOp, + responseMsg: message.InboundStateSummaryFrontier(ids.Empty, requestID, []byte("summary"), ids.EmptyNodeID), + timeoutMsg: message.InternalGetStateSummaryFrontierFailed(ids.EmptyNodeID, ids.Empty, requestID), }, - benchlist.NewNoBenchlist(), - "", - prometheus.NewRegistry(), - ) - require.NoError(err) - - go tm.Dispatch() - defer tm.Stop() - - // Create a router - chainRouter := ChainRouter{} - require.NoError(chainRouter.Initialize( - ids.EmptyNodeID, - logging.NoLog{}, - tm, - time.Millisecond, - set.Set[ids.ID]{}, - true, - set.Set[ids.ID]{}, - nil, - HealthConfig{}, - "", - prometheus.NewRegistry(), - )) - defer chainRouter.Shutdown(context.Background()) - - // Create bootstrapper, engine and handler - ctx := snow.DefaultConsensusContextTest() - vdrs := validators.NewManager() - require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) - - resourceTracker, err := tracker.NewResourceTracker( - prometheus.NewRegistry(), - resource.NoUsage, - meter.ContinuousFactory{}, - time.Second, - ) - require.NoError(err) - h, err := handler.New( - ctx, - vdrs, - nil, - time.Second, - testThreadPoolSize, - resourceTracker, - validators.UnhandledSubnetConnector, - subnets.New(ctx.NodeID, subnets.Config{}), - commontracker.NewPeers(), - ) - require.NoError(err) - - bootstrapper := &common.BootstrapperTest{ - EngineTest: common.EngineTest{ - T: t, + { + name: "AcceptedStateSummary", + responseOp: message.AcceptedStateSummaryOp, + responseMsg: message.InboundAcceptedStateSummary(ids.Empty, requestID, []ids.ID{ids.GenerateTestID()}, ids.EmptyNodeID), + timeoutMsg: message.InternalGetAcceptedStateSummaryFailed(ids.EmptyNodeID, ids.Empty, requestID), }, - } - bootstrapper.Default(false) - bootstrapper.ContextF = func() *snow.ConsensusContext { - return ctx - } - - engine := &common.EngineTest{T: t} - engine.Default(false) - engine.ContextF = func() *snow.ConsensusContext { - return ctx - } - h.SetEngineManager(&handler.EngineManager{ - Avalanche: &handler.Engine{ - StateSyncer: nil, - Bootstrapper: bootstrapper, - Consensus: engine, + { + name: "AcceptedFrontierOp", + responseOp: message.AcceptedFrontierOp, + responseMsg: message.InboundAcceptedFrontier(ids.Empty, requestID, ids.GenerateTestID(), ids.EmptyNodeID), + timeoutMsg: message.InternalGetAcceptedFrontierFailed(ids.EmptyNodeID, ids.Empty, requestID, engineType), }, - Snowman: &handler.Engine{ - StateSyncer: nil, - Bootstrapper: bootstrapper, - Consensus: engine, + { + name: "Accepted", + responseOp: message.AcceptedOp, + responseMsg: message.InboundAccepted(ids.Empty, requestID, []ids.ID{ids.GenerateTestID()}, ids.EmptyNodeID), + timeoutMsg: message.InternalGetAcceptedFailed(ids.EmptyNodeID, ids.Empty, requestID, engineType), + }, + { + name: "Chits", + responseOp: message.ChitsOp, + responseMsg: message.InboundChits(ids.Empty, requestID, ids.GenerateTestID(), ids.GenerateTestID(), ids.GenerateTestID(), ids.EmptyNodeID), + timeoutMsg: message.InternalQueryFailed(ids.EmptyNodeID, ids.Empty, requestID, engineType), + }, + { + name: "AppResponse", + responseOp: message.AppResponseOp, + responseMsg: message.InboundAppResponse(ids.Empty, requestID, []byte("responseMsg"), ids.EmptyNodeID), + timeoutMsg: message.InboundAppError(ids.EmptyNodeID, ids.Empty, requestID, 123, "error"), + }, + { + name: "AppError", + responseOp: message.AppResponseOp, + responseMsg: message.InboundAppError(ids.EmptyNodeID, ids.Empty, requestID, 1234, "custom error"), + timeoutMsg: message.InboundAppError(ids.EmptyNodeID, ids.Empty, requestID, 123, "error"), + }, + { + name: "CrossChainAppResponse", + responseOp: message.CrossChainAppResponseOp, + responseMsg: message.InternalCrossChainAppResponse(ids.EmptyNodeID, ids.Empty, ids.Empty, requestID, []byte("responseMsg")), + timeoutMsg: message.InternalCrossChainAppError(ids.EmptyNodeID, ids.Empty, ids.Empty, requestID, 123, "error"), + }, + { + name: "CrossChainAppError", + responseOp: message.CrossChainAppResponseOp, + responseMsg: message.InternalCrossChainAppError(ids.EmptyNodeID, ids.Empty, ids.Empty, requestID, 1234, "custom error"), + timeoutMsg: message.InternalCrossChainAppError(ids.EmptyNodeID, ids.Empty, ids.Empty, requestID, 123, "error"), }, - }) - ctx.State.Set(snow.EngineState{ - Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, - State: snow.NormalOp, // assumed bootstrapping is done - }) - - chainRouter.AddChain(context.Background(), h) - - bootstrapper.StartF = func(context.Context, uint32) error { - return nil - } - h.Start(context.Background(), false) - - nodeID := ids.GenerateTestNodeID() - requestID := uint32(0) - { - chainRouter.RegisterRequest( - context.Background(), - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - message.StateSummaryFrontierOp, - message.InternalGetStateSummaryFrontierFailed( - nodeID, - ctx.ChainID, - requestID, - ), - engineType, - ) - msg := message.InboundStateSummaryFrontier( - ctx.ChainID, - requestID, - nil, - nodeID, - ) - chainRouter.HandleInbound(context.Background(), msg) - } - - { - requestID++ - chainRouter.RegisterRequest( - context.Background(), - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - message.AcceptedStateSummaryOp, - message.InternalGetAcceptedStateSummaryFailed( - nodeID, - ctx.ChainID, - requestID, - ), - engineType, - ) - msg := message.InboundAcceptedStateSummary( - ctx.ChainID, - requestID, - nil, - nodeID, - ) - chainRouter.HandleInbound(context.Background(), msg) } - { - requestID++ - chainRouter.RegisterRequest( - context.Background(), - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - message.AcceptedFrontierOp, - message.InternalGetAcceptedFrontierFailed( - nodeID, - ctx.ChainID, - requestID, - engineType, - ), - engineType, - ) - msg := message.InboundAcceptedFrontier( - ctx.ChainID, - requestID, - ids.Empty, - nodeID, - ) - chainRouter.HandleInbound(context.Background(), msg) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) - { - requestID++ - chainRouter.RegisterRequest( - context.Background(), - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - message.AcceptedOp, - message.InternalGetAcceptedFailed( - nodeID, - ctx.ChainID, - requestID, - engineType, - ), - engineType, - ) - msg := message.InboundAccepted( - ctx.ChainID, - requestID, - nil, - nodeID, - ) - chainRouter.HandleInbound(context.Background(), msg) - } + chainRouter, _ := newChainRouterTest(t) - { - requestID++ - chainRouter.RegisterRequest( - context.Background(), - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - message.ChitsOp, - message.InternalQueryFailed( - nodeID, - ctx.ChainID, + chainRouter.RegisterRequest( + context.Background(), + ids.EmptyNodeID, + ids.Empty, + ids.Empty, requestID, + tt.responseOp, + tt.timeoutMsg, engineType, - ), - engineType, - ) - msg := message.InboundChits( - ctx.ChainID, - requestID, - ids.Empty, - ids.Empty, - ids.Empty, - nodeID, - ) - chainRouter.HandleInbound(context.Background(), msg) - } + ) - { - requestID++ - chainRouter.RegisterRequest( - context.Background(), - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - message.AppResponseOp, - message.InternalAppRequestFailed( - nodeID, - ctx.ChainID, - requestID, - ), - engineType, - ) - msg := message.InboundAppResponse( - ctx.ChainID, - requestID, - nil, - nodeID, - ) - chainRouter.HandleInbound(context.Background(), msg) - } - - { - requestID++ - chainRouter.RegisterRequest( - context.Background(), - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - message.CrossChainAppResponseOp, - message.InternalCrossChainAppRequestFailed( - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - ), - p2p.EngineType_ENGINE_TYPE_UNSPECIFIED, - ) - msg := message.InternalCrossChainAppResponse( - nodeID, - ctx.ChainID, - ctx.ChainID, - requestID, - nil, - ) - chainRouter.HandleInbound(context.Background(), msg) + chainRouter.HandleInbound(context.Background(), tt.responseMsg) + require.Zero(chainRouter.timedRequests.Len()) + }) } - - require.Zero(chainRouter.timedRequests.Len()) } func TestValidatorOnlyMessageDrops(t *testing.T) { @@ -1253,179 +1059,6 @@ func TestValidatorOnlyMessageDrops(t *testing.T) { require.True(calledF) // should be called since this is a validator request } -func TestRouterCrossChainMessages(t *testing.T) { - require := require.New(t) - - tm, err := timeout.NewManager( - &timer.AdaptiveTimeoutConfig{ - InitialTimeout: 3 * time.Second, - MinimumTimeout: 3 * time.Second, - MaximumTimeout: 5 * time.Minute, - TimeoutCoefficient: 1, - TimeoutHalflife: 5 * time.Minute, - }, - benchlist.NewNoBenchlist(), - "timeoutManager", - prometheus.NewRegistry(), - ) - require.NoError(err) - - go tm.Dispatch() - defer tm.Stop() - - // Create chain router - nodeID := ids.GenerateTestNodeID() - chainRouter := ChainRouter{} - require.NoError(chainRouter.Initialize( - nodeID, - logging.NoLog{}, - tm, - time.Millisecond, - set.Set[ids.ID]{}, - true, - set.Set[ids.ID]{}, - nil, - HealthConfig{}, - "", - prometheus.NewRegistry(), - )) - defer chainRouter.Shutdown(context.Background()) - - requester := snow.DefaultConsensusContextTest() - requester.ChainID = ids.GenerateTestID() - requester.Registerer = prometheus.NewRegistry() - requester.Metrics = metrics.NewOptionalGatherer() - requester.Executing.Set(false) - - // Set up validators - vdrs := validators.NewManager() - require.NoError(vdrs.AddStaker(requester.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) - - // Create bootstrapper, engine and handler - resourceTracker, err := tracker.NewResourceTracker( - prometheus.NewRegistry(), - resource.NoUsage, - meter.ContinuousFactory{}, - time.Second, - ) - require.NoError(err) - - requesterHandler, err := handler.New( - requester, - vdrs, - nil, - time.Second, - testThreadPoolSize, - resourceTracker, - validators.UnhandledSubnetConnector, - subnets.New(requester.NodeID, subnets.Config{}), - commontracker.NewPeers(), - ) - require.NoError(err) - requesterHandler.SetEngineManager(&handler.EngineManager{ - Avalanche: &handler.Engine{ - StateSyncer: nil, - Bootstrapper: &common.BootstrapperTest{}, - Consensus: &common.EngineTest{}, - }, - Snowman: &handler.Engine{ - StateSyncer: nil, - Bootstrapper: &common.BootstrapperTest{}, - Consensus: &common.EngineTest{}, - }, - }) - - responder := snow.DefaultConsensusContextTest() - responder.ChainID = ids.GenerateTestID() - responder.Registerer = prometheus.NewRegistry() - responder.Metrics = metrics.NewOptionalGatherer() - responder.Executing.Set(false) - - responderHandler, err := handler.New( - responder, - vdrs, - nil, - time.Second, - testThreadPoolSize, - resourceTracker, - validators.UnhandledSubnetConnector, - subnets.New(responder.NodeID, subnets.Config{}), - commontracker.NewPeers(), - ) - require.NoError(err) - responderHandler.SetEngineManager(&handler.EngineManager{ - Avalanche: &handler.Engine{ - StateSyncer: nil, - Bootstrapper: &common.BootstrapperTest{}, - Consensus: &common.EngineTest{}, - }, - Snowman: &handler.Engine{ - StateSyncer: nil, - Bootstrapper: &common.BootstrapperTest{}, - Consensus: &common.EngineTest{}, - }, - }) - - // assumed bootstrapping is done - responder.State.Set(snow.EngineState{ - Type: engineType, - State: snow.NormalOp, - }) - requester.State.Set(snow.EngineState{ - Type: engineType, - State: snow.NormalOp, - }) - - // router tracks two chains - one will send a message to the other - chainRouter.AddChain(context.Background(), requesterHandler) - chainRouter.AddChain(context.Background(), responderHandler) - - // Each chain should start off with a connected message - require.Equal(1, chainRouter.chainHandlers[requester.ChainID].Len()) - require.Equal(1, chainRouter.chainHandlers[responder.ChainID].Len()) - - // Requester sends a request to the responder - msgBytes := []byte("foobar") - msg := message.InternalCrossChainAppRequest( - requester.NodeID, - requester.ChainID, - responder.ChainID, - uint32(1), - time.Minute, - msgBytes, - ) - chainRouter.HandleInbound(context.Background(), msg) - require.Equal(2, chainRouter.chainHandlers[responder.ChainID].Len()) - - // We register the cross-chain response on the requester-side so we don't - // drop it. - chainRouter.RegisterRequest( - context.Background(), - nodeID, - requester.ChainID, - responder.ChainID, - uint32(1), - message.CrossChainAppResponseOp, - message.InternalCrossChainAppRequestFailed( - nodeID, - responder.ChainID, - requester.ChainID, - uint32(1), - ), - p2p.EngineType_ENGINE_TYPE_UNSPECIFIED, - ) - // Responder sends a response back to the requester. - msg = message.InternalCrossChainAppResponse( - nodeID, - responder.ChainID, - requester.ChainID, - uint32(1), - msgBytes, - ) - chainRouter.HandleInbound(context.Background(), msg) - require.Equal(2, chainRouter.chainHandlers[requester.ChainID].Len()) -} - func TestConnectedSubnet(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) @@ -1713,3 +1346,274 @@ func TestValidatorOnlyAllowedNodeMessageDrops(t *testing.T) { wg.Wait() require.True(calledF) // should be called since this is a validator request } + +// Tests that a response, peer error, or a timeout clears the timeout and calls +// the handler +func TestAppRequest(t *testing.T) { + wantRequestID := uint32(123) + wantResponse := []byte("response") + + errFoo := common.AppError{ + Code: 456, + Message: "foo", + } + + tests := []struct { + name string + responseOp message.Op + timeoutMsg message.InboundMessage + inboundMsg message.InboundMessage + }{ + { + name: "AppRequest - chain response", + responseOp: message.AppResponseOp, + timeoutMsg: message.InboundAppError(ids.EmptyNodeID, ids.Empty, wantRequestID, errFoo.Code, errFoo.Message), + inboundMsg: message.InboundAppResponse(ids.Empty, wantRequestID, wantResponse, ids.EmptyNodeID), + }, + { + name: "AppRequest - chain error", + responseOp: message.AppResponseOp, + timeoutMsg: message.InboundAppError(ids.EmptyNodeID, ids.Empty, wantRequestID, errFoo.Code, errFoo.Message), + inboundMsg: message.InboundAppError(ids.EmptyNodeID, ids.Empty, wantRequestID, errFoo.Code, errFoo.Message), + }, + { + name: "AppRequest - timeout", + responseOp: message.AppResponseOp, + timeoutMsg: message.InboundAppError(ids.EmptyNodeID, ids.Empty, wantRequestID, errFoo.Code, errFoo.Message), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + + wg := &sync.WaitGroup{} + chainRouter, engine := newChainRouterTest(t) + + wg.Add(1) + if tt.inboundMsg == nil || tt.inboundMsg.Op() == message.AppErrorOp { + engine.AppRequestFailedF = func(_ context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error { + defer wg.Done() + require.Zero(chainRouter.timedRequests.Len()) + + require.Equal(ids.EmptyNodeID, nodeID) + require.Equal(wantRequestID, requestID) + require.Equal(errFoo.Code, appErr.Code) + require.Equal(errFoo.Message, appErr.Message) + + return nil + } + } else if tt.inboundMsg.Op() == message.AppResponseOp { + engine.AppResponseF = func(ctx context.Context, nodeID ids.NodeID, requestID uint32, msg []byte) error { + defer wg.Done() + require.Zero(chainRouter.timedRequests.Len()) + + require.Equal(ids.EmptyNodeID, nodeID) + require.Equal(wantRequestID, requestID) + require.Equal(wantResponse, msg) + + return nil + } + } + + ctx := context.Background() + chainRouter.RegisterRequest(ctx, ids.EmptyNodeID, ids.Empty, ids.Empty, wantRequestID, tt.responseOp, tt.timeoutMsg, engineType) + require.Equal(1, chainRouter.timedRequests.Len()) + + if tt.inboundMsg != nil { + chainRouter.HandleInbound(ctx, tt.inboundMsg) + } + + wg.Wait() + }) + } +} + +// Tests that a response, peer error, or a timeout clears the timeout and calls +// the handler +func TestCrossChainAppRequest(t *testing.T) { + wantRequestID := uint32(123) + wantResponse := []byte("response") + + errFoo := common.AppError{ + Code: 456, + Message: "foo", + } + + tests := []struct { + name string + responseOp message.Op + timeoutMsg message.InboundMessage + inboundMsg message.InboundMessage + }{ + { + name: "CrossChainAppRequest - chain response", + responseOp: message.CrossChainAppResponseOp, + timeoutMsg: message.InternalCrossChainAppError(ids.EmptyNodeID, ids.Empty, ids.Empty, wantRequestID, errFoo.Code, errFoo.Message), + inboundMsg: message.InternalCrossChainAppResponse(ids.EmptyNodeID, ids.Empty, ids.Empty, wantRequestID, wantResponse), + }, + { + name: "CrossChainAppRequest - chain error", + responseOp: message.CrossChainAppResponseOp, + timeoutMsg: message.InternalCrossChainAppError(ids.EmptyNodeID, ids.Empty, ids.Empty, wantRequestID, errFoo.Code, errFoo.Message), + inboundMsg: message.InternalCrossChainAppError(ids.EmptyNodeID, ids.Empty, ids.Empty, wantRequestID, errFoo.Code, errFoo.Message), + }, + { + name: "CrossChainAppRequest - timeout", + responseOp: message.CrossChainAppResponseOp, + timeoutMsg: message.InternalCrossChainAppError(ids.EmptyNodeID, ids.Empty, ids.Empty, wantRequestID, errFoo.Code, errFoo.Message), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + + wg := &sync.WaitGroup{} + chainRouter, engine := newChainRouterTest(t) + + wg.Add(1) + if tt.inboundMsg == nil || tt.inboundMsg.Op() == message.CrossChainAppErrorOp { + engine.CrossChainAppRequestFailedF = func(_ context.Context, chainID ids.ID, requestID uint32, appErr *common.AppError) error { + defer wg.Done() + require.Zero(chainRouter.timedRequests.Len()) + + require.Equal(ids.Empty, chainID) + require.Equal(wantRequestID, requestID) + require.Equal(errFoo.Code, appErr.Code) + require.Equal(errFoo.Message, appErr.Message) + + return nil + } + } else if tt.inboundMsg.Op() == message.CrossChainAppResponseOp { + engine.CrossChainAppResponseF = func(ctx context.Context, chainID ids.ID, requestID uint32, msg []byte) error { + defer wg.Done() + require.Zero(chainRouter.timedRequests.Len()) + + require.Equal(ids.Empty, chainID) + require.Equal(wantRequestID, requestID) + require.Equal(wantResponse, msg) + + return nil + } + } + + ctx := context.Background() + chainRouter.RegisterRequest(ctx, ids.EmptyNodeID, ids.Empty, ids.Empty, wantRequestID, tt.responseOp, tt.timeoutMsg, engineType) + require.Equal(1, chainRouter.timedRequests.Len()) + + if tt.inboundMsg != nil { + chainRouter.HandleInbound(ctx, tt.inboundMsg) + } + + wg.Wait() + }) + } +} + +func newChainRouterTest(t *testing.T) (*ChainRouter, *common.EngineTest) { + // Create a timeout manager + tm, err := timeout.NewManager( + &timer.AdaptiveTimeoutConfig{ + InitialTimeout: 3 * time.Second, + MinimumTimeout: 3 * time.Second, + MaximumTimeout: 5 * time.Minute, + TimeoutCoefficient: 1, + TimeoutHalflife: 5 * time.Minute, + }, + benchlist.NewNoBenchlist(), + "", + prometheus.NewRegistry(), + ) + require.NoError(t, err) + + go tm.Dispatch() + + // Create a router + chainRouter := &ChainRouter{} + require.NoError(t, chainRouter.Initialize( + ids.EmptyNodeID, + logging.NoLog{}, + tm, + time.Millisecond, + set.Set[ids.ID]{}, + true, + set.Set[ids.ID]{}, + nil, + HealthConfig{}, + "", + prometheus.NewRegistry(), + )) + + // Create bootstrapper, engine and handler + ctx := snow.DefaultConsensusContextTest() + vdrs := validators.NewManager() + require.NoError(t, vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) + + resourceTracker, err := tracker.NewResourceTracker( + prometheus.NewRegistry(), + resource.NoUsage, + meter.ContinuousFactory{}, + time.Second, + ) + require.NoError(t, err) + h, err := handler.New( + ctx, + vdrs, + nil, + time.Second, + testThreadPoolSize, + resourceTracker, + validators.UnhandledSubnetConnector, + subnets.New(ctx.NodeID, subnets.Config{}), + commontracker.NewPeers(), + ) + require.NoError(t, err) + + bootstrapper := &common.BootstrapperTest{ + EngineTest: common.EngineTest{ + T: t, + }, + } + bootstrapper.Default(false) + bootstrapper.ContextF = func() *snow.ConsensusContext { + return ctx + } + + engine := &common.EngineTest{T: t} + engine.Default(false) + engine.ContextF = func() *snow.ConsensusContext { + return ctx + } + h.SetEngineManager(&handler.EngineManager{ + Avalanche: &handler.Engine{ + StateSyncer: nil, + Bootstrapper: bootstrapper, + Consensus: engine, + }, + Snowman: &handler.Engine{ + StateSyncer: nil, + Bootstrapper: bootstrapper, + Consensus: engine, + }, + }) + ctx.State.Set(snow.EngineState{ + Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, + State: snow.NormalOp, // assumed bootstrapping is done + }) + + chainRouter.AddChain(context.Background(), h) + + bootstrapper.StartF = func(context.Context, uint32) error { + return nil + } + + h.Start(context.Background(), false) + + t.Cleanup(func() { + tm.Stop() + chainRouter.Shutdown(context.Background()) + }) + + return chainRouter, engine +} diff --git a/snow/networking/sender/sender.go b/snow/networking/sender/sender.go index b30e267a19bf..b6fe0bbb2844 100644 --- a/snow/networking/sender/sender.go +++ b/snow/networking/sender/sender.go @@ -1210,11 +1210,13 @@ func (s *sender) SendCrossChainAppRequest(ctx context.Context, chainID ids.ID, r ctx = utils.Detach(ctx) // The failed message is treated as if it was sent by the requested chain - failedMsg := message.InternalCrossChainAppRequestFailed( + failedMsg := message.InternalCrossChainAppError( s.ctx.NodeID, chainID, s.ctx.ChainID, requestID, + common.ErrTimeout.Code, + common.ErrTimeout.Message, ) s.router.RegisterRequest( ctx, @@ -1262,10 +1264,12 @@ func (s *sender) SendAppRequest(ctx context.Context, nodeIDs set.Set[ids.NodeID] // to send them a message, to avoid busy looping when disconnected from // the internet. for nodeID := range nodeIDs { - inMsg := message.InternalAppRequestFailed( + inMsg := message.InboundAppError( nodeID, s.ctx.ChainID, requestID, + common.ErrTimeout.Code, + common.ErrTimeout.Message, ) s.router.RegisterRequest( ctx, @@ -1308,10 +1312,12 @@ func (s *sender) SendAppRequest(ctx context.Context, nodeIDs set.Set[ids.NodeID] // Immediately register a failure. Do so asynchronously to avoid // deadlock. - inMsg := message.InternalAppRequestFailed( + inMsg := message.InboundAppError( nodeID, s.ctx.ChainID, requestID, + common.ErrTimeout.Code, + common.ErrTimeout.Message, ) go s.router.HandleInbound(ctx, inMsg) } @@ -1366,10 +1372,12 @@ func (s *sender) SendAppRequest(ctx context.Context, nodeIDs set.Set[ids.NodeID] // Register failures for nodes we didn't send a request to. s.timeouts.RegisterRequestToUnreachableValidator() - inMsg := message.InternalAppRequestFailed( + inMsg := message.InboundAppError( nodeID, s.ctx.ChainID, requestID, + common.ErrTimeout.Code, + common.ErrTimeout.Message, ) go s.router.HandleInbound(ctx, inMsg) } diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index a6da8738e1fa..b0e9280d2e16 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -201,8 +201,18 @@ func TestTimeout(t *testing.T) { bootstrapper.GetAncestorsFailedF = failed bootstrapper.GetFailedF = failed bootstrapper.QueryFailedF = failed - bootstrapper.AppRequestFailedF = failed - bootstrapper.CrossChainAppRequestFailedF = func(ctx context.Context, chainID ids.ID, _ uint32) error { + bootstrapper.AppRequestFailedF = func(ctx context.Context, nodeID ids.NodeID, _ uint32, appErr *common.AppError) error { + require.NoError(ctx.Err()) + + failedLock.Lock() + defer failedLock.Unlock() + + failedVDRs.Add(nodeID) + wg.Done() + return nil + } + + bootstrapper.CrossChainAppRequestFailedF = func(ctx context.Context, chainID ids.ID, _ uint32, _ *common.AppError) error { require.NoError(ctx.Err()) failedLock.Lock() diff --git a/vms/avm/network/atomic.go b/vms/avm/network/atomic.go index c6b011dab1cf..aaa1c5822235 100644 --- a/vms/avm/network/atomic.go +++ b/vms/avm/network/atomic.go @@ -51,12 +51,14 @@ func (a *atomic) CrossChainAppRequestFailed( ctx context.Context, chainID ids.ID, requestID uint32, + appErr *common.AppError, ) error { h := a.handler.Get() return h.CrossChainAppRequestFailed( ctx, chainID, requestID, + appErr, ) } @@ -96,12 +98,14 @@ func (a *atomic) AppRequestFailed( ctx context.Context, nodeID ids.NodeID, requestID uint32, + appErr *common.AppError, ) error { h := a.handler.Get() return h.AppRequestFailed( ctx, nodeID, requestID, + appErr, ) } diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go index 8f6c82e3d77d..2441792ac703 100644 --- a/vms/rpcchainvm/vm_client.go +++ b/vms/rpcchainvm/vm_client.go @@ -544,14 +544,15 @@ func (vm *VMClient) CrossChainAppRequest(ctx context.Context, chainID ids.ID, re return err } -func (vm *VMClient) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32) error { - _, err := vm.client.CrossChainAppRequestFailed( - ctx, - &vmpb.CrossChainAppRequestFailedMsg{ - ChainId: chainID[:], - RequestId: requestID, - }, - ) +func (vm *VMClient) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *common.AppError) error { + msg := &vmpb.CrossChainAppRequestFailedMsg{ + ChainId: chainID[:], + RequestId: requestID, + ErrorCode: appErr.Code, + ErrorMessage: appErr.Message, + } + + _, err := vm.client.CrossChainAppRequestFailed(ctx, msg) return err } @@ -592,14 +593,15 @@ func (vm *VMClient) AppResponse(ctx context.Context, nodeID ids.NodeID, requestI return err } -func (vm *VMClient) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { - _, err := vm.client.AppRequestFailed( - ctx, - &vmpb.AppRequestFailedMsg{ - NodeId: nodeID.Bytes(), - RequestId: requestID, - }, - ) +func (vm *VMClient) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error { + msg := &vmpb.AppRequestFailedMsg{ + NodeId: nodeID.Bytes(), + RequestId: requestID, + ErrorCode: appErr.Code, + ErrorMessage: appErr.Message, + } + + _, err := vm.client.AppRequestFailed(ctx, msg) return err } diff --git a/vms/rpcchainvm/vm_server.go b/vms/rpcchainvm/vm_server.go index e35e7a950e9b..e3253043fbad 100644 --- a/vms/rpcchainvm/vm_server.go +++ b/vms/rpcchainvm/vm_server.go @@ -537,7 +537,12 @@ func (vm *VMServer) CrossChainAppRequestFailed(ctx context.Context, msg *vmpb.Cr if err != nil { return nil, err } - return &emptypb.Empty{}, vm.vm.CrossChainAppRequestFailed(ctx, chainID, msg.RequestId) + + appErr := &common.AppError{ + Code: msg.ErrorCode, + Message: msg.ErrorMessage, + } + return &emptypb.Empty{}, vm.vm.CrossChainAppRequestFailed(ctx, chainID, msg.RequestId, appErr) } func (vm *VMServer) CrossChainAppResponse(ctx context.Context, msg *vmpb.CrossChainAppResponseMsg) (*emptypb.Empty, error) { @@ -565,7 +570,12 @@ func (vm *VMServer) AppRequestFailed(ctx context.Context, req *vmpb.AppRequestFa if err != nil { return nil, err } - return &emptypb.Empty{}, vm.vm.AppRequestFailed(ctx, nodeID, req.RequestId) + + appErr := &common.AppError{ + Code: req.ErrorCode, + Message: req.ErrorMessage, + } + return &emptypb.Empty{}, vm.vm.AppRequestFailed(ctx, nodeID, req.RequestId, appErr) } func (vm *VMServer) AppResponse(ctx context.Context, req *vmpb.AppResponseMsg) (*emptypb.Empty, error) { From 0b2b109e9c46bc06f66db63fd62b481eaf760c29 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 12 Dec 2023 16:48:28 -0500 Subject: [PATCH 138/267] `vms/platformvm`: Verify txs before building a block (#2359) Co-authored-by: Stephen Buttolph --- vms/platformvm/block/builder/builder.go | 147 ++++++++++++++----- vms/platformvm/block/builder/builder_test.go | 96 ++++++++++++ vms/platformvm/block/executor/verifier.go | 5 +- vms/platformvm/txs/mempool/mempool.go | 42 ------ vms/platformvm/txs/mempool/mempool_test.go | 23 --- vms/platformvm/txs/mempool/mock_mempool.go | 15 -- 6 files changed, 213 insertions(+), 115 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 53602ef3ed93..fc272453aba5 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -14,10 +14,12 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/state" + "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" @@ -192,16 +194,9 @@ func (b *builder) ShutdownBlockTimer() { // This method removes the transactions from the returned // blocks from the mempool. func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { - defer func() { - // If we need to advance the chain's timestamp in a standard block, but - // we build an invalid block, then we need to re-trigger block building. - // - // TODO: Remove once we are guaranteed to build a valid block. - b.ResetBlockTimer() - // If there are still transactions in the mempool, then we need to - // re-trigger block building. - b.Mempool.RequestBuildBlock(false /*=emptyBlockPermitted*/) - }() + // If there are still transactions in the mempool, then we need to + // re-trigger block building. + defer b.Mempool.RequestBuildBlock(false /*=emptyBlockPermitted*/) b.txExecutorBackend.Ctx.Log.Debug("starting to attempt to build a block") @@ -259,38 +254,41 @@ func buildBlock( return nil, fmt.Errorf("could not build tx to reward staker: %w", err) } + var blockTxs []*txs.Tx + // TODO: Cleanup post-Durango + if builder.txExecutorBackend.Config.IsDurangoActivated(timestamp) { + blockTxs, err = packBlockTxs( + parentID, + parentState, + builder.Mempool, + builder.txExecutorBackend, + builder.blkManager, + timestamp, + ) + if err != nil { + return nil, fmt.Errorf("failed to pack block txs: %w", err) + } + } + return block.NewBanffProposalBlock( timestamp, parentID, height, rewardValidatorTx, - []*txs.Tx{}, // TODO: Populate with StandardBlock txs + blockTxs, ) } - // Clean out the mempool's transactions with invalid timestamps. - droppedStakerTxIDs := builder.Mempool.DropExpiredStakerTxs(timestamp.Add(txexecutor.SyncBound)) - for _, txID := range droppedStakerTxIDs { - builder.txExecutorBackend.Ctx.Log.Debug("dropping tx", - zap.Stringer("txID", txID), - zap.Error(err), - ) - } - - var ( - blockTxs []*txs.Tx - remainingSize = targetBlockSize + blockTxs, err := packBlockTxs( + parentID, + parentState, + builder.Mempool, + builder.txExecutorBackend, + builder.blkManager, + timestamp, ) - - for { - tx, exists := builder.Mempool.Peek() - if !exists || len(tx.Bytes()) > remainingSize { - break - } - builder.Mempool.Remove([]*txs.Tx{tx}) - - remainingSize -= len(tx.Bytes()) - blockTxs = append(blockTxs, tx) + if err != nil { + return nil, fmt.Errorf("failed to pack block txs: %w", err) } // If there is no reason to build a block, don't. @@ -308,6 +306,89 @@ func buildBlock( ) } +func packBlockTxs( + parentID ids.ID, + parentState state.Chain, + mempool mempool.Mempool, + backend *txexecutor.Backend, + manager blockexecutor.Manager, + timestamp time.Time, +) ([]*txs.Tx, error) { + stateDiff, err := state.NewDiffOn(parentState) + if err != nil { + return nil, err + } + + changes, err := txexecutor.AdvanceTimeTo(backend, stateDiff, timestamp) + if err != nil { + return nil, err + } + changes.Apply(stateDiff) + stateDiff.SetTimestamp(timestamp) + + var ( + blockTxs []*txs.Tx + inputs set.Set[ids.ID] + remainingSize = targetBlockSize + ) + + for { + tx, exists := mempool.Peek() + if !exists { + break + } + txSize := len(tx.Bytes()) + if txSize > remainingSize { + break + } + mempool.Remove([]*txs.Tx{tx}) + + // Invariant: [tx] has already been syntactically verified. + + txDiff, err := state.NewDiffOn(stateDiff) + if err != nil { + return nil, err + } + + executor := &txexecutor.StandardTxExecutor{ + Backend: backend, + State: txDiff, + Tx: tx, + } + + err = tx.Unsigned.Visit(executor) + if err != nil { + txID := tx.ID() + mempool.MarkDropped(txID, err) + continue + } + + if inputs.Overlaps(executor.Inputs) { + txID := tx.ID() + mempool.MarkDropped(txID, blockexecutor.ErrConflictingBlockTxs) + continue + } + err = manager.VerifyUniqueInputs(parentID, executor.Inputs) + if err != nil { + txID := tx.ID() + mempool.MarkDropped(txID, err) + continue + } + inputs.Union(executor.Inputs) + + txDiff.AddTx(tx, status.Committed) + err = txDiff.Apply(stateDiff) + if err != nil { + return nil, err + } + + remainingSize -= txSize + blockTxs = append(blockTxs, tx) + } + + return blockTxs, nil +} + // getNextStakerToReward returns the next staker txID to remove from the staking // set with a RewardValidatorTx rather than an AdvanceTimeTx. [chainTimestamp] // is the timestamp of the chain at the time this validator would be getting diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index ee603c484622..4b683bf9e1e3 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -288,6 +288,102 @@ func TestBuildBlockForceAdvanceTime(t *testing.T) { require.Equal(nextTime.Unix(), standardBlk.Timestamp().Unix()) } +func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { + require := require.New(t) + + env := newEnvironment(t) + env.ctx.Lock.Lock() + defer func() { + require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() + }() + + var ( + now = env.backend.Clk.Time() + defaultValidatorStake = 100 * units.MilliAvax + + // Add a validator with StartTime in the future within [MaxFutureStartTime] + validatorStartTime = now.Add(txexecutor.MaxFutureStartTime - 1*time.Second) + validatorEndTime = validatorStartTime.Add(360 * 24 * time.Hour) + ) + + tx1, err := env.txBuilder.NewAddValidatorTx( + defaultValidatorStake, + uint64(validatorStartTime.Unix()), + uint64(validatorEndTime.Unix()), + ids.GenerateTestNodeID(), + preFundedKeys[0].PublicKey().Address(), + reward.PercentDenominator, + []*secp256k1.PrivateKey{preFundedKeys[0]}, + preFundedKeys[0].PublicKey().Address(), + ) + require.NoError(err) + require.NoError(env.mempool.Add(tx1)) + tx1ID := tx1.ID() + require.True(env.mempool.Has(tx1ID)) + + // Add a validator with StartTime before current chain time + validator2StartTime := now.Add(-5 * time.Second) + validator2EndTime := validator2StartTime.Add(360 * 24 * time.Hour) + + tx2, err := env.txBuilder.NewAddValidatorTx( + defaultValidatorStake, + uint64(validator2StartTime.Unix()), + uint64(validator2EndTime.Unix()), + ids.GenerateTestNodeID(), + preFundedKeys[1].PublicKey().Address(), + reward.PercentDenominator, + []*secp256k1.PrivateKey{preFundedKeys[1]}, + preFundedKeys[1].PublicKey().Address(), + ) + require.NoError(err) + require.NoError(env.mempool.Add(tx2)) + tx2ID := tx2.ID() + require.True(env.mempool.Has(tx2ID)) + + // Add a validator with StartTime in the future past [MaxFutureStartTime] + validator3StartTime := now.Add(txexecutor.MaxFutureStartTime + 5*time.Second) + validator3EndTime := validator2StartTime.Add(360 * 24 * time.Hour) + + tx3, err := env.txBuilder.NewAddValidatorTx( + defaultValidatorStake, + uint64(validator3StartTime.Unix()), + uint64(validator3EndTime.Unix()), + ids.GenerateTestNodeID(), + preFundedKeys[2].PublicKey().Address(), + reward.PercentDenominator, + []*secp256k1.PrivateKey{preFundedKeys[2]}, + preFundedKeys[2].PublicKey().Address(), + ) + require.NoError(err) + require.NoError(env.mempool.Add(tx3)) + tx3ID := tx3.ID() + require.True(env.mempool.Has(tx3ID)) + + // Only tx1 should be in a built block + blkIntf, err := env.Builder.BuildBlock(context.Background()) + require.NoError(err) + + require.IsType(&blockexecutor.Block{}, blkIntf) + blk := blkIntf.(*blockexecutor.Block) + require.Len(blk.Txs(), 1) + require.Equal(tx1ID, blk.Txs()[0].ID()) + + // Mempool should have none of the txs + require.False(env.mempool.Has(tx1ID)) + require.False(env.mempool.Has(tx2ID)) + require.False(env.mempool.Has(tx3ID)) + + // Only tx2 and tx3 should be dropped + require.NoError(env.mempool.GetDropReason(tx1ID)) + + tx2DropReason := env.mempool.GetDropReason(tx2ID) + require.ErrorIs(tx2DropReason, txexecutor.ErrTimestampNotBeforeStartTime) + + tx3DropReason := env.mempool.GetDropReason(tx3ID) + require.ErrorIs(tx3DropReason, txexecutor.ErrFutureStakeTime) +} + func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { require := require.New(t) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 4e81c8470ba3..37129f8cc03a 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -20,12 +20,13 @@ import ( var ( _ block.Visitor = (*verifier)(nil) + ErrConflictingBlockTxs = errors.New("block contains conflicting transactions") + errApricotBlockIssuedAfterFork = errors.New("apricot block issued after fork") errBanffProposalBlockWithMultipleTransactions = errors.New("BanffProposalBlock contains multiple transactions") errBanffStandardBlockWithoutChanges = errors.New("BanffStandardBlock performs no state changes") errIncorrectBlockHeight = errors.New("incorrect block height") errChildBlockEarlierThanParent = errors.New("proposed timestamp before current chain time") - errConflictingBatchTxs = errors.New("block contains conflicting transactions") errOptionBlockTimestampNotMatchingParent = errors.New("option block proposed timestamp not matching parent block one") ) @@ -468,7 +469,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID } // ensure it doesn't overlap with current input batch if inputs.Overlaps(txExecutor.Inputs) { - return nil, nil, nil, errConflictingBatchTxs + return nil, nil, nil, ErrConflictingBlockTxs } // Add UTXOs to batch inputs.Union(txExecutor.Inputs) diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index d4783adf5a4c..7e7aee09520a 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -6,7 +6,6 @@ package mempool import ( "errors" "fmt" - "time" "github.com/prometheus/client_golang/prometheus" @@ -53,12 +52,6 @@ type Mempool interface { // Peek returns the oldest tx in the mempool. Peek() (tx *txs.Tx, exists bool) - // Drops all [txs.Staker] transactions whose [StartTime] is before - // [minStartTime] from [mempool]. The dropped tx ids are returned. - // - // TODO: Remove once [StartTime] field is ignored in staker txs - DropExpiredStakerTxs(minStartTime time.Time) []ids.ID - // RequestBuildBlock notifies the consensus engine that a block should be // built. If [emptyBlockPermitted] is true, the notification will be sent // regardless of whether there are no transactions in the mempool. If not, @@ -229,38 +222,3 @@ func (m *mempool) RequestBuildBlock(emptyBlockPermitted bool) { default: } } - -// Drops all [txs.Staker] transactions whose [StartTime] is before -// [minStartTime] from [mempool]. The dropped tx ids are returned. -// -// TODO: Remove once [StartTime] field is ignored in staker txs -func (m *mempool) DropExpiredStakerTxs(minStartTime time.Time) []ids.ID { - var droppedTxIDs []ids.ID - - txIter := m.unissuedTxs.NewIterator() - for txIter.Next() { - tx := txIter.Value() - stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) - if !ok { - continue - } - - startTime := stakerTx.StartTime() - if !startTime.Before(minStartTime) { - continue - } - - txID := tx.ID() - err := fmt.Errorf( - "synchrony bound (%s) is later than staker start time (%s)", - minStartTime, - startTime, - ) - - m.Remove([]*txs.Tx{tx}) - m.MarkDropped(txID, err) // cache tx as dropped - droppedTxIDs = append(droppedTxIDs, txID) - } - - return droppedTxIDs -} diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index 9877b0384288..2f6b9782d2fe 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -199,29 +199,6 @@ func generateAddValidatorTx(startTime uint64, endTime uint64) (*txs.Tx, error) { return txs.NewSigned(utx, txs.Codec, nil) } -func TestDropExpiredStakerTxs(t *testing.T) { - require := require.New(t) - - registerer := prometheus.NewRegistry() - mempool, err := New("mempool", registerer, nil) - require.NoError(err) - - tx1, err := generateAddValidatorTx(10, 20) - require.NoError(err) - require.NoError(mempool.Add(tx1)) - - tx2, err := generateAddValidatorTx(8, 20) - require.NoError(err) - require.NoError(mempool.Add(tx2)) - - tx3, err := generateAddValidatorTx(15, 20) - require.NoError(err) - require.NoError(mempool.Add(tx3)) - - minStartTime := time.Unix(9, 0) - require.Len(mempool.DropExpiredStakerTxs(minStartTime), 1) -} - func TestPeekTxs(t *testing.T) { require := require.New(t) diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index 5ccb1ec1820f..384959d46694 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -9,7 +9,6 @@ package mempool import ( reflect "reflect" - time "time" ids "github.com/ava-labs/avalanchego/ids" txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -53,20 +52,6 @@ func (mr *MockMempoolMockRecorder) Add(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockMempool)(nil).Add), arg0) } -// DropExpiredStakerTxs mocks base method. -func (m *MockMempool) DropExpiredStakerTxs(arg0 time.Time) []ids.ID { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DropExpiredStakerTxs", arg0) - ret0, _ := ret[0].([]ids.ID) - return ret0 -} - -// DropExpiredStakerTxs indicates an expected call of DropExpiredStakerTxs. -func (mr *MockMempoolMockRecorder) DropExpiredStakerTxs(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DropExpiredStakerTxs", reflect.TypeOf((*MockMempool)(nil).DropExpiredStakerTxs), arg0) -} - // Get mocks base method. func (m *MockMempool) Get(arg0 ids.ID) *txs.Tx { m.ctrl.T.Helper() From ac5a00ef6bb6c2009215fc1ccb5fa62d0749770c Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:42:32 -0500 Subject: [PATCH 139/267] Refactor p2p unit tests (#2475) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Dan Laine --- go.mod | 2 +- go.sum | 4 +- network/p2p/gossip/gossip.go | 7 + network/p2p/gossip/gossip_test.go | 26 +- network/p2p/mocks/mock_handler.go | 82 ---- network/p2p/network_test.go | 597 +++++++++++++++--------------- network/p2p/validators_test.go | 2 +- scripts/mocks.mockgen.txt | 1 - snow/engine/common/test_sender.go | 64 +++- 9 files changed, 389 insertions(+), 396 deletions(-) delete mode 100644 network/p2p/mocks/mock_handler.go diff --git a/go.mod b/go.mod index 5bbdeab03311..e9afffd7d9e7 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231206202846-fc088a944e76 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231212220437-f9ec2ecc2714 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index b0bec442701d..b7d1d9c26982 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231206202846-fc088a944e76 h1:0hYwcuOfndE1I61SvWv2dEa7N3QRJL3RpB9fmJy0sr0= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231206202846-fc088a944e76/go.mod h1:dH0LOVIEm1uHKozwhDV223BOyP0ElVsYclizRJzEY4s= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231212220437-f9ec2ecc2714 h1:dhuxCYjB+4isvJMHViHkS50NgkQ/dHY2ZZmk8ESAyxw= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231212220437-f9ec2ecc2714/go.mod h1:LwQhIuKmd8JPemahE1f7TvsE3WRzCFdjvNWBPxXSaNo= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index 94d49260da40..05b46a0bd99a 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -23,6 +23,7 @@ import ( var ( _ Gossiper = (*ValidatorGossiper)(nil) _ Gossiper = (*PullGossiper[testTx, *testTx])(nil) + _ Gossiper = (*NoOpGossiper)(nil) ) // Gossiper gossips Gossipables to other nodes @@ -196,3 +197,9 @@ func Every(ctx context.Context, log logging.Logger, gossiper Gossiper, frequency } } } + +type NoOpGossiper struct{} + +func (NoOpGossiper) Gossip(context.Context) error { + return nil +} diff --git a/network/p2p/gossip/gossip_test.go b/network/p2p/gossip/gossip_test.go index d30fac0008e7..f2150e8f6afd 100644 --- a/network/p2p/gossip/gossip_test.go +++ b/network/p2p/gossip/gossip_test.go @@ -115,8 +115,11 @@ func TestGossiperGossip(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { require := require.New(t) + ctx := context.Background() - responseSender := &common.SenderTest{} + responseSender := &common.FakeSender{ + SentAppResponse: make(chan []byte, 1), + } responseNetwork := p2p.NewNetwork(logging.NoLog{}, responseSender, prometheus.NewRegistry(), "") responseBloom, err := NewBloomFilter(1000, 0.01) require.NoError(err) @@ -133,25 +136,13 @@ func TestGossiperGossip(t *testing.T) { _, err = responseNetwork.NewAppProtocol(0x0, handler) require.NoError(err) - requestSender := &common.SenderTest{ - SendAppRequestF: func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { - go func() { - require.NoError(responseNetwork.AppRequest(ctx, ids.EmptyNodeID, requestID, time.Time{}, request)) - }() - return nil - }, + requestSender := &common.FakeSender{ + SentAppRequest: make(chan []byte, 1), } requestNetwork := p2p.NewNetwork(logging.NoLog{}, requestSender, prometheus.NewRegistry(), "") require.NoError(requestNetwork.Connected(context.Background(), ids.EmptyNodeID, nil)) - gossiped := make(chan struct{}) - responseSender.SendAppResponseF = func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appResponseBytes []byte) error { - require.NoError(requestNetwork.AppResponse(ctx, nodeID, requestID, appResponseBytes)) - close(gossiped) - return nil - } - bloom, err := NewBloomFilter(1000, 0.01) require.NoError(err) requestSet := testSet{ @@ -181,8 +172,9 @@ func TestGossiperGossip(t *testing.T) { received.Add(tx) } - require.NoError(gossiper.Gossip(context.Background())) - <-gossiped + require.NoError(gossiper.Gossip(ctx)) + require.NoError(responseNetwork.AppRequest(ctx, ids.EmptyNodeID, 1, time.Time{}, <-requestSender.SentAppRequest)) + require.NoError(requestNetwork.AppResponse(ctx, ids.EmptyNodeID, 1, <-responseSender.SentAppResponse)) require.Len(requestSet.set, tt.expectedLen) require.Subset(tt.expectedPossibleValues, requestSet.set.List()) diff --git a/network/p2p/mocks/mock_handler.go b/network/p2p/mocks/mock_handler.go deleted file mode 100644 index 0d4147d23183..000000000000 --- a/network/p2p/mocks/mock_handler.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/network/p2p (interfaces: Handler) - -// Package mocks is a generated GoMock package. -package mocks - -import ( - context "context" - reflect "reflect" - time "time" - - ids "github.com/ava-labs/avalanchego/ids" - gomock "go.uber.org/mock/gomock" -) - -// MockHandler is a mock of Handler interface. -type MockHandler struct { - ctrl *gomock.Controller - recorder *MockHandlerMockRecorder -} - -// MockHandlerMockRecorder is the mock recorder for MockHandler. -type MockHandlerMockRecorder struct { - mock *MockHandler -} - -// NewMockHandler creates a new mock instance. -func NewMockHandler(ctrl *gomock.Controller) *MockHandler { - mock := &MockHandler{ctrl: ctrl} - mock.recorder = &MockHandlerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockHandler) EXPECT() *MockHandlerMockRecorder { - return m.recorder -} - -// AppGossip mocks base method. -func (m *MockHandler) AppGossip(arg0 context.Context, arg1 ids.NodeID, arg2 []byte) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AppGossip", arg0, arg1, arg2) -} - -// AppGossip indicates an expected call of AppGossip. -func (mr *MockHandlerMockRecorder) AppGossip(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*MockHandler)(nil).AppGossip), arg0, arg1, arg2) -} - -// AppRequest mocks base method. -func (m *MockHandler) AppRequest(arg0 context.Context, arg1 ids.NodeID, arg2 time.Time, arg3 []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppRequest", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// AppRequest indicates an expected call of AppRequest. -func (mr *MockHandlerMockRecorder) AppRequest(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*MockHandler)(nil).AppRequest), arg0, arg1, arg2, arg3) -} - -// CrossChainAppRequest mocks base method. -func (m *MockHandler) CrossChainAppRequest(arg0 context.Context, arg1 ids.ID, arg2 time.Time, arg3 []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CrossChainAppRequest", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CrossChainAppRequest indicates an expected call of CrossChainAppRequest. -func (mr *MockHandlerMockRecorder) CrossChainAppRequest(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequest", reflect.TypeOf((*MockHandler)(nil).CrossChainAppRequest), arg0, arg1, arg2, arg3) -} diff --git a/network/p2p/network_test.go b/network/p2p/network_test.go index 17b02a3fa0a2..1adb25f81371 100644 --- a/network/p2p/network_test.go +++ b/network/p2p/network_test.go @@ -5,18 +5,13 @@ package p2p import ( "context" - "sync" "testing" "time" "github.com/prometheus/client_golang/prometheus" - "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/network/p2p/mocks" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" @@ -25,294 +20,348 @@ import ( "github.com/ava-labs/avalanchego/version" ) +const ( + handlerID = 123 + handlerPrefix = byte(handlerID) +) + var errFoo = &common.AppError{ Code: 123, Message: "foo", } +func TestMessageRouting(t *testing.T) { + require := require.New(t) + ctx := context.Background() + wantNodeID := ids.GenerateTestNodeID() + wantChainID := ids.GenerateTestID() + wantMsg := []byte("message") + + var appGossipCalled, appRequestCalled, crossChainAppRequestCalled bool + testHandler := &testHandler{ + appGossipF: func(_ context.Context, nodeID ids.NodeID, msg []byte) { + appGossipCalled = true + require.Equal(wantNodeID, nodeID) + require.Equal(wantMsg, msg) + }, + appRequestF: func(_ context.Context, nodeID ids.NodeID, _ time.Time, msg []byte) ([]byte, error) { + appRequestCalled = true + require.Equal(wantNodeID, nodeID) + require.Equal(wantMsg, msg) + return nil, nil + }, + crossChainAppRequestF: func(_ context.Context, chainID ids.ID, _ time.Time, msg []byte) ([]byte, error) { + crossChainAppRequestCalled = true + require.Equal(wantChainID, chainID) + require.Equal(wantMsg, msg) + return nil, nil + }, + } + + sender := &common.FakeSender{ + SentAppGossip: make(chan []byte, 1), + SentAppRequest: make(chan []byte, 1), + SentCrossChainAppRequest: make(chan []byte, 1), + } + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + client, err := network.NewAppProtocol(1, testHandler) + require.NoError(err) + + require.NoError(client.AppGossip(ctx, wantMsg)) + require.NoError(network.AppGossip(ctx, wantNodeID, <-sender.SentAppGossip)) + require.True(appGossipCalled) + + require.NoError(client.AppRequest(ctx, set.Of(ids.EmptyNodeID), wantMsg, func(context.Context, ids.NodeID, []byte, error) {})) + require.NoError(network.AppRequest(ctx, wantNodeID, 1, time.Time{}, <-sender.SentAppRequest)) + require.True(appRequestCalled) + + require.NoError(client.CrossChainAppRequest(ctx, ids.Empty, wantMsg, func(context.Context, ids.ID, []byte, error) {})) + require.NoError(network.CrossChainAppRequest(ctx, wantChainID, 1, time.Time{}, <-sender.SentCrossChainAppRequest)) + require.True(crossChainAppRequestCalled) +} + +// Tests that the Client prefixes messages with the handler prefix +func TestClientPrefixesMessages(t *testing.T) { + require := require.New(t) + ctx := context.Background() + + sender := common.FakeSender{ + SentAppRequest: make(chan []byte, 1), + SentAppGossip: make(chan []byte, 1), + SentAppGossipSpecific: make(chan []byte, 1), + SentCrossChainAppRequest: make(chan []byte, 1), + } + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + require.NoError(network.Connected(ctx, ids.EmptyNodeID, nil)) + + client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + require.NoError(err) + + want := []byte("message") + + require.NoError(client.AppRequest( + ctx, + set.Of(ids.EmptyNodeID), + want, + func(context.Context, ids.NodeID, []byte, error) {}, + )) + gotAppRequest := <-sender.SentAppRequest + require.Equal(handlerPrefix, gotAppRequest[0]) + require.Equal(want, gotAppRequest[1:]) + + require.NoError(client.AppRequestAny( + ctx, + want, + func(context.Context, ids.NodeID, []byte, error) {}, + )) + gotAppRequest = <-sender.SentAppRequest + require.Equal(handlerPrefix, gotAppRequest[0]) + require.Equal(want, gotAppRequest[1:]) + + require.NoError(client.CrossChainAppRequest( + ctx, + ids.Empty, + want, + func(context.Context, ids.ID, []byte, error) {}, + )) + gotCrossChainAppRequest := <-sender.SentCrossChainAppRequest + require.Equal(handlerPrefix, gotCrossChainAppRequest[0]) + require.Equal(want, gotCrossChainAppRequest[1:]) + + require.NoError(client.AppGossip(ctx, want)) + gotAppGossip := <-sender.SentAppGossip + require.Equal(handlerPrefix, gotAppGossip[0]) + require.Equal(want, gotAppGossip[1:]) + + require.NoError(client.AppGossipSpecific(ctx, set.Of(ids.EmptyNodeID), want)) + gotAppGossip = <-sender.SentAppGossipSpecific + require.Equal(handlerPrefix, gotAppGossip[0]) + require.Equal(want, gotAppGossip[1:]) +} + +// Tests that the Client callback is called on a successful response func TestAppRequestResponse(t *testing.T) { - handlerID := uint64(0x0) - request := []byte("request") - response := []byte("response") - nodeID := ids.GenerateTestNodeID() - chainID := ids.GenerateTestID() + require := require.New(t) + ctx := context.Background() - ctxKey := new(string) - ctxVal := new(string) - *ctxKey = "foo" - *ctxVal = "bar" + sender := common.FakeSender{ + SentAppRequest: make(chan []byte, 1), + } + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - tests := []struct { - name string - requestFunc func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) - }{ - { - name: "app request", - requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.SendAppRequestF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { - for range nodeIDs { - go func() { - require.NoError(t, network.AppRequest(ctx, nodeID, requestID, time.Time{}, request)) - }() - } + client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + require.NoError(err) - return nil - } - sender.SendAppResponseF = func(ctx context.Context, _ ids.NodeID, requestID uint32, response []byte) error { - go func() { - ctx = context.WithValue(ctx, ctxKey, ctxVal) - require.NoError(t, network.AppResponse(ctx, nodeID, requestID, response)) - }() + wantResponse := []byte("response") + wantNodeID := ids.GenerateTestNodeID() + done := make(chan struct{}) - return nil - } - handler.EXPECT(). - AppRequest(context.Background(), nodeID, gomock.Any(), request). - DoAndReturn(func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { - return response, nil - }) - - callback := func(ctx context.Context, actualNodeID ids.NodeID, actualResponse []byte, err error) { - defer wg.Done() - - require.NoError(t, err) - require.Equal(t, ctxVal, ctx.Value(ctxKey)) - require.Equal(t, nodeID, actualNodeID) - require.Equal(t, response, actualResponse) - } + callback := func(_ context.Context, gotNodeID ids.NodeID, gotResponse []byte, err error) { + require.Equal(wantNodeID, gotNodeID) + require.NoError(err) + require.Equal(wantResponse, gotResponse) - require.NoError(t, client.AppRequestAny(context.Background(), request, callback)) - }, - }, - { - name: "app request failed", - requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.SendAppRequestF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { - for range nodeIDs { - go func() { - require.NoError(t, network.AppRequestFailed(ctx, nodeID, requestID, errFoo)) - }() - } + close(done) + } - return nil - } + require.NoError(client.AppRequest(ctx, set.Of(wantNodeID), []byte("request"), callback)) + <-sender.SentAppRequest - callback := func(_ context.Context, actualNodeID ids.NodeID, actualResponse []byte, err error) { - defer wg.Done() + require.NoError(network.AppResponse(ctx, wantNodeID, 1, wantResponse)) + <-done +} - require.ErrorIs(t, err, errFoo) - require.Equal(t, nodeID, actualNodeID) - require.Nil(t, actualResponse) - } +// Tests that the Client callback is given an error if the request fails +func TestAppRequestFailed(t *testing.T) { + require := require.New(t) + ctx := context.Background() - require.NoError(t, client.AppRequest(context.Background(), set.Of(nodeID), request, callback)) - }, - }, - { - name: "cross-chain app request", - requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { - chainID := ids.GenerateTestID() - sender.SendCrossChainAppRequestF = func(ctx context.Context, chainID ids.ID, requestID uint32, request []byte) { - go func() { - require.NoError(t, network.CrossChainAppRequest(ctx, chainID, requestID, time.Time{}, request)) - }() - } - sender.SendCrossChainAppResponseF = func(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) { - go func() { - ctx = context.WithValue(ctx, ctxKey, ctxVal) - require.NoError(t, network.CrossChainAppResponse(ctx, chainID, requestID, response)) - }() - } - handler.EXPECT(). - CrossChainAppRequest(context.Background(), chainID, gomock.Any(), request). - DoAndReturn(func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { - return response, nil - }) - - callback := func(ctx context.Context, actualChainID ids.ID, actualResponse []byte, err error) { - defer wg.Done() - require.NoError(t, err) - require.Equal(t, ctxVal, ctx.Value(ctxKey)) - require.Equal(t, chainID, actualChainID) - require.Equal(t, response, actualResponse) - } + sender := common.FakeSender{ + SentAppRequest: make(chan []byte, 1), + } + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - require.NoError(t, client.CrossChainAppRequest(context.Background(), chainID, request, callback)) - }, - }, - { - name: "cross-chain app request failed", - requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.SendCrossChainAppRequestF = func(ctx context.Context, chainID ids.ID, requestID uint32, request []byte) { - go func() { - require.NoError(t, network.CrossChainAppRequestFailed(ctx, chainID, requestID, errFoo)) - }() - } + client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + require.NoError(err) - callback := func(_ context.Context, actualChainID ids.ID, actualResponse []byte, err error) { - defer wg.Done() + wantNodeID := ids.GenerateTestNodeID() + done := make(chan struct{}) - require.ErrorIs(t, err, errFoo) - require.Equal(t, chainID, actualChainID) - require.Nil(t, actualResponse) - } + callback := func(_ context.Context, gotNodeID ids.NodeID, gotResponse []byte, err error) { + require.Equal(wantNodeID, gotNodeID) + require.ErrorIs(err, errFoo) + require.Nil(gotResponse) - require.NoError(t, client.CrossChainAppRequest(context.Background(), chainID, request, callback)) - }, - }, - { - name: "app gossip", - requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.SendAppGossipF = func(ctx context.Context, gossip []byte) error { - go func() { - require.NoError(t, network.AppGossip(ctx, nodeID, gossip)) - }() + close(done) + } - return nil - } - handler.EXPECT(). - AppGossip(context.Background(), nodeID, request). - DoAndReturn(func(context.Context, ids.NodeID, []byte) error { - defer wg.Done() - return nil - }) - - require.NoError(t, client.AppGossip(context.Background(), request)) - }, - }, - { - name: "app gossip specific", - requestFunc: func(t *testing.T, network *Network, client *Client, sender *common.SenderTest, handler *mocks.MockHandler, wg *sync.WaitGroup) { - sender.SendAppGossipSpecificF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], bytes []byte) error { - for n := range nodeIDs { - nodeID := n - go func() { - require.NoError(t, network.AppGossip(ctx, nodeID, bytes)) - }() - } + require.NoError(client.AppRequest(ctx, set.Of(wantNodeID), []byte("request"), callback)) + <-sender.SentAppRequest - return nil - } - handler.EXPECT(). - AppGossip(context.Background(), nodeID, request). - DoAndReturn(func(context.Context, ids.NodeID, []byte) error { - defer wg.Done() - return nil - }) - - require.NoError(t, client.AppGossipSpecific(context.Background(), set.Of(nodeID), request)) - }, - }, + require.NoError(network.AppRequestFailed(ctx, wantNodeID, 1, errFoo)) + <-done +} + +// Tests that the Client callback is called on a successful response +func TestCrossChainAppRequestResponse(t *testing.T) { + require := require.New(t) + ctx := context.Background() + + sender := common.FakeSender{ + SentCrossChainAppRequest: make(chan []byte, 1), } + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require := require.New(t) - ctrl := gomock.NewController(t) + client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + require.NoError(err) - sender := &common.SenderTest{} - handler := mocks.NewMockHandler(ctrl) - n := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - require.NoError(n.Connected(context.Background(), nodeID, nil)) - client, err := n.NewAppProtocol(handlerID, handler) - require.NoError(err) + wantChainID := ids.GenerateTestID() + wantResponse := []byte("response") + done := make(chan struct{}) - wg := &sync.WaitGroup{} - wg.Add(1) - tt.requestFunc(t, n, client, sender, handler, wg) - wg.Wait() - }) + callback := func(_ context.Context, gotChainID ids.ID, gotResponse []byte, err error) { + require.Equal(wantChainID, gotChainID) + require.NoError(err) + require.Equal(wantResponse, gotResponse) + + close(done) } + + require.NoError(client.CrossChainAppRequest(ctx, wantChainID, []byte("request"), callback)) + <-sender.SentCrossChainAppRequest + + require.NoError(network.CrossChainAppResponse(ctx, wantChainID, 1, wantResponse)) + <-done } -func TestNetworkDropMessage(t *testing.T) { - unregistered := byte(0x0) +// Tests that the Client callback is given an error if the request fails +func TestCrossChainAppRequestFailed(t *testing.T) { + require := require.New(t) + ctx := context.Background() + + sender := common.FakeSender{ + SentCrossChainAppRequest: make(chan []byte, 1), + } + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + + client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + require.NoError(err) + + wantChainID := ids.GenerateTestID() + done := make(chan struct{}) + callback := func(_ context.Context, gotChainID ids.ID, gotResponse []byte, err error) { + require.Equal(wantChainID, gotChainID) + require.ErrorIs(err, errFoo) + require.Nil(gotResponse) + + close(done) + } + + require.NoError(client.CrossChainAppRequest(ctx, wantChainID, []byte("request"), callback)) + <-sender.SentCrossChainAppRequest + + require.NoError(network.CrossChainAppRequestFailed(ctx, wantChainID, 1, errFoo)) + <-done +} + +// Messages for unregistered handlers should be dropped gracefully +func TestMessageForUnregisteredHandler(t *testing.T) { tests := []struct { - name string - requestFunc func(network *Network) error - err error + name string + msg []byte }{ { - name: "drop unregistered app request message", - requestFunc: func(network *Network) error { - return network.AppRequest(context.Background(), ids.GenerateTestNodeID(), 0, time.Time{}, []byte{unregistered}) - }, - err: nil, - }, - { - name: "drop empty app request message", - requestFunc: func(network *Network) error { - return network.AppRequest(context.Background(), ids.GenerateTestNodeID(), 0, time.Time{}, []byte{}) - }, - err: nil, - }, - { - name: "drop unregistered cross-chain app request message", - requestFunc: func(network *Network) error { - return network.CrossChainAppRequest(context.Background(), ids.GenerateTestID(), 0, time.Time{}, []byte{unregistered}) - }, - err: nil, - }, - { - name: "drop empty cross-chain app request message", - requestFunc: func(network *Network) error { - return network.CrossChainAppRequest(context.Background(), ids.GenerateTestID(), 0, time.Time{}, []byte{}) - }, - err: nil, + name: "nil", + msg: nil, }, { - name: "drop unregistered gossip message", - requestFunc: func(network *Network) error { - return network.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte{unregistered}) - }, - err: nil, + name: "empty", + msg: []byte{}, }, { - name: "drop empty gossip message", - requestFunc: func(network *Network) error { - return network.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte{}) - }, - err: nil, - }, - { - name: "drop unrequested app request failed", - requestFunc: func(network *Network) error { - return network.AppRequestFailed(context.Background(), ids.GenerateTestNodeID(), 0, errFoo) - }, - err: ErrUnrequestedResponse, + name: "non-empty", + msg: []byte("foobar"), }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + ctx := context.Background() + handler := &testHandler{ + appGossipF: func(context.Context, ids.NodeID, []byte) { + require.Fail("should not be called") + }, + appRequestF: func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { + require.Fail("should not be called") + return nil, nil + }, + crossChainAppRequestF: func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { + require.Fail("should not be called") + return nil, nil + }, + } + network := NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + _, err := network.NewAppProtocol(handlerID, handler) + require.NoError(err) + + require.Nil(network.AppRequest(ctx, ids.EmptyNodeID, 0, time.Time{}, tt.msg)) + require.Nil(network.AppGossip(ctx, ids.EmptyNodeID, tt.msg)) + require.Nil(network.CrossChainAppRequest(ctx, ids.Empty, 0, time.Time{}, tt.msg)) + }) + } +} + +// A response or timeout for a request we never made should return an error +func TestResponseForUnrequestedRequest(t *testing.T) { + tests := []struct { + name string + msg []byte + }{ { - name: "drop unrequested app response", - requestFunc: func(network *Network) error { - return network.AppResponse(context.Background(), ids.GenerateTestNodeID(), 0, nil) - }, - err: ErrUnrequestedResponse, + name: "nil", + msg: nil, }, { - name: "drop unrequested cross-chain request failed", - requestFunc: func(network *Network) error { - return network.CrossChainAppRequestFailed(context.Background(), ids.GenerateTestID(), 0, errFoo) - }, - err: ErrUnrequestedResponse, + name: "empty", + msg: []byte{}, }, { - name: "drop unrequested cross-chain response", - requestFunc: func(network *Network) error { - return network.CrossChainAppResponse(context.Background(), ids.GenerateTestID(), 0, nil) - }, - err: ErrUnrequestedResponse, + name: "non-empty", + msg: []byte("foobar"), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { require := require.New(t) + ctx := context.Background() + handler := &testHandler{ + appGossipF: func(context.Context, ids.NodeID, []byte) { + require.Fail("should not be called") + }, + appRequestF: func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { + require.Fail("should not be called") + return nil, nil + }, + crossChainAppRequestF: func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { + require.Fail("should not be called") + return nil, nil + }, + } + network := NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") + _, err := network.NewAppProtocol(handlerID, handler) + require.NoError(err) - network := NewNetwork(logging.NoLog{}, &common.SenderTest{}, prometheus.NewRegistry(), "") - - err := tt.requestFunc(network) - require.ErrorIs(err, tt.err) + err = network.AppResponse(ctx, ids.EmptyNodeID, 0, []byte("foobar")) + require.ErrorIs(err, ErrUnrequestedResponse) + err = network.AppRequestFailed(ctx, ids.EmptyNodeID, 0, errFoo) + require.ErrorIs(err, ErrUnrequestedResponse) + err = network.CrossChainAppResponse(ctx, ids.Empty, 0, []byte("foobar")) + require.ErrorIs(err, ErrUnrequestedResponse) + err = network.CrossChainAppRequestFailed(ctx, ids.Empty, 0, errFoo) + require.ErrorIs(err, ErrUnrequestedResponse) }) } } @@ -322,58 +371,25 @@ func TestNetworkDropMessage(t *testing.T) { // not attempt to issue another request until the previous one has cleared. func TestAppRequestDuplicateRequestIDs(t *testing.T) { require := require.New(t) - ctrl := gomock.NewController(t) + ctx := context.Background() - handler := mocks.NewMockHandler(ctrl) - sender := &common.SenderTest{ - SendAppResponseF: func(context.Context, ids.NodeID, uint32, []byte) error { - return nil - }, - } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - nodeID := ids.GenerateTestNodeID() - - requestSent := &sync.WaitGroup{} - sender.SendAppRequestF = func(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, request []byte) error { - for range nodeIDs { - requestSent.Add(1) - go func() { - require.NoError(network.AppRequest(ctx, nodeID, requestID, time.Time{}, request)) - requestSent.Done() - }() - } - - return nil + sender := &common.FakeSender{ + SentAppRequest: make(chan []byte, 1), } - timeout := &sync.WaitGroup{} - response := []byte("response") - handler.EXPECT().AppRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - DoAndReturn(func(ctx context.Context, nodeID ids.NodeID, deadline time.Time, request []byte) ([]byte, error) { - timeout.Wait() - return response, nil - }).AnyTimes() - - require.NoError(network.Connected(context.Background(), nodeID, nil)) - client, err := network.NewAppProtocol(0x1, handler) + network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + client, err := network.NewAppProtocol(0x1, &NoOpHandler{}) require.NoError(err) - onResponse := func(ctx context.Context, nodeID ids.NodeID, got []byte, err error) { - require.NoError(err) - require.Equal(response, got) - } - - require.NoError(client.AppRequest(context.Background(), set.Of(nodeID), []byte{}, onResponse)) - requestSent.Wait() + noOpCallback := func(context.Context, ids.NodeID, []byte, error) {} + // create a request that never gets a response + require.NoError(client.AppRequest(ctx, set.Of(ids.EmptyNodeID), []byte{}, noOpCallback)) + <-sender.SentAppRequest // force the network to use the same requestID network.router.requestID = 1 - timeout.Add(1) - err = client.AppRequest(context.Background(), set.Of(nodeID), []byte{}, nil) - requestSent.Wait() + err = client.AppRequest(context.Background(), set.Of(ids.EmptyNodeID), []byte{}, noOpCallback) require.ErrorIs(err, ErrRequestPending) - - timeout.Done() } // Sample should always return up to [limit] peers, and less if fewer than @@ -442,7 +458,7 @@ func TestPeersSample(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - network := NewNetwork(logging.NoLog{}, &common.SenderTest{}, prometheus.NewRegistry(), "") + network := NewNetwork(logging.NoLog{}, &common.FakeSender{}, prometheus.NewRegistry(), "") for connected := range tt.connected { require.NoError(network.Connected(context.Background(), connected, nil)) @@ -486,9 +502,7 @@ func TestAppRequestAnyNodeSelection(t *testing.T) { sent := set.Set[ids.NodeID]{} sender := &common.SenderTest{ SendAppRequestF: func(_ context.Context, nodeIDs set.Set[ids.NodeID], _ uint32, _ []byte) error { - for nodeID := range nodeIDs { - sent.Add(nodeID) - } + sent = nodeIDs return nil }, } @@ -503,6 +517,7 @@ func TestAppRequestAnyNodeSelection(t *testing.T) { err = client.AppRequestAny(context.Background(), []byte("foobar"), nil) require.ErrorIs(err, tt.expected) + require.Subset(tt.peers, sent.List()) }) } } diff --git a/network/p2p/validators_test.go b/network/p2p/validators_test.go index e721b4a978af..d1ce9dd1735e 100644 --- a/network/p2p/validators_test.go +++ b/network/p2p/validators_test.go @@ -179,7 +179,7 @@ func TestValidatorsSample(t *testing.T) { } gomock.InOrder(calls...) - network := NewNetwork(logging.NoLog{}, &common.SenderTest{}, prometheus.NewRegistry(), "") + network := NewNetwork(logging.NoLog{}, &common.FakeSender{}, prometheus.NewRegistry(), "") ctx := context.Background() require.NoError(network.Connected(ctx, nodeID1, nil)) require.NoError(network.Connected(ctx, nodeID2, nil)) diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 0e32a76aec26..3ec7849d6e0b 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -6,7 +6,6 @@ github.com/ava-labs/avalanchego/database=Iterator=database/mock_iterator.go github.com/ava-labs/avalanchego/message=OutboundMessage=message/mock_message.go github.com/ava-labs/avalanchego/message=OutboundMsgBuilder=message/mock_outbound_message_builder.go github.com/ava-labs/avalanchego/network/peer=GossipTracker=network/peer/mock_gossip_tracker.go -github.com/ava-labs/avalanchego/network/p2p=Handler=network/p2p/mocks/mock_handler.go github.com/ava-labs/avalanchego/snow/consensus/snowman=Block=snow/consensus/snowman/mock_block.go github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex=LinearizableVM=snow/engine/avalanche/vertex/mock_vm.go github.com/ava-labs/avalanchego/snow/engine/snowman/block=BuildBlockWithContextChainVM=snow/engine/snowman/block/mocks/build_block_with_context_vm.go diff --git a/snow/engine/common/test_sender.go b/snow/engine/common/test_sender.go index 5b76f3b6a2f4..4ef33192bd93 100644 --- a/snow/engine/common/test_sender.go +++ b/snow/engine/common/test_sender.go @@ -15,7 +15,8 @@ import ( ) var ( - _ Sender = (*SenderTest)(nil) + _ Sender = (*SenderTest)(nil) + _ AppSender = (*FakeSender)(nil) errAccept = errors.New("unexpectedly called Accept") errSendAppRequest = errors.New("unexpectedly called SendAppRequest") @@ -358,3 +359,64 @@ func (s *SenderTest) SendAppGossipSpecific(ctx context.Context, nodeIDs set.Set[ } return errSendAppGossipSpecific } + +// FakeSender is used for testing +type FakeSender struct { + SentAppRequest, SentAppResponse, + SentAppGossip, SentAppGossipSpecific, + SentCrossChainAppRequest, SentCrossChainAppResponse chan []byte +} + +func (f FakeSender) SendAppRequest(_ context.Context, _ set.Set[ids.NodeID], _ uint32, bytes []byte) error { + if f.SentAppRequest == nil { + return nil + } + + f.SentAppRequest <- bytes + return nil +} + +func (f FakeSender) SendAppResponse(_ context.Context, _ ids.NodeID, _ uint32, bytes []byte) error { + if f.SentAppResponse == nil { + return nil + } + + f.SentAppResponse <- bytes + return nil +} + +func (f FakeSender) SendAppGossip(_ context.Context, bytes []byte) error { + if f.SentAppGossip == nil { + return nil + } + + f.SentAppGossip <- bytes + return nil +} + +func (f FakeSender) SendAppGossipSpecific(_ context.Context, _ set.Set[ids.NodeID], bytes []byte) error { + if f.SentAppGossipSpecific == nil { + return nil + } + + f.SentAppGossipSpecific <- bytes + return nil +} + +func (f FakeSender) SendCrossChainAppRequest(_ context.Context, _ ids.ID, _ uint32, bytes []byte) error { + if f.SentCrossChainAppRequest == nil { + return nil + } + + f.SentCrossChainAppRequest <- bytes + return nil +} + +func (f FakeSender) SendCrossChainAppResponse(_ context.Context, _ ids.ID, _ uint32, bytes []byte) error { + if f.SentCrossChainAppResponse == nil { + return nil + } + + f.SentCrossChainAppResponse <- bytes + return nil +} From 82fbc973718605d999b026bafaed4aea6104568b Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 12 Dec 2023 18:30:09 -0500 Subject: [PATCH 140/267] Add ACP signaling (#2476) --- api/info/service.go | 63 ++++ config/config.go | 23 ++ config/flags.go | 4 + config/keys.go | 2 + message/mock_outbound_message_builder.go | 8 +- message/outbound_msg_builder.go | 6 + network/config.go | 3 + network/network.go | 2 + network/peer/config.go | 3 + network/peer/info.go | 5 +- network/peer/peer.go | 37 +- node/node.go | 20 ++ proto/p2p/p2p.proto | 2 + proto/pb/p2p/p2p.pb.go | 415 ++++++++++++----------- utils/constants/acps.go | 19 ++ 15 files changed, 406 insertions(+), 206 deletions(-) create mode 100644 utils/constants/acps.go diff --git a/api/info/service.go b/api/info/service.go index 47112e55b630..0ce1b38188c9 100644 --- a/api/info/service.go +++ b/api/info/service.go @@ -17,10 +17,12 @@ import ( "github.com/ava-labs/avalanchego/network" "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/snow/networking/benchlist" + "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/json" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms" "github.com/ava-labs/avalanchego/vms/platformvm/signer" @@ -32,6 +34,7 @@ var errNoChainProvided = errors.New("argument 'chain' not given") type Info struct { Parameters log logging.Logger + validators validators.Manager myIP ips.DynamicIPPort networking network.Network chainManager chains.Manager @@ -59,6 +62,7 @@ type Parameters struct { func NewService( parameters Parameters, log logging.Logger, + validators validators.Manager, chainManager chains.Manager, vmManager vms.Manager, myIP ips.DynamicIPPort, @@ -73,6 +77,7 @@ func NewService( &Info{ Parameters: parameters, log: log, + validators: validators, chainManager: chainManager, vmManager: vmManager, myIP: myIP, @@ -319,6 +324,64 @@ func (i *Info) Uptime(_ *http.Request, args *UptimeRequest, reply *UptimeRespons return nil } +type ACP struct { + SupportWeight json.Uint64 `json:"supportWeight"` + Supporters set.Set[ids.NodeID] `json:"supporters"` + ObjectWeight json.Uint64 `json:"objectWeight"` + Objectors set.Set[ids.NodeID] `json:"objectors"` + AbstainWeight json.Uint64 `json:"abstainWeight"` +} + +type ACPsReply struct { + ACPs map[uint32]*ACP `json:"acps"` +} + +func (a *ACPsReply) getACP(acpNum uint32) *ACP { + acp, ok := a.ACPs[acpNum] + if !ok { + acp = &ACP{} + a.ACPs[acpNum] = acp + } + return acp +} + +func (i *Info) Acps(_ *http.Request, _ *struct{}, reply *ACPsReply) error { + i.log.Debug("API called", + zap.String("service", "info"), + zap.String("method", "acps"), + ) + + reply.ACPs = make(map[uint32]*ACP, constants.CurrentACPs.Len()) + peers := i.networking.PeerInfo(nil) + for _, peer := range peers { + weight := json.Uint64(i.validators.GetWeight(constants.PrimaryNetworkID, peer.ID)) + if weight == 0 { + continue + } + + for acpNum := range peer.SupportedACPs { + acp := reply.getACP(acpNum) + acp.Supporters.Add(peer.ID) + acp.SupportWeight += weight + } + for acpNum := range peer.ObjectedACPs { + acp := reply.getACP(acpNum) + acp.Objectors.Add(peer.ID) + acp.ObjectWeight += weight + } + } + + totalWeight, err := i.validators.TotalWeight(constants.PrimaryNetworkID) + if err != nil { + return err + } + for acpNum := range constants.CurrentACPs { + acp := reply.getACP(acpNum) + acp.AbstainWeight = json.Uint64(totalWeight) - acp.SupportWeight - acp.ObjectWeight + } + return nil +} + type GetTxFeeResponse struct { TxFee json.Uint64 `json:"txFee"` CreateAssetTxFee json.Uint64 `json:"createAssetTxFee"` diff --git a/config/config.go b/config/config.go index d894e832d889..4cae079f3572 100644 --- a/config/config.go +++ b/config/config.go @@ -81,6 +81,7 @@ var ( ConsensusGossipOnAcceptPeerSizeKey: acceptedFrontierGossipDeprecationMsg, } + errConflictingACPOpinion = errors.New("supporting and objecting to the same ACP") errSybilProtectionDisabledStakerWeights = errors.New("sybil protection disabled weights must be positive") errSybilProtectionDisabledOnPublicNetwork = errors.New("sybil protection disabled on public network") errAuthPasswordTooWeak = errors.New("API auth password is not strong enough") @@ -346,6 +347,25 @@ func getNetworkConfig( allowPrivateIPs = v.GetBool(NetworkAllowPrivateIPsKey) } + var supportedACPs set.Set[uint32] + for _, acp := range v.GetIntSlice(ACPSupportKey) { + if acp < 0 || acp > math.MaxInt32 { + return network.Config{}, fmt.Errorf("invalid ACP: %d", acp) + } + supportedACPs.Add(uint32(acp)) + } + + var objectedACPs set.Set[uint32] + for _, acp := range v.GetIntSlice(ACPObjectKey) { + if acp < 0 || acp > math.MaxInt32 { + return network.Config{}, fmt.Errorf("invalid ACP: %d", acp) + } + objectedACPs.Add(uint32(acp)) + } + if supportedACPs.Overlaps(objectedACPs) { + return network.Config{}, errConflictingACPOpinion + } + config := network.Config{ ThrottlerConfig: network.ThrottlerConfig{ MaxInboundConnsPerSec: maxInboundConnsPerSec, @@ -425,6 +445,9 @@ func getNetworkConfig( UptimeMetricFreq: v.GetDuration(UptimeMetricFreqKey), MaximumInboundMessageTimeout: v.GetDuration(NetworkMaximumInboundTimeoutKey), + SupportedACPs: supportedACPs, + ObjectedACPs: objectedACPs, + RequireValidatorToConnect: v.GetBool(NetworkRequireValidatorToConnectKey), PeerReadBufferSize: int(v.GetUint(NetworkPeerReadBufferSizeKey)), PeerWriteBufferSize: int(v.GetUint(NetworkPeerWriteBufferSizeKey)), diff --git a/config/flags.go b/config/flags.go index 6e381e1c6a85..333ea302be07 100644 --- a/config/flags.go +++ b/config/flags.go @@ -92,6 +92,10 @@ func addNodeFlags(fs *pflag.FlagSet) { // Network ID fs.String(NetworkNameKey, constants.MainnetName, "Network ID this node will connect to") + // ACP flagging + fs.IntSlice(ACPSupportKey, nil, "ACPs to support adoption") + fs.IntSlice(ACPObjectKey, nil, "ACPs to object adoption") + // AVAX fees fs.Uint64(TxFeeKey, genesis.LocalParams.TxFee, "Transaction fee, in nAVAX") fs.Uint64(CreateAssetTxFeeKey, genesis.LocalParams.CreateAssetTxFee, "Transaction fee, in nAVAX, for transactions that create new assets") diff --git a/config/keys.go b/config/keys.go index c627abfc1b57..078e08465721 100644 --- a/config/keys.go +++ b/config/keys.go @@ -13,6 +13,8 @@ const ( GenesisFileKey = "genesis-file" GenesisFileContentKey = "genesis-file-content" NetworkNameKey = "network-id" + ACPSupportKey = "acp-support" + ACPObjectKey = "acp-object" TxFeeKey = "tx-fee" CreateAssetTxFeeKey = "create-asset-tx-fee" CreateSubnetTxFeeKey = "create-subnet-tx-fee" diff --git a/message/mock_outbound_message_builder.go b/message/mock_outbound_message_builder.go index 5f224e90da45..baed0d10b9c3 100644 --- a/message/mock_outbound_message_builder.go +++ b/message/mock_outbound_message_builder.go @@ -371,16 +371,16 @@ func (mr *MockOutboundMsgBuilderMockRecorder) StateSummaryFrontier(arg0, arg1, a } // Version mocks base method. -func (m *MockOutboundMsgBuilder) Version(arg0 uint32, arg1 uint64, arg2 ips.IPPort, arg3, arg4 string, arg5, arg6, arg7 uint32, arg8 uint64, arg9 []byte, arg10 []ids.ID) (OutboundMessage, error) { +func (m *MockOutboundMsgBuilder) Version(arg0 uint32, arg1 uint64, arg2 ips.IPPort, arg3, arg4 string, arg5, arg6, arg7 uint32, arg8 uint64, arg9 []byte, arg10 []ids.ID, arg11, arg12 []uint32) (OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Version", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) + ret := m.ctrl.Call(m, "Version", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) ret0, _ := ret[0].(OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Version indicates an expected call of Version. -func (mr *MockOutboundMsgBuilderMockRecorder) Version(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Version(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Version), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Version), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) } diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index dc2cb4f7d6ba..1705463931cb 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -30,6 +30,8 @@ type OutboundMsgBuilder interface { myVersionTime uint64, sig []byte, trackedSubnets []ids.ID, + supportedACPs []uint32, + objectedACPs []uint32, ) (OutboundMessage, error) PeerList( @@ -240,6 +242,8 @@ func (b *outMsgBuilder) Version( myVersionTime uint64, sig []byte, trackedSubnets []ids.ID, + supportedACPs []uint32, + objectedACPs []uint32, ) (OutboundMessage, error) { subnetIDBytes := make([][]byte, len(trackedSubnets)) encodeIDs(trackedSubnets, subnetIDBytes) @@ -261,6 +265,8 @@ func (b *outMsgBuilder) Version( Minor: minor, Patch: patch, }, + SupportedAcps: supportedACPs, + ObjectedAcps: objectedACPs, }, }, }, diff --git a/network/config.go b/network/config.go index 1ca1addc0117..e1a32e4ee1a5 100644 --- a/network/config.go +++ b/network/config.go @@ -126,6 +126,9 @@ type Config struct { PingFrequency time.Duration `json:"pingFrequency"` AllowPrivateIPs bool `json:"allowPrivateIPs"` + SupportedACPs set.Set[uint32] `json:"supportedACPs"` + ObjectedACPs set.Set[uint32] `json:"objectedACPs"` + // The compression type to use when compressing outbound messages. // Assumes all peers support this compression type. CompressionType compression.Type `json:"compressionType"` diff --git a/network/network.go b/network/network.go index 3f89e0ea00ef..6c182e0554ec 100644 --- a/network/network.go +++ b/network/network.go @@ -271,6 +271,8 @@ func NewNetwork( PingFrequency: config.PingFrequency, PongTimeout: config.PingPongTimeout, MaxClockDifference: config.MaxClockDifference, + SupportedACPs: config.SupportedACPs.List(), + ObjectedACPs: config.ObjectedACPs.List(), ResourceTracker: config.ResourceTracker, UptimeCalculator: config.UptimeCalculator, IPSigner: peer.NewIPSigner(config.MyIPPort, config.TLSKey), diff --git a/network/peer/config.go b/network/peer/config.go index b4fd03db2166..1d3d23b7fc36 100644 --- a/network/peer/config.go +++ b/network/peer/config.go @@ -40,6 +40,9 @@ type Config struct { PongTimeout time.Duration MaxClockDifference time.Duration + SupportedACPs []uint32 + ObjectedACPs []uint32 + // Unix time of the last message sent and received respectively // Must only be accessed atomically LastSent, LastReceived int64 diff --git a/network/peer/info.go b/network/peer/info.go index 45f7a3cdd4a6..468d00be9fef 100644 --- a/network/peer/info.go +++ b/network/peer/info.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/json" + "github.com/ava-labs/avalanchego/utils/set" ) type Info struct { @@ -19,5 +20,7 @@ type Info struct { LastReceived time.Time `json:"lastReceived"` ObservedUptime json.Uint32 `json:"observedUptime"` ObservedSubnetUptimes map[ids.ID]json.Uint32 `json:"observedSubnetUptimes"` - TrackedSubnets []ids.ID `json:"trackedSubnets"` + TrackedSubnets set.Set[ids.ID] `json:"trackedSubnets"` + SupportedACPs set.Set[uint32] `json:"supportedACPs"` + ObjectedACPs set.Set[uint32] `json:"objectedACPs"` } diff --git a/network/peer/peer.go b/network/peer/peer.go index e35d1ba027f0..c9182eecb744 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -128,6 +128,9 @@ type peer struct { // trackedSubnets is the subset of subnetIDs the peer sent us in the Version // message that we are also tracking. trackedSubnets set.Set[ids.ID] + // options of ACPs provided in the Version message. + supportedACPs set.Set[uint32] + objectedACPs set.Set[uint32] observedUptimesLock sync.RWMutex // [observedUptimesLock] must be held while accessing [observedUptime] @@ -246,10 +249,9 @@ func (p *peer) Info() Info { publicIPStr = p.ip.IPPort.String() } - trackedSubnets := p.trackedSubnets.List() - uptimes := make(map[ids.ID]json.Uint32, len(trackedSubnets)) + uptimes := make(map[ids.ID]json.Uint32, p.trackedSubnets.Len()) - for _, subnetID := range trackedSubnets { + for subnetID := range p.trackedSubnets { uptime, exist := p.ObservedUptime(subnetID) if !exist { continue @@ -271,7 +273,9 @@ func (p *peer) Info() Info { LastReceived: p.LastReceived(), ObservedUptime: json.Uint32(primaryUptime), ObservedSubnetUptimes: uptimes, - TrackedSubnets: trackedSubnets, + TrackedSubnets: p.trackedSubnets, + SupportedACPs: p.supportedACPs, + ObjectedACPs: p.objectedACPs, } } @@ -517,6 +521,8 @@ func (p *peer) writeMessages() { mySignedIP.Timestamp, mySignedIP.Signature, p.MySubnets.List(), + p.SupportedACPs, + p.ObjectedACPs, ) if err != nil { p.Log.Error("failed to create message", @@ -956,6 +962,29 @@ func (p *peer) handleVersion(msg *p2p.Version) { } } + for _, acp := range msg.SupportedAcps { + if constants.CurrentACPs.Contains(acp) { + p.supportedACPs.Add(acp) + } + } + for _, acp := range msg.ObjectedAcps { + if constants.CurrentACPs.Contains(acp) { + p.objectedACPs.Add(acp) + } + } + + if p.supportedACPs.Overlaps(p.objectedACPs) { + p.Log.Debug("message with invalid field", + zap.Stringer("nodeID", p.id), + zap.Stringer("messageOp", message.VersionOp), + zap.String("field", "ACPs"), + zap.Reflect("supportedACPs", p.supportedACPs), + zap.Reflect("objectedACPs", p.objectedACPs), + ) + p.StartClose() + return + } + // "net.IP" type in Golang is 16-byte if ipLen := len(msg.IpAddr); ipLen != net.IPv6len { p.Log.Debug("message with invalid field", diff --git a/node/node.go b/node/node.go index 1dbe4c6cc0df..22be7d5436eb 100644 --- a/node/node.go +++ b/node/node.go @@ -439,6 +439,25 @@ func (n *Node) initNetworking() error { ) } + // We allow nodes to gossip unknown ACPs in case the current ACPs constant + // becomes out of date. + var unknownACPs set.Set[uint32] + for acp := range n.Config.NetworkConfig.SupportedACPs { + if !constants.CurrentACPs.Contains(acp) { + unknownACPs.Add(acp) + } + } + for acp := range n.Config.NetworkConfig.ObjectedACPs { + if !constants.CurrentACPs.Contains(acp) { + unknownACPs.Add(acp) + } + } + if unknownACPs.Len() > 0 { + n.Log.Warn("gossipping unknown ACPs", + zap.Reflect("acps", unknownACPs), + ) + } + tlsConfig := peer.TLSConfig(n.Config.StakingTLSCert, n.tlsKeyLogWriterCloser) // Configure benchlist @@ -1272,6 +1291,7 @@ func (n *Node) initInfoAPI() error { VMManager: n.VMManager, }, n.Log, + n.vdrs, n.chainManager, n.VMManager, n.Config.NetworkConfig.MyIPPort, diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 4f37af848fdb..c3a2f71f01ec 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -116,6 +116,8 @@ message Version { // Subnets the peer is tracking repeated bytes tracked_subnets = 8; Client client = 9; + repeated uint32 supported_acps = 10; + repeated uint32 objected_acps = 11; } // Metadata about a peer's P2P client used to determine compatibility diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index 235637d1dd0c..55c43f3ab1c9 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -713,6 +713,8 @@ type Version struct { // Subnets the peer is tracking TrackedSubnets [][]byte `protobuf:"bytes,8,rep,name=tracked_subnets,json=trackedSubnets,proto3" json:"tracked_subnets,omitempty"` Client *Client `protobuf:"bytes,9,opt,name=client,proto3" json:"client,omitempty"` + SupportedAcps []uint32 `protobuf:"varint,10,rep,packed,name=supported_acps,json=supportedAcps,proto3" json:"supported_acps,omitempty"` + ObjectedAcps []uint32 `protobuf:"varint,11,rep,packed,name=objected_acps,json=objectedAcps,proto3" json:"objected_acps,omitempty"` } func (x *Version) Reset() { @@ -810,6 +812,20 @@ func (x *Version) GetClient() *Client { return nil } +func (x *Version) GetSupportedAcps() []uint32 { + if x != nil { + return x.SupportedAcps + } + return nil +} + +func (x *Version) GetObjectedAcps() []uint32 { + if x != nil { + return x.ObjectedAcps + } + return nil +} + // Metadata about a peer's P2P client used to determine compatibility type Client struct { state protoimpl.MessageState @@ -2708,7 +2724,7 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0x9a, 0x02, 0x0a, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0xe6, 0x02, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, @@ -2726,219 +2742,224 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x5e, 0x0a, 0x06, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, - 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, - 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, - 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, - 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, - 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, - 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, - 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, - 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, - 0x72, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x12, 0x13, - 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, - 0x78, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x22, 0x3e, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, - 0x12, 0x29, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, - 0x6b, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, - 0x02, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, - 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, - 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, - 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, - 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x9d, 0x01, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, - 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x75, 0x0a, - 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, + 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, + 0x0d, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, + 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, + 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x41, 0x63, 0x70, 0x73, 0x22, 0x5e, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, + 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, + 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, + 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, + 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, + 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, + 0x3c, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3e, 0x0a, + 0x0b, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x09, + 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x52, 0x08, 0x70, + 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6f, 0x0a, + 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, + 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, + 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x4a, 0x04, - 0x08, 0x04, 0x10, 0x05, 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, - 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, - 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x6f, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x75, 0x0a, 0x10, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x04, - 0x10, 0x05, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6b, - 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x01, 0x0a, 0x03, - 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8f, - 0x01, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, + 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6f, 0x0a, + 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb9, + 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, + 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, + 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x6e, + 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, + 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, + 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, + 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x01, 0x0a, + 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, - 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, + 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x22, 0xdc, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, - 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, + 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x09, + 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, + 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, - 0xe1, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, - 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, - 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, + 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, + 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, + 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, - 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, - 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, - 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, - 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, - 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, - 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, - 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, - 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, + 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, + 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, + 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, + 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, + 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, + 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/utils/constants/acps.go b/utils/constants/acps.go new file mode 100644 index 000000000000..ea49d7c7812f --- /dev/null +++ b/utils/constants/acps.go @@ -0,0 +1,19 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package constants + +import "github.com/ava-labs/avalanchego/utils/set" + +// CurrentACPs is the set of ACPs that are currently, at the time of release, +// marked as implementable. +// +// See: https://github.com/avalanche-foundation/ACPs/tree/main#readme +var CurrentACPs = set.Of[uint32]( + 23, // https://github.com/avalanche-foundation/ACPs/blob/main/ACPs/23-p-chain-native-transfers.md + 24, // https://github.com/avalanche-foundation/ACPs/blob/main/ACPs/24-shanghai-eips.md + 25, // https://github.com/avalanche-foundation/ACPs/blob/main/ACPs/25-vm-application-errors.md + 30, // https://github.com/avalanche-foundation/ACPs/blob/main/ACPs/30-avalanche-warp-x-evm.md + 31, // https://github.com/avalanche-foundation/ACPs/blob/main/ACPs/31-enable-subnet-ownership-transfer.md + 41, // https://github.com/avalanche-foundation/ACPs/blob/main/ACPs/41-remove-pending-stakers.md +) From 832632ae7b143a9e5acb598198480beea772f9df Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 12 Dec 2023 23:30:00 -0500 Subject: [PATCH 141/267] Refactor SDK (#2452) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Dan Laine Co-authored-by: Stephen Buttolph --- go.mod | 2 +- go.sum | 4 +- network/p2p/client.go | 9 +- network/p2p/gossip/gossip_test.go | 12 +- network/p2p/handler.go | 36 +++- network/p2p/handler_test.go | 20 +- network/p2p/network.go | 139 +++++++++++-- network/p2p/network_test.go | 75 ++++--- network/p2p/router.go | 282 +++++++++++++++----------- network/p2p/throttler_handler.go | 32 ++- network/p2p/throttler_handler_test.go | 20 +- network/p2p/validators_test.go | 6 +- 12 files changed, 414 insertions(+), 223 deletions(-) diff --git a/go.mod b/go.mod index e9afffd7d9e7..15052ca3f366 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231212220437-f9ec2ecc2714 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213002358-53424dd5480c github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index b7d1d9c26982..b74c5dbbb979 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231212220437-f9ec2ecc2714 h1:dhuxCYjB+4isvJMHViHkS50NgkQ/dHY2ZZmk8ESAyxw= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231212220437-f9ec2ecc2714/go.mod h1:LwQhIuKmd8JPemahE1f7TvsE3WRzCFdjvNWBPxXSaNo= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213002358-53424dd5480c h1:bWPdqoi+J6ztfVhEl7iexFSaKyaFlMpIltIMVTpXDQY= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213002358-53424dd5480c/go.mod h1:v8pqR8wC9VuyPTEbI6/wmflXPIAmUr6SUwEKP+hi9iU= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/network/p2p/client.go b/network/p2p/client.go index 6f2e35c26896..982b7c50f1f0 100644 --- a/network/p2p/client.go +++ b/network/p2p/client.go @@ -40,6 +40,7 @@ type CrossChainAppResponseCallback func( type Client struct { handlerID uint64 + handlerIDStr string handlerPrefix []byte router *router sender common.AppSender @@ -95,8 +96,8 @@ func (c *Client) AppRequest( } c.router.pendingAppRequests[requestID] = pendingAppRequest{ - AppResponseCallback: onResponse, - metrics: c.router.handlers[c.handlerID].metrics, + handlerID: c.handlerIDStr, + callback: onResponse, } c.router.requestID += 2 } @@ -158,8 +159,8 @@ func (c *Client) CrossChainAppRequest( } c.router.pendingCrossChainAppRequests[requestID] = pendingCrossChainAppRequest{ - CrossChainAppResponseCallback: onResponse, - metrics: c.router.handlers[c.handlerID].metrics, + handlerID: c.handlerIDStr, + callback: onResponse, } c.router.requestID += 2 diff --git a/network/p2p/gossip/gossip_test.go b/network/p2p/gossip/gossip_test.go index f2150e8f6afd..a55cec20da59 100644 --- a/network/p2p/gossip/gossip_test.go +++ b/network/p2p/gossip/gossip_test.go @@ -120,7 +120,9 @@ func TestGossiperGossip(t *testing.T) { responseSender := &common.FakeSender{ SentAppResponse: make(chan []byte, 1), } - responseNetwork := p2p.NewNetwork(logging.NoLog{}, responseSender, prometheus.NewRegistry(), "") + responseNetwork, err := p2p.NewNetwork(logging.NoLog{}, responseSender, prometheus.NewRegistry(), "") + require.NoError(err) + responseBloom, err := NewBloomFilter(1000, 0.01) require.NoError(err) responseSet := testSet{ @@ -133,14 +135,14 @@ func TestGossiperGossip(t *testing.T) { handler, err := NewHandler[*testTx](responseSet, tt.config, prometheus.NewRegistry()) require.NoError(err) - _, err = responseNetwork.NewAppProtocol(0x0, handler) - require.NoError(err) + require.NoError(responseNetwork.AddHandler(0x0, handler)) requestSender := &common.FakeSender{ SentAppRequest: make(chan []byte, 1), } - requestNetwork := p2p.NewNetwork(logging.NoLog{}, requestSender, prometheus.NewRegistry(), "") + requestNetwork, err := p2p.NewNetwork(logging.NoLog{}, requestSender, prometheus.NewRegistry(), "") + require.NoError(err) require.NoError(requestNetwork.Connected(context.Background(), ids.EmptyNodeID, nil)) bloom, err := NewBloomFilter(1000, 0.01) @@ -153,7 +155,7 @@ func TestGossiperGossip(t *testing.T) { require.NoError(requestSet.Add(item)) } - requestClient, err := requestNetwork.NewAppProtocol(0x0, nil) + requestClient := requestNetwork.NewClient(0x0) require.NoError(err) config := Config{ diff --git a/network/p2p/handler.go b/network/p2p/handler.go index b85195a5255c..27c220565a04 100644 --- a/network/p2p/handler.go +++ b/network/p2p/handler.go @@ -63,28 +63,48 @@ func (NoOpHandler) CrossChainAppRequest(context.Context, ids.ID, time.Time, []by return nil, nil } +func NewValidatorHandler( + handler Handler, + validatorSet ValidatorSet, + log logging.Logger, +) *ValidatorHandler { + return &ValidatorHandler{ + handler: handler, + validatorSet: validatorSet, + log: log, + } +} + // ValidatorHandler drops messages from non-validators type ValidatorHandler struct { - Handler - ValidatorSet ValidatorSet - Log logging.Logger + handler Handler + validatorSet ValidatorSet + log logging.Logger } func (v ValidatorHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { - if !v.ValidatorSet.Has(ctx, nodeID) { - v.Log.Debug("dropping message", zap.Stringer("nodeID", nodeID)) + if !v.validatorSet.Has(ctx, nodeID) { + v.log.Debug( + "dropping message", + zap.Stringer("nodeID", nodeID), + zap.String("reason", "not a validator"), + ) return } - v.Handler.AppGossip(ctx, nodeID, gossipBytes) + v.handler.AppGossip(ctx, nodeID, gossipBytes) } func (v ValidatorHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { - if !v.ValidatorSet.Has(ctx, nodeID) { + if !v.validatorSet.Has(ctx, nodeID) { return nil, ErrNotValidator } - return v.Handler.AppRequest(ctx, nodeID, deadline, requestBytes) + return v.handler.AppRequest(ctx, nodeID, deadline, requestBytes) +} + +func (v ValidatorHandler) CrossChainAppRequest(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) { + return v.handler.CrossChainAppRequest(ctx, chainID, deadline, requestBytes) } // responder automatically sends the response for a given request diff --git a/network/p2p/handler_test.go b/network/p2p/handler_test.go index b7a1b6bec899..3bbb6bc46711 100644 --- a/network/p2p/handler_test.go +++ b/network/p2p/handler_test.go @@ -55,15 +55,15 @@ func TestValidatorHandlerAppGossip(t *testing.T) { require := require.New(t) called := false - handler := ValidatorHandler{ - Handler: testHandler{ + handler := NewValidatorHandler( + &testHandler{ appGossipF: func(context.Context, ids.NodeID, []byte) { called = true }, }, - ValidatorSet: tt.validatorSet, - Log: logging.NoLog{}, - } + tt.validatorSet, + logging.NoLog{}, + ) handler.AppGossip(context.Background(), tt.nodeID, []byte("foobar")) require.Equal(tt.expected, called) @@ -100,11 +100,11 @@ func TestValidatorHandlerAppRequest(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - handler := ValidatorHandler{ - Handler: NoOpHandler{}, - ValidatorSet: tt.validatorSet, - Log: logging.NoLog{}, - } + handler := NewValidatorHandler( + NoOpHandler{}, + tt.validatorSet, + logging.NoLog{}, + ) _, err := handler.AppRequest(context.Background(), tt.nodeID, time.Time{}, []byte("foobar")) require.ErrorIs(err, tt.expected) diff --git a/network/p2p/network.go b/network/p2p/network.go index bed562b1204d..76b5c13e76ad 100644 --- a/network/p2p/network.go +++ b/network/p2p/network.go @@ -6,6 +6,7 @@ package p2p import ( "context" "encoding/binary" + "strconv" "sync" "time" @@ -14,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" @@ -23,6 +25,9 @@ var ( _ validators.Connector = (*Network)(nil) _ common.AppHandler = (*Network)(nil) _ NodeSampler = (*peerSampler)(nil) + + handlerLabel = "handlerID" + labelNames = []string{handlerLabel} ) // ClientOption configures Client @@ -53,17 +58,108 @@ type clientOptions struct { func NewNetwork( log logging.Logger, sender common.AppSender, - metrics prometheus.Registerer, + registerer prometheus.Registerer, namespace string, -) *Network { - return &Network{ - Peers: &Peers{}, - log: log, - sender: sender, - metrics: metrics, - namespace: namespace, - router: newRouter(log, sender, metrics, namespace), +) (*Network, error) { + metrics := metrics{ + appRequestTime: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "app_request_time", + Help: "app request time (ns)", + }, labelNames), + appRequestCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "app_request_count", + Help: "app request count (n)", + }, labelNames), + appResponseTime: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "app_response_time", + Help: "app response time (ns)", + }, labelNames), + appResponseCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "app_response_count", + Help: "app response count (n)", + }, labelNames), + appRequestFailedTime: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "app_request_failed_time", + Help: "app request failed time (ns)", + }, labelNames), + appRequestFailedCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "app_request_failed_count", + Help: "app request failed count (ns)", + }, labelNames), + appGossipTime: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "app_gossip_time", + Help: "app gossip time (ns)", + }, labelNames), + appGossipCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "app_gossip_count", + Help: "app gossip count (n)", + }, labelNames), + crossChainAppRequestTime: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "cross_chain_app_request_time", + Help: "cross chain app request time (ns)", + }, labelNames), + crossChainAppRequestCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "cross_chain_app_request_count", + Help: "cross chain app request count (n)", + }, labelNames), + crossChainAppResponseTime: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "cross_chain_app_response_time", + Help: "cross chain app response time (ns)", + }, labelNames), + crossChainAppResponseCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "cross_chain_app_response_count", + Help: "cross chain app response count (n)", + }, labelNames), + crossChainAppRequestFailedTime: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "cross_chain_app_request_failed_time", + Help: "cross chain app request failed time (ns)", + }, labelNames), + crossChainAppRequestFailedCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "cross_chain_app_request_failed_count", + Help: "cross chain app request failed count (n)", + }, labelNames), + } + + err := utils.Err( + registerer.Register(metrics.appRequestTime), + registerer.Register(metrics.appRequestCount), + registerer.Register(metrics.appResponseTime), + registerer.Register(metrics.appResponseCount), + registerer.Register(metrics.appRequestFailedTime), + registerer.Register(metrics.appRequestFailedCount), + registerer.Register(metrics.appGossipTime), + registerer.Register(metrics.appGossipCount), + registerer.Register(metrics.crossChainAppRequestTime), + registerer.Register(metrics.crossChainAppRequestCount), + registerer.Register(metrics.crossChainAppResponseTime), + registerer.Register(metrics.crossChainAppResponseCount), + registerer.Register(metrics.crossChainAppRequestFailedTime), + registerer.Register(metrics.crossChainAppRequestFailedCount), + ) + if err != nil { + return nil, err } + + return &Network{ + Peers: &Peers{}, + log: log, + sender: sender, + router: newRouter(log, sender, metrics), + }, nil } // Network exposes networking state and supports building p2p application @@ -71,10 +167,8 @@ func NewNetwork( type Network struct { Peers *Peers - log logging.Logger - sender common.AppSender - metrics prometheus.Registerer - namespace string + log logging.Logger + sender common.AppSender router *router } @@ -117,16 +211,12 @@ func (n *Network) Disconnected(_ context.Context, nodeID ids.NodeID) error { return nil } -// NewAppProtocol reserves an identifier for an application protocol handler and -// returns a Client that can be used to send messages for the corresponding -// protocol. -func (n *Network) NewAppProtocol(handlerID uint64, handler Handler, options ...ClientOption) (*Client, error) { - if err := n.router.addHandler(handlerID, handler); err != nil { - return nil, err - } - +// NewClient returns a Client that can be used to send messages for the +// corresponding protocol. +func (n *Network) NewClient(handlerID uint64, options ...ClientOption) *Client { client := &Client{ handlerID: handlerID, + handlerIDStr: strconv.FormatUint(handlerID, 10), handlerPrefix: binary.AppendUvarint(nil, handlerID), sender: n.sender, router: n.router, @@ -141,7 +231,12 @@ func (n *Network) NewAppProtocol(handlerID uint64, handler Handler, options ...C option.apply(client.options) } - return client, nil + return client +} + +// AddHandler reserves an identifier for an application protocol +func (n *Network) AddHandler(handlerID uint64, handler Handler) error { + return n.router.addHandler(handlerID, handler) } // Peers contains metadata about the current set of connected peers diff --git a/network/p2p/network_test.go b/network/p2p/network_test.go index 1adb25f81371..b8775c112d9c 100644 --- a/network/p2p/network_test.go +++ b/network/p2p/network_test.go @@ -63,9 +63,11 @@ func TestMessageRouting(t *testing.T) { SentAppRequest: make(chan []byte, 1), SentCrossChainAppRequest: make(chan []byte, 1), } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - client, err := network.NewAppProtocol(1, testHandler) + + network, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) + require.NoError(network.AddHandler(1, testHandler)) + client := network.NewClient(1) require.NoError(client.AppGossip(ctx, wantMsg)) require.NoError(network.AppGossip(ctx, wantNodeID, <-sender.SentAppGossip)) @@ -91,11 +93,11 @@ func TestClientPrefixesMessages(t *testing.T) { SentAppGossipSpecific: make(chan []byte, 1), SentCrossChainAppRequest: make(chan []byte, 1), } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - require.NoError(network.Connected(ctx, ids.EmptyNodeID, nil)) - client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + network, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) + require.NoError(network.Connected(ctx, ids.EmptyNodeID, nil)) + client := network.NewClient(handlerID) want := []byte("message") @@ -147,10 +149,9 @@ func TestAppRequestResponse(t *testing.T) { sender := common.FakeSender{ SentAppRequest: make(chan []byte, 1), } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - - client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + network, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) + client := network.NewClient(handlerID) wantResponse := []byte("response") wantNodeID := ids.GenerateTestNodeID() @@ -179,10 +180,9 @@ func TestAppRequestFailed(t *testing.T) { sender := common.FakeSender{ SentAppRequest: make(chan []byte, 1), } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - - client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + network, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) + client := network.NewClient(handlerID) wantNodeID := ids.GenerateTestNodeID() done := make(chan struct{}) @@ -210,10 +210,9 @@ func TestCrossChainAppRequestResponse(t *testing.T) { sender := common.FakeSender{ SentCrossChainAppRequest: make(chan []byte, 1), } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - - client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + network, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) + client := network.NewClient(handlerID) wantChainID := ids.GenerateTestID() wantResponse := []byte("response") @@ -242,10 +241,9 @@ func TestCrossChainAppRequestFailed(t *testing.T) { sender := common.FakeSender{ SentCrossChainAppRequest: make(chan []byte, 1), } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - - client, err := network.NewAppProtocol(handlerID, &NoOpHandler{}) + network, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) + client := network.NewClient(handlerID) wantChainID := ids.GenerateTestID() done := make(chan struct{}) @@ -302,9 +300,9 @@ func TestMessageForUnregisteredHandler(t *testing.T) { return nil, nil }, } - network := NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") - _, err := network.NewAppProtocol(handlerID, handler) + network, err := NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(err) + require.NoError(network.AddHandler(handlerID, handler)) require.Nil(network.AppRequest(ctx, ids.EmptyNodeID, 0, time.Time{}, tt.msg)) require.Nil(network.AppGossip(ctx, ids.EmptyNodeID, tt.msg)) @@ -350,17 +348,18 @@ func TestResponseForUnrequestedRequest(t *testing.T) { return nil, nil }, } - network := NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") - _, err := network.NewAppProtocol(handlerID, handler) + network, err := NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(err) + require.NoError(network.AddHandler(handlerID, handler)) err = network.AppResponse(ctx, ids.EmptyNodeID, 0, []byte("foobar")) require.ErrorIs(err, ErrUnrequestedResponse) - err = network.AppRequestFailed(ctx, ids.EmptyNodeID, 0, errFoo) + err = network.AppRequestFailed(ctx, ids.EmptyNodeID, 0, common.ErrTimeout) require.ErrorIs(err, ErrUnrequestedResponse) err = network.CrossChainAppResponse(ctx, ids.Empty, 0, []byte("foobar")) require.ErrorIs(err, ErrUnrequestedResponse) - err = network.CrossChainAppRequestFailed(ctx, ids.Empty, 0, errFoo) + err = network.CrossChainAppRequestFailed(ctx, ids.Empty, 0, common.ErrTimeout) + require.ErrorIs(err, ErrUnrequestedResponse) }) } @@ -377,12 +376,13 @@ func TestAppRequestDuplicateRequestIDs(t *testing.T) { SentAppRequest: make(chan []byte, 1), } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") - client, err := network.NewAppProtocol(0x1, &NoOpHandler{}) + network, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(err) + client := network.NewClient(0x1) noOpCallback := func(context.Context, ids.NodeID, []byte, error) {} // create a request that never gets a response + network.router.requestID = 1 require.NoError(client.AppRequest(ctx, set.Of(ids.EmptyNodeID), []byte{}, noOpCallback)) <-sender.SentAppRequest @@ -458,7 +458,8 @@ func TestPeersSample(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - network := NewNetwork(logging.NoLog{}, &common.FakeSender{}, prometheus.NewRegistry(), "") + network, err := NewNetwork(logging.NoLog{}, &common.FakeSender{}, prometheus.NewRegistry(), "") + require.NoError(err) for connected := range tt.connected { require.NoError(network.Connected(context.Background(), connected, nil)) @@ -507,13 +508,13 @@ func TestAppRequestAnyNodeSelection(t *testing.T) { }, } - n := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + n, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + require.NoError(err) for _, peer := range tt.peers { require.NoError(n.Connected(context.Background(), peer, &version.Application{})) } - client, err := n.NewAppProtocol(1, nil) - require.NoError(err) + client := n.NewClient(1) err = client.AppRequestAny(context.Background(), []byte("foobar"), nil) require.ErrorIs(err, tt.expected) @@ -596,14 +597,14 @@ func TestNodeSamplerClientOption(t *testing.T) { return nil }, } - network := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + network, err := NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") + require.NoError(err) ctx := context.Background() for _, peer := range tt.peers { require.NoError(network.Connected(ctx, peer, nil)) } - client, err := network.NewAppProtocol(0x0, nil, tt.option(t, network)) - require.NoError(err) + client := network.NewClient(0, tt.option(t, network)) if err = client.AppRequestAny(ctx, []byte("request"), nil); err != nil { close(done) @@ -614,3 +615,13 @@ func TestNodeSamplerClientOption(t *testing.T) { }) } } + +// Tests that a given protocol can have more than one client +func TestMultipleClients(t *testing.T) { + require := require.New(t) + + n, err := NewNetwork(logging.NoLog{}, &common.SenderTest{}, prometheus.NewRegistry(), "") + require.NoError(err) + _ = n.NewClient(0) + _ = n.NewClient(0) +} diff --git a/network/p2p/router.go b/network/p2p/router.go index 0b4eff4eb576..5c52b3d1aaa2 100644 --- a/network/p2p/router.go +++ b/network/p2p/router.go @@ -8,6 +8,7 @@ import ( "encoding/binary" "errors" "fmt" + "strconv" "sync" "time" @@ -19,7 +20,6 @@ import ( "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/utils/metric" ) var ( @@ -29,40 +29,46 @@ var ( _ common.AppHandler = (*router)(nil) ) -type metrics struct { - appRequestTime metric.Averager - appRequestFailedTime metric.Averager - appResponseTime metric.Averager - appGossipTime metric.Averager - crossChainAppRequestTime metric.Averager - crossChainAppRequestFailedTime metric.Averager - crossChainAppResponseTime metric.Averager -} - type pendingAppRequest struct { - *metrics - AppResponseCallback + handlerID string + callback AppResponseCallback } type pendingCrossChainAppRequest struct { - *metrics - CrossChainAppResponseCallback + handlerID string + callback CrossChainAppResponseCallback } // meteredHandler emits metrics for a Handler type meteredHandler struct { *responder - *metrics + metrics +} + +type metrics struct { + appRequestTime *prometheus.CounterVec + appRequestCount *prometheus.CounterVec + appResponseTime *prometheus.CounterVec + appResponseCount *prometheus.CounterVec + appRequestFailedTime *prometheus.CounterVec + appRequestFailedCount *prometheus.CounterVec + appGossipTime *prometheus.CounterVec + appGossipCount *prometheus.CounterVec + crossChainAppRequestTime *prometheus.CounterVec + crossChainAppRequestCount *prometheus.CounterVec + crossChainAppResponseTime *prometheus.CounterVec + crossChainAppResponseCount *prometheus.CounterVec + crossChainAppRequestFailedTime *prometheus.CounterVec + crossChainAppRequestFailedCount *prometheus.CounterVec } // router routes incoming application messages to the corresponding registered // app handler. App messages must be made using the registered handler's // corresponding Client. type router struct { - log logging.Logger - sender common.AppSender - metrics prometheus.Registerer - namespace string + log logging.Logger + sender common.AppSender + metrics metrics lock sync.RWMutex handlers map[uint64]*meteredHandler @@ -75,14 +81,12 @@ type router struct { func newRouter( log logging.Logger, sender common.AppSender, - metrics prometheus.Registerer, - namespace string, + metrics metrics, ) *router { return &router{ log: log, sender: sender, metrics: metrics, - namespace: namespace, handlers: make(map[uint64]*meteredHandler), pendingAppRequests: make(map[uint32]pendingAppRequest), pendingCrossChainAppRequests: make(map[uint32]pendingCrossChainAppRequest), @@ -99,76 +103,6 @@ func (r *router) addHandler(handlerID uint64, handler Handler) error { return fmt.Errorf("failed to register handler id %d: %w", handlerID, ErrExistingAppProtocol) } - appRequestTime, err := metric.NewAverager( - r.namespace, - fmt.Sprintf("handler_%d_app_request", handlerID), - "app request time (ns)", - r.metrics, - ) - if err != nil { - return fmt.Errorf("failed to register app request metric for handler_%d: %w", handlerID, err) - } - - appRequestFailedTime, err := metric.NewAverager( - r.namespace, - fmt.Sprintf("handler_%d_app_request_failed", handlerID), - "app request failed time (ns)", - r.metrics, - ) - if err != nil { - return fmt.Errorf("failed to register app request failed metric for handler_%d: %w", handlerID, err) - } - - appResponseTime, err := metric.NewAverager( - r.namespace, - fmt.Sprintf("handler_%d_app_response", handlerID), - "app response time (ns)", - r.metrics, - ) - if err != nil { - return fmt.Errorf("failed to register app response metric for handler_%d: %w", handlerID, err) - } - - appGossipTime, err := metric.NewAverager( - r.namespace, - fmt.Sprintf("handler_%d_app_gossip", handlerID), - "app gossip time (ns)", - r.metrics, - ) - if err != nil { - return fmt.Errorf("failed to register app gossip metric for handler_%d: %w", handlerID, err) - } - - crossChainAppRequestTime, err := metric.NewAverager( - r.namespace, - fmt.Sprintf("handler_%d_cross_chain_app_request", handlerID), - "cross chain app request time (ns)", - r.metrics, - ) - if err != nil { - return fmt.Errorf("failed to register cross-chain app request metric for handler_%d: %w", handlerID, err) - } - - crossChainAppRequestFailedTime, err := metric.NewAverager( - r.namespace, - fmt.Sprintf("handler_%d_cross_chain_app_request_failed", handlerID), - "app request failed time (ns)", - r.metrics, - ) - if err != nil { - return fmt.Errorf("failed to register cross-chain app request failed metric for handler_%d: %w", handlerID, err) - } - - crossChainAppResponseTime, err := metric.NewAverager( - r.namespace, - fmt.Sprintf("handler_%d_cross_chain_app_response", handlerID), - "cross chain app response time (ns)", - r.metrics, - ) - if err != nil { - return fmt.Errorf("failed to register cross-chain app response metric for handler_%d: %w", handlerID, err) - } - r.handlers[handlerID] = &meteredHandler{ responder: &responder{ Handler: handler, @@ -176,15 +110,7 @@ func (r *router) addHandler(handlerID uint64, handler Handler) error { log: r.log, sender: r.sender, }, - metrics: &metrics{ - appRequestTime: appRequestTime, - appRequestFailedTime: appRequestFailedTime, - appResponseTime: appResponseTime, - appGossipTime: appGossipTime, - crossChainAppRequestTime: crossChainAppRequestTime, - crossChainAppRequestFailedTime: crossChainAppRequestFailedTime, - crossChainAppResponseTime: crossChainAppResponseTime, - }, + metrics: r.metrics, } return nil @@ -197,7 +123,7 @@ func (r *router) addHandler(handlerID uint64, handler Handler) error { // considered fatal func (r *router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { start := time.Now() - parsedMsg, handler, ok := r.parse(request) + parsedMsg, handler, handlerID, ok := r.parse(request) if !ok { r.log.Debug("failed to process message", zap.Stringer("messageOp", message.AppRequestOp), @@ -214,7 +140,23 @@ func (r *router) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID ui return err } - handler.metrics.appRequestTime.Observe(float64(time.Since(start))) + labels := prometheus.Labels{ + handlerLabel: handlerID, + } + + metricCount, err := r.metrics.appRequestCount.GetMetricWith(labels) + if err != nil { + return err + } + + metricTime, err := r.metrics.appRequestTime.GetMetricWith(labels) + if err != nil { + return err + } + + metricCount.Inc() + metricTime.Add(float64(time.Since(start))) + return nil } @@ -231,8 +173,25 @@ func (r *router) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, reques return ErrUnrequestedResponse } - pending.AppResponseCallback(ctx, nodeID, nil, appErr) - pending.appRequestFailedTime.Observe(float64(time.Since(start))) + pending.callback(ctx, nodeID, nil, appErr) + + labels := prometheus.Labels{ + handlerLabel: pending.handlerID, + } + + metricCount, err := r.metrics.appRequestFailedCount.GetMetricWith(labels) + if err != nil { + return err + } + + metricTime, err := r.metrics.appRequestFailedTime.GetMetricWith(labels) + if err != nil { + return err + } + + metricCount.Inc() + metricTime.Add(float64(time.Since(start))) + return nil } @@ -249,8 +208,25 @@ func (r *router) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID u return ErrUnrequestedResponse } - pending.AppResponseCallback(ctx, nodeID, response, nil) - pending.appResponseTime.Observe(float64(time.Since(start))) + pending.callback(ctx, nodeID, response, nil) + + labels := prometheus.Labels{ + handlerLabel: pending.handlerID, + } + + metricCount, err := r.metrics.appResponseCount.GetMetricWith(labels) + if err != nil { + return err + } + + metricTime, err := r.metrics.appResponseTime.GetMetricWith(labels) + if err != nil { + return err + } + + metricCount.Inc() + metricTime.Add(float64(time.Since(start))) + return nil } @@ -261,7 +237,7 @@ func (r *router) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID u // considered fatal func (r *router) AppGossip(ctx context.Context, nodeID ids.NodeID, gossip []byte) error { start := time.Now() - parsedMsg, handler, ok := r.parse(gossip) + parsedMsg, handler, handlerID, ok := r.parse(gossip) if !ok { r.log.Debug("failed to process message", zap.Stringer("messageOp", message.AppGossipOp), @@ -273,7 +249,23 @@ func (r *router) AppGossip(ctx context.Context, nodeID ids.NodeID, gossip []byte handler.AppGossip(ctx, nodeID, parsedMsg) - handler.metrics.appGossipTime.Observe(float64(time.Since(start))) + labels := prometheus.Labels{ + handlerLabel: handlerID, + } + + metricCount, err := r.metrics.appGossipCount.GetMetricWith(labels) + if err != nil { + return err + } + + metricTime, err := r.metrics.appGossipTime.GetMetricWith(labels) + if err != nil { + return err + } + + metricCount.Inc() + metricTime.Add(float64(time.Since(start))) + return nil } @@ -291,7 +283,7 @@ func (r *router) CrossChainAppRequest( msg []byte, ) error { start := time.Now() - parsedMsg, handler, ok := r.parse(msg) + parsedMsg, handler, handlerID, ok := r.parse(msg) if !ok { r.log.Debug("failed to process message", zap.Stringer("messageOp", message.CrossChainAppRequestOp), @@ -307,7 +299,23 @@ func (r *router) CrossChainAppRequest( return err } - handler.metrics.crossChainAppRequestTime.Observe(float64(time.Since(start))) + labels := prometheus.Labels{ + handlerLabel: handlerID, + } + + metricCount, err := r.metrics.crossChainAppRequestCount.GetMetricWith(labels) + if err != nil { + return err + } + + metricTime, err := r.metrics.crossChainAppRequestTime.GetMetricWith(labels) + if err != nil { + return err + } + + metricCount.Inc() + metricTime.Add(float64(time.Since(start))) + return nil } @@ -324,8 +332,25 @@ func (r *router) CrossChainAppRequestFailed(ctx context.Context, chainID ids.ID, return ErrUnrequestedResponse } - pending.CrossChainAppResponseCallback(ctx, chainID, nil, appErr) - pending.crossChainAppRequestFailedTime.Observe(float64(time.Since(start))) + pending.callback(ctx, chainID, nil, appErr) + + labels := prometheus.Labels{ + handlerLabel: pending.handlerID, + } + + metricCount, err := r.metrics.crossChainAppRequestFailedCount.GetMetricWith(labels) + if err != nil { + return err + } + + metricTime, err := r.metrics.crossChainAppRequestFailedTime.GetMetricWith(labels) + if err != nil { + return err + } + + metricCount.Inc() + metricTime.Add(float64(time.Since(start))) + return nil } @@ -342,8 +367,25 @@ func (r *router) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requ return ErrUnrequestedResponse } - pending.CrossChainAppResponseCallback(ctx, chainID, response, nil) - pending.crossChainAppResponseTime.Observe(float64(time.Since(start))) + pending.callback(ctx, chainID, response, nil) + + labels := prometheus.Labels{ + handlerLabel: pending.handlerID, + } + + metricCount, err := r.metrics.crossChainAppResponseCount.GetMetricWith(labels) + if err != nil { + return err + } + + metricTime, err := r.metrics.crossChainAppResponseTime.GetMetricWith(labels) + if err != nil { + return err + } + + metricCount.Inc() + metricTime.Add(float64(time.Since(start))) + return nil } @@ -353,20 +395,22 @@ func (r *router) CrossChainAppResponse(ctx context.Context, chainID ids.ID, requ // Returns: // - The unprefixed protocol message. // - The protocol responder. +// - The protocol metric name. // - A boolean indicating that parsing succeeded. // // Invariant: Assumes [r.lock] isn't held. -func (r *router) parse(msg []byte) ([]byte, *meteredHandler, bool) { +func (r *router) parse(msg []byte) ([]byte, *meteredHandler, string, bool) { handlerID, bytesRead := binary.Uvarint(msg) if bytesRead <= 0 { - return nil, nil, false + return nil, nil, "", false } r.lock.RLock() defer r.lock.RUnlock() + handlerStr := strconv.FormatUint(handlerID, 10) handler, ok := r.handlers[handlerID] - return msg[bytesRead:], handler, ok + return msg[bytesRead:], handler, handlerStr, ok } // Invariant: Assumes [r.lock] isn't held. diff --git a/network/p2p/throttler_handler.go b/network/p2p/throttler_handler.go index 4dd142c400c1..aee5bee70795 100644 --- a/network/p2p/throttler_handler.go +++ b/network/p2p/throttler_handler.go @@ -20,25 +20,41 @@ var ( _ Handler = (*ThrottlerHandler)(nil) ) +func NewThrottlerHandler(handler Handler, throttler Throttler, log logging.Logger) *ThrottlerHandler { + return &ThrottlerHandler{ + handler: handler, + throttler: throttler, + log: log, + } +} + type ThrottlerHandler struct { - Handler - Throttler Throttler - Log logging.Logger + handler Handler + throttler Throttler + log logging.Logger } func (t ThrottlerHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { - if !t.Throttler.Handle(nodeID) { - t.Log.Debug("dropping message", zap.Stringer("nodeID", nodeID)) + if !t.throttler.Handle(nodeID) { + t.log.Debug( + "dropping message", + zap.Stringer("nodeID", nodeID), + zap.String("reason", "throttled"), + ) return } - t.Handler.AppGossip(ctx, nodeID, gossipBytes) + t.handler.AppGossip(ctx, nodeID, gossipBytes) } func (t ThrottlerHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { - if !t.Throttler.Handle(nodeID) { + if !t.throttler.Handle(nodeID) { return nil, fmt.Errorf("dropping message from %s: %w", nodeID, ErrThrottled) } - return t.Handler.AppRequest(ctx, nodeID, deadline, requestBytes) + return t.handler.AppRequest(ctx, nodeID, deadline, requestBytes) +} + +func (t ThrottlerHandler) CrossChainAppRequest(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) { + return t.handler.CrossChainAppRequest(ctx, chainID, deadline, requestBytes) } diff --git a/network/p2p/throttler_handler_test.go b/network/p2p/throttler_handler_test.go index 1e4ed9578bf6..79b1dc88665d 100644 --- a/network/p2p/throttler_handler_test.go +++ b/network/p2p/throttler_handler_test.go @@ -37,15 +37,15 @@ func TestThrottlerHandlerAppGossip(t *testing.T) { require := require.New(t) called := false - handler := ThrottlerHandler{ - Handler: testHandler{ + handler := NewThrottlerHandler( + testHandler{ appGossipF: func(context.Context, ids.NodeID, []byte) { called = true }, }, - Throttler: tt.Throttler, - Log: logging.NoLog{}, - } + tt.Throttler, + logging.NoLog{}, + ) handler.AppGossip(context.Background(), ids.GenerateTestNodeID(), []byte("foobar")) require.Equal(tt.expected, called) @@ -73,11 +73,11 @@ func TestThrottlerHandlerAppRequest(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - handler := ThrottlerHandler{ - Handler: NoOpHandler{}, - Throttler: tt.Throttler, - Log: logging.NoLog{}, - } + handler := NewThrottlerHandler( + NoOpHandler{}, + tt.Throttler, + logging.NoLog{}, + ) _, err := handler.AppRequest(context.Background(), ids.GenerateTestNodeID(), time.Time{}, []byte("foobar")) require.ErrorIs(err, tt.expectedErr) }) diff --git a/network/p2p/validators_test.go b/network/p2p/validators_test.go index d1ce9dd1735e..9e90242e201d 100644 --- a/network/p2p/validators_test.go +++ b/network/p2p/validators_test.go @@ -179,7 +179,9 @@ func TestValidatorsSample(t *testing.T) { } gomock.InOrder(calls...) - network := NewNetwork(logging.NoLog{}, &common.FakeSender{}, prometheus.NewRegistry(), "") + network, err := NewNetwork(logging.NoLog{}, &common.FakeSender{}, prometheus.NewRegistry(), "") + require.NoError(err) + ctx := context.Background() require.NoError(network.Connected(ctx, nodeID1, nil)) require.NoError(network.Connected(ctx, nodeID2, nil)) @@ -187,7 +189,7 @@ func TestValidatorsSample(t *testing.T) { v := NewValidators(network.Peers, network.log, subnetID, mockValidators, tt.maxStaleness) for _, call := range tt.calls { v.lastUpdated = call.time - sampled := v.Sample(context.Background(), call.limit) + sampled := v.Sample(ctx, call.limit) require.LessOrEqual(len(sampled), call.limit) require.Subset(call.expected, sampled) } From 1461137996419d70cee5bdd2f78747c3da89d4d9 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 13 Dec 2023 00:22:02 -0500 Subject: [PATCH 142/267] Cleanup CI (#2480) Co-authored-by: Stephen Buttolph --- .github/workflows/auto-generated-checker.yml | 53 ------ .github/workflows/buf-lint.yml | 27 --- .github/workflows/build-linux-binaries.yml | 7 +- .../workflows/build-ubuntu-amd64-release.yml | 7 +- .../workflows/build-ubuntu-arm64-release.yml | 7 +- .github/workflows/ci.yml | 180 ++++++++++++++++++ .github/workflows/static-analysis.yml | 27 --- .github/workflows/test.e2e.existing.yml | 39 ---- .github/workflows/test.e2e.yml | 39 ---- .github/workflows/test.unit.yml | 44 ----- .github/workflows/test.upgrade.yml | 41 ---- 11 files changed, 195 insertions(+), 276 deletions(-) delete mode 100644 .github/workflows/auto-generated-checker.yml delete mode 100644 .github/workflows/buf-lint.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/static-analysis.yml delete mode 100644 .github/workflows/test.e2e.existing.yml delete mode 100644 .github/workflows/test.e2e.yml delete mode 100644 .github/workflows/test.unit.yml delete mode 100644 .github/workflows/test.upgrade.yml diff --git a/.github/workflows/auto-generated-checker.yml b/.github/workflows/auto-generated-checker.yml deleted file mode 100644 index cca52dfa382a..000000000000 --- a/.github/workflows/auto-generated-checker.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Auto-Generated Code Checker -on: - push: - tags: - - "*" - branches: - - master - - dev - pull_request: - merge_group: - types: [checks_requested] - -jobs: - protobuf_codegen: - name: Protobuf - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: '~1.20.12' - check-latest: true - - uses: bufbuild/buf-setup-action@v1.26.1 - - shell: bash - run: scripts/protobuf_codegen.sh - - shell: bash - run: .github/workflows/check-clean-branch.sh - mock_gen: - name: Mocks - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: '~1.20.12' - check-latest: true - - shell: bash - run: scripts/mock.gen.sh - - shell: bash - run: .github/workflows/check-clean-branch.sh - go_mod_tidy: - name: go mod tidy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: '~1.20.12' - check-latest: true - - shell: bash - run: go mod tidy - - shell: bash - run: .github/workflows/check-clean-branch.sh diff --git a/.github/workflows/buf-lint.yml b/.github/workflows/buf-lint.yml deleted file mode 100644 index 5665842e2fff..000000000000 --- a/.github/workflows/buf-lint.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Lint proto files - -on: - push: - tags: - - "*" - branches: - - master - - dev - pull_request: - merge_group: - types: [checks_requested] - -permissions: - contents: read - -jobs: - buf-lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: bufbuild/buf-setup-action@v1.26.1 - with: - github_token: ${{ github.token }} - - uses: bufbuild/buf-lint-action@v1 - with: - input: "proto" diff --git a/.github/workflows/build-linux-binaries.yml b/.github/workflows/build-linux-binaries.yml index 7053379ef508..e9c0bfde74be 100644 --- a/.github/workflows/build-linux-binaries.yml +++ b/.github/workflows/build-linux-binaries.yml @@ -10,6 +10,9 @@ on: tags: - "*" +env: + go_version: '~1.20.12' + jobs: build-x86_64-binaries-tarball: runs-on: ubuntu-20.04 @@ -19,7 +22,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: '~1.20.12' + go-version: ${{ env.go_version }} check-latest: true - run: go version @@ -81,7 +84,7 @@ jobs: - uses: actions/setup-go@v3 with: - go-version: '~1.20.12' + go-version: ${{ env.go_version }} check-latest: true - run: go version diff --git a/.github/workflows/build-ubuntu-amd64-release.yml b/.github/workflows/build-ubuntu-amd64-release.yml index 640cff56a53f..627d696e412b 100644 --- a/.github/workflows/build-ubuntu-amd64-release.yml +++ b/.github/workflows/build-ubuntu-amd64-release.yml @@ -10,6 +10,9 @@ on: tags: - "*" +env: + go_version: '~1.20.12' + jobs: build-jammy-amd64-package: runs-on: ubuntu-22.04 @@ -18,7 +21,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.12' + go-version: ${{ env.go_version }} check-latest: true - run: go version @@ -78,7 +81,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.12' + go-version: ${{ env.go_version }} check-latest: true - run: go version diff --git a/.github/workflows/build-ubuntu-arm64-release.yml b/.github/workflows/build-ubuntu-arm64-release.yml index ac660b8cd678..054cd4f2c827 100644 --- a/.github/workflows/build-ubuntu-arm64-release.yml +++ b/.github/workflows/build-ubuntu-arm64-release.yml @@ -10,6 +10,9 @@ on: tags: - "*" +env: + go_version: '~1.20.12' + jobs: build-jammy-arm64-package: runs-on: [self-hosted, linux, ARM64, jammy] @@ -18,7 +21,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.12' + go-version: ${{ env.go_version }} check-latest: true - run: go version @@ -78,7 +81,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.20.12' + go-version: ${{ env.go_version }} check-latest: true - run: go version diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000000..5d15e973748e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,180 @@ +name: Tests + +on: + push: + tags: + - "*" + branches: + - master + - dev + pull_request: + merge_group: + types: [checks_requested] + +permissions: + contents: read + +# Cancel ongoing workflow runs if a new one is started +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + go_version: '~1.20.12' + +jobs: + Unit: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [macos-12, ubuntu-20.04, ubuntu-22.04, windows-2022, [self-hosted, linux, ARM64, focal], [self-hosted, linux, ARM64, jammy]] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - name: Set timeout on Windows # Windows UT run slower and need a longer timeout + shell: bash + if: matrix.os == 'windows-2022' + run: echo "TIMEOUT=240s" >> $GITHUB_ENV + - name: build_test + shell: bash + run: ./scripts/build_test.sh + env: + TIMEOUT: ${{ env.TIMEOUT }} + Fuzz: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - name: fuzz_test + shell: bash + run: ./scripts/build_fuzz.sh 15 # Run each fuzz test 15 seconds + e2e: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - name: Build AvalancheGo Binary + shell: bash + run: ./scripts/build.sh -r + - name: Run e2e tests + shell: bash + run: E2E_SERIAL=1 ./scripts/tests.e2e.sh + - name: Upload tmpnet network dir + uses: actions/upload-artifact@v3 + if: always() + with: + name: e2e-artifact + path: ~/.tmpnet/networks/1000 + e2e_existing_network: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - name: Build AvalancheGo Binary + shell: bash + run: ./scripts/build.sh -r + - name: Run e2e tests with existing network + shell: bash + run: E2E_SERIAL=1 ./scripts/tests.e2e.existing.sh + - name: Upload tmpnet network dir + uses: actions/upload-artifact@v3 + if: always() + with: + name: e2e-existing-network-tmpnet-artifact + path: ~/.tmpnet/networks/1000 + Upgrade: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - name: Build AvalancheGo Binary + shell: bash + run: ./scripts/build.sh + - name: Run e2e tests + shell: bash + # 1.10.7 is the first version compatible with the ephnet fixture by + # virtue of writing a process context file on node start. + run: ./scripts/tests.upgrade.sh 1.10.7 + - name: Upload ephnet network dir + uses: actions/upload-artifact@v3 + if: always() + with: + name: upgrade-artifact + path: ~/.ephnet/networks/1000 + Lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - name: Run static analysis tests + shell: bash + run: scripts/lint.sh + buf-lint: + name: Protobuf Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: bufbuild/buf-setup-action@v1.26.1 + with: + github_token: ${{ github.token }} + - uses: bufbuild/buf-lint-action@v1 + with: + input: "proto" + check_generated_protobuf: + name: Up-to-date protobuf + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - uses: bufbuild/buf-setup-action@v1.26.1 + - shell: bash + run: scripts/protobuf_codegen.sh + - shell: bash + run: .github/workflows/check-clean-branch.sh + check_mockgen: + name: Up-to-date mocks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - shell: bash + run: scripts/mock.gen.sh + - shell: bash + run: .github/workflows/check-clean-branch.sh + go_mod_tidy: + name: Up-to-date go.mod and go.sum + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.go_version }} + check-latest: true + - shell: bash + run: go mod tidy + - shell: bash + run: .github/workflows/check-clean-branch.sh diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml deleted file mode 100644 index 81f488a55ef3..000000000000 --- a/.github/workflows/static-analysis.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Static analysis -on: - push: - tags: - - "*" - branches: - - master - - dev - pull_request: - merge_group: - types: [checks_requested] - -jobs: - run_static_analysis: - name: Static analysis - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '~1.20.12' - check-latest: true - - name: Run static analysis tests - shell: bash - run: scripts/lint.sh diff --git a/.github/workflows/test.e2e.existing.yml b/.github/workflows/test.e2e.existing.yml deleted file mode 100644 index c00a328610d1..000000000000 --- a/.github/workflows/test.e2e.existing.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Test e2e with existing network - -on: - push: - tags: - - "*" - branches: - - master - - dev - pull_request: - merge_group: - types: [checks_requested] - -permissions: - contents: read - -jobs: - test_e2e_existing: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '~1.20.12' - check-latest: true - - name: Build the avalanchego binary - shell: bash - run: ./scripts/build.sh -r - - name: Run e2e tests with existing network - shell: bash - run: E2E_SERIAL=1 ./scripts/tests.e2e.existing.sh - - name: Upload tmpnet network dir - uses: actions/upload-artifact@v3 - if: always() - with: - name: tmpnet-data - path: ~/.tmpnet/networks/1000 diff --git a/.github/workflows/test.e2e.yml b/.github/workflows/test.e2e.yml deleted file mode 100644 index 2f8e30156f72..000000000000 --- a/.github/workflows/test.e2e.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Test e2e - -on: - push: - tags: - - "*" - branches: - - master - - dev - pull_request: - merge_group: - types: [checks_requested] - -permissions: - contents: read - -jobs: - test_e2e: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '~1.20.12' - check-latest: true - - name: Build the avalanchego binary - shell: bash - run: ./scripts/build.sh -r - - name: Run e2e tests - shell: bash - run: E2E_SERIAL=1 ./scripts/tests.e2e.sh - - name: Upload tmpnet network dir - uses: actions/upload-artifact@v3 - if: always() - with: - name: tmpnet-data - path: ~/.tmpnet/networks/1000 diff --git a/.github/workflows/test.unit.yml b/.github/workflows/test.unit.yml deleted file mode 100644 index dc766f07484f..000000000000 --- a/.github/workflows/test.unit.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Unit Tests - -on: - push: - tags: - - "*" - branches: - - master - - dev - pull_request: - merge_group: - types: [checks_requested] - -# Cancel ongoing workflow runs if a new one is started -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - unit_tests: - name: unit_tests - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [macos-12, ubuntu-20.04, ubuntu-22.04, windows-2022, [self-hosted, linux, ARM64, focal], [self-hosted, linux, ARM64, jammy]] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v3 - with: - go-version: '~1.20.12' - check-latest: true - - name: Set timeout on Windows # Windows UT run slower and need a longer timeout - shell: bash - if: matrix.os == 'windows-2022' - run: echo "TIMEOUT=240s" >> $GITHUB_ENV - - name: build_test - shell: bash - run: ./scripts/build_test.sh - env: - TIMEOUT: ${{ env.TIMEOUT }} - - name: fuzz_test - shell: bash - if: matrix.os == 'ubuntu-22.04' # Only run on Ubuntu 22.04 - run: ./scripts/build_fuzz.sh 15 # Run each fuzz test 15 seconds diff --git a/.github/workflows/test.upgrade.yml b/.github/workflows/test.upgrade.yml deleted file mode 100644 index 8f8ec5fc35ed..000000000000 --- a/.github/workflows/test.upgrade.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Test upgrade - -on: - push: - tags: - - "*" - branches: - - master - - dev - pull_request: - merge_group: - types: [checks_requested] - -permissions: - contents: read - -jobs: - test_upgrade: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '~1.20.12' - check-latest: true - - name: Build the avalanchego binary - shell: bash - run: ./scripts/build.sh - - name: Run upgrade tests - shell: bash - # 1.10.7 is the first version compatible with the ephnet fixture by - # virtue of writing a process context file on node start. - run: ./scripts/tests.upgrade.sh 1.10.7 - - name: Upload ephnet network dir - uses: actions/upload-artifact@v3 - if: always() - with: - name: ephnet-data - path: ~/.ephnet/networks/1000 From 36fbe548bec32b9aa1d573a3439bb3743a52480a Mon Sep 17 00:00:00 2001 From: marun Date: Wed, 13 Dec 2023 11:00:47 -0800 Subject: [PATCH 143/267] Ensure upgrade test uses the correct binary on restart (#2478) --- .github/workflows/ci.yml | 22 ++++++++++++---------- scripts/tests.upgrade.sh | 13 ++++++++++--- tests/upgrade/upgrade_test.go | 4 +++- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d15e973748e..46ef21af2140 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ concurrency: env: go_version: '~1.20.12' + tmpnet_data_path: ~/.tmpnet/networks/1000 jobs: Unit: @@ -72,8 +73,9 @@ jobs: uses: actions/upload-artifact@v3 if: always() with: - name: e2e-artifact - path: ~/.tmpnet/networks/1000 + name: e2e-tmpnet-data + path: ${{ env.tmpnet_data_path }} + if-no-files-found: error e2e_existing_network: runs-on: ubuntu-latest steps: @@ -92,8 +94,9 @@ jobs: uses: actions/upload-artifact@v3 if: always() with: - name: e2e-existing-network-tmpnet-artifact - path: ~/.tmpnet/networks/1000 + name: e2e-existing-network-tmpnet-data + path: ${{ env.tmpnet_data_path }} + if-no-files-found: error Upgrade: runs-on: ubuntu-latest steps: @@ -107,15 +110,14 @@ jobs: run: ./scripts/build.sh - name: Run e2e tests shell: bash - # 1.10.7 is the first version compatible with the ephnet fixture by - # virtue of writing a process context file on node start. - run: ./scripts/tests.upgrade.sh 1.10.7 - - name: Upload ephnet network dir + run: ./scripts/tests.upgrade.sh + - name: Upload tmpnet network dir uses: actions/upload-artifact@v3 if: always() with: - name: upgrade-artifact - path: ~/.ephnet/networks/1000 + name: upgrade-tmpnet-data + path: ${{ env.tmpnet_data_path }} + if-no-files-found: error Lint: runs-on: ubuntu-latest steps: diff --git a/scripts/tests.upgrade.sh b/scripts/tests.upgrade.sh index 34d5617bd128..8b274180cd12 100755 --- a/scripts/tests.upgrade.sh +++ b/scripts/tests.upgrade.sh @@ -3,14 +3,21 @@ set -euo pipefail # e.g., -# ./scripts/tests.upgrade.sh 1.7.16 -# AVALANCHEGO_PATH=./path/to/avalanchego ./scripts/tests.upgrade.sh 1.7.16 # Customization of avalanchego path +# ./scripts/tests.upgrade.sh # Use default version +# ./scripts/tests.upgrade.sh 1.10.18 # Specify a version +# AVALANCHEGO_PATH=./path/to/avalanchego ./scripts/tests.upgrade.sh 1.10.18 # Customization of avalanchego path if ! [[ "$0" =~ scripts/tests.upgrade.sh ]]; then echo "must be run from repository root" exit 255 fi -VERSION="${1:-}" +# 1.10.17 is the first version compatible with bls signing keys being +# included in the genesis. Attempting to upgrade from prior versions +# will result in nodes failing to boot due to the hash of the genesis +# not matching the hash of the committed genesis block. +DEFAULT_VERSION="1.10.17" + +VERSION="${1:-${DEFAULT_VERSION}}" if [[ -z "${VERSION}" ]]; then echo "Missing version argument!" echo "Usage: ${0} [VERSION]" >>/dev/stderr diff --git a/tests/upgrade/upgrade_test.go b/tests/upgrade/upgrade_test.go index b8f8147c831a..97a57a34b6a0 100644 --- a/tests/upgrade/upgrade_test.go +++ b/tests/upgrade/upgrade_test.go @@ -69,7 +69,9 @@ var _ = ginkgo.Describe("[Upgrade]", func() { node.Flags[config.BootstrapIPsKey] = strings.Join(bootstrapIPs, ",") require.NoError(node.WriteConfig()) - require.NoError(node.Start(ginkgo.GinkgoWriter, avalancheGoExecPath)) + // Ensure the new node starts with the upgrade binary + node.ExecPath = avalancheGoExecPathToUpgradeTo + require.NoError(node.Start(ginkgo.GinkgoWriter, "" /* defaultExecPath */)) ginkgo.By(fmt.Sprintf("waiting for node %q to report healthy after restart", node.GetID())) e2e.WaitForHealthy(node) From f69d68fea0572a3b3ef306b690881cd9f90613c1 Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Wed, 13 Dec 2023 14:03:24 -0500 Subject: [PATCH 144/267] Prefetch Improvement (#2435) Signed-off-by: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Co-authored-by: Dan Laine --- x/merkledb/db.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 4e70c02fbd8f..bcc8a2a803f2 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -481,9 +481,17 @@ func (db *merkleDB) PrefetchPath(key []byte) error { func (db *merkleDB) prefetchPath(view *trieView, keyBytes []byte) error { return view.visitPathToKey(ToKey(keyBytes), func(n *node) error { if !n.hasValue() { + // this value is already in the cache, so skip writing + // to avoid grabbing the cache write lock + if _, ok := db.intermediateNodeDB.nodeCache.Get(n.key); ok { + return nil + } return db.intermediateNodeDB.nodeCache.Put(n.key, n) } - + // this value is already in the cache, so skip writing + if _, ok := db.valueNodeDB.nodeCache.Get(n.key); ok { + return nil + } db.valueNodeDB.nodeCache.Put(n.key, n) return nil }) From bf0cc440c200e5d83aeef32e21c3ac0b98109462 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 13 Dec 2023 15:03:56 -0500 Subject: [PATCH 145/267] ci: run each fuzz test for 10 seconds (#2483) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 46ef21af2140..f81c05786ef9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,7 @@ jobs: check-latest: true - name: fuzz_test shell: bash - run: ./scripts/build_fuzz.sh 15 # Run each fuzz test 15 seconds + run: ./scripts/build_fuzz.sh 10 # Run each fuzz test 10 seconds e2e: runs-on: ubuntu-latest steps: From 61deacca7e3316a96507ae183967651b7c0660e6 Mon Sep 17 00:00:00 2001 From: Cesar <137245636+nytzuga@users.noreply.github.com> Date: Wed, 13 Dec 2023 18:31:45 -0300 Subject: [PATCH 146/267] Remove nullable options (#2481) Co-authored-by: Stephen Buttolph --- codec/reflectcodec/struct_fielder.go | 15 +--- codec/reflectcodec/type_codec.go | 117 ++++++++------------------ codec/reflectcodec/type_codec_test.go | 30 ------- codec/test_codec.go | 93 +++----------------- 4 files changed, 46 insertions(+), 209 deletions(-) delete mode 100644 codec/reflectcodec/type_codec_test.go diff --git a/codec/reflectcodec/struct_fielder.go b/codec/reflectcodec/struct_fielder.go index d266b60a3ebf..2fa9133b7d02 100644 --- a/codec/reflectcodec/struct_fielder.go +++ b/codec/reflectcodec/struct_fielder.go @@ -18,10 +18,6 @@ const ( // TagValue is the value the tag must have to be serialized. TagValue = "true" - - // TagValue is the value the tag must have to be serialized, this variant - // includes the nullable option - TagWithNullableValue = "true,nullable" ) var _ StructFielder = (*structFielder)(nil) @@ -29,7 +25,6 @@ var _ StructFielder = (*structFielder)(nil) type FieldDesc struct { Index int MaxSliceLen uint32 - Nullable bool } // StructFielder handles discovery of serializable fields in a struct. @@ -89,17 +84,10 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error) // any tag with the right value var ( captureField bool - nullable bool ) for _, tag := range s.tags { - switch field.Tag.Get(tag) { - case TagValue: - captureField = true - case TagWithNullableValue: + if field.Tag.Get(tag) == TagValue { captureField = true - nullable = true - } - if captureField { break } } @@ -121,7 +109,6 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error) serializedFields = append(serializedFields, FieldDesc{ Index: i, MaxSliceLen: maxSliceLen, - Nullable: nullable, }) } s.serializedFieldIndices[t] = serializedFields // cache result diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index 6f18f8500272..9ff06a9eba4d 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -90,16 +90,14 @@ func (c *genericCodec) Size(value interface{}) (int, error) { return 0, errMarshalNil // can't marshal nil } - size, _, err := c.size(reflect.ValueOf(value), false /*=nullable*/, nil /*=typeStack*/) + size, _, err := c.size(reflect.ValueOf(value), nil /*=typeStack*/) return size, err } // size returns the size of the value along with whether the value is constant -// sized. This function takes into account a `nullable` property which allows -// pointers and interfaces to serialize nil values +// sized. func (c *genericCodec) size( value reflect.Value, - nullable bool, typeStack set.Set[reflect.Type], ) (int, bool, error) { switch valueKind := value.Kind(); valueKind { @@ -125,24 +123,14 @@ func (c *genericCodec) size( return wrappers.StringLen(value.String()), false, nil case reflect.Ptr: if value.IsNil() { - if !nullable { - return 0, false, errMarshalNil - } - return wrappers.BoolLen, false, nil + return 0, false, errMarshalNil } - size, constSize, err := c.size(value.Elem(), false /*=nullable*/, typeStack) - if nullable { - return wrappers.BoolLen + size, false, err - } - return size, constSize, err + return c.size(value.Elem(), typeStack) case reflect.Interface: if value.IsNil() { - if !nullable { - return 0, false, errMarshalNil - } - return wrappers.BoolLen, false, nil + return 0, false, errMarshalNil } underlyingValue := value.Interface() @@ -153,12 +141,9 @@ func (c *genericCodec) size( typeStack.Add(underlyingType) prefixSize := c.typer.PrefixSize(underlyingType) - valueSize, _, err := c.size(value.Elem(), false /*=nullable*/, typeStack) + valueSize, _, err := c.size(value.Elem(), typeStack) typeStack.Remove(underlyingType) - if nullable { - return wrappers.BoolLen + prefixSize + valueSize, false, err - } return prefixSize + valueSize, false, err case reflect.Slice: @@ -167,7 +152,7 @@ func (c *genericCodec) size( return wrappers.IntLen, false, nil } - size, constSize, err := c.size(value.Index(0), nullable, typeStack) + size, constSize, err := c.size(value.Index(0), typeStack) if err != nil { return 0, false, err } @@ -179,7 +164,7 @@ func (c *genericCodec) size( } for i := 1; i < numElts; i++ { - innerSize, _, err := c.size(value.Index(i), nullable, typeStack) + innerSize, _, err := c.size(value.Index(i), typeStack) if err != nil { return 0, false, err } @@ -193,7 +178,7 @@ func (c *genericCodec) size( return 0, true, nil } - size, constSize, err := c.size(value.Index(0), nullable, typeStack) + size, constSize, err := c.size(value.Index(0), typeStack) if err != nil { return 0, false, err } @@ -205,7 +190,7 @@ func (c *genericCodec) size( } for i := 1; i < numElts; i++ { - innerSize, _, err := c.size(value.Index(i), nullable, typeStack) + innerSize, _, err := c.size(value.Index(i), typeStack) if err != nil { return 0, false, err } @@ -224,7 +209,7 @@ func (c *genericCodec) size( constSize = true ) for _, fieldDesc := range serializedFields { - innerSize, innerConstSize, err := c.size(value.Field(fieldDesc.Index), fieldDesc.Nullable, typeStack) + innerSize, innerConstSize, err := c.size(value.Field(fieldDesc.Index), typeStack) if err != nil { return 0, false, err } @@ -239,11 +224,11 @@ func (c *genericCodec) size( return wrappers.IntLen, false, nil } - keySize, keyConstSize, err := c.size(iter.Key(), false /*=nullable*/, typeStack) + keySize, keyConstSize, err := c.size(iter.Key(), typeStack) if err != nil { return 0, false, err } - valueSize, valueConstSize, err := c.size(iter.Value(), nullable, typeStack) + valueSize, valueConstSize, err := c.size(iter.Value(), typeStack) if err != nil { return 0, false, err } @@ -258,7 +243,7 @@ func (c *genericCodec) size( totalValueSize = valueSize ) for iter.Next() { - valueSize, _, err := c.size(iter.Value(), nullable, typeStack) + valueSize, _, err := c.size(iter.Value(), typeStack) if err != nil { return 0, false, err } @@ -272,7 +257,7 @@ func (c *genericCodec) size( totalKeySize = keySize ) for iter.Next() { - keySize, _, err := c.size(iter.Key(), false /*=nullable*/, typeStack) + keySize, _, err := c.size(iter.Key(), typeStack) if err != nil { return 0, false, err } @@ -283,11 +268,11 @@ func (c *genericCodec) size( default: totalSize := wrappers.IntLen + keySize + valueSize for iter.Next() { - keySize, _, err := c.size(iter.Key(), false /*=nullable*/, typeStack) + keySize, _, err := c.size(iter.Key(), typeStack) if err != nil { return 0, false, err } - valueSize, _, err := c.size(iter.Value(), nullable, typeStack) + valueSize, _, err := c.size(iter.Value(), typeStack) if err != nil { return 0, false, err } @@ -307,7 +292,7 @@ func (c *genericCodec) MarshalInto(value interface{}, p *wrappers.Packer) error return errMarshalNil // can't marshal nil } - return c.marshal(reflect.ValueOf(value), p, c.maxSliceLen, false /*=nullable*/, nil /*=typeStack*/) + return c.marshal(reflect.ValueOf(value), p, c.maxSliceLen, nil /*=typeStack*/) } // marshal writes the byte representation of [value] to [p] @@ -317,7 +302,6 @@ func (c *genericCodec) marshal( value reflect.Value, p *wrappers.Packer, maxSliceLen uint32, - nullable bool, typeStack set.Set[reflect.Type], ) error { switch valueKind := value.Kind(); valueKind { @@ -352,25 +336,13 @@ func (c *genericCodec) marshal( p.PackBool(value.Bool()) return p.Err case reflect.Ptr: - isNil := value.IsNil() - if nullable { - p.PackBool(isNil) - if isNil || p.Err != nil { - return p.Err - } - } else if isNil { + if value.IsNil() { return errMarshalNil } - return c.marshal(value.Elem(), p, c.maxSliceLen, false /*=nullable*/, typeStack) + return c.marshal(value.Elem(), p, c.maxSliceLen, typeStack) case reflect.Interface: - isNil := value.IsNil() - if nullable { - p.PackBool(isNil) - if isNil || p.Err != nil { - return p.Err - } - } else if isNil { + if value.IsNil() { return errMarshalNil } @@ -383,7 +355,7 @@ func (c *genericCodec) marshal( if err := c.typer.PackPrefix(p, underlyingType); err != nil { return err } - if err := c.marshal(value.Elem(), p, c.maxSliceLen, false /*=nullable*/, typeStack); err != nil { + if err := c.marshal(value.Elem(), p, c.maxSliceLen, typeStack); err != nil { return err } typeStack.Remove(underlyingType) @@ -414,7 +386,7 @@ func (c *genericCodec) marshal( return p.Err } for i := 0; i < numElts; i++ { // Process each element in the slice - if err := c.marshal(value.Index(i), p, c.maxSliceLen, nullable, typeStack); err != nil { + if err := c.marshal(value.Index(i), p, c.maxSliceLen, typeStack); err != nil { return err } } @@ -434,7 +406,7 @@ func (c *genericCodec) marshal( ) } for i := 0; i < numElts; i++ { // Process each element in the array - if err := c.marshal(value.Index(i), p, c.maxSliceLen, nullable, typeStack); err != nil { + if err := c.marshal(value.Index(i), p, c.maxSliceLen, typeStack); err != nil { return err } } @@ -445,7 +417,7 @@ func (c *genericCodec) marshal( return err } for _, fieldDesc := range serializedFields { // Go through all fields of this struct that are serialized - if err := c.marshal(value.Field(fieldDesc.Index), p, fieldDesc.MaxSliceLen, fieldDesc.Nullable, typeStack); err != nil { // Serialize the field and write to byte array + if err := c.marshal(value.Field(fieldDesc.Index), p, fieldDesc.MaxSliceLen, typeStack); err != nil { // Serialize the field and write to byte array return err } } @@ -476,7 +448,7 @@ func (c *genericCodec) marshal( startOffset := p.Offset endOffset := p.Offset for i, key := range keys { - if err := c.marshal(key, p, c.maxSliceLen, false /*=nullable*/, typeStack); err != nil { + if err := c.marshal(key, p, c.maxSliceLen, typeStack); err != nil { return err } if p.Err != nil { @@ -509,7 +481,7 @@ func (c *genericCodec) marshal( } // serialize and pack value - if err := c.marshal(value.MapIndex(key.key), p, c.maxSliceLen, nullable, typeStack); err != nil { + if err := c.marshal(value.MapIndex(key.key), p, c.maxSliceLen, typeStack); err != nil { return err } } @@ -534,7 +506,7 @@ func (c *genericCodec) Unmarshal(bytes []byte, dest interface{}) error { if destPtr.Kind() != reflect.Ptr { return errNeedPointer } - if err := c.unmarshal(&p, destPtr.Elem(), c.maxSliceLen, false /*=nullable*/, nil /*=typeStack*/); err != nil { + if err := c.unmarshal(&p, destPtr.Elem(), c.maxSliceLen, nil /*=typeStack*/); err != nil { return err } if p.Offset != len(bytes) { @@ -549,16 +521,11 @@ func (c *genericCodec) Unmarshal(bytes []byte, dest interface{}) error { // Unmarshal from p.Bytes into [value]. [value] must be addressable. // -// The [nullable] property affects how pointers and interfaces are unmarshalled, -// as an extra byte would be used to unmarshal nil values for pointers and -// interaces -// // c.lock should be held for the duration of this function func (c *genericCodec) unmarshal( p *wrappers.Packer, value reflect.Value, maxSliceLen uint32, - nullable bool, typeStack set.Set[reflect.Type], ) error { switch value.Kind() { @@ -651,7 +618,7 @@ func (c *genericCodec) unmarshal( zeroValue := reflect.Zero(innerType) for i := 0; i < numElts; i++ { value.Set(reflect.Append(value, zeroValue)) - if err := c.unmarshal(p, value.Index(i), c.maxSliceLen, nullable, typeStack); err != nil { + if err := c.unmarshal(p, value.Index(i), c.maxSliceLen, typeStack); err != nil { return err } } @@ -669,7 +636,7 @@ func (c *genericCodec) unmarshal( return nil } for i := 0; i < numElts; i++ { - if err := c.unmarshal(p, value.Index(i), c.maxSliceLen, nullable, typeStack); err != nil { + if err := c.unmarshal(p, value.Index(i), c.maxSliceLen, typeStack); err != nil { return err } } @@ -681,13 +648,6 @@ func (c *genericCodec) unmarshal( } return nil case reflect.Interface: - if nullable { - isNil := p.UnpackBool() - if isNil || p.Err != nil { - return p.Err - } - } - intfImplementor, err := c.typer.UnpackPrefix(p, value.Type()) if err != nil { return err @@ -699,7 +659,7 @@ func (c *genericCodec) unmarshal( typeStack.Add(intfImplementorType) // Unmarshal into the struct - if err := c.unmarshal(p, intfImplementor, c.maxSliceLen, false /*=nullable*/, typeStack); err != nil { + if err := c.unmarshal(p, intfImplementor, c.maxSliceLen, typeStack); err != nil { return err } @@ -714,25 +674,18 @@ func (c *genericCodec) unmarshal( } // Go through the fields and umarshal into them for _, fieldDesc := range serializedFieldIndices { - if err := c.unmarshal(p, value.Field(fieldDesc.Index), fieldDesc.MaxSliceLen, fieldDesc.Nullable, typeStack); err != nil { + if err := c.unmarshal(p, value.Field(fieldDesc.Index), fieldDesc.MaxSliceLen, typeStack); err != nil { return err } } return nil case reflect.Ptr: - if nullable { - isNil := p.UnpackBool() - if isNil || p.Err != nil { - return p.Err - } - } - // Get the type this pointer points to t := value.Type().Elem() // Create a new pointer to a new value of the underlying type v := reflect.New(t) // Fill the value - if err := c.unmarshal(p, v.Elem(), c.maxSliceLen, false /*=nullable*/, typeStack); err != nil { + if err := c.unmarshal(p, v.Elem(), c.maxSliceLen, typeStack); err != nil { return err } // Assign to the top-level struct's member @@ -767,7 +720,7 @@ func (c *genericCodec) unmarshal( keyStartOffset := p.Offset - if err := c.unmarshal(p, mapKey, c.maxSliceLen, false /*=nullable*/, typeStack); err != nil { + if err := c.unmarshal(p, mapKey, c.maxSliceLen, typeStack); err != nil { return err } @@ -785,7 +738,7 @@ func (c *genericCodec) unmarshal( // Get the value mapValue := reflect.New(mapValueType).Elem() - if err := c.unmarshal(p, mapValue, c.maxSliceLen, nullable, typeStack); err != nil { + if err := c.unmarshal(p, mapValue, c.maxSliceLen, typeStack); err != nil { return err } diff --git a/codec/reflectcodec/type_codec_test.go b/codec/reflectcodec/type_codec_test.go deleted file mode 100644 index 42b256c4a6c9..000000000000 --- a/codec/reflectcodec/type_codec_test.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package reflectcodec - -import ( - "reflect" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestSizeWithNil(t *testing.T) { - require := require.New(t) - var x *int32 - y := int32(1) - c := genericCodec{} - _, _, err := c.size(reflect.ValueOf(x), false /*=nullable*/, nil /*=typeStack*/) - require.ErrorIs(err, errMarshalNil) - len, _, err := c.size(reflect.ValueOf(x), true /*=nullable*/, nil /*=typeStack*/) - require.Empty(err) - require.Equal(1, len) - x = &y - len, _, err = c.size(reflect.ValueOf(y), true /*=nullable*/, nil /*=typeStack*/) - require.Empty(err) - require.Equal(4, len) - len, _, err = c.size(reflect.ValueOf(x), true /*=nullable*/, nil /*=typeStack*/) - require.Empty(err) - require.Equal(5, len) -} diff --git a/codec/test_codec.go b/codec/test_codec.go index 341912a823af..b24784ac7d6a 100644 --- a/codec/test_codec.go +++ b/codec/test_codec.go @@ -23,7 +23,6 @@ var ( TestBigArray, TestPointerToStruct, TestSliceOfStruct, - TestStructWithNullable, TestInterface, TestSliceOfInterface, TestArrayOfInterface, @@ -64,8 +63,7 @@ type Foo interface { } type MyInnerStruct struct { - Str string `serialize:"true"` - NumberNotProvided *int32 `serialize:"true,nullable"` + Str string `serialize:"true"` } func (*MyInnerStruct) Foo() int { @@ -88,15 +86,6 @@ type MyInnerStruct3 struct { F Foo `serialize:"true"` } -type MyStructWithNullable struct { - Interface any `serialize:"true,nullable"` - Int32 *int32 `serialize:"true,nullable"` - Int64 *int64 `serialize:"true,nullable"` - Int32Slice []*int32 `serialize:"true,nullable"` - Int32Array [2]*int32 `serialize:"true,nullable"` - Int32Map map[int32]*int32 `serialize:"true,nullable"` -} - type myStruct struct { InnerStruct MyInnerStruct `serialize:"true"` InnerStruct2 *MyInnerStruct `serialize:"true"` @@ -156,23 +145,21 @@ func TestStruct(codec GeneralCodec, t testing.TB) { myMap7["key"] = "value" myMap7[int32(1)] = int32(2) - number := int32(8) - myStructInstance := myStruct{ - InnerStruct: MyInnerStruct{"hello", nil}, - InnerStruct2: &MyInnerStruct{"yello", nil}, + InnerStruct: MyInnerStruct{"hello"}, + InnerStruct2: &MyInnerStruct{"yello"}, Member1: 1, Member2: 2, MySlice: []byte{1, 2, 3, 4}, MySlice2: []string{"one", "two", "three"}, - MySlice3: []MyInnerStruct{{"abc", nil}, {"ab", &number}, {"c", nil}}, + MySlice3: []MyInnerStruct{{"abc"}, {"ab"}, {"c"}}, MySlice4: []*MyInnerStruct2{{true}, {}}, MySlice5: []Foo{&MyInnerStruct2{true}, &MyInnerStruct2{}}, MyArray: [4]byte{5, 6, 7, 8}, MyArray2: [5]string{"four", "five", "six", "seven"}, - MyArray3: [3]MyInnerStruct{{"d", nil}, {"e", nil}, {"f", nil}}, + MyArray3: [3]MyInnerStruct{{"d"}, {"e"}, {"f"}}, MyArray4: [2]*MyInnerStruct2{{}, {true}}, - MyInterface: &MyInnerStruct{"yeet", &number}, + MyInterface: &MyInnerStruct{"yeet"}, InnerStruct3: MyInnerStruct3{ Str: "str", M1: MyInnerStruct{ @@ -427,79 +414,19 @@ func TestPointerToStruct(codec GeneralCodec, t testing.TB) { require.Equal(myPtr, myPtrUnmarshaled) } -func TestStructWithNullable(codec GeneralCodec, t testing.TB) { - require := require.New(t) - n1 := int32(5) - n2 := int64(10) - struct1 := MyStructWithNullable{ - Interface: nil, - Int32: &n1, - Int64: &n2, - Int32Slice: []*int32{ - nil, - nil, - &n1, - }, - Int32Array: [2]*int32{ - nil, - &n1, - }, - Int32Map: map[int32]*int32{ - 1: nil, - 2: &n1, - }, - } - - require.NoError(codec.RegisterType(&MyStructWithNullable{})) - manager := NewDefaultManager() - require.NoError(manager.RegisterCodec(0, codec)) - - bytes, err := manager.Marshal(0, struct1) - require.NoError(err) - - bytesLen, err := manager.Size(0, struct1) - require.NoError(err) - require.Len(bytes, bytesLen) - - var struct1Unmarshaled MyStructWithNullable - version, err := manager.Unmarshal(bytes, &struct1Unmarshaled) - require.NoError(err) - require.Zero(version) - require.Equal(struct1, struct1Unmarshaled) - - struct1 = MyStructWithNullable{ - Int32Slice: []*int32{}, - Int32Map: map[int32]*int32{}, - } - bytes, err = manager.Marshal(0, struct1) - require.NoError(err) - - bytesLen, err = manager.Size(0, struct1) - require.NoError(err) - require.Len(bytes, bytesLen) - - var struct1Unmarshaled2 MyStructWithNullable - version, err = manager.Unmarshal(bytes, &struct1Unmarshaled2) - require.NoError(err) - require.Zero(version) - require.Equal(struct1, struct1Unmarshaled2) -} - // Test marshalling a slice of structs func TestSliceOfStruct(codec GeneralCodec, t testing.TB) { require := require.New(t) - n1 := int32(-1) - n2 := int32(0xff) mySlice := []MyInnerStruct3{ { Str: "One", - M1: MyInnerStruct{"Two", &n1}, - F: &MyInnerStruct{"Three", &n2}, + M1: MyInnerStruct{"Two"}, + F: &MyInnerStruct{"Three"}, }, { Str: "Four", - M1: MyInnerStruct{"Five", nil}, - F: &MyInnerStruct{"Six", nil}, + M1: MyInnerStruct{"Five"}, + F: &MyInnerStruct{"Six"}, }, } require.NoError(codec.RegisterType(&MyInnerStruct{})) From f80cb929b2866900f9fcbe73b0260319d0e85e6e Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 14 Dec 2023 09:13:24 -0500 Subject: [PATCH 147/267] `merkledb` -- dynamic root (#2177) Signed-off-by: Dan Laine Co-authored-by: dboehm-avalabs --- scripts/mocks.mockgen.txt | 1 - x/merkledb/codec.go | 32 ++- x/merkledb/codec_test.go | 16 +- x/merkledb/db.go | 132 ++++++----- x/merkledb/db_test.go | 53 ++++- x/merkledb/history.go | 20 +- x/merkledb/history_test.go | 23 +- x/merkledb/metrics_test.go | 6 +- x/merkledb/mock_db.go | 406 +++++++++++++++++----------------- x/merkledb/node.go | 5 + x/merkledb/proof.go | 27 +-- x/merkledb/proof_test.go | 152 ++++++++++--- x/merkledb/trie.go | 10 +- x/merkledb/trie_test.go | 167 ++++++++------ x/merkledb/trieview.go | 245 ++++++++++---------- x/sync/client_test.go | 23 +- x/sync/g_db/db_client.go | 8 + x/sync/manager.go | 23 ++ x/sync/network_server.go | 4 + x/sync/network_server_test.go | 20 +- x/sync/sync_test.go | 29 ++- 21 files changed, 842 insertions(+), 560 deletions(-) diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 3ec7849d6e0b..714c3b5932e4 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -43,5 +43,4 @@ github.com/ava-labs/avalanchego/vms/registry=VMGetter=vms/registry/mock_vm_gette github.com/ava-labs/avalanchego/vms/registry=VMRegisterer=vms/registry/mock_vm_registerer.go github.com/ava-labs/avalanchego/vms/registry=VMRegistry=vms/registry/mock_vm_registry.go github.com/ava-labs/avalanchego/vms=Factory,Manager=vms/mock_manager.go -github.com/ava-labs/avalanchego/x/merkledb=MerkleDB=x/merkledb/mock_db.go github.com/ava-labs/avalanchego/x/sync=Client=x/sync/mock_client.go diff --git a/x/merkledb/codec.go b/x/merkledb/codec.go index 973dd5888ab6..c14534d9cead 100644 --- a/x/merkledb/codec.go +++ b/x/merkledb/codec.go @@ -66,11 +66,13 @@ type encoder interface { // Returns the bytes that will be hashed to generate [n]'s ID. // Assumes [n] is non-nil. encodeHashValues(n *node) []byte + encodeKey(key Key) []byte } type decoder interface { // Assumes [n] is non-nil. decodeDBNode(bytes []byte, n *dbNode) error + decodeKey(bytes []byte) (Key, error) } func newCodec() encoderDecoder { @@ -98,7 +100,6 @@ func (c *codecImpl) encodeDBNode(n *dbNode) []byte { estimatedLen = estimatedValueLen + minVarIntLen + estimatedNodeChildLen*numChildren buf = bytes.NewBuffer(make([]byte, 0, estimatedLen)) ) - c.encodeMaybeByteSlice(buf, n.value) c.encodeUint(buf, uint64(numChildren)) // Note we insert children in order of increasing index @@ -108,7 +109,7 @@ func (c *codecImpl) encodeDBNode(n *dbNode) []byte { for _, index := range keys { entry := n.children[index] c.encodeUint(buf, uint64(index)) - c.encodeKey(buf, entry.compressedKey) + c.encodeKeyToBuffer(buf, entry.compressedKey) _, _ = buf.Write(entry.id[:]) c.encodeBool(buf, entry.hasValue) } @@ -134,7 +135,7 @@ func (c *codecImpl) encodeHashValues(n *node) []byte { _, _ = buf.Write(entry.id[:]) } c.encodeMaybeByteSlice(buf, n.valueDigest) - c.encodeKey(buf, n.key) + c.encodeKeyToBuffer(buf, n.key) return buf.Bytes() } @@ -172,7 +173,7 @@ func (c *codecImpl) decodeDBNode(b []byte, n *dbNode) error { } previousChild = index - compressedKey, err := c.decodeKey(src) + compressedKey, err := c.decodeKeyFromReader(src) if err != nil { return err } @@ -330,12 +331,31 @@ func (*codecImpl) decodeID(src *bytes.Reader) (ids.ID, error) { return id, err } -func (c *codecImpl) encodeKey(dst *bytes.Buffer, key Key) { +func (c *codecImpl) encodeKey(key Key) []byte { + estimatedLen := binary.MaxVarintLen64 + len(key.Bytes()) + dst := bytes.NewBuffer(make([]byte, 0, estimatedLen)) + c.encodeKeyToBuffer(dst, key) + return dst.Bytes() +} + +func (c *codecImpl) encodeKeyToBuffer(dst *bytes.Buffer, key Key) { c.encodeUint(dst, uint64(key.length)) _, _ = dst.Write(key.Bytes()) } -func (c *codecImpl) decodeKey(src *bytes.Reader) (Key, error) { +func (c *codecImpl) decodeKey(b []byte) (Key, error) { + src := bytes.NewReader(b) + key, err := c.decodeKeyFromReader(src) + if err != nil { + return Key{}, err + } + if src.Len() != 0 { + return Key{}, errExtraSpace + } + return key, err +} + +func (c *codecImpl) decodeKeyFromReader(src *bytes.Reader) (Key, error) { if minKeyLen > src.Len() { return Key{}, io.ErrUnexpectedEOF } diff --git a/x/merkledb/codec_test.go b/x/merkledb/codec_test.go index 699db9a4bd81..1f463ca50858 100644 --- a/x/merkledb/codec_test.go +++ b/x/merkledb/codec_test.go @@ -81,21 +81,14 @@ func FuzzCodecKey(f *testing.F) { ) { require := require.New(t) codec := codec.(*codecImpl) - reader := bytes.NewReader(b) - startLen := reader.Len() - got, err := codec.decodeKey(reader) + got, err := codec.decodeKey(b) if err != nil { t.SkipNow() } - endLen := reader.Len() - numRead := startLen - endLen // Encoding [got] should be the same as [b]. - var buf bytes.Buffer - codec.encodeKey(&buf, got) - bufBytes := buf.Bytes() - require.Len(bufBytes, numRead) - require.Equal(b[:numRead], bufBytes) + gotBytes := codec.encodeKey(got) + require.Equal(b, gotBytes) }, ) } @@ -248,7 +241,6 @@ func FuzzEncodeHashValues(f *testing.F) { func TestCodecDecodeKeyLengthOverflowRegression(t *testing.T) { codec := codec.(*codecImpl) - bytes := bytes.NewReader(binary.AppendUvarint(nil, math.MaxInt)) - _, err := codec.decodeKey(bytes) + _, err := codec.decodeKey(binary.AppendUvarint(nil, math.MaxInt)) require.ErrorIs(t, err, io.ErrUnexpectedEOF) } diff --git a/x/merkledb/db.go b/x/merkledb/db.go index bcc8a2a803f2..823f754d2f3c 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -51,11 +51,11 @@ var ( intermediateNodePrefix = []byte{2} cleanShutdownKey = []byte(string(metadataPrefix) + "cleanShutdown") + rootDBKey = []byte(string(metadataPrefix) + "root") hadCleanShutdown = []byte{1} didNotHaveCleanShutdown = []byte{0} - errSameRoot = errors.New("start and end root are the same") - errNoNewSentinel = errors.New("there was no updated sentinel node in change list") + errSameRoot = errors.New("start and end root are the same") ) type ChangeProofer interface { @@ -64,6 +64,9 @@ type ChangeProofer interface { // Returns at most [maxLength] key/value pairs. // Returns [ErrInsufficientHistory] if this node has insufficient history // to generate the proof. + // Returns ErrEmptyProof if [endRootID] is ids.Empty. + // Note that [endRootID] == ids.Empty means the trie is empty + // (i.e. we don't need a change proof.) // Returns [ErrNoEndRoot], which wraps [ErrInsufficientHistory], if the // history doesn't contain the [endRootID]. GetChangeProof( @@ -102,6 +105,9 @@ type RangeProofer interface { // [start, end] when the root of the trie was [rootID]. // If [start] is Nothing, there's no lower bound on the range. // If [end] is Nothing, there's no upper bound on the range. + // Returns ErrEmptyProof if [rootID] is ids.Empty. + // Note that [rootID] == ids.Empty means the trie is empty + // (i.e. we don't need a range proof.) GetRangeProofAtRoot( ctx context.Context, rootID ids.ID, @@ -203,11 +209,11 @@ type merkleDB struct { debugTracer trace.Tracer infoTracer trace.Tracer - // The sentinel node of this trie. - // It is the node with a nil key and is the ancestor of all nodes in the trie. - // If it has a value or has multiple children, it is also the root of the trie. - sentinelNode *node - rootID ids.ID + // The root of this trie. + // Nothing if the trie is empty. + root maybe.Maybe[*node] + + rootID ids.ID // Valid children of this trie. childViews []*trieView @@ -270,6 +276,9 @@ func newDatabase( // add current root to history (has no changes) trieDB.history.record(&changeSummary{ rootID: trieDB.rootID, + rootChange: change[maybe.Maybe[*node]]{ + after: trieDB.root, + }, values: map[Key]*change[maybe.Maybe[[]byte]]{}, nodes: map[Key]*change[*node]{}, }) @@ -297,7 +306,8 @@ func newDatabase( // Deletes every intermediate node and rebuilds them by re-adding every key/value. // TODO: make this more efficient by only clearing out the stale portions of the trie. func (db *merkleDB) rebuild(ctx context.Context, cacheSize int) error { - db.sentinelNode = newNode(Key{}) + db.root = maybe.Nothing[*node]() + db.rootID = ids.Empty // Delete intermediate nodes. if err := database.ClearPrefix(db.baseDB, intermediateNodePrefix, rebuildIntermediateDeletionWriteSize); err != nil { @@ -591,13 +601,6 @@ func (db *merkleDB) getMerkleRoot() ids.ID { return db.rootID } -// isSentinelNodeTheRoot returns true if the passed in sentinel node has a value and or multiple child nodes -// When this is true, the root of the trie is the sentinel node -// When this is false, the root of the trie is the sentinel node's single child -func isSentinelNodeTheRoot(sentinel *node) bool { - return sentinel.valueDigest.HasValue() || len(sentinel.children) != 1 -} - func (db *merkleDB) GetProof(ctx context.Context, key []byte) (*Proof, error) { db.commitLock.RLock() defer db.commitLock.RUnlock() @@ -606,7 +609,6 @@ func (db *merkleDB) GetProof(ctx context.Context, key []byte) (*Proof, error) { } // Assumes [db.commitLock] is read locked. -// Assumes [db.lock] is not held func (db *merkleDB) getProof(ctx context.Context, key []byte) (*Proof, error) { if db.closed { return nil, database.ErrClosed @@ -654,11 +656,13 @@ func (db *merkleDB) getRangeProofAtRoot( end maybe.Maybe[[]byte], maxLength int, ) (*RangeProof, error) { - if db.closed { + switch { + case db.closed: return nil, database.ErrClosed - } - if maxLength <= 0 { + case maxLength <= 0: return nil, fmt.Errorf("%w but was %d", ErrInvalidMaxLength, maxLength) + case rootID == ids.Empty: + return nil, ErrEmptyProof } historicalView, err := db.getHistoricalViewForRange(rootID, start, end) @@ -676,11 +680,13 @@ func (db *merkleDB) GetChangeProof( end maybe.Maybe[[]byte], maxLength int, ) (*ChangeProof, error) { - if start.HasValue() && end.HasValue() && bytes.Compare(start.Value(), end.Value()) == 1 { + switch { + case start.HasValue() && end.HasValue() && bytes.Compare(start.Value(), end.Value()) == 1: return nil, ErrStartAfterEnd - } - if startRootID == endRootID { + case startRootID == endRootID: return nil, errSameRoot + case endRootID == ids.Empty: + return nil, ErrEmptyProof } db.commitLock.RLock() @@ -941,13 +947,7 @@ func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *trieView) e return nil } - sentinelChange, ok := changes.nodes[Key{}] - if !ok { - return errNoNewSentinel - } - currentValueNodeBatch := db.valueNodeDB.NewBatch() - _, nodesSpan := db.infoTracer.Start(ctx, "MerkleDB.commitChanges.writeNodes") for key, nodeChange := range changes.nodes { shouldAddIntermediate := nodeChange.after != nil && !nodeChange.after.hasValue() @@ -983,12 +983,18 @@ func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *trieView) e return err } - // Only modify in-memory state after the commit succeeds - // so that we don't need to clean up on error. - db.sentinelNode = sentinelChange.after - db.rootID = changes.rootID db.history.record(changes) - return nil + + // Update root in database. + db.root = changes.rootChange.after + db.rootID = changes.rootID + + if db.root.IsNothing() { + return db.baseDB.Delete(rootDBKey) + } + + rootKey := codec.encodeKey(db.root.Value().key) + return db.baseDB.Put(rootDBKey, rootKey) } // moveChildViewsToDB removes any child views from the trieToCommit and moves them to the db @@ -1024,7 +1030,7 @@ func (db *merkleDB) VerifyChangeProof( case start.HasValue() && end.HasValue() && bytes.Compare(start.Value(), end.Value()) > 0: return ErrStartAfterEnd case proof.Empty(): - return ErrNoMerkleProof + return ErrEmptyProof case end.HasValue() && len(proof.KeyChanges) == 0 && len(proof.EndProof) == 0: // We requested an end proof but didn't get one. return ErrNoEndProof @@ -1166,37 +1172,41 @@ func (db *merkleDB) invalidateChildrenExcept(exception *trieView) { } } +// If the root is on disk, set [db.root] to it. +// Otherwise leave [db.root] as Nothing. func (db *merkleDB) initializeRoot() error { - // Not sure if the sentinel node exists or if it had a value, - // so check under both prefixes - var err error - db.sentinelNode, err = db.intermediateNodeDB.Get(Key{}) + rootKeyBytes, err := db.baseDB.Get(rootDBKey) + if err != nil { + if !errors.Is(err, database.ErrNotFound) { + return err + } + // Root isn't on disk. + return nil + } - if errors.Is(err, database.ErrNotFound) { - // Didn't find the sentinel in the intermediateNodeDB, check the valueNodeDB - db.sentinelNode, err = db.valueNodeDB.Get(Key{}) + // Root is on disk. + rootKey, err := codec.decodeKey(rootKeyBytes) + if err != nil { + return err } + // First, see if root is an intermediate node. + var root *node + root, err = db.getEditableNode(rootKey, false /* hasValue */) if err != nil { if !errors.Is(err, database.ErrNotFound) { return err } - // Sentinel node doesn't exist in either database prefix. - // Make a new one and store it in the intermediateNodeDB - db.sentinelNode = newNode(Key{}) - if err := db.intermediateNodeDB.Put(Key{}, db.sentinelNode); err != nil { + // The root must be a value node. + root, err = db.getEditableNode(rootKey, true /* hasValue */) + if err != nil { return err } } - db.rootID = db.sentinelNode.calculateID(db.metrics) - if !isSentinelNodeTheRoot(db.sentinelNode) { - // If the sentinel node is not the root, the trie's root is the sentinel node's only child - for _, childEntry := range db.sentinelNode.children { - db.rootID = childEntry.id - } - } + db.rootID = root.calculateID(db.metrics) + db.root = maybe.Some(root) return nil } @@ -1204,7 +1214,6 @@ func (db *merkleDB) initializeRoot() error { // If [start] is Nothing, there's no lower bound on the range. // If [end] is Nothing, there's no upper bound on the range. // Assumes [db.commitLock] is read locked. -// Assumes [db.lock] isn't held. func (db *merkleDB) getHistoricalViewForRange( rootID ids.ID, start maybe.Maybe[[]byte], @@ -1273,12 +1282,17 @@ func (db *merkleDB) getNode(key Key, hasValue bool) (*node, error) { switch { case db.closed: return nil, database.ErrClosed - case key == Key{}: - return db.sentinelNode, nil + case db.root.HasValue() && key == db.root.Value().key: + return db.root.Value(), nil case hasValue: return db.valueNodeDB.Get(key) + default: + return db.intermediateNodeDB.Get(key) } - return db.intermediateNodeDB.Get(key) +} + +func (db *merkleDB) getRoot() maybe.Maybe[*node] { + return db.root } func (db *merkleDB) Clear() error { @@ -1297,13 +1311,13 @@ func (db *merkleDB) Clear() error { } // Clear root - db.sentinelNode = newNode(Key{}) - db.rootID = db.sentinelNode.calculateID(db.metrics) + db.root = maybe.Nothing[*node]() + db.rootID = ids.Empty // Clear history db.history = newTrieHistory(db.history.maxHistoryLen) db.history.record(&changeSummary{ - rootID: db.getMerkleRoot(), + rootID: db.rootID, values: map[Key]*change[maybe.Maybe[[]byte]]{}, nodes: map[Key]*change[*node]{}, }) diff --git a/x/merkledb/db_test.go b/x/merkledb/db_test.go index 1cbce5a7792d..e14149ae1471 100644 --- a/x/merkledb/db_test.go +++ b/x/merkledb/db_test.go @@ -31,8 +31,6 @@ import ( const defaultHistoryLength = 300 -var emptyKey Key - // newDB returns a new merkle database with the underlying type so that tests can access unexported fields func newDB(ctx context.Context, db database.Database, config Config) (*merkleDB, error) { db, err := New(ctx, db, config) @@ -153,7 +151,7 @@ func Test_MerkleDB_DB_Load_Root_From_DB(t *testing.T) { require.NoError(db.Close()) - // reloading the db, should set the root back to the one that was saved to [baseDB] + // reloading the db should set the root back to the one that was saved to [baseDB] db, err = New( context.Background(), baseDB, @@ -804,8 +802,8 @@ func TestMerkleDBClear(t *testing.T) { iter := db.NewIterator() defer iter.Release() require.False(iter.Next()) - require.Equal(emptyRootID, db.getMerkleRoot()) - require.Equal(emptyKey, db.sentinelNode.key) + require.Equal(ids.Empty, db.getMerkleRoot()) + require.True(db.root.IsNothing()) // Assert caches are empty. require.Zero(db.valueNodeDB.nodeCache.Len()) @@ -948,6 +946,10 @@ func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, token } rangeProof, err := db.GetRangeProofAtRoot(context.Background(), root, start, end, maxProofLen) + if root == ids.Empty { + require.ErrorIs(err, ErrEmptyProof) + continue + } require.NoError(err) require.LessOrEqual(len(rangeProof.KeyValues), maxProofLen) @@ -981,6 +983,10 @@ func runRandDBTest(require *require.Assertions, r *rand.Rand, rt randTest, token require.ErrorIs(err, errSameRoot) continue } + if root == ids.Empty { + require.ErrorIs(err, ErrEmptyProof) + continue + } require.NoError(err) require.LessOrEqual(len(changeProof.KeyChanges), maxProofLen) @@ -1242,3 +1248,40 @@ func insertRandomKeyValues( } } } + +func TestGetRangeProofAtRootEmptyRootID(t *testing.T) { + require := require.New(t) + + db, err := getBasicDB() + require.NoError(err) + + _, err = db.getRangeProofAtRoot( + context.Background(), + ids.Empty, + maybe.Nothing[[]byte](), + maybe.Nothing[[]byte](), + 10, + ) + require.ErrorIs(err, ErrEmptyProof) +} + +func TestGetChangeProofEmptyRootID(t *testing.T) { + require := require.New(t) + + db, err := getBasicDB() + require.NoError(err) + + require.NoError(db.Put([]byte("key"), []byte("value"))) + + rootID := db.getMerkleRoot() + + _, err = db.GetChangeProof( + context.Background(), + rootID, + ids.Empty, + maybe.Nothing[[]byte](), + maybe.Nothing[[]byte](), + 10, + ) + require.ErrorIs(err, ErrEmptyProof) +} diff --git a/x/merkledb/history.go b/x/merkledb/history.go index 3717f9ef9b96..1f55b93c5d58 100644 --- a/x/merkledb/history.go +++ b/x/merkledb/history.go @@ -54,15 +54,20 @@ type changeSummaryAndInsertNumber struct { // Tracks all the node and value changes that resulted in the rootID. type changeSummary struct { + // The ID of the trie after these changes. rootID ids.ID - nodes map[Key]*change[*node] - values map[Key]*change[maybe.Maybe[[]byte]] + // The root before/after this change. + // Set in [calculateNodeIDs]. + rootChange change[maybe.Maybe[*node]] + nodes map[Key]*change[*node] + values map[Key]*change[maybe.Maybe[[]byte]] } func newChangeSummary(estimatedSize int) *changeSummary { return &changeSummary{ - nodes: make(map[Key]*change[*node], estimatedSize), - values: make(map[Key]*change[maybe.Maybe[[]byte]], estimatedSize), + nodes: make(map[Key]*change[*node], estimatedSize), + values: make(map[Key]*change[maybe.Maybe[[]byte]], estimatedSize), + rootChange: change[maybe.Maybe[*node]]{}, } } @@ -250,6 +255,13 @@ func (th *trieHistory) getChangesToGetToRoot(rootID ids.ID, start maybe.Maybe[[] for i := mostRecentChangeIndex; i > lastRootChangeIndex; i-- { changes, _ := th.history.Index(i) + if i == mostRecentChangeIndex { + combinedChanges.rootChange.before = changes.rootChange.after + } + if i == lastRootChangeIndex+1 { + combinedChanges.rootChange.after = changes.rootChange.before + } + for key, changedNode := range changes.nodes { combinedChanges.nodes[key] = &change[*node]{ after: changedNode.before, diff --git a/x/merkledb/history_test.go b/x/merkledb/history_test.go index 3c8e8700d567..6af39e0e08e3 100644 --- a/x/merkledb/history_test.go +++ b/x/merkledb/history_test.go @@ -36,8 +36,7 @@ func Test_History_Simple(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - - origRootID := db.getMerkleRoot() + origRootID := db.rootID require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -338,8 +337,7 @@ func Test_History_RepeatedRoot(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - - origRootID := db.getMerkleRoot() + origRootID := db.rootID require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -381,8 +379,7 @@ func Test_History_ExcessDeletes(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - - origRootID := db.getMerkleRoot() + origRootID := db.rootID require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -414,8 +411,7 @@ func Test_History_DontIncludeAllNodes(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - - origRootID := db.getMerkleRoot() + origRootID := db.rootID require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -443,7 +439,7 @@ func Test_History_Branching2Nodes(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - origRootID := db.getMerkleRoot() + origRootID := db.rootID require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -471,8 +467,7 @@ func Test_History_Branching3Nodes(t *testing.T) { origProof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), 10) require.NoError(err) require.NotNil(origProof) - - origRootID := db.getMerkleRoot() + origRootID := db.rootID require.NoError(origProof.Verify(context.Background(), maybe.Some([]byte("k")), maybe.Some([]byte("key3")), origRootID, db.tokenSize)) batch = db.NewBatch() @@ -657,6 +652,9 @@ func TestHistoryGetChangesToRoot(t *testing.T) { for i := 0; i < maxHistoryLen; i++ { // Fill the history changes = append(changes, &changeSummary{ rootID: ids.GenerateTestID(), + rootChange: change[maybe.Maybe[*node]]{ + before: maybe.Some(&node{}), + }, nodes: map[Key]*change[*node]{ ToKey([]byte{byte(i)}): { before: &node{}, @@ -692,7 +690,8 @@ func TestHistoryGetChangesToRoot(t *testing.T) { name: "most recent change", rootID: changes[maxHistoryLen-1].rootID, validateFunc: func(require *require.Assertions, got *changeSummary) { - require.Equal(newChangeSummary(defaultPreallocationSize), got) + expected := newChangeSummary(defaultPreallocationSize) + require.Equal(expected, got) }, }, { diff --git a/x/merkledb/metrics_test.go b/x/merkledb/metrics_test.go index 3bf5a9480a54..304c3027133b 100644 --- a/x/merkledb/metrics_test.go +++ b/x/merkledb/metrics_test.go @@ -34,20 +34,20 @@ func Test_Metrics_Basic_Usage(t *testing.T) { require.Equal(t, int64(1), db.metrics.(*mockMetrics).keyReadCount) require.Equal(t, int64(1), db.metrics.(*mockMetrics).keyWriteCount) - require.Equal(t, int64(2), db.metrics.(*mockMetrics).hashCount) + require.Equal(t, int64(1), db.metrics.(*mockMetrics).hashCount) require.NoError(t, db.Delete([]byte("key"))) require.Equal(t, int64(1), db.metrics.(*mockMetrics).keyReadCount) require.Equal(t, int64(2), db.metrics.(*mockMetrics).keyWriteCount) - require.Equal(t, int64(3), db.metrics.(*mockMetrics).hashCount) + require.Equal(t, int64(1), db.metrics.(*mockMetrics).hashCount) _, err = db.Get([]byte("key2")) require.ErrorIs(t, err, database.ErrNotFound) require.Equal(t, int64(2), db.metrics.(*mockMetrics).keyReadCount) require.Equal(t, int64(2), db.metrics.(*mockMetrics).keyWriteCount) - require.Equal(t, int64(3), db.metrics.(*mockMetrics).hashCount) + require.Equal(t, int64(1), db.metrics.(*mockMetrics).hashCount) } func Test_Metrics_Initialize(t *testing.T) { diff --git a/x/merkledb/mock_db.go b/x/merkledb/mock_db.go index a4d1d6b6d6f3..e07354e6b3e8 100644 --- a/x/merkledb/mock_db.go +++ b/x/merkledb/mock_db.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/x/merkledb (interfaces: MerkleDB) @@ -8,439 +5,452 @@ package merkledb import ( - context "context" - reflect "reflect" - - database "github.com/ava-labs/avalanchego/database" - ids "github.com/ava-labs/avalanchego/ids" - maybe "github.com/ava-labs/avalanchego/utils/maybe" - gomock "go.uber.org/mock/gomock" + reflect "reflect" + context "context" + database "github.com/ava-labs/avalanchego/database" + ids "github.com/ava-labs/avalanchego/ids" + maybe "github.com/ava-labs/avalanchego/utils/maybe" + gomock "go.uber.org/mock/gomock" ) // MockMerkleDB is a mock of MerkleDB interface. type MockMerkleDB struct { - ctrl *gomock.Controller - recorder *MockMerkleDBMockRecorder + ctrl *gomock.Controller + recorder *MockMerkleDBMockRecorder } // MockMerkleDBMockRecorder is the mock recorder for MockMerkleDB. type MockMerkleDBMockRecorder struct { - mock *MockMerkleDB + mock *MockMerkleDB } // NewMockMerkleDB creates a new mock instance. func NewMockMerkleDB(ctrl *gomock.Controller) *MockMerkleDB { - mock := &MockMerkleDB{ctrl: ctrl} - mock.recorder = &MockMerkleDBMockRecorder{mock} - return mock + mock := &MockMerkleDB{ctrl: ctrl} + mock.recorder = &MockMerkleDBMockRecorder{mock} + return mock } // EXPECT returns an object that allows the caller to indicate expected use. func (m *MockMerkleDB) EXPECT() *MockMerkleDBMockRecorder { - return m.recorder + return m.recorder } // Clear mocks base method. func (m *MockMerkleDB) Clear() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Clear") - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Clear") + ret0, _ := ret[0].(error) + return ret0 } // Clear indicates an expected call of Clear. func (mr *MockMerkleDBMockRecorder) Clear() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clear", reflect.TypeOf((*MockMerkleDB)(nil).Clear)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clear", reflect.TypeOf((*MockMerkleDB)(nil).Clear)) } // Close mocks base method. func (m *MockMerkleDB) Close() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 } // Close indicates an expected call of Close. func (mr *MockMerkleDBMockRecorder) Close() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockMerkleDB)(nil).Close)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockMerkleDB)(nil).Close)) } // CommitChangeProof mocks base method. func (m *MockMerkleDB) CommitChangeProof(arg0 context.Context, arg1 *ChangeProof) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CommitChangeProof", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CommitChangeProof", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // CommitChangeProof indicates an expected call of CommitChangeProof. func (mr *MockMerkleDBMockRecorder) CommitChangeProof(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitChangeProof), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitChangeProof), arg0, arg1) } // CommitRangeProof mocks base method. func (m *MockMerkleDB) CommitRangeProof(arg0 context.Context, arg1, arg2 maybe.Maybe[[]uint8], arg3 *RangeProof) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CommitRangeProof", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CommitRangeProof", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 } // CommitRangeProof indicates an expected call of CommitRangeProof. func (mr *MockMerkleDBMockRecorder) CommitRangeProof(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitRangeProof), arg0, arg1, arg2, arg3) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitRangeProof), arg0, arg1, arg2, arg3) } // Compact mocks base method. func (m *MockMerkleDB) Compact(arg0, arg1 []byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Compact", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Compact", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // Compact indicates an expected call of Compact. func (mr *MockMerkleDBMockRecorder) Compact(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Compact", reflect.TypeOf((*MockMerkleDB)(nil).Compact), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Compact", reflect.TypeOf((*MockMerkleDB)(nil).Compact), arg0, arg1) } // Delete mocks base method. func (m *MockMerkleDB) Delete(arg0 []byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(error) + return ret0 } // Delete indicates an expected call of Delete. func (mr *MockMerkleDBMockRecorder) Delete(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockMerkleDB)(nil).Delete), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockMerkleDB)(nil).Delete), arg0) } // Get mocks base method. func (m *MockMerkleDB) Get(arg0 []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 } // Get indicates an expected call of Get. func (mr *MockMerkleDBMockRecorder) Get(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMerkleDB)(nil).Get), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMerkleDB)(nil).Get), arg0) } // GetChangeProof mocks base method. func (m *MockMerkleDB) GetChangeProof(arg0 context.Context, arg1, arg2 ids.ID, arg3, arg4 maybe.Maybe[[]uint8], arg5 int) (*ChangeProof, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChangeProof", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].(*ChangeProof) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetChangeProof", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(*ChangeProof) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetChangeProof indicates an expected call of GetChangeProof. func (mr *MockMerkleDBMockRecorder) GetChangeProof(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetChangeProof), arg0, arg1, arg2, arg3, arg4, arg5) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetChangeProof), arg0, arg1, arg2, arg3, arg4, arg5) } // GetMerkleRoot mocks base method. func (m *MockMerkleDB) GetMerkleRoot(arg0 context.Context) (ids.ID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMerkleRoot", arg0) - ret0, _ := ret[0].(ids.ID) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMerkleRoot", arg0) + ret0, _ := ret[0].(ids.ID) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetMerkleRoot indicates an expected call of GetMerkleRoot. func (mr *MockMerkleDBMockRecorder) GetMerkleRoot(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMerkleRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetMerkleRoot), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMerkleRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetMerkleRoot), arg0) } // GetProof mocks base method. func (m *MockMerkleDB) GetProof(arg0 context.Context, arg1 []byte) (*Proof, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProof", arg0, arg1) - ret0, _ := ret[0].(*Proof) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetProof", arg0, arg1) + ret0, _ := ret[0].(*Proof) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetProof indicates an expected call of GetProof. func (mr *MockMerkleDBMockRecorder) GetProof(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProof", reflect.TypeOf((*MockMerkleDB)(nil).GetProof), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProof", reflect.TypeOf((*MockMerkleDB)(nil).GetProof), arg0, arg1) } // GetRangeProof mocks base method. func (m *MockMerkleDB) GetRangeProof(arg0 context.Context, arg1, arg2 maybe.Maybe[[]uint8], arg3 int) (*RangeProof, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRangeProof", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*RangeProof) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRangeProof", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*RangeProof) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetRangeProof indicates an expected call of GetRangeProof. func (mr *MockMerkleDBMockRecorder) GetRangeProof(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProof), arg0, arg1, arg2, arg3) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProof), arg0, arg1, arg2, arg3) } // GetRangeProofAtRoot mocks base method. func (m *MockMerkleDB) GetRangeProofAtRoot(arg0 context.Context, arg1 ids.ID, arg2, arg3 maybe.Maybe[[]uint8], arg4 int) (*RangeProof, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRangeProofAtRoot", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(*RangeProof) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRangeProofAtRoot", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(*RangeProof) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetRangeProofAtRoot indicates an expected call of GetRangeProofAtRoot. func (mr *MockMerkleDBMockRecorder) GetRangeProofAtRoot(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProofAtRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProofAtRoot), arg0, arg1, arg2, arg3, arg4) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProofAtRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProofAtRoot), arg0, arg1, arg2, arg3, arg4) } // GetValue mocks base method. func (m *MockMerkleDB) GetValue(arg0 context.Context, arg1 []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValue", arg0, arg1) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValue", arg0, arg1) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetValue indicates an expected call of GetValue. func (mr *MockMerkleDBMockRecorder) GetValue(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValue", reflect.TypeOf((*MockMerkleDB)(nil).GetValue), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValue", reflect.TypeOf((*MockMerkleDB)(nil).GetValue), arg0, arg1) } // GetValues mocks base method. func (m *MockMerkleDB) GetValues(arg0 context.Context, arg1 [][]byte) ([][]byte, []error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValues", arg0, arg1) - ret0, _ := ret[0].([][]byte) - ret1, _ := ret[1].([]error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValues", arg0, arg1) + ret0, _ := ret[0].([][]byte) + ret1, _ := ret[1].([]error) + return ret0, ret1 } // GetValues indicates an expected call of GetValues. func (mr *MockMerkleDBMockRecorder) GetValues(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValues", reflect.TypeOf((*MockMerkleDB)(nil).GetValues), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValues", reflect.TypeOf((*MockMerkleDB)(nil).GetValues), arg0, arg1) } // Has mocks base method. func (m *MockMerkleDB) Has(arg0 []byte) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Has", arg0) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Has", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 } // Has indicates an expected call of Has. func (mr *MockMerkleDBMockRecorder) Has(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMerkleDB)(nil).Has), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMerkleDB)(nil).Has), arg0) } // HealthCheck mocks base method. func (m *MockMerkleDB) HealthCheck(arg0 context.Context) (interface{}, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HealthCheck", arg0) - ret0, _ := ret[0].(interface{}) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HealthCheck", arg0) + ret0, _ := ret[0].(interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 } // HealthCheck indicates an expected call of HealthCheck. func (mr *MockMerkleDBMockRecorder) HealthCheck(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockMerkleDB)(nil).HealthCheck), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockMerkleDB)(nil).HealthCheck), arg0) } // NewBatch mocks base method. func (m *MockMerkleDB) NewBatch() database.Batch { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewBatch") - ret0, _ := ret[0].(database.Batch) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewBatch") + ret0, _ := ret[0].(database.Batch) + return ret0 } // NewBatch indicates an expected call of NewBatch. func (mr *MockMerkleDBMockRecorder) NewBatch() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBatch", reflect.TypeOf((*MockMerkleDB)(nil).NewBatch)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBatch", reflect.TypeOf((*MockMerkleDB)(nil).NewBatch)) } // NewIterator mocks base method. func (m *MockMerkleDB) NewIterator() database.Iterator { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIterator") - ret0, _ := ret[0].(database.Iterator) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewIterator") + ret0, _ := ret[0].(database.Iterator) + return ret0 } // NewIterator indicates an expected call of NewIterator. func (mr *MockMerkleDBMockRecorder) NewIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIterator", reflect.TypeOf((*MockMerkleDB)(nil).NewIterator)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIterator", reflect.TypeOf((*MockMerkleDB)(nil).NewIterator)) } // NewIteratorWithPrefix mocks base method. func (m *MockMerkleDB) NewIteratorWithPrefix(arg0 []byte) database.Iterator { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithPrefix", arg0) - ret0, _ := ret[0].(database.Iterator) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewIteratorWithPrefix", arg0) + ret0, _ := ret[0].(database.Iterator) + return ret0 } // NewIteratorWithPrefix indicates an expected call of NewIteratorWithPrefix. func (mr *MockMerkleDBMockRecorder) NewIteratorWithPrefix(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithPrefix), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithPrefix), arg0) } // NewIteratorWithStart mocks base method. func (m *MockMerkleDB) NewIteratorWithStart(arg0 []byte) database.Iterator { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithStart", arg0) - ret0, _ := ret[0].(database.Iterator) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewIteratorWithStart", arg0) + ret0, _ := ret[0].(database.Iterator) + return ret0 } // NewIteratorWithStart indicates an expected call of NewIteratorWithStart. func (mr *MockMerkleDBMockRecorder) NewIteratorWithStart(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStart", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStart), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStart", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStart), arg0) } // NewIteratorWithStartAndPrefix mocks base method. func (m *MockMerkleDB) NewIteratorWithStartAndPrefix(arg0, arg1 []byte) database.Iterator { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithStartAndPrefix", arg0, arg1) - ret0, _ := ret[0].(database.Iterator) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewIteratorWithStartAndPrefix", arg0, arg1) + ret0, _ := ret[0].(database.Iterator) + return ret0 } // NewIteratorWithStartAndPrefix indicates an expected call of NewIteratorWithStartAndPrefix. func (mr *MockMerkleDBMockRecorder) NewIteratorWithStartAndPrefix(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStartAndPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStartAndPrefix), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStartAndPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStartAndPrefix), arg0, arg1) } // NewView mocks base method. func (m *MockMerkleDB) NewView(arg0 context.Context, arg1 ViewChanges) (TrieView, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewView", arg0, arg1) - ret0, _ := ret[0].(TrieView) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewView", arg0, arg1) + ret0, _ := ret[0].(TrieView) + ret1, _ := ret[1].(error) + return ret0, ret1 } // NewView indicates an expected call of NewView. func (mr *MockMerkleDBMockRecorder) NewView(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewView", reflect.TypeOf((*MockMerkleDB)(nil).NewView), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewView", reflect.TypeOf((*MockMerkleDB)(nil).NewView), arg0, arg1) } // PrefetchPath mocks base method. func (m *MockMerkleDB) PrefetchPath(arg0 []byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PrefetchPath", arg0) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrefetchPath", arg0) + ret0, _ := ret[0].(error) + return ret0 } // PrefetchPath indicates an expected call of PrefetchPath. func (mr *MockMerkleDBMockRecorder) PrefetchPath(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPath", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPath), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPath", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPath), arg0) } // PrefetchPaths mocks base method. func (m *MockMerkleDB) PrefetchPaths(arg0 [][]byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PrefetchPaths", arg0) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrefetchPaths", arg0) + ret0, _ := ret[0].(error) + return ret0 } // PrefetchPaths indicates an expected call of PrefetchPaths. func (mr *MockMerkleDBMockRecorder) PrefetchPaths(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPaths", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPaths), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPaths", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPaths), arg0) } // Put mocks base method. func (m *MockMerkleDB) Put(arg0, arg1 []byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Put", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Put", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // Put indicates an expected call of Put. func (mr *MockMerkleDBMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockMerkleDB)(nil).Put), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockMerkleDB)(nil).Put), arg0, arg1) } // VerifyChangeProof mocks base method. func (m *MockMerkleDB) VerifyChangeProof(arg0 context.Context, arg1 *ChangeProof, arg2, arg3 maybe.Maybe[[]uint8], arg4 ids.ID) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VerifyChangeProof", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VerifyChangeProof", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 } // VerifyChangeProof indicates an expected call of VerifyChangeProof. func (mr *MockMerkleDBMockRecorder) VerifyChangeProof(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).VerifyChangeProof), arg0, arg1, arg2, arg3, arg4) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).VerifyChangeProof), arg0, arg1, arg2, arg3, arg4) } // getEditableNode mocks base method. func (m *MockMerkleDB) getEditableNode(arg0 Key, arg1 bool) (*node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getEditableNode", arg0, arg1) - ret0, _ := ret[0].(*node) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getEditableNode", arg0, arg1) + ret0, _ := ret[0].(*node) + ret1, _ := ret[1].(error) + return ret0, ret1 } // getEditableNode indicates an expected call of getEditableNode. func (mr *MockMerkleDBMockRecorder) getEditableNode(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getEditableNode", reflect.TypeOf((*MockMerkleDB)(nil).getEditableNode), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getEditableNode", reflect.TypeOf((*MockMerkleDB)(nil).getEditableNode), arg0, arg1) +} + +// getRoot mocks base method. +func (m *MockMerkleDB) getRoot() maybe.Maybe[*node] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getRoot") + ret0, _ := ret[0].(maybe.Maybe[*node]) + return ret0 +} + +// getRoot indicates an expected call of getRoot. +func (mr *MockMerkleDBMockRecorder) getRoot() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getRoot", reflect.TypeOf((*MockMerkleDB)(nil).getRoot)) } // getValue mocks base method. func (m *MockMerkleDB) getValue(arg0 Key) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getValue", arg0) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getValue", arg0) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 } // getValue indicates an expected call of getValue. func (mr *MockMerkleDBMockRecorder) getValue(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getValue", reflect.TypeOf((*MockMerkleDB)(nil).getValue), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getValue", reflect.TypeOf((*MockMerkleDB)(nil).getValue), arg0) } diff --git a/x/merkledb/node.go b/x/merkledb/node.go index 9a63ef82c4a7..d15eb6ae7e14 100644 --- a/x/merkledb/node.go +++ b/x/merkledb/node.go @@ -105,10 +105,15 @@ func (n *node) setValueDigest() { // Assumes [child]'s key is valid as a child of [n]. // That is, [n.key] is a prefix of [child.key]. func (n *node) addChild(childNode *node, tokenSize int) { + n.addChildWithID(childNode, tokenSize, ids.Empty) +} + +func (n *node) addChildWithID(childNode *node, tokenSize int, childID ids.ID) { n.setChildEntry( childNode.key.Token(n.key.length, tokenSize), &child{ compressedKey: childNode.key.Skip(n.key.length + tokenSize), + id: childID, hasValue: childNode.hasValue(), }, ) diff --git a/x/merkledb/proof.go b/x/merkledb/proof.go index 39ceff3d3157..940c172deecf 100644 --- a/x/merkledb/proof.go +++ b/x/merkledb/proof.go @@ -31,11 +31,13 @@ var ( ErrNonIncreasingValues = errors.New("keys sent are not in increasing order") ErrStateFromOutsideOfRange = errors.New("state key falls outside of the start->end range") ErrNonIncreasingProofNodes = errors.New("each proof node key must be a strict prefix of the next") + ErrExtraProofNodes = errors.New("extra proof nodes in path") + ErrDataInMissingRootProof = errors.New("there should be no state or deleted keys in a change proof that had a missing root") + ErrEmptyProof = errors.New("proof is empty") ErrNoMerkleProof = errors.New("empty key response must include merkle proof") ErrShouldJustBeRoot = errors.New("end proof should only contain root") ErrNoStartProof = errors.New("no start proof") ErrNoEndProof = errors.New("no end proof") - ErrNoProof = errors.New("proof has no nodes") ErrProofNodeNotForKey = errors.New("the provided node has a key that is not a prefix of the specified key") ErrProofValueDoesntMatch = errors.New("the provided value does not match the proof node for the provided key's value") ErrProofNodeHasUnincludedValue = errors.New("the provided proof has a value for a key within the range that is not present in the provided key/values") @@ -121,7 +123,7 @@ func (node *ProofNode) UnmarshalProto(pbNode *pb.ProofNode) error { type Proof struct { // Nodes in the proof path from root --> target key // (or node that would be where key is if it doesn't exist). - // Must always be non-empty (i.e. have the root node). + // Always contains at least the root. Path []ProofNode // This is a proof that [key] exists/doesn't exist. Key Key @@ -137,8 +139,9 @@ type Proof struct { func (proof *Proof) Verify(ctx context.Context, expectedRootID ids.ID, tokenSize int) error { // Make sure the proof is well-formed. if len(proof.Path) == 0 { - return ErrNoProof + return ErrEmptyProof } + if err := verifyProofPath(proof.Path, maybe.Some(proof.Key)); err != nil { return err } @@ -249,16 +252,12 @@ type RangeProof struct { // they are also in [EndProof]. StartProof []ProofNode - // If no upper range bound was given, [KeyValues] is empty, - // and [StartProof] is non-empty, this is empty. - // - // If no upper range bound was given, [KeyValues] is empty, - // and [StartProof] is empty, this is the root. + // If no upper range bound was given and [KeyValues] is empty, this is empty. // - // If an upper range bound was given and [KeyValues] is empty, - // this is a proof for the upper range bound. + // If no upper range bound was given and [KeyValues] is non-empty, this is + // a proof for the largest key in [KeyValues]. // - // Otherwise, this is a proof for the largest key in [KeyValues]. + // Otherwise this is a proof for the upper range bound. EndProof []ProofNode // This proof proves that the key-value pairs in [KeyValues] are in the trie. @@ -287,11 +286,9 @@ func (proof *RangeProof) Verify( case start.HasValue() && end.HasValue() && bytes.Compare(start.Value(), end.Value()) > 0: return ErrStartAfterEnd case len(proof.KeyValues) == 0 && len(proof.StartProof) == 0 && len(proof.EndProof) == 0: - return ErrNoMerkleProof - case end.IsNothing() && len(proof.KeyValues) == 0 && len(proof.StartProof) > 0 && len(proof.EndProof) != 0: + return ErrEmptyProof + case end.IsNothing() && len(proof.KeyValues) == 0 && len(proof.EndProof) != 0: return ErrUnexpectedEndProof - case end.IsNothing() && len(proof.KeyValues) == 0 && len(proof.StartProof) == 0 && len(proof.EndProof) != 1: - return ErrShouldJustBeRoot case len(proof.EndProof) == 0 && (end.HasValue() || len(proof.KeyValues) > 0): return ErrNoEndProof } diff --git a/x/merkledb/proof_test.go b/x/merkledb/proof_test.go index fbee117d4e68..e00326a56408 100644 --- a/x/merkledb/proof_test.go +++ b/x/merkledb/proof_test.go @@ -24,7 +24,7 @@ import ( func Test_Proof_Empty(t *testing.T) { proof := &Proof{} err := proof.Verify(context.Background(), ids.Empty, 4) - require.ErrorIs(t, err, ErrNoProof) + require.ErrorIs(t, err, ErrEmptyProof) } func Test_Proof_Simple(t *testing.T) { @@ -59,6 +59,13 @@ func Test_Proof_Verify_Bad_Data(t *testing.T) { malform: func(proof *Proof) {}, expectedErr: nil, }, + { + name: "empty", + malform: func(proof *Proof) { + proof.Path = nil + }, + expectedErr: ErrEmptyProof, + }, { name: "odd length key path with value", malform: func(proof *Proof) { @@ -150,7 +157,7 @@ func Test_RangeProof_Extra_Value(t *testing.T) { context.Background(), maybe.Some([]byte{1}), maybe.Some([]byte{5, 5}), - db.getMerkleRoot(), + db.rootID, db.tokenSize, )) @@ -160,7 +167,7 @@ func Test_RangeProof_Extra_Value(t *testing.T) { context.Background(), maybe.Some([]byte{1}), maybe.Some([]byte{5, 5}), - db.getMerkleRoot(), + db.rootID, db.tokenSize, ) require.ErrorIs(err, ErrInvalidProof) @@ -179,6 +186,15 @@ func Test_RangeProof_Verify_Bad_Data(t *testing.T) { malform: func(proof *RangeProof) {}, expectedErr: nil, }, + { + name: "empty", + malform: func(proof *RangeProof) { + proof.KeyValues = nil + proof.StartProof = nil + proof.EndProof = nil + }, + expectedErr: ErrEmptyProof, + }, { name: "StartProof: last proof node has missing value", malform: func(proof *RangeProof) { @@ -276,6 +292,8 @@ func Test_Proof(t *testing.T) { require.Equal(ToKey([]byte("key")), proof.Path[0].Key) require.Equal(maybe.Some([]byte("value")), proof.Path[0].ValueOrHash) + require.Equal(ToKey([]byte("key0")).Take(28), proof.Path[1].Key) + require.True(proof.Path[1].ValueOrHash.IsNothing()) // intermediate node require.Equal(ToKey([]byte("key1")), proof.Path[2].Key) require.Equal(maybe.Some([]byte("value1")), proof.Path[2].ValueOrHash) @@ -283,10 +301,9 @@ func Test_Proof(t *testing.T) { require.NoError(err) require.NoError(proof.Verify(context.Background(), expectedRootID, dbTrie.tokenSize)) - proof.Path[0].ValueOrHash = maybe.Some([]byte("value2")) - + proof.Path[0].Key = ToKey([]byte("key1")) err = proof.Verify(context.Background(), expectedRootID, dbTrie.tokenSize) - require.ErrorIs(err, ErrInvalidProof) + require.ErrorIs(err, ErrProofNodeNotForKey) } func Test_RangeProof_Syntactic_Verify(t *testing.T) { @@ -307,11 +324,11 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { expectedErr: ErrStartAfterEnd, }, { - name: "empty", // Also tests start can be > end if end is nil + name: "empty", start: maybe.Some([]byte{1}), end: maybe.Nothing[[]byte](), proof: &RangeProof{}, - expectedErr: ErrNoMerkleProof, + expectedErr: ErrEmptyProof, }, { name: "unexpected end proof", @@ -323,15 +340,6 @@ func Test_RangeProof_Syntactic_Verify(t *testing.T) { }, expectedErr: ErrUnexpectedEndProof, }, - { - name: "should just be root", - start: maybe.Nothing[[]byte](), - end: maybe.Nothing[[]byte](), - proof: &RangeProof{ - EndProof: []ProofNode{{}, {}}, - }, - expectedErr: ErrShouldJustBeRoot, - }, { name: "no end proof; has end bound", start: maybe.Some([]byte{1}), @@ -501,7 +509,9 @@ func Test_RangeProof(t *testing.T) { require.Equal([]byte{2}, proof.KeyValues[1].Value) require.Equal([]byte{3}, proof.KeyValues[2].Value) + require.Len(proof.EndProof, 2) require.Equal([]byte{0}, proof.EndProof[0].Key.Bytes()) + require.Len(proof.EndProof[0].Children, 5) // 0,1,2,3,4 require.Equal([]byte{3}, proof.EndProof[1].Key.Bytes()) // only a single node here since others are duplicates in endproof @@ -511,7 +521,7 @@ func Test_RangeProof(t *testing.T) { context.Background(), maybe.Some([]byte{1}), maybe.Some([]byte{3, 5}), - db.getMerkleRoot(), + db.rootID, db.tokenSize, )) } @@ -522,6 +532,8 @@ func Test_RangeProof_BadBounds(t *testing.T) { db, err := getBasicDB() require.NoError(err) + require.NoError(db.Put(nil, nil)) + // non-nil start/end proof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte{4}), maybe.Some([]byte{3}), 50) require.ErrorIs(err, ErrStartAfterEnd) @@ -556,14 +568,14 @@ func Test_RangeProof_NilStart(t *testing.T) { require.Equal([]byte("value1"), proof.KeyValues[0].Value) require.Equal([]byte("value2"), proof.KeyValues[1].Value) - require.Equal(ToKey([]byte("key2")), proof.EndProof[1].Key) + require.Equal(ToKey([]byte("key2")), proof.EndProof[1].Key, db.tokenSize) require.Equal(ToKey([]byte("key2")).Take(28), proof.EndProof[0].Key) require.NoError(proof.Verify( context.Background(), maybe.Nothing[[]byte](), maybe.Some([]byte("key35")), - db.getMerkleRoot(), + db.rootID, db.tokenSize, )) } @@ -573,10 +585,16 @@ func Test_RangeProof_NilEnd(t *testing.T) { db, err := getBasicDB() require.NoError(err) + writeBasicBatch(t, db) require.NoError(err) - proof, err := db.GetRangeProof(context.Background(), maybe.Some([]byte{1}), maybe.Nothing[[]byte](), 2) + proof, err := db.GetRangeProof( // Should have keys [1], [2] + context.Background(), + maybe.Some([]byte{1}), + maybe.Nothing[[]byte](), + 2, + ) require.NoError(err) require.NotNil(proof) @@ -590,14 +608,14 @@ func Test_RangeProof_NilEnd(t *testing.T) { require.Equal([]byte{1}, proof.StartProof[0].Key.Bytes()) - require.Equal([]byte{0}, proof.EndProof[0].Key.Bytes()) + require.Equal(db.root.Value().key, proof.EndProof[0].Key) require.Equal([]byte{2}, proof.EndProof[1].Key.Bytes()) require.NoError(proof.Verify( context.Background(), maybe.Some([]byte{1}), maybe.Nothing[[]byte](), - db.getMerkleRoot(), + db.rootID, db.tokenSize, )) } @@ -633,29 +651,68 @@ func Test_RangeProof_EmptyValues(t *testing.T) { require.Equal(ToKey([]byte("key1")), proof.StartProof[0].Key) require.Len(proof.EndProof, 2) - require.Equal(ToKey([]byte("key2")), proof.EndProof[1].Key) - require.Equal(ToKey([]byte("key2")).Take(28), proof.EndProof[0].Key) + require.Equal(ToKey([]byte("key1")).Take(28), proof.EndProof[0].Key, db.tokenSize) // root + require.Equal(ToKey([]byte("key2")), proof.EndProof[1].Key, db.tokenSize) require.NoError(proof.Verify( context.Background(), maybe.Some([]byte("key1")), maybe.Some([]byte("key2")), - db.getMerkleRoot(), + db.rootID, db.tokenSize, )) } func Test_ChangeProof_Missing_History_For_EndRoot(t *testing.T) { require := require.New(t) + seed := time.Now().UnixNano() + t.Logf("Seed: %d", seed) + rand := rand.New(rand.NewSource(seed)) // #nosec G404 db, err := getBasicDB() require.NoError(err) - startRoot, err := db.GetMerkleRoot(context.Background()) - require.NoError(err) - _, err = db.GetChangeProof(context.Background(), startRoot, ids.Empty, maybe.Nothing[[]byte](), maybe.Nothing[[]byte](), 50) + roots := []ids.ID{} + for i := 0; i < defaultHistoryLength+1; i++ { + key := make([]byte, 16) + _, _ = rand.Read(key) + require.NoError(db.Put(key, nil)) + root, err := db.GetMerkleRoot(context.Background()) + require.NoError(err) + roots = append(roots, root) + } + + _, err = db.GetChangeProof( + context.Background(), + roots[len(roots)-1], + ids.GenerateTestID(), + maybe.Nothing[[]byte](), + maybe.Nothing[[]byte](), + 50, + ) require.ErrorIs(err, ErrNoEndRoot) require.ErrorIs(err, ErrInsufficientHistory) + + _, err = db.GetChangeProof( + context.Background(), + roots[0], + roots[len(roots)-1], + maybe.Nothing[[]byte](), + maybe.Nothing[[]byte](), + 50, + ) + require.NotErrorIs(err, ErrNoEndRoot) + require.ErrorIs(err, ErrInsufficientHistory) + + _, err = db.GetChangeProof( + context.Background(), + roots[1], + roots[len(roots)-1], + maybe.Nothing[[]byte](), + maybe.Nothing[[]byte](), + 50, + ) + require.NoError(err) } func Test_ChangeProof_BadBounds(t *testing.T) { @@ -816,13 +873,26 @@ func Test_ChangeProof_Verify_Bad_Data(t *testing.T) { dbClone, err := getBasicDB() require.NoError(err) - proof, err := db.GetChangeProof(context.Background(), startRoot, endRoot, maybe.Some([]byte{2}), maybe.Some([]byte{3, 0}), 50) + proof, err := db.GetChangeProof( + context.Background(), + startRoot, + endRoot, + maybe.Some([]byte{2}), + maybe.Some([]byte{3, 0}), + 50, + ) require.NoError(err) require.NotNil(proof) tt.malform(proof) - err = dbClone.VerifyChangeProof(context.Background(), proof, maybe.Some([]byte{2}), maybe.Some([]byte{3, 0}), db.getMerkleRoot()) + err = dbClone.VerifyChangeProof( + context.Background(), + proof, + maybe.Some([]byte{2}), + maybe.Some([]byte{3, 0}), + db.getMerkleRoot(), + ) require.ErrorIs(err, tt.expectedErr) }) } @@ -850,7 +920,7 @@ func Test_ChangeProof_Syntactic_Verify(t *testing.T) { proof: &ChangeProof{}, start: maybe.Nothing[[]byte](), end: maybe.Nothing[[]byte](), - expectedErr: ErrNoMerkleProof, + expectedErr: ErrEmptyProof, }, { name: "no end proof", @@ -1627,6 +1697,9 @@ func FuzzRangeProofInvariants(f *testing.F) { if maxProofLen == 0 { t.SkipNow() } + if numKeyValues == 0 { + t.SkipNow() + } // Make sure proof bounds are valid if len(endBytes) != 0 && bytes.Compare(startBytes, endBytes) > 0 { @@ -1657,15 +1730,19 @@ func FuzzRangeProofInvariants(f *testing.F) { end = maybe.Some(endBytes) } + rootID, err := db.GetMerkleRoot(context.Background()) + require.NoError(err) + rangeProof, err := db.GetRangeProof( context.Background(), start, end, int(maxProofLen), ) - require.NoError(err) - - rootID, err := db.GetMerkleRoot(context.Background()) + if rootID == ids.Empty { + require.ErrorIs(err, ErrEmptyProof) + return + } require.NoError(err) require.NoError(rangeProof.Verify( @@ -1761,10 +1838,15 @@ func FuzzProofVerification(f *testing.F) { deletePortion, ) + if db.getMerkleRoot() == ids.Empty { + return + } + proof, err := db.GetProof( context.Background(), key, ) + require.NoError(err) rootID, err := db.GetMerkleRoot(context.Background()) diff --git a/x/merkledb/trie.go b/x/merkledb/trie.go index d4b01d2de29a..1e6870df27cb 100644 --- a/x/merkledb/trie.go +++ b/x/merkledb/trie.go @@ -12,13 +12,15 @@ import ( ) type MerkleRootGetter interface { - // GetMerkleRoot returns the merkle root of the Trie + // GetMerkleRoot returns the merkle root of the trie. + // Returns ids.Empty if the trie is empty. GetMerkleRoot(ctx context.Context) (ids.ID, error) } type ProofGetter interface { // GetProof generates a proof of the value associated with a particular key, // or a proof of its absence from the trie + // Returns ErrEmptyProof if the trie is empty. GetProof(ctx context.Context, keyBytes []byte) (*Proof, error) } @@ -38,6 +40,11 @@ type ReadOnlyTrie interface { // database.ErrNotFound if the key is not present getValue(key Key) ([]byte, error) + // If this trie is non-empty, returns the root node. + // Must be copied before modification. + // Otherwise returns Nothing. + getRoot() maybe.Maybe[*node] + // get an editable copy of the node with the given key path // hasValue indicates which db to look in (value or intermediate) getEditableNode(key Key, hasValue bool) (*node, error) @@ -46,6 +53,7 @@ type ReadOnlyTrie interface { // keys in range [start, end]. // If [start] is Nothing, there's no lower bound on the range. // If [end] is Nothing, there's no upper bound on the range. + // Returns ErrEmptyProof if the trie is empty. GetRangeProof(ctx context.Context, start maybe.Maybe[[]byte], end maybe.Maybe[[]byte], maxLength int) (*RangeProof, error) database.Iteratee diff --git a/x/merkledb/trie_test.go b/x/merkledb/trie_test.go index a431dd6b254d..fec8a435d60a 100644 --- a/x/merkledb/trie_test.go +++ b/x/merkledb/trie_test.go @@ -124,9 +124,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { return nil })) - // Just the root - require.Len(nodePath, 1) - require.Equal(trie.sentinelNode, nodePath[0]) + require.Empty(nodePath) // Insert a key key1 := []byte{0} @@ -143,17 +141,15 @@ func TestTrieViewVisitPathToKey(t *testing.T) { trie = trieIntf.(*trieView) require.NoError(trie.calculateNodeIDs(context.Background())) - nodePath = make([]*node, 0, 2) + nodePath = make([]*node, 0, 1) require.NoError(trie.visitPathToKey(ToKey(key1), func(n *node) error { nodePath = append(nodePath, n) return nil })) - // Root and 1 value - require.Len(nodePath, 2) - - require.Equal(trie.sentinelNode, nodePath[0]) - require.Equal(ToKey(key1), nodePath[1].key) + // 1 value + require.Len(nodePath, 1) + require.Equal(ToKey(key1), nodePath[0].key) // Insert another key which is a child of the first key2 := []byte{0, 1} @@ -170,17 +166,20 @@ func TestTrieViewVisitPathToKey(t *testing.T) { trie = trieIntf.(*trieView) require.NoError(trie.calculateNodeIDs(context.Background())) - nodePath = make([]*node, 0, 3) + nodePath = make([]*node, 0, 2) require.NoError(trie.visitPathToKey(ToKey(key2), func(n *node) error { nodePath = append(nodePath, n) return nil })) - require.Len(nodePath, 3) - - require.Equal(trie.sentinelNode, nodePath[0]) - require.Equal(ToKey(key1), nodePath[1].key) - require.Equal(ToKey(key2), nodePath[2].key) - + require.Len(nodePath, 2) + require.Equal(trie.root.Value(), nodePath[0]) + require.Equal(ToKey(key1), nodePath[0].key) + require.Equal(ToKey(key2), nodePath[1].key) + + // Trie is: + // [0] + // | + // [0,1] // Insert a key which shares no prefix with the others key3 := []byte{255} trieIntf, err = trie.NewView( @@ -196,6 +195,12 @@ func TestTrieViewVisitPathToKey(t *testing.T) { trie = trieIntf.(*trieView) require.NoError(trie.calculateNodeIDs(context.Background())) + // Trie is: + // [] + // / \ + // [0] [255] + // | + // [0,1] nodePath = make([]*node, 0, 2) require.NoError(trie.visitPathToKey(ToKey(key3), func(n *node) error { nodePath = append(nodePath, n) @@ -203,8 +208,8 @@ func TestTrieViewVisitPathToKey(t *testing.T) { })) require.Len(nodePath, 2) - - require.Equal(trie.sentinelNode, nodePath[0]) + require.Equal(trie.root.Value(), nodePath[0]) + require.Zero(trie.root.Value().key.length) require.Equal(ToKey(key3), nodePath[1].key) // Other key path not affected @@ -214,8 +219,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { return nil })) require.Len(nodePath, 3) - - require.Equal(trie.sentinelNode, nodePath[0]) + require.Equal(trie.root.Value(), nodePath[0]) require.Equal(ToKey(key1), nodePath[1].key) require.Equal(ToKey(key2), nodePath[2].key) @@ -228,7 +232,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { })) require.Len(nodePath, 3) - require.Equal(trie.sentinelNode, nodePath[0]) + require.Equal(trie.root.Value(), nodePath[0]) require.Equal(ToKey(key1), nodePath[1].key) require.Equal(ToKey(key2), nodePath[2].key) @@ -240,7 +244,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { return nil })) require.Len(nodePath, 1) - require.Equal(trie.sentinelNode, nodePath[0]) + require.Equal(trie.root.Value(), nodePath[0]) } func Test_Trie_ViewOnCommitedView(t *testing.T) { @@ -490,7 +494,7 @@ func Test_Trie_ExpandOnKeyPath(t *testing.T) { require.Equal([]byte("value12"), value) } -func Test_Trie_compressedKeys(t *testing.T) { +func Test_Trie_CompressedKeys(t *testing.T) { require := require.New(t) dbTrie, err := getBasicDB() @@ -589,9 +593,9 @@ func Test_Trie_HashCountOnBranch(t *testing.T) { require.NoError(err) require.NotNil(dbTrie) - key1, key2, keyPrefix := []byte("key12"), []byte("key1F"), []byte("key1") + key1, key2, keyPrefix := []byte("12"), []byte("1F"), []byte("1") - trieIntf, err := dbTrie.NewView( + view1, err := dbTrie.NewView( context.Background(), ViewChanges{ BatchOps: []database.BatchOp{ @@ -599,11 +603,13 @@ func Test_Trie_HashCountOnBranch(t *testing.T) { }, }) require.NoError(err) - trie := trieIntf.(*trieView) + + // trie is: + // [1] // create new node with common prefix whose children // are key1, key2 - view2, err := trie.NewView( + view2, err := view1.NewView( context.Background(), ViewChanges{ BatchOps: []database.BatchOp{ @@ -612,20 +618,27 @@ func Test_Trie_HashCountOnBranch(t *testing.T) { }) require.NoError(err) + // trie is: + // [1] + // / \ + // [12] [1F] + // clear the hash count to ignore setup dbTrie.metrics.(*mockMetrics).hashCount = 0 - // force the new root to calculate + // calculate the root _, err = view2.GetMerkleRoot(context.Background()) require.NoError(err) - // Make sure the branch node with the common prefix was created. + // Make sure the root is an intermediate node with the expected common prefix. // Note it's only created on call to GetMerkleRoot, not in NewView. - _, err = view2.getEditableNode(ToKey(keyPrefix), false) + prefixNode, err := view2.getEditableNode(ToKey(keyPrefix), false) require.NoError(err) + root := view2.getRoot().Value() + require.Equal(root, prefixNode) + require.Len(root.children, 2) - // only hashes the new branch node, the new child node, and root - // shouldn't hash the existing node + // Had to hash each of the new nodes ("12" and "1F") and the new root require.Equal(int64(3), dbTrie.metrics.(*mockMetrics).hashCount) } @@ -667,7 +680,16 @@ func Test_Trie_HashCountOnDelete(t *testing.T) { require.NoError(err) require.NoError(view.CommitToDB(context.Background())) - // the root is the only updated node so only one new hash + // trie is: + // [key0] (first 28 bits) + // / \ + // [key1] [key2] + root := view.getRoot().Value() + expectedRootKey := ToKey([]byte("key0")).Take(28) + require.Equal(expectedRootKey, root.key) + require.Len(root.children, 2) + + // Had to hash the new root but not [key1] or [key2] nodes require.Equal(oldCount+1, dbTrie.metrics.(*mockMetrics).hashCount) } @@ -762,9 +784,11 @@ func Test_Trie_ChainDeletion(t *testing.T) { require.NoError(err) require.NoError(newTrie.(*trieView).calculateNodeIDs(context.Background())) - root, err := newTrie.getEditableNode(Key{}, false) + maybeRoot := newTrie.getRoot() require.NoError(err) - require.Len(root.children, 1) + require.True(maybeRoot.HasValue()) + require.Equal([]byte("value0"), maybeRoot.Value().value.Value()) + require.Len(maybeRoot.Value().children, 1) newTrie, err = newTrie.NewView( context.Background(), @@ -779,10 +803,10 @@ func Test_Trie_ChainDeletion(t *testing.T) { ) require.NoError(err) require.NoError(newTrie.(*trieView).calculateNodeIDs(context.Background())) - root, err = newTrie.getEditableNode(Key{}, false) - require.NoError(err) - // since all values have been deleted, the nodes should have been cleaned up - require.Empty(root.children) + + // trie should be empty + root := newTrie.getRoot() + require.False(root.HasValue()) } func Test_Trie_Invalidate_Siblings_On_Commit(t *testing.T) { @@ -829,54 +853,63 @@ func Test_Trie_NodeCollapse(t *testing.T) { require.NoError(err) require.NotNil(dbTrie) + kvs := []database.BatchOp{ + {Key: []byte("k"), Value: []byte("value0")}, + {Key: []byte("ke"), Value: []byte("value1")}, + {Key: []byte("key"), Value: []byte("value2")}, + {Key: []byte("key1"), Value: []byte("value3")}, + {Key: []byte("key2"), Value: []byte("value4")}, + } + trie, err := dbTrie.NewView( context.Background(), ViewChanges{ - BatchOps: []database.BatchOp{ - {Key: []byte("k"), Value: []byte("value0")}, - {Key: []byte("ke"), Value: []byte("value1")}, - {Key: []byte("key"), Value: []byte("value2")}, - {Key: []byte("key1"), Value: []byte("value3")}, - {Key: []byte("key2"), Value: []byte("value4")}, - }, + BatchOps: kvs, }, ) require.NoError(err) require.NoError(trie.(*trieView).calculateNodeIDs(context.Background())) - root, err := trie.getEditableNode(Key{}, false) - require.NoError(err) - require.Len(root.children, 1) - root, err = trie.getEditableNode(Key{}, false) - require.NoError(err) - require.Len(root.children, 1) + for _, kv := range kvs { + node, err := trie.getEditableNode(ToKey(kv.Key), true) + require.NoError(err) - firstNode, err := trie.getEditableNode(getSingleChildKey(root, dbTrie.tokenSize), true) - require.NoError(err) - require.Len(firstNode.children, 1) + require.Equal(kv.Value, node.value.Value()) + } + + // delete some values + deletedKVs, remainingKVs := kvs[:3], kvs[3:] + deleteOps := make([]database.BatchOp, len(deletedKVs)) + for i, kv := range deletedKVs { + deleteOps[i] = database.BatchOp{ + Key: kv.Key, + Delete: true, + } + } - // delete the middle values trie, err = trie.NewView( context.Background(), ViewChanges{ - BatchOps: []database.BatchOp{ - {Key: []byte("k"), Delete: true}, - {Key: []byte("ke"), Delete: true}, - {Key: []byte("key"), Delete: true}, - }, + BatchOps: deleteOps, }, ) require.NoError(err) + require.NoError(trie.(*trieView).calculateNodeIDs(context.Background())) - root, err = trie.getEditableNode(Key{}, false) - require.NoError(err) - require.Len(root.children, 1) + for _, kv := range deletedKVs { + _, err := trie.getEditableNode(ToKey(kv.Key), true) + require.ErrorIs(err, database.ErrNotFound) + } - firstNode, err = trie.getEditableNode(getSingleChildKey(root, dbTrie.tokenSize), true) - require.NoError(err) - require.Len(firstNode.children, 2) + // make sure the other values are still there + for _, kv := range remainingKVs { + node, err := trie.getEditableNode(ToKey(kv.Key), true) + require.NoError(err) + + require.Equal(kv.Value, node.value.Value()) + } } func Test_Trie_MultipleStates(t *testing.T) { diff --git a/x/merkledb/trieview.go b/x/merkledb/trieview.go index 730d4b0187d0..35be62f8a5f9 100644 --- a/x/merkledb/trieview.go +++ b/x/merkledb/trieview.go @@ -37,7 +37,7 @@ var ( ) ErrVisitPathToKey = errors.New("failed to visit expected node during insertion") ErrStartAfterEnd = errors.New("start key > end key") - ErrNoValidRoot = errors.New("a valid root was not provided to the trieView constructor") + ErrNoChanges = errors.New("no changes provided") ErrParentNotDatabase = errors.New("parent trie is not database") ErrNodesAlreadyCalculated = errors.New("cannot modify the trie after the node changes have been calculated") ) @@ -96,9 +96,8 @@ type trieView struct { db *merkleDB - // The nil key node - // It is either the root of the trie or the root of the trie is its single child node - sentinelNode *node + // The root of the trie represented by this view. + root maybe.Maybe[*node] tokenSize int } @@ -142,26 +141,17 @@ func (t *trieView) NewView( } // Creates a new view with the given [parentTrie]. -// Assumes [parentTrie] isn't locked. func newTrieView( db *merkleDB, parentTrie TrieView, changes ViewChanges, ) (*trieView, error) { - sentinelNode, err := parentTrie.getEditableNode(Key{}, false /* hasValue */) - if err != nil { - if errors.Is(err, database.ErrNotFound) { - return nil, ErrNoValidRoot - } - return nil, err - } - newView := &trieView{ - sentinelNode: sentinelNode, - db: db, - parentTrie: parentTrie, - changes: newChangeSummary(len(changes.BatchOps) + len(changes.MapOps)), - tokenSize: db.tokenSize, + root: maybe.Bind(parentTrie.getRoot(), (*node).clone), + db: db, + parentTrie: parentTrie, + changes: newChangeSummary(len(changes.BatchOps) + len(changes.MapOps)), + tokenSize: db.tokenSize, } for _, op := range changes.BatchOps { @@ -192,26 +182,22 @@ func newTrieView( return newView, nil } -// Creates a view of the db at a historical root using the provided changes +// Creates a view of the db at a historical root using the provided [changes]. +// Returns ErrNoChanges if [changes] is empty. func newHistoricalTrieView( db *merkleDB, changes *changeSummary, ) (*trieView, error) { if changes == nil { - return nil, ErrNoValidRoot - } - - passedSentinelChange, ok := changes.nodes[Key{}] - if !ok { - return nil, ErrNoValidRoot + return nil, ErrNoChanges } newView := &trieView{ - sentinelNode: passedSentinelChange.after, - db: db, - parentTrie: db, - changes: changes, - tokenSize: db.tokenSize, + root: changes.rootChange.after, + db: db, + parentTrie: db, + changes: changes, + tokenSize: db.tokenSize, } // since this is a set of historical changes, all nodes have already been calculated // since no new changes have occurred, no new calculations need to be done @@ -220,6 +206,10 @@ func newHistoricalTrieView( return newView, nil } +func (t *trieView) getRoot() maybe.Maybe[*node] { + return t.root +} + // Recalculates the node IDs for all changed nodes in the trie. // Cancelling [ctx] doesn't cancel calculation. It's used only for tracing. func (t *trieView) calculateNodeIDs(ctx context.Context) error { @@ -231,6 +221,8 @@ func (t *trieView) calculateNodeIDs(ctx context.Context) error { } defer t.nodesAlreadyCalculated.Set(true) + oldRoot := maybe.Bind(t.root, (*node).clone) + // We wait to create the span until after checking that we need to actually // calculateNodeIDs to make traces more useful (otherwise there may be a span // per key modified even though IDs are not re-calculated). @@ -250,15 +242,17 @@ func (t *trieView) calculateNodeIDs(ctx context.Context) error { } } - _ = t.db.calculateNodeIDsSema.Acquire(context.Background(), 1) - t.changes.rootID = t.calculateNodeIDsHelper(t.sentinelNode) - t.db.calculateNodeIDsSema.Release(1) + if !t.root.IsNothing() { + _ = t.db.calculateNodeIDsSema.Acquire(context.Background(), 1) + t.changes.rootID = t.calculateNodeIDsHelper(t.root.Value()) + t.db.calculateNodeIDsSema.Release(1) + } else { + t.changes.rootID = ids.Empty + } - // If the sentinel node is not the root, the trie's root is the sentinel node's only child - if !isSentinelNodeTheRoot(t.sentinelNode) { - for _, childEntry := range t.sentinelNode.children { - t.changes.rootID = childEntry.id - } + t.changes.rootChange = change[maybe.Maybe[*node]]{ + before: oldRoot, + after: t.root, } // ensure no ancestor changes occurred during execution @@ -320,11 +314,15 @@ func (t *trieView) GetProof(ctx context.Context, key []byte) (*Proof, error) { return t.getProof(ctx, key) } -// Returns a proof that [bytesPath] is in or not in trie [t]. +// Returns a proof that [key] is in or not in [t]. func (t *trieView) getProof(ctx context.Context, key []byte) (*Proof, error) { _, span := t.db.infoTracer.Start(ctx, "MerkleDB.trieview.getProof") defer span.End() + if t.root.IsNothing() { + return nil, ErrEmptyProof + } + proof := &Proof{ Key: ToKey(key), } @@ -332,26 +330,18 @@ func (t *trieView) getProof(ctx context.Context, key []byte) (*Proof, error) { var closestNode *node if err := t.visitPathToKey(proof.Key, func(n *node) error { closestNode = n + // From root --> node from left --> right. proof.Path = append(proof.Path, n.asProofNode()) return nil }); err != nil { return nil, err } - root, err := t.getRoot() - if err != nil { - return nil, err - } - // The sentinel node is always the first node in the path. - // If the sentinel node is not the root, remove it from the proofPath. - if root != t.sentinelNode { - proof.Path = proof.Path[1:] - - // if there are no nodes in the proof path, add the root to serve as an exclusion proof - if len(proof.Path) == 0 { - proof.Path = []ProofNode{root.asProofNode()} - return proof, nil - } + if len(proof.Path) == 0 { + // No key in [t] is a prefix of [key]. + // The root alone proves that [key] isn't in [t]. + proof.Path = append(proof.Path, t.root.Value().asProofNode()) + return proof, nil } if closestNode.key == proof.Key { @@ -407,6 +397,10 @@ func (t *trieView) GetRangeProof( return nil, err } + if t.root.IsNothing() { + return nil, ErrEmptyProof + } + var result RangeProof result.KeyValues = make([]KeyValue, 0, initKeyValuesSize) @@ -462,19 +456,6 @@ func (t *trieView) GetRangeProof( result.StartProof = result.StartProof[i:] } - if len(result.StartProof) == 0 && len(result.EndProof) == 0 && len(result.KeyValues) == 0 { - // If the range is empty, return the root proof. - root, err := t.getRoot() - if err != nil { - return nil, err - } - rootProof, err := t.getProof(ctx, root.key.Bytes()) - if err != nil { - return nil, err - } - result.EndProof = rootProof.Path - } - if t.isInvalid() { return nil, ErrInvalid } @@ -630,14 +611,14 @@ func (t *trieView) remove(key Key) error { keyNode, err := t.getNode(key, true) if err != nil { if errors.Is(err, database.ErrNotFound) { - // key didn't exist + // [key] isn't in the trie. return nil } return err } - // node doesn't contain a value if !keyNode.hasValue() { + // [key] doesn't have a value. return nil } @@ -655,43 +636,50 @@ func (t *trieView) remove(key Key) error { } nodeToDelete.setValue(maybe.Nothing[[]byte]()) - if len(nodeToDelete.children) != 0 { - // merge this node and its child into a single node if possible - return t.compressNodePath(parent, nodeToDelete) - } // if the removed node has no children, the node can be removed from the trie - if err := t.recordNodeDeleted(nodeToDelete); err != nil { - return err - } - if parent != nil { + if len(nodeToDelete.children) == 0 { + if err := t.recordNodeDeleted(nodeToDelete); err != nil { + return err + } + + if nodeToDelete.key == t.root.Value().key { + // We deleted the root. The trie is empty now. + t.root = maybe.Nothing[*node]() + return nil + } + + // Note [parent] != nil since [nodeToDelete.key] != [t.root.key]. + // i.e. There's the root and at least one more node. parent.removeChild(nodeToDelete, t.tokenSize) // merge the parent node and its child into a single node if possible return t.compressNodePath(grandParent, parent) } - return nil + + // merge this node and its descendants into a single node if possible + return t.compressNodePath(parent, nodeToDelete) } -// Merges together nodes in the inclusive descendants of [node] that +// Merges together nodes in the inclusive descendants of [n] that // have no value and a single child into one node with a compressed // path until a node that doesn't meet those criteria is reached. -// [parent] is [node]'s parent. +// [parent] is [n]'s parent. If [parent] is nil, [n] is the root +// node and [t.root] is updated to [n]. // Assumes at least one of the following is true: -// * [node] has a value. -// * [node] has children. +// * [n] has a value. +// * [n] has children. // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) compressNodePath(parent, node *node) error { +func (t *trieView) compressNodePath(parent, n *node) error { if t.nodesAlreadyCalculated.Get() { return ErrNodesAlreadyCalculated } - // don't collapse into this node if it's the root, doesn't have 1 child, or has a value - if parent == nil || len(node.children) != 1 || node.hasValue() { + if len(n.children) != 1 || n.hasValue() { return nil } - if err := t.recordNodeDeleted(node); err != nil { + if err := t.recordNodeDeleted(n); err != nil { return err } @@ -702,13 +690,20 @@ func (t *trieView) compressNodePath(parent, node *node) error { // There is only one child, but we don't know the index. // "Cycle" over the key/values to find the only child. // Note this iteration once because len(node.children) == 1. - for index, entry := range node.children { - childKey = node.key.Extend(ToToken(index, t.tokenSize), entry.compressedKey) + for index, entry := range n.children { + childKey = n.key.Extend(ToToken(index, t.tokenSize), entry.compressedKey) childEntry = entry } - // [node] is the first node with multiple children. - // combine it with the [node] passed in. + if parent == nil { + root, err := t.getNode(childKey, childEntry.hasValue) + if err != nil { + return err + } + t.root = maybe.Some(root) + return nil + } + parent.setChildEntry(childKey.Token(parent.key.length, t.tokenSize), &child{ compressedKey: childKey.Skip(parent.key.length + t.tokenSize), @@ -718,15 +713,21 @@ func (t *trieView) compressNodePath(parent, node *node) error { return t.recordNodeChange(parent) } -// Returns the nodes along the path to [key]. -// The first node is the root, and the last node is either the node with the -// given [key], if it's in the trie, or the node with the largest prefix of -// the [key] if it isn't in the trie. -// Always returns at least the root node. +// Calls [visitNode] on each node along the path to [key]. +// The first node (if any) is the root, and the last node is either the +// node with the given [key], if it's in [t], or the node with the +// largest prefix of [key] otherwise. func (t *trieView) visitPathToKey(key Key, visitNode func(*node) error) error { + if t.root.IsNothing() { + return nil + } + root := t.root.Value() + if !key.HasPrefix(root.key) { + return nil + } var ( - // all node paths start at the sentinelNode since its nil key is a prefix of all keys - currentNode = t.sentinelNode + // all node paths start at the root + currentNode = root err error ) if err := visitNode(currentNode); err != nil { @@ -785,14 +786,49 @@ func (t *trieView) insert( return nil, ErrNodesAlreadyCalculated } + if t.root.IsNothing() { + // the trie is empty, so create a new root node. + root := newNode(key) + root.setValue(value) + t.root = maybe.Some(root) + return root, t.recordNewNode(root) + } + + // Find the node that most closely matches [key]. var closestNode *node if err := t.visitPathToKey(key, func(n *node) error { closestNode = n + // Need to recalculate ID for all nodes on path to [key]. return t.recordNodeChange(n) }); err != nil { return nil, err } + if closestNode == nil { + // [t.root.key] isn't a prefix of [key]. + var ( + oldRoot = t.root.Value() + commonPrefixLength = getLengthOfCommonPrefix(oldRoot.key, key, 0 /*offset*/, t.tokenSize) + commonPrefix = oldRoot.key.Take(commonPrefixLength) + newRoot = newNode(commonPrefix) + oldRootID = oldRoot.calculateID(t.db.metrics) + ) + + // Call addChildWithID instead of addChild so the old root is added + // to the new root with the correct ID. + // TODO: + // [oldRootID] shouldn't need to be calculated here. + // Either oldRootID should already be calculated or will be calculated at the end with the other nodes + // Initialize the t.changes.rootID during newTrieView and then use that here instead of oldRootID + newRoot.addChildWithID(oldRoot, t.tokenSize, oldRootID) + if err := t.recordNewNode(newRoot); err != nil { + return nil, err + } + t.root = maybe.Some(newRoot) + + closestNode = newRoot + } + // a node with that exact key already exists so update its value if closestNode.key == key { closestNode.setValue(value) @@ -890,26 +926,9 @@ func (t *trieView) recordNodeChange(after *node) error { // Records that the node associated with the given key has been deleted. // Must not be called after [calculateNodeIDs] has returned. func (t *trieView) recordNodeDeleted(after *node) error { - // don't delete the root. - if after.key.length == 0 { - return t.recordKeyChange(after.key, after, after.hasValue(), false /* newNode */) - } return t.recordKeyChange(after.key, nil, after.hasValue(), false /* newNode */) } -func (t *trieView) getRoot() (*node, error) { - if !isSentinelNodeTheRoot(t.sentinelNode) { - // sentinelNode has one child, which is the root - for index, childEntry := range t.sentinelNode.children { - return t.getNode( - t.sentinelNode.key.Extend(ToToken(index, t.tokenSize), childEntry.compressedKey), - childEntry.hasValue) - } - } - - return t.sentinelNode, nil -} - // Records that the node associated with the given key has been changed. // If it is an existing node, record what its value was before it was changed. // Must not be called after [calculateNodeIDs] has returned. diff --git a/x/sync/client_test.go b/x/sync/client_test.go index f6c67debe5ee..0c71ccb52e75 100644 --- a/x/sync/client_test.go +++ b/x/sync/client_test.go @@ -339,11 +339,11 @@ func TestGetRangeProof(t *testing.T) { BytesLimit: defaultRequestByteSizeLimit, }, modifyResponse: func(response *merkledb.RangeProof) { - response.KeyValues = nil response.StartProof = nil response.EndProof = nil + response.KeyValues = nil }, - expectedErr: merkledb.ErrNoMerkleProof, + expectedErr: merkledb.ErrEmptyProof, }, } @@ -524,7 +524,7 @@ func TestGetChangeProof(t *testing.T) { newDefaultDBConfig(), ) require.NoError(t, err) - startRoot, err := serverDB.GetMerkleRoot(context.Background()) // TODO uncomment + startRoot, err := serverDB.GetMerkleRoot(context.Background()) require.NoError(t, err) // create changes @@ -566,6 +566,8 @@ func TestGetChangeProof(t *testing.T) { endRoot, err := serverDB.GetMerkleRoot(context.Background()) require.NoError(t, err) + fakeRootID := ids.GenerateTestID() + tests := map[string]struct { db DB request *pb.SyncGetChangeProofRequest @@ -662,24 +664,11 @@ func TestGetChangeProof(t *testing.T) { }, expectedErr: merkledb.ErrInvalidProof, }, - "range proof response happy path": { - request: &pb.SyncGetChangeProofRequest{ - // Server doesn't have the (non-existent) start root - // so should respond with range proof. - StartRootHash: ids.Empty[:], - EndRootHash: endRoot[:], - KeyLimit: defaultRequestKeyLimit, - BytesLimit: defaultRequestByteSizeLimit, - }, - modifyChangeProofResponse: nil, - expectedErr: nil, - expectRangeProof: true, - }, "range proof response; remove first key": { request: &pb.SyncGetChangeProofRequest{ // Server doesn't have the (non-existent) start root // so should respond with range proof. - StartRootHash: ids.Empty[:], + StartRootHash: fakeRootID[:], EndRootHash: endRoot[:], KeyLimit: defaultRequestKeyLimit, BytesLimit: defaultRequestByteSizeLimit, diff --git a/x/sync/g_db/db_client.go b/x/sync/g_db/db_client.go index af1ce1c9080b..376bff6aeab9 100644 --- a/x/sync/g_db/db_client.go +++ b/x/sync/g_db/db_client.go @@ -45,6 +45,10 @@ func (c *DBClient) GetChangeProof( endKey maybe.Maybe[[]byte], keyLimit int, ) (*merkledb.ChangeProof, error) { + if endRootID == ids.Empty { + return nil, merkledb.ErrEmptyProof + } + resp, err := c.client.GetChangeProof(ctx, &pb.GetChangeProofRequest{ StartRootHash: startRootID[:], EndRootHash: endRootID[:], @@ -136,6 +140,10 @@ func (c *DBClient) GetRangeProofAtRoot( endKey maybe.Maybe[[]byte], keyLimit int, ) (*merkledb.RangeProof, error) { + if rootID == ids.Empty { + return nil, merkledb.ErrEmptyProof + } + resp, err := c.client.GetRangeProof(ctx, &pb.GetRangeProofRequest{ RootHash: rootID[:], StartKey: &pb.MaybeBytes{ diff --git a/x/sync/manager.go b/x/sync/manager.go index a7a6858d5122..d094f33165cb 100644 --- a/x/sync/manager.go +++ b/x/sync/manager.go @@ -266,6 +266,18 @@ func (m *Manager) getAndApplyChangeProof(ctx context.Context, work *workItem) { return } + if targetRootID == ids.Empty { + // The trie is empty after this change. + // Delete all the key-value pairs in the range. + if err := m.config.DB.Clear(); err != nil { + m.setError(err) + return + } + work.start = maybe.Nothing[[]byte]() + m.completeWorkItem(ctx, work, maybe.Nothing[[]byte](), targetRootID, nil) + return + } + changeOrRangeProof, err := m.config.Client.GetChangeProof( ctx, &pb.SyncGetChangeProofRequest{ @@ -332,6 +344,17 @@ func (m *Manager) getAndApplyChangeProof(ctx context.Context, work *workItem) { // Assumes [m.workLock] is not held. func (m *Manager) getAndApplyRangeProof(ctx context.Context, work *workItem) { targetRootID := m.getTargetRoot() + + if targetRootID == ids.Empty { + if err := m.config.DB.Clear(); err != nil { + m.setError(err) + return + } + work.start = maybe.Nothing[[]byte]() + m.completeWorkItem(ctx, work, maybe.Nothing[[]byte](), targetRootID, nil) + return + } + proof, err := m.config.Client.GetRangeProof(ctx, &pb.SyncGetRangeProofRequest{ RootHash: targetRootID[:], diff --git a/x/sync/network_server.go b/x/sync/network_server.go index 8027a05042f1..e31e6d8f3ace 100644 --- a/x/sync/network_server.go +++ b/x/sync/network_server.go @@ -397,6 +397,8 @@ func validateChangeProofRequest(req *pb.SyncGetChangeProofRequest) error { return errInvalidStartRootHash case len(req.EndRootHash) != hashing.HashLen: return errInvalidEndRootHash + case bytes.Equal(req.EndRootHash, ids.Empty[:]): + return merkledb.ErrEmptyProof case req.StartKey != nil && req.StartKey.IsNothing && len(req.StartKey.Value) > 0: return errInvalidStartKey case req.EndKey != nil && req.EndKey.IsNothing && len(req.EndKey.Value) > 0: @@ -418,6 +420,8 @@ func validateRangeProofRequest(req *pb.SyncGetRangeProofRequest) error { return errInvalidKeyLimit case len(req.RootHash) != ids.IDLen: return errInvalidRootHash + case bytes.Equal(req.RootHash, ids.Empty[:]): + return merkledb.ErrEmptyProof case req.StartKey != nil && req.StartKey.IsNothing && len(req.StartKey.Value) > 0: return errInvalidStartKey case req.EndKey != nil && req.EndKey.IsNothing && len(req.EndKey.Value) > 0: diff --git a/x/sync/network_server_test.go b/x/sync/network_server_test.go index 7b83afc3e7d5..a73aa3736979 100644 --- a/x/sync/network_server_test.go +++ b/x/sync/network_server_test.go @@ -93,6 +93,14 @@ func Test_Server_GetRangeProof(t *testing.T) { }, expectedMaxResponseBytes: defaultRequestByteSizeLimit, }, + "empty proof": { + request: &pb.SyncGetRangeProofRequest{ + RootHash: ids.Empty[:], + KeyLimit: defaultRequestKeyLimit, + BytesLimit: defaultRequestByteSizeLimit, + }, + proofNil: true, + }, } for name, test := range tests { @@ -252,7 +260,7 @@ func Test_Server_GetChangeProof(t *testing.T) { request: &pb.SyncGetChangeProofRequest{ // This root doesn't exist so server has insufficient history // to serve a change proof - StartRootHash: ids.Empty[:], + StartRootHash: fakeRootID[:], EndRootHash: endRoot[:], KeyLimit: defaultRequestKeyLimit, BytesLimit: defaultRequestByteSizeLimit, @@ -272,6 +280,16 @@ func Test_Server_GetChangeProof(t *testing.T) { expectedMaxResponseBytes: defaultRequestByteSizeLimit, proofNil: true, }, + "empt proof": { + request: &pb.SyncGetChangeProofRequest{ + StartRootHash: fakeRootID[:], + EndRootHash: ids.Empty[:], + KeyLimit: defaultRequestKeyLimit, + BytesLimit: defaultRequestByteSizeLimit, + }, + expectedMaxResponseBytes: defaultRequestByteSizeLimit, + proofNil: true, + }, } for name, test := range tests { diff --git a/x/sync/sync_test.go b/x/sync/sync_test.go index 71871e95db56..f970229aa2f5 100644 --- a/x/sync/sync_test.go +++ b/x/sync/sync_test.go @@ -102,14 +102,17 @@ func Test_Completion(t *testing.T) { newDefaultDBConfig(), ) require.NoError(err) + emptyRoot, err := emptyDB.GetMerkleRoot(context.Background()) require.NoError(err) + db, err := merkledb.New( context.Background(), memdb.New(), newDefaultDBConfig(), ) require.NoError(err) + syncer, err := NewManager(ManagerConfig{ DB: db, Client: newCallthroughSyncClient(ctrl, emptyDB), @@ -120,8 +123,10 @@ func Test_Completion(t *testing.T) { }) require.NoError(err) require.NotNil(syncer) + require.NoError(syncer.Start(context.Background())) require.NoError(syncer.Wait(context.Background())) + syncer.workLock.Lock() require.Zero(syncer.unprocessedWork.Len()) require.Equal(1, syncer.processedWork.Len()) @@ -332,25 +337,26 @@ func Test_Sync_FindNextKey_BranchInLocal(t *testing.T) { require.NoError(db.Put([]byte{0x11}, []byte{1})) require.NoError(db.Put([]byte{0x11, 0x11}, []byte{2})) - syncRoot, err := db.GetMerkleRoot(context.Background()) + targetRoot, err := db.GetMerkleRoot(context.Background()) require.NoError(err) + proof, err := db.GetProof(context.Background(), []byte{0x11, 0x11}) require.NoError(err) syncer, err := NewManager(ManagerConfig{ DB: db, Client: NewMockClient(ctrl), - TargetRoot: syncRoot, + TargetRoot: targetRoot, SimultaneousWorkLimit: 5, Log: logging.NoLog{}, BranchFactor: merkledb.BranchFactor16, }) require.NoError(err) - require.NoError(db.Put([]byte{0x12}, []byte{4})) + require.NoError(db.Put([]byte{0x11, 0x15}, []byte{4})) nextKey, err := syncer.findNextKey(context.Background(), []byte{0x11, 0x11}, maybe.Some([]byte{0x20}), proof.Path) require.NoError(err) - require.Equal(maybe.Some([]byte{0x12}), nextKey) + require.Equal(maybe.Some([]byte{0x11, 0x15}), nextKey) } func Test_Sync_FindNextKey_BranchInReceived(t *testing.T) { @@ -365,27 +371,28 @@ func Test_Sync_FindNextKey_BranchInReceived(t *testing.T) { require.NoError(err) require.NoError(db.Put([]byte{0x11}, []byte{1})) require.NoError(db.Put([]byte{0x12}, []byte{2})) - require.NoError(db.Put([]byte{0x11, 0x11}, []byte{3})) + require.NoError(db.Put([]byte{0x12, 0xA0}, []byte{4})) - syncRoot, err := db.GetMerkleRoot(context.Background()) + targetRoot, err := db.GetMerkleRoot(context.Background()) require.NoError(err) - proof, err := db.GetProof(context.Background(), []byte{0x11, 0x11}) + + proof, err := db.GetProof(context.Background(), []byte{0x12}) require.NoError(err) syncer, err := NewManager(ManagerConfig{ DB: db, Client: NewMockClient(ctrl), - TargetRoot: syncRoot, + TargetRoot: targetRoot, SimultaneousWorkLimit: 5, Log: logging.NoLog{}, BranchFactor: merkledb.BranchFactor16, }) require.NoError(err) - require.NoError(db.Delete([]byte{0x12})) + require.NoError(db.Delete([]byte{0x12, 0xA0})) - nextKey, err := syncer.findNextKey(context.Background(), []byte{0x11, 0x11}, maybe.Some([]byte{0x20}), proof.Path) + nextKey, err := syncer.findNextKey(context.Background(), []byte{0x12}, maybe.Some([]byte{0x20}), proof.Path) require.NoError(err) - require.Equal(maybe.Some([]byte{0x12}), nextKey) + require.Equal(maybe.Some([]byte{0x12, 0xA0}), nextKey) } func Test_Sync_FindNextKey_ExtraValues(t *testing.T) { From cf5e869a3e6a51ab064ba35bf0df5c54487bebcb Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 14 Dec 2023 12:09:22 -0500 Subject: [PATCH 148/267] fix onEvictCache (#2484) --- x/merkledb/cache.go | 1 + x/merkledb/db.go | 8 ++--- x/merkledb/intermediate_node_db_test.go | 39 +++++++++++++++++++++++++ x/merkledb/value_node_db_test.go | 4 +-- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/x/merkledb/cache.go b/x/merkledb/cache.go index 7b280c1208d4..c4cebd27f8a2 100644 --- a/x/merkledb/cache.go +++ b/x/merkledb/cache.go @@ -25,6 +25,7 @@ type onEvictCache[K comparable, V any] struct { onEviction func(K, V) error } +// [size] must always return a positive number. func newOnEvictCache[K comparable, V any]( maxSize int, size func(K, V) int, diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 823f754d2f3c..5b046c8bb834 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -32,13 +32,13 @@ import ( ) const ( - // TODO: name better rebuildViewSizeFractionOfCacheSize = 50 minRebuildViewSizePerCommit = 1000 clearBatchSize = units.MiB rebuildIntermediateDeletionWriteSize = units.MiB valueNodePrefixLen = 1 + cacheEntryOverHead = 8 ) var ( @@ -1352,11 +1352,11 @@ func getBufferFromPool(bufferPool *sync.Pool, size int) []byte { return buffer } -// cacheEntrySize returns a rough approximation of the memory consumed by storing the key and node +// cacheEntrySize returns a rough approximation of the memory consumed by storing the key and node. func cacheEntrySize(key Key, n *node) int { if n == nil { - return len(key.Bytes()) + return cacheEntryOverHead + len(key.Bytes()) } // nodes cache their bytes representation so the total memory consumed is roughly twice that - return len(key.Bytes()) + 2*len(n.bytes()) + return cacheEntryOverHead + len(key.Bytes()) + 2*len(n.bytes()) } diff --git a/x/merkledb/intermediate_node_db_test.go b/x/merkledb/intermediate_node_db_test.go index 91709708f148..0c27beebfd38 100644 --- a/x/merkledb/intermediate_node_db_test.go +++ b/x/merkledb/intermediate_node_db_test.go @@ -242,3 +242,42 @@ func TestIntermediateNodeDBClear(t *testing.T) { require.Zero(db.nodeCache.currentSize) } + +// Test that deleting the empty key and flushing works correctly. +// Previously, there was a bug that occurred when deleting the empty key +// if the cache was empty. The size of the cache entry was reported as 0, +// which caused the cache's currentSize to be 0, so on resize() we didn't +// call onEviction. This caused the empty key to not be deleted from the baseDB. +func TestIntermediateNodeDBDeleteEmptyKey(t *testing.T) { + require := require.New(t) + cacheSize := 200 + evictionBatchSize := cacheSize + baseDB := memdb.New() + db := newIntermediateNodeDB( + baseDB, + &sync.Pool{ + New: func() interface{} { return make([]byte, 0) }, + }, + &mockMetrics{}, + cacheSize, + evictionBatchSize, + 4, + ) + + emptyKey := ToKey([]byte{}) + require.NoError(db.Put(emptyKey, newNode(emptyKey))) + require.NoError(db.Flush()) + + emptyDBKey := db.constructDBKey(emptyKey) + has, err := baseDB.Has(emptyDBKey) + require.NoError(err) + require.True(has) + + require.NoError(db.Delete(ToKey([]byte{}))) + require.NoError(db.Flush()) + + emptyDBKey = db.constructDBKey(emptyKey) + has, err = baseDB.Has(emptyDBKey) + require.NoError(err) + require.False(has) +} diff --git a/x/merkledb/value_node_db_test.go b/x/merkledb/value_node_db_test.go index c87f0ab5ebf8..78dfe62b1e3b 100644 --- a/x/merkledb/value_node_db_test.go +++ b/x/merkledb/value_node_db_test.go @@ -20,14 +20,14 @@ func TestValueNodeDB(t *testing.T) { baseDB := memdb.New() - size := 10 + cacheSize := 10_000 db := newValueNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, }, &mockMetrics{}, - size, + cacheSize, ) // Getting a key that doesn't exist should return an error. From 4909a204f7bbf3fbe604e4142e518c7d1ccb8730 Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:36:22 -0500 Subject: [PATCH 149/267] Remove cached node bytes from merkle nodes (#2393) Signed-off-by: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Co-authored-by: Dan Laine --- x/merkledb/codec.go | 58 +++++++++++++++++++++++++++++++--------- x/merkledb/codec_test.go | 11 +++++++- x/merkledb/db.go | 3 +-- x/merkledb/node.go | 22 +++------------ x/merkledb/trieview.go | 1 - 5 files changed, 60 insertions(+), 35 deletions(-) diff --git a/x/merkledb/codec.go b/x/merkledb/codec.go index c14534d9cead..ea6bc10363f4 100644 --- a/x/merkledb/codec.go +++ b/x/merkledb/codec.go @@ -29,11 +29,8 @@ const ( minDBNodeLen = minMaybeByteSliceLen + minVarIntLen minChildLen = minVarIntLen + minKeyLen + ids.IDLen + boolLen - estimatedKeyLen = 64 - estimatedValueLen = 64 - estimatedCompressedKeyLen = 8 - // Child index, child compressed key, child ID, child has value - estimatedNodeChildLen = minVarIntLen + estimatedCompressedKeyLen + ids.IDLen + boolLen + estimatedKeyLen = 64 + estimatedValueLen = 64 // Child index, child ID hashValuesChildLen = minVarIntLen + ids.IDLen ) @@ -62,6 +59,7 @@ type encoderDecoder interface { type encoder interface { // Assumes [n] is non-nil. encodeDBNode(n *dbNode) []byte + encodedDBNodeSize(n *dbNode) int // Returns the bytes that will be hashed to generate [n]'s ID. // Assumes [n] is non-nil. @@ -93,15 +91,51 @@ type codecImpl struct { varIntPool sync.Pool } +func (c *codecImpl) childSize(index byte, childEntry *child) int { + // * index + // * child ID + // * child key + // * bool indicating whether the child has a value + return c.uintSize(uint64(index)) + ids.IDLen + c.keySize(childEntry.compressedKey) + boolLen +} + +// based on the current implementation of codecImpl.encodeUint which uses binary.PutUvarint +func (*codecImpl) uintSize(value uint64) int { + // binary.PutUvarint repeatedly divides by 128 until the value is under 128, + // so count the number of times that will occur + i := 0 + for value >= 0x80 { + value >>= 7 + i++ + } + return i + 1 +} + +func (c *codecImpl) keySize(p Key) int { + return c.uintSize(uint64(p.length)) + bytesNeeded(p.length) +} + +func (c *codecImpl) encodedDBNodeSize(n *dbNode) int { + // * number of children + // * bool indicating whether [n] has a value + // * the value (optional) + // * children + size := c.uintSize(uint64(len(n.children))) + boolLen + if n.value.HasValue() { + valueLen := len(n.value.Value()) + size += c.uintSize(uint64(valueLen)) + valueLen + } + // for each non-nil entry, we add the additional size of the child entry + for index, entry := range n.children { + size += c.childSize(index, entry) + } + return size +} + func (c *codecImpl) encodeDBNode(n *dbNode) []byte { - var ( - numChildren = len(n.children) - // Estimate size of [n] to prevent memory allocations - estimatedLen = estimatedValueLen + minVarIntLen + estimatedNodeChildLen*numChildren - buf = bytes.NewBuffer(make([]byte, 0, estimatedLen)) - ) + buf := bytes.NewBuffer(make([]byte, 0, c.encodedDBNodeSize(n))) c.encodeMaybeByteSlice(buf, n.value) - c.encodeUint(buf, uint64(numChildren)) + c.encodeUint(buf, uint64(len(n.children))) // Note we insert children in order of increasing index // for determinism. keys := maps.Keys(n.children) diff --git a/x/merkledb/codec_test.go b/x/merkledb/codec_test.go index 1f463ca50858..991368a823f4 100644 --- a/x/merkledb/codec_test.go +++ b/x/merkledb/codec_test.go @@ -158,7 +158,7 @@ func FuzzCodecDBNodeDeterministic(f *testing.F) { } nodeBytes := codec.encodeDBNode(&node) - + require.Len(nodeBytes, codec.encodedDBNodeSize(&node)) var gotNode dbNode require.NoError(codec.decodeDBNode(nodeBytes, &gotNode)) require.Equal(node, gotNode) @@ -244,3 +244,12 @@ func TestCodecDecodeKeyLengthOverflowRegression(t *testing.T) { _, err := codec.decodeKey(binary.AppendUvarint(nil, math.MaxInt)) require.ErrorIs(t, err, io.ErrUnexpectedEOF) } + +func TestUintSize(t *testing.T) { + c := codec.(*codecImpl) + for i := uint64(0); i < math.MaxInt16; i++ { + expectedSize := c.uintSize(i) + actualSize := binary.PutUvarint(make([]byte, binary.MaxVarintLen64), i) + require.Equal(t, expectedSize, actualSize, i) + } +} diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 5b046c8bb834..d26d56d6a9f9 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -1357,6 +1357,5 @@ func cacheEntrySize(key Key, n *node) int { if n == nil { return cacheEntryOverHead + len(key.Bytes()) } - // nodes cache their bytes representation so the total memory consumed is roughly twice that - return cacheEntryOverHead + len(key.Bytes()) + 2*len(n.bytes()) + return cacheEntryOverHead + len(key.Bytes()) + codec.encodedDBNodeSize(&n.dbNode) } diff --git a/x/merkledb/node.go b/x/merkledb/node.go index d15eb6ae7e14..4caad76f294a 100644 --- a/x/merkledb/node.go +++ b/x/merkledb/node.go @@ -29,7 +29,6 @@ type child struct { type node struct { dbNode key Key - nodeBytes []byte valueDigest maybe.Maybe[[]byte] } @@ -50,9 +49,8 @@ func parseNode(key Key, nodeBytes []byte) (*node, error) { return nil, err } result := &node{ - dbNode: n, - key: key, - nodeBytes: nodeBytes, + dbNode: n, + key: key, } result.setValueDigest() @@ -66,17 +64,7 @@ func (n *node) hasValue() bool { // Returns the byte representation of this node. func (n *node) bytes() []byte { - if n.nodeBytes == nil { - n.nodeBytes = codec.encodeDBNode(&n.dbNode) - } - - return n.nodeBytes -} - -// clear the cached values that will need to be recalculated whenever the node changes -// for example, node ID and byte representation -func (n *node) onNodeChanged() { - n.nodeBytes = nil + return codec.encodeDBNode(&n.dbNode) } // Returns and caches the ID of this node. @@ -88,7 +76,6 @@ func (n *node) calculateID(metrics merkleMetrics) ids.ID { // Set [n]'s value to [val]. func (n *node) setValue(val maybe.Maybe[[]byte]) { - n.onNodeChanged() n.value = val n.setValueDigest() } @@ -121,13 +108,11 @@ func (n *node) addChildWithID(childNode *node, tokenSize int, childID ids.ID) { // Adds a child to [n] without a reference to the child node. func (n *node) setChildEntry(index byte, childEntry *child) { - n.onNodeChanged() n.children[index] = childEntry } // Removes [child] from [n]'s children. func (n *node) removeChild(child *node, tokenSize int) { - n.onNodeChanged() delete(n.children, child.key.Token(n.key.length, tokenSize)) } @@ -143,7 +128,6 @@ func (n *node) clone() *node { children: make(map[byte]*child, len(n.children)), }, valueDigest: n.valueDigest, - nodeBytes: n.nodeBytes, } for key, existing := range n.children { result.children[key] = &child{ diff --git a/x/merkledb/trieview.go b/x/merkledb/trieview.go index 35be62f8a5f9..12a17e7bbbac 100644 --- a/x/merkledb/trieview.go +++ b/x/merkledb/trieview.go @@ -278,7 +278,6 @@ func (t *trieView) calculateNodeIDsHelper(n *node) ids.ID { // This child wasn't changed. continue } - n.onNodeChanged() childEntry.hasValue = childNodeChange.after.hasValue() // Try updating the child and its descendants in a goroutine. From f887e48eb34c2b913fd2dcd37a34a32709d8e31a Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Thu, 14 Dec 2023 13:25:48 -0500 Subject: [PATCH 150/267] Fix race in view iteration (#2486) Co-authored-by: Dan Laine --- x/merkledb/db.go | 3 +++ x/merkledb/view_iterator.go | 8 +----- x/merkledb/view_iterator_test.go | 43 +++++++++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/x/merkledb/db.go b/x/merkledb/db.go index d26d56d6a9f9..211c11950bba 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -440,6 +440,9 @@ func (db *merkleDB) Close() error { return database.ErrClosed } + // mark all children as no longer valid because the db has closed + db.invalidateChildrenExcept(nil) + db.closed = true db.valueNodeDB.Close() // Flush intermediary nodes to disk. diff --git a/x/merkledb/view_iterator.go b/x/merkledb/view_iterator.go index 66f4712daf7a..0216bcc45199 100644 --- a/x/merkledb/view_iterator.go +++ b/x/merkledb/view_iterator.go @@ -71,13 +71,7 @@ type viewIterator struct { // based on if the in memory changes or the underlying db should be read next func (it *viewIterator) Next() bool { switch { - case it.view.db.closed: - // Short-circuit and set an error if the underlying database has been closed. - it.key = nil - it.value = nil - it.err = database.ErrClosed - return false - case it.view.invalidated: + case it.view.isInvalid(): it.key = nil it.value = nil it.err = ErrInvalid diff --git a/x/merkledb/view_iterator_test.go b/x/merkledb/view_iterator_test.go index 6ec5c8f49b37..8b439b3a90df 100644 --- a/x/merkledb/view_iterator_test.go +++ b/x/merkledb/view_iterator_test.go @@ -34,7 +34,9 @@ func Test_TrieView_Iterator(t *testing.T) { require.NoError(db.Put(key1, value1)) require.NoError(db.Put(key2, value2)) - iterator := db.NewIterator() + view, err := db.NewView(context.Background(), ViewChanges{}) + require.NoError(err) + iterator := view.NewIterator() require.NotNil(iterator) defer iterator.Release() @@ -53,6 +55,33 @@ func Test_TrieView_Iterator(t *testing.T) { require.NoError(iterator.Error()) } +func Test_TrieView_Iterator_DBClosed(t *testing.T) { + require := require.New(t) + + key1 := []byte("hello1") + value1 := []byte("world1") + + db, err := getBasicDB() + require.NoError(err) + + require.NoError(db.Put(key1, value1)) + + view, err := db.NewView(context.Background(), ViewChanges{}) + require.NoError(err) + iterator := view.NewIterator() + require.NotNil(iterator) + + defer iterator.Release() + + require.NoError(db.Close()) + + require.False(iterator.Next()) + require.Nil(iterator.Key()) + require.Nil(iterator.Value()) + err = iterator.Error() + require.ErrorIs(err, ErrInvalid) +} + // Test_TrieView_IteratorStart tests to make sure the iterator can be configured to // start midway through the database. func Test_TrieView_IteratorStart(t *testing.T) { @@ -69,7 +98,9 @@ func Test_TrieView_IteratorStart(t *testing.T) { require.NoError(db.Put(key1, value1)) require.NoError(db.Put(key2, value2)) - iterator := db.NewIteratorWithStart(key2) + view, err := db.NewView(context.Background(), ViewChanges{}) + require.NoError(err) + iterator := view.NewIteratorWithStart(key2) require.NotNil(iterator) defer iterator.Release() @@ -104,7 +135,9 @@ func Test_TrieView_IteratorPrefix(t *testing.T) { require.NoError(db.Put(key2, value2)) require.NoError(db.Put(key3, value3)) - iterator := db.NewIteratorWithPrefix([]byte("h")) + view, err := db.NewView(context.Background(), ViewChanges{}) + require.NoError(err) + iterator := view.NewIteratorWithPrefix([]byte("h")) require.NotNil(iterator) defer iterator.Release() @@ -139,7 +172,9 @@ func Test_TrieView_IteratorStartPrefix(t *testing.T) { require.NoError(db.Put(key2, value2)) require.NoError(db.Put(key3, value3)) - iterator := db.NewIteratorWithStartAndPrefix(key1, []byte("h")) + view, err := db.NewView(context.Background(), ViewChanges{}) + require.NoError(err) + iterator := view.NewIteratorWithStartAndPrefix(key1, []byte("h")) require.NotNil(iterator) defer iterator.Release() From 0f4cff16d9baecb9e853f3d8d3fde80321f4d2da Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Thu, 14 Dec 2023 13:43:32 -0500 Subject: [PATCH 151/267] MerkleDB -- update readme (#2423) --- x/merkledb/README.md | 178 +++++++++++++++++++++++++++++++++---------- 1 file changed, 137 insertions(+), 41 deletions(-) diff --git a/x/merkledb/README.md b/x/merkledb/README.md index 6c7d9d68775c..acbddc16c2ca 100644 --- a/x/merkledb/README.md +++ b/x/merkledb/README.md @@ -1,44 +1,138 @@ -# Path Based Merkelized Radix Trie +# MerkleDB -## TODOs +## Structure -- [ ] Remove special casing around the root node from the physical structure of the hashed tree. -- [ ] Analyze performance of using database snapshots rather than in-memory history -- [ ] Improve intermediate node regeneration after ungraceful shutdown by reusing successfully written subtrees -## Introduction +A _Merkle radix trie_ is a data structure that is both a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) and a [radix trie](https://en.wikipedia.org/wiki/Radix_tree). MerkleDB is an implementation of a persisted key-value store (sometimes just called "a store") using a Merkle radix trie. We sometimes use "Merkle radix trie" and "MerkleDB instance" interchangeably below, but the two are not the same. MerkleDB maintains data in a Merkle radix trie, but not all Merkle radix tries implement a key-value store. + +Like all tries, a MerkleDB instance is composed of nodes. Conceputally, a node has: + * A unique _key_ which identifies its position in the trie. A node's key is a prefix of its childrens' keys. + * A unique _ID_, which is the hash of the node. + * A _children_ array, where each element is the ID of the child at that index. A child at a lower index is to the "left" of children at higher indices. + * An optional value. If a node has a value, then the node's key maps to its value in the key-value store. Otherwise the key isn't present in the store. + +and looks like this: +``` +Node ++--------------------------------------------+ +| ID: 32 bytes | +| Key: ? bytes | +| Value: Some(value) | None | +| Children: | +| 0: Some(child0ID) | None | +| 1: Some(child2ID) | None | +| ... | +| BranchFactor-1: Some(child15ID) | None | ++--------------------------------------------+ +``` + +This conceptual picture differs slightly from the implementation of the `node` in MerkleDB but is still useful in understanding how MerkleDB works. + +## Root IDs and Revisions + +The ID of the root node is called the _root ID_, or sometimes just the _root_ of the trie. If any node in a MerkleDB instance changes, the root ID will change. This follows from the fact that changing a node changes its ID, which changes its parent's reference to it, which changes the parent, which changes the parent's ID, and so on until the root. + +The root ID also serves as a unique identifier of a given state; instances with the same key-value mappings always have the same root ID, and instances with different key-value mappings always have different root IDs. We call a state with a given root ID a _revision_, and we sometimes say that a MerkleDB instance is "at" a given revision or root ID. The two are equivalent. + +## Views + +A _view_ is a proposal to modify a MerkleDB. If a view is _committed_, its changes are written to the MerkleDB. It can be queried, and when it is, it will return the state that the MerkleDB will contain if the view is committed. + +A view can be built atop the MerkleDB itself, or it can be built atop another view. Views can be chained together. For example, we might have: + +``` + db + / \ +view1 view2 + | +view3 +``` + +where `view1` and `view2` are built atop MerkleDB instance `db` and `view3` is built atop `view1`. Equivalently, we say that `db` is the parent of `view1` and `view2`, and `view3` is a child of `view1`. `view1` and `view2` are _siblings_. + +`view1` contains all the key-value pairs in `db`, except those modified by `view1`. That is, if `db` has key-value pair `(k,v)`, and `view1` doesn't modify that pair, then `view1` will return `v` when queried for the value of `k`. If `db` has `(k,v)` but `view1` modifies the pair to `(k, v')` then it will return `v'` when queried for the value of `k`. Similar for `view2`. + +`view3` has all of the key-value pairs as `view1`, except those modified in `view3`. That is, it has the state after the changes in `view1` are applied to `db`, followed by those in `view3`. + +A view can be committed only if its parent is the MerkleDB (and not another view). A view can only be committed once. In the above diagram, `view3` can't be committed until `view1` is committed. + +### Validity + +When a view is committed, its siblings and all of their descendants are _invalidated_. An invalid view can't be read or committed. Method calls on it will return `ErrInvalid`. + +In the diagram above, if `view1` were committed, `view2` would be invalidated. It `view2` were committed, `view1` and `view3` would be invalidated. -The Merkle Trie is a data structure that allows efficient and secure verification of the contents. It is a combination of a [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree) and a [Radix Trie](https://en.wikipedia.org/wiki/Radix_tree). +## Proofs -The trie contains `Merkle Nodes`, which store key/value and children information. +### Simple Proofs -Each `Merkle Node` represents a key path into the trie. It stores the key, the value (if one exists), its ID, and the IDs of its children nodes. The children have keys that contain the current node's key path as a prefix, and the index of each child indicates the next nibble in that child's key. For example, if we have two nodes, Node 1 with key path `0x91A` and Node 2 with key path `0x91A4`, Node 2 is stored in index `0x4` of Node 1's children (since 0x4 is the first value after the common prefix). +MerkleDB instances can produce _merkle proofs_, sometimes just called "proofs." A merkle proof uses cryptography to prove that a given key-value pair is or isn't in the key-value store with a given root. That is, a MerkleDB instance with root ID `r` can create a proof that shows that it has a key-value pair `(k,v)`, or that `k` is not present. -To reduce the depth of nodes in the trie, a `Merkle Node` utilizes path compression. Instead of having a long chain of nodes each containing only a single nibble of the key, we can "compress" the path by recording additional key information with each of a node's children. For example, if we have three nodes, Node 1 with key path `0x91A`, Node 2 with key path `0x91A4`, and Node 3 with key path `0x91A5132`, then Node 1 has a key of `0x91A`. Node 2 is stored at index `0x4` of Node 1's children since `4` is the next nibble in Node 2's key after skipping the common nibbles from Node 1's key. Node 3 is stored at index `0x5` of Node 1's children. Rather than have extra nodes for the remainder of Node 3's key, we instead store the rest of the key (`132`) in Node 1's children info. +Proofs can be useful as a client fetching data in a Byzantine environment. Suppose there are one or more servers, which may be Byzantine, serving a distirbuted key-value store using MerkleDB, and a client that wants to retrieve key-value pairs. Suppose also that the client can learn a "trusted" root ID, perhaps because it's posted on a blockchain. The client can request a key-value pair from a server, and use the returned proof to verify that the returned key-value pair is actually in the key-value store with (or isn't, as it were.) To put a finer point on it, the flow is: +```mermaid +flowchart TD + A[Client] -->|"ProofRequest(k,r)"| B(Server) + B --> |"Proof(k,r)"| C(Client) + C --> |Proof Valid| D(Client trusts key-value pair from proof) + C --> |Proof Invalid| E(Client doesn't trust key-value pair from proof) ``` -+-----------------------------------+ -| Merkle Node | -| | -| ID: 0x0131 | an id representing the current node, derived from the node's value and all children ids -| Key: 0x91 | prefix of the key, representing the location of the node in the trie -| Value: 0x00 | the value, if one exists, that is stored at the key (keyPrefix + compressedKey) -| Children: | a map of children node ids for any nodes in the trie that have this node's key as a prefix -| 0: [:0x00542F] | child 0 represents a node with key 0x910 with ID 0x00542F -| 1: [0x432:0xA0561C] | child 1 represents a node with key 0x911432 with ID 0xA0561C -| ... | -| 15: [0x9A67B:0x02FB093] | child 15 represents a node with key 0x91F9A67B with ID 0x02FB093 -+-----------------------------------+ + +`ProofRequest(k,r)` is a request for the value that `k` maps to in the MerkleDB instance with root `r` and a proof for that data's correctness. + +`Proof(k,r)` is a proof that purports to show either that key-value pair `(k,v)` exists in the revision at `r`, or that `k` isn't in the revision. + +### Range Proofs + +MerkleDB instances can also produce _range proofs_. A range proof proves that a contiguous set of key-value pairs is or isn't in the key-value store with a given root. This is similar to the merkle proofs described above, except for multiple key-value pairs. Similar to above, the flow is: + +```mermaid +flowchart TD + A[Client] -->|"RangeProofRequest(start,end,r)"| B(Server) + B --> |"RangeProof(start,end,r)"| C(Client) + C --> |Proof Valid| D(Client trusts key-value pairs) + C --> |Proof Invalid| E(Client doesn't trust key-value pairs) +``` + +`RangeProofRequest(start,end,r)` is a request for all of the key-value pairs, in order, between keys `start` and `end` at revision `r`. + +`RangeProof(start,end,r)` contains a list of key-value pairs `kvs`, sorted by increasing key. It purports to show that, at revision `r`: +* Each element of `kvs` is a key-value pair in the store. +* There are no keys at/after `start` but before the first key in `kvs`. +* For adjacent key-value pairs `(k1,v1)` and `(k2,v2)` in `kvs`, there doesn't exist a key-value pair `(k3,v3)` in the store such that `k1 < k3 < k2`. In other words, `kvs` is a contiguous set of key-value pairs. + +Clients can use range proofs to efficiently download many key-value pairs at a time from a MerkleDB instance, as opposed to getting a proof for each key-value pair individually. + +Like simple proofs, range proofs can be verified without any additional context or knowledge of the contents of the key-value store. + +### Change Proofs + +Finally, MerkleDB instances can produce and verify _change proofs_. A change proof proves that a set of key-value changes were applied to a MerkleDB instance in the process of changing its root from `r` to `r'`. For example, suppose there's an instance with root `r` + +```mermaid +flowchart TD + A[Client] -->|"ChangeProofRequest(start,end,r,r')"| B(Server) + B --> |"ChangeProof(start,end,r,r')"| C(Client) + C --> |Proof Valid| D(Client trusts key-value pair changes) + C --> |Proof Invalid| E(Client doesn't trust key-value changes) ``` +`ChangeProofRequest(start,end,r,r')` is a request for all key-value pairs, in order, between keys `start` and `end`, that occurred after the root of was `r` and before the root was `r'`. + +`ChangeProof(start,end,r,r')` contains a set of key-value pairs `kvs`. It purports to show that: +* Each element of `kvs` is a key-value pair in the at revision `r'` but not at revision `r`. +* There are no key-value changes between `r` and `r'` such that the key is at/after `start` but before the first key in `kvs`. +* For adjacent key-value changes `(k1,v1)` and `(k2,v2)` in `kvs`, there doesn't exist a key-value change `(k3,v3)` between `r` and `r'` such that `k1 < k3 < k2`. In other words, `kvs` is a contiguous set of key-value changes. + +Change proofs are useful for applying changes between revisions. For example, suppose a client has a MerkleDB instance at revision `r`. The client learns that the state has been updated and that the new root is `r'`. The client can request a change proof from a server at revision `r'`, and apply the changes in the change proof to change its state from `r` to `r'`. Note that `r` and `r'` need not be "consecutive" revisions. For example, it's possible that the state goes from revision `r` to `r1` to `r2` to `r'`. The client apply changes to get directly from `r` to `r'`, without ever needing to be at revision `r1` or `r2`. + ## Serialization ### Node -Nodes are persisted in an underlying database. In order to persist nodes, we must first serialize them. -Serialization is done by the `encoder` interface defined in `codec.go`. +Nodes are persisted in an underlying database. In order to persist nodes, we must first serialize them. Serialization is done by the `encoder` interface defined in `codec.go`. -The node serialization format is as follows: +The node serialization format is: ``` +----------------------------------------------------+ @@ -91,9 +185,9 @@ For each child of the node, we have an additional: +----------------------------------------------------+ | Child index (varint) | +----------------------------------------------------+ -| Child compressed key length (varint) | +| Child compressed key length (varint) | +----------------------------------------------------+ -| Child compressed key (variable length bytes) | +| Child compressed key (variable length bytes) | +----------------------------------------------------+ | Child ID (32 bytes) | +----------------------------------------------------+ @@ -134,10 +228,10 @@ The second is at child index `14`, has compressed key `0x0F0F0F` and ID (in hex) | Child index (varint) | | 0x00 | +--------------------------------------------------------------------+ -| Child compressed key length (varint) | +| Child compressed key length (varint) | | 0x02 | +--------------------------------------------------------------------+ -| Child compressed key (variable length bytes) | +| Child compressed key (variable length bytes) | | 0x10 | +--------------------------------------------------------------------+ | Child ID (32 bytes) | @@ -146,10 +240,10 @@ The second is at child index `14`, has compressed key `0x0F0F0F` and ID (in hex) | Child index (varint) | | 0x0E | +--------------------------------------------------------------------+ -| Child compressed key length (varint) | +| Child compressed key length (varint) | | 0x06 | +--------------------------------------------------------------------+ -| Child compressed key (variable length bytes) | +| Child compressed key (variable length bytes) | | 0xFFF0 | +--------------------------------------------------------------------+ | Child ID (32 bytes) | @@ -216,22 +310,18 @@ Bytes are encoded by simply copying them onto the buffer. ## Design choices ### []byte copying -Nodes contain a []byte which represents its value. This slice should never be edited internally. This allows usage without having to make copies of it for safety. -Anytime these values leave the library, for example in `Get`, `GetValue`, `GetProof`, `GetRangeProof`, etc, they need to be copied into a new slice to prevent -edits made outside the library from being reflected in the DB/TrieViews. + +A node may contain a value, which is represented in Go as a `[]byte`. This slice is never edited, allowing it to be used without copying it first in many places. When a value leaves the library, for example when returned in `Get`, `GetValue`, `GetProof`, `GetRangeProof`, etc., the value is copied to prevent edits made outside the library from being reflected in the database. ### Split Node Storage -The nodes are stored under two different prefixes depending on if the node contains a value. -If it does contain a value it is stored within the ValueNodeDB and if it doesn't it is stored in the IntermediateNodeDB. -By splitting the nodes up by value, it allows better key/value iteration and a more compact key format. -### Single node type +Nodes with values ("value nodes") are persisted under one database prefix, while nodes without values ("intermediate nodes") are persisted under another database prefix. This separation allows for easy iteration over all key-value pairs in the database, as this is simply iterating over the database prefix containing value nodes. -A `Merkle Node` holds the IDs of its children, its value, as well as any key extension. This simplifies some logic and allows all of the data about a node to be loaded in a single database read. This trades off a small amount of storage efficiency (some fields may be `nil` but are still stored for every node). +### Single Node Type -### Validity +MerkleDB uses one type to represent nodes, rather than having multiple types (e.g. branch nodes, value nodes, extension nodes) as other Merkle Trie implementations do. -A `trieView` is built atop another trie, and there may be other `trieView`s built atop the same trie. We call these *siblings*. If one sibling is committed to database, we *invalidate* all other siblings and their descendants. Operations on an invalid trie return `ErrInvalid`. The children of the committed `trieView` are updated so that their new `parentTrie` is the database. +Not using extension nodes results in worse storage efficiency (some nodes may have mostly empty children) but simpler code. ### Locking @@ -252,3 +342,9 @@ This pattern is safe because the `merkleDB` is locked, so no data under the view To prevent deadlocks, `trieView` and `merkleDB` never acquire the `commitLock` of descendant views. That is, locking is always done from a view toward to the underlying `merkleDB`, never the other way around. The `validityTrackingLock` goes the opposite way. A view can lock the `validityTrackingLock` of its children, but not its ancestors. Because of this, any function that takes the `validityTrackingLock` must not take the `commitLock` as this may cause a deadlock. Keeping `commitLock` solely in the ancestor direction and `validityTrackingLock` solely in the descendant direction prevents deadlocks from occurring. + +## TODOs + +- [ ] Remove special casing around the root node from the physical structure of the hashed tree. +- [ ] Analyze performance of using database snapshots rather than in-memory history +- [ ] Improve intermediate node regeneration after ungraceful shutdown by reusing successfully written subtrees From abf4fbc90f60cd7a02860812b0366e4e57fefb34 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 11:33:04 -0700 Subject: [PATCH 152/267] Drop Pending Stakers 3 - persist stakers' StartTime (#2306) Co-authored-by: Stephen Buttolph Co-authored-by: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> --- vms/platformvm/block/builder/helpers_test.go | 6 +- vms/platformvm/block/executor/helpers_test.go | 6 +- vms/platformvm/state/metadata_codec.go | 12 +- vms/platformvm/state/metadata_delegator.go | 27 +++- .../state/metadata_delegator_test.go | 141 ++++++++++++++++++ vms/platformvm/state/metadata_validator.go | 5 +- .../state/metadata_validator_test.go | 10 +- vms/platformvm/state/state.go | 80 ++++++---- vms/platformvm/state/state_test.go | 4 +- vms/platformvm/txs/executor/helpers_test.go | 16 +- .../validators/manager_benchmark_test.go | 4 +- vms/platformvm/vm.go | 2 +- vms/platformvm/vm_regression_test.go | 4 +- 13 files changed, 262 insertions(+), 55 deletions(-) create mode 100644 vms/platformvm/state/metadata_delegator_test.go diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 529c06a52d1b..412804425921 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -135,7 +135,7 @@ func newEnvironment(t *testing.T) *environment { res.fx = defaultFx(t, res.clk, res.ctx.Log, res.isBootstrapped.Get()) rewardsCalc := reward.NewCalculator(res.config.RewardConfig) - res.state = defaultState(t, res.config.Validators, res.ctx, res.baseDB, rewardsCalc) + res.state = defaultState(t, res.config, res.ctx, res.baseDB, rewardsCalc) res.atomicUTXOs = avax.NewAtomicUTXOManager(res.ctx.SharedMemory, txs.Codec) res.uptimes = uptime.NewManager(res.state, res.clk) @@ -237,7 +237,7 @@ func addSubnet(t *testing.T, env *environment) { func defaultState( t *testing.T, - validators validators.Manager, + cfg *config.Config, ctx *snow.Context, db database.Database, rewards reward.Calculator, @@ -250,7 +250,7 @@ func defaultState( db, genesisBytes, prometheus.NewRegistry(), - validators, + cfg, execCfg, ctx, metrics.Noop, diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 778d9b203181..5221f4a97d15 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -145,7 +145,7 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller) *environment { res.atomicUTXOs = avax.NewAtomicUTXOManager(res.ctx.SharedMemory, txs.Codec) if ctrl == nil { - res.state = defaultState(res.config.Validators, res.ctx, res.baseDB, rewardsCalc) + res.state = defaultState(res.config, res.ctx, res.baseDB, rewardsCalc) res.uptimes = uptime.NewManager(res.state, res.clk) res.utxosHandler = utxo.NewHandler(res.ctx, res.clk, res.fx) res.txBuilder = p_tx_builder.New( @@ -263,7 +263,7 @@ func addSubnet(env *environment) { } func defaultState( - validators validators.Manager, + cfg *config.Config, ctx *snow.Context, db database.Database, rewards reward.Calculator, @@ -274,7 +274,7 @@ func defaultState( db, genesisBytes, prometheus.NewRegistry(), - validators, + cfg, execCfg, ctx, metrics.Noop, diff --git a/vms/platformvm/state/metadata_codec.go b/vms/platformvm/state/metadata_codec.go index 6240bbd879ca..50b3988c7d75 100644 --- a/vms/platformvm/state/metadata_codec.go +++ b/vms/platformvm/state/metadata_codec.go @@ -8,20 +8,28 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" + "github.com/ava-labs/avalanchego/utils" ) const ( v0tag = "v0" v0 = uint16(0) + + v1tag = "v1" + v1 = uint16(1) ) var metadataCodec codec.Manager func init() { - c := linearcodec.New([]string{v0tag}, math.MaxInt32) + c0 := linearcodec.New([]string{v0tag}, math.MaxInt32) + c1 := linearcodec.New([]string{v0tag, v1tag}, math.MaxInt32) metadataCodec = codec.NewManager(math.MaxInt32) - err := metadataCodec.RegisterCodec(v0, c) + err := utils.Err( + metadataCodec.RegisterCodec(v0, c0), + metadataCodec.RegisterCodec(v1, c1), + ) if err != nil { panic(err) } diff --git a/vms/platformvm/state/metadata_delegator.go b/vms/platformvm/state/metadata_delegator.go index 04e7ef6a8795..852cbe607408 100644 --- a/vms/platformvm/state/metadata_delegator.go +++ b/vms/platformvm/state/metadata_delegator.go @@ -9,17 +9,36 @@ import ( ) type delegatorMetadata struct { - PotentialReward uint64 + PotentialReward uint64 `v1:"true"` + StakerStartTime uint64 `v1:"true"` txID ids.ID } func parseDelegatorMetadata(bytes []byte, metadata *delegatorMetadata) error { var err error - metadata.PotentialReward, err = database.ParseUInt64(bytes) + switch len(bytes) { + case database.Uint64Size: + // only potential reward was stored + metadata.PotentialReward, err = database.ParseUInt64(bytes) + default: + _, err = metadataCodec.Unmarshal(bytes, metadata) + } return err } -func writeDelegatorMetadata(db database.KeyValueWriter, metadata *delegatorMetadata) error { - return database.PutUInt64(db, metadata.txID[:], metadata.PotentialReward) +func writeDelegatorMetadata(db database.KeyValueWriter, metadata *delegatorMetadata, codecVersion uint16) error { + // The "0" codec is skipped for [delegatorMetadata]. This is to ensure the + // [validatorMetadata] codec version is the same as the [delegatorMetadata] + // codec version. + // + // TODO: Cleanup post-Durango activation. + if codecVersion == 0 { + return database.PutUInt64(db, metadata.txID[:], metadata.PotentialReward) + } + metadataBytes, err := metadataCodec.Marshal(codecVersion, metadata) + if err != nil { + return err + } + return db.Put(metadata.txID[:], metadataBytes) } diff --git a/vms/platformvm/state/metadata_delegator_test.go b/vms/platformvm/state/metadata_delegator_test.go new file mode 100644 index 000000000000..889854d313a2 --- /dev/null +++ b/vms/platformvm/state/metadata_delegator_test.go @@ -0,0 +1,141 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package state + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/database/memdb" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/wrappers" +) + +func TestParseDelegatorMetadata(t *testing.T) { + type test struct { + name string + bytes []byte + expected *delegatorMetadata + expectedErr error + } + tests := []test{ + { + name: "potential reward only no codec", + bytes: []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + }, + expected: &delegatorMetadata{ + PotentialReward: 123, + StakerStartTime: 0, + }, + expectedErr: nil, + }, + { + name: "potential reward + staker start time with codec v1", + bytes: []byte{ + // codec version + 0x00, 0x01, + // potential reward + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + // staker start time + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8, + }, + expected: &delegatorMetadata{ + PotentialReward: 123, + StakerStartTime: 456, + }, + expectedErr: nil, + }, + { + name: "invalid codec version", + bytes: []byte{ + // codec version + 0x00, 0x02, + // potential reward + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + // staker start time + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8, + }, + expected: nil, + expectedErr: codec.ErrUnknownVersion, + }, + { + name: "short byte len", + bytes: []byte{ + // codec version + 0x00, 0x01, + // potential reward + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + // staker start time + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + expected: nil, + expectedErr: wrappers.ErrInsufficientLength, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + var metadata delegatorMetadata + err := parseDelegatorMetadata(tt.bytes, &metadata) + require.ErrorIs(err, tt.expectedErr) + if tt.expectedErr != nil { + return + } + require.Equal(tt.expected, &metadata) + }) + } +} + +func TestWriteDelegatorMetadata(t *testing.T) { + type test struct { + name string + version uint16 + metadata *delegatorMetadata + expected []byte + } + tests := []test{ + { + name: "v0", + version: v0, + metadata: &delegatorMetadata{ + PotentialReward: 123, + StakerStartTime: 456, + }, + expected: []byte{ + // potential reward + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + }, + }, + { + name: "v1", + version: v1, + metadata: &delegatorMetadata{ + PotentialReward: 123, + StakerStartTime: 456, + }, + expected: []byte{ + // codec version + 0x00, 0x01, + // potential reward + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + // staker start time + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + db := memdb.New() + tt.metadata.txID = ids.GenerateTestID() + require.NoError(writeDelegatorMetadata(db, tt.metadata, tt.version)) + bytes, err := db.Get(tt.metadata.txID[:]) + require.NoError(err) + require.Equal(tt.expected, bytes) + }) + } +} diff --git a/vms/platformvm/state/metadata_validator.go b/vms/platformvm/state/metadata_validator.go index 6b839ccad801..ed62b723eeac 100644 --- a/vms/platformvm/state/metadata_validator.go +++ b/vms/platformvm/state/metadata_validator.go @@ -32,6 +32,7 @@ type validatorMetadata struct { LastUpdated uint64 `v0:"true"` // Unix time in seconds PotentialReward uint64 `v0:"true"` PotentialDelegateeReward uint64 `v0:"true"` + StakerStartTime uint64 ` v1:"true"` txID ids.ID lastUpdated time.Time @@ -130,6 +131,7 @@ type validatorState interface { WriteValidatorMetadata( dbPrimary database.KeyValueWriter, dbSubnet database.KeyValueWriter, + codecVersion uint16, ) error } @@ -230,13 +232,14 @@ func (m *metadata) DeleteValidatorMetadata(vdrID ids.NodeID, subnetID ids.ID) { func (m *metadata) WriteValidatorMetadata( dbPrimary database.KeyValueWriter, dbSubnet database.KeyValueWriter, + codecVersion uint16, ) error { for vdrID, updatedSubnets := range m.updatedMetadata { for subnetID := range updatedSubnets { metadata := m.metadata[vdrID][subnetID] metadata.LastUpdated = uint64(metadata.lastUpdated.Unix()) - metadataBytes, err := metadataCodec.Marshal(v0, metadata) + metadataBytes, err := metadataCodec.Marshal(codecVersion, metadata) if err != nil { return err } diff --git a/vms/platformvm/state/metadata_validator_test.go b/vms/platformvm/state/metadata_validator_test.go index 68f18e62bd72..67ba494a88f7 100644 --- a/vms/platformvm/state/metadata_validator_test.go +++ b/vms/platformvm/state/metadata_validator_test.go @@ -81,8 +81,10 @@ func TestWriteValidatorMetadata(t *testing.T) { primaryDB := memdb.New() subnetDB := memdb.New() + + codecVersion := v1 // write empty uptimes - require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB)) + require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, codecVersion)) // load uptime nodeID := ids.GenerateTestNodeID() @@ -96,7 +98,7 @@ func TestWriteValidatorMetadata(t *testing.T) { state.LoadValidatorMetadata(nodeID, subnetID, testUptimeReward) // write state, should not reflect to DB yet - require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB)) + require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, codecVersion)) require.False(primaryDB.Has(testUptimeReward.txID[:])) require.False(subnetDB.Has(testUptimeReward.txID[:])) @@ -112,7 +114,7 @@ func TestWriteValidatorMetadata(t *testing.T) { require.NoError(state.SetUptime(nodeID, subnetID, newUpDuration, newLastUpdated)) // write uptimes, should reflect to subnet DB - require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB)) + require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, codecVersion)) require.False(primaryDB.Has(testUptimeReward.txID[:])) require.True(subnetDB.Has(testUptimeReward.txID[:])) } @@ -252,7 +254,7 @@ func TestParseValidatorMetadata(t *testing.T) { name: "invalid codec version", bytes: []byte{ // codec version - 0x00, 0x01, + 0x00, 0x02, // up duration 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x8D, 0x80, // last updated diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index c130326ef26b..6b981ab7b675 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -289,6 +289,7 @@ type state struct { validators validators.Manager ctx *snow.Context + cfg *config.Config metrics metrics.Metrics rewards reward.Calculator @@ -452,7 +453,7 @@ func New( db database.Database, genesisBytes []byte, metricsReg prometheus.Registerer, - validators validators.Manager, + cfg *config.Config, execCfg *config.ExecutionConfig, ctx *snow.Context, metrics metrics.Metrics, @@ -461,7 +462,7 @@ func New( s, err := newState( db, metrics, - validators, + cfg, execCfg, ctx, metricsReg, @@ -505,7 +506,7 @@ func New( func newState( db database.Database, metrics metrics.Metrics, - validators validators.Manager, + cfg *config.Config, execCfg *config.ExecutionConfig, ctx *snow.Context, metricsReg prometheus.Registerer, @@ -628,8 +629,9 @@ func newState( return &state{ validatorState: newValidatorState(), - validators: validators, + validators: cfg.Validators, ctx: ctx, + cfg: cfg, metrics: metrics, rewards: rewards, baseDB: baseDB, @@ -1346,6 +1348,8 @@ func (s *state) syncGenesis(genesisBlk block.Block, genesis *genesis.Genesis) er return err } + // Note: We use [StartTime()] here because genesis transactions are + // guaranteed to be pre-Durango activation. staker, err := NewCurrentStaker(vdrTx.ID(), validatorTx, validatorTx.StartTime(), potentialReward) if err != nil { return err @@ -1455,16 +1459,22 @@ func (s *state) loadCurrentValidators() error { return fmt.Errorf("failed loading validator transaction txID %s, %w", txID, err) } - stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) + stakerTx, ok := tx.Unsigned.(txs.Staker) if !ok { - return fmt.Errorf("expected tx type txs.ScheduledStaker but got %T", tx.Unsigned) + return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } metadataBytes := validatorIt.Value() metadata := &validatorMetadata{ txID: txID, - // Note: we don't provide [LastUpdated] here because we expect it to + } + if scheduledStakerTx, ok := tx.Unsigned.(txs.ScheduledStaker); ok { + // Populate [StakerStartTime] using the tx as a default in the event + // it was added pre-durango and is not stored in the database. + // + // Note: We do not populate [LastUpdated] since it is expected to // always be present on disk. + metadata.StakerStartTime = uint64(scheduledStakerTx.StartTime().Unix()) } if err := parseValidatorMetadata(metadataBytes, metadata); err != nil { return err @@ -1473,7 +1483,7 @@ func (s *state) loadCurrentValidators() error { staker, err := NewCurrentStaker( txID, stakerTx, - stakerTx.StartTime(), + time.Unix(int64(metadata.StakerStartTime), 0), metadata.PotentialReward) if err != nil { return err @@ -1500,18 +1510,21 @@ func (s *state) loadCurrentValidators() error { return err } - stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) + stakerTx, ok := tx.Unsigned.(txs.Staker) if !ok { - return fmt.Errorf("expected tx type txs.ScheduledStaker but got %T", tx.Unsigned) + return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } metadataBytes := subnetValidatorIt.Value() - startTime := stakerTx.StartTime() metadata := &validatorMetadata{ txID: txID, - // use the start time as the fallback value - // in case it's not stored in the database - LastUpdated: uint64(startTime.Unix()), + } + if scheduledStakerTx, ok := tx.Unsigned.(txs.ScheduledStaker); ok { + // Populate [StakerStartTime] and [LastUpdated] using the tx as a + // default in the event they are not stored in the database. + startTime := uint64(scheduledStakerTx.StartTime().Unix()) + metadata.StakerStartTime = startTime + metadata.LastUpdated = startTime } if err := parseValidatorMetadata(metadataBytes, metadata); err != nil { return err @@ -1520,7 +1533,7 @@ func (s *state) loadCurrentValidators() error { staker, err := NewCurrentStaker( txID, stakerTx, - startTime, + time.Unix(int64(metadata.StakerStartTime), 0), metadata.PotentialReward, ) if err != nil { @@ -1552,15 +1565,22 @@ func (s *state) loadCurrentValidators() error { return err } - stakerTx, ok := tx.Unsigned.(txs.ScheduledStaker) + stakerTx, ok := tx.Unsigned.(txs.Staker) if !ok { - return fmt.Errorf("expected tx type txs.ScheduledStaker but got %T", tx.Unsigned) + return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } + metadataBytes := delegatorIt.Value() metadata := &delegatorMetadata{ txID: txID, } - err = parseDelegatorMetadata(delegatorIt.Value(), metadata) + if scheduledStakerTx, ok := tx.Unsigned.(txs.ScheduledStaker); ok { + // Populate [StakerStartTime] using the tx as a default in the + // event it was added pre-durango and is not stored in the + // database. + metadata.StakerStartTime = uint64(scheduledStakerTx.StartTime().Unix()) + } + err = parseDelegatorMetadata(metadataBytes, metadata) if err != nil { return err } @@ -1568,7 +1588,7 @@ func (s *state) loadCurrentValidators() error { staker, err := NewCurrentStaker( txID, stakerTx, - stakerTx.StartTime(), + time.Unix(int64(metadata.StakerStartTime), 0), metadata.PotentialReward, ) if err != nil { @@ -1714,11 +1734,16 @@ func (s *state) initValidatorSets() error { } func (s *state) write(updateValidators bool, height uint64) error { + codecVersion := v1 + if !s.cfg.IsDurangoActivated(s.GetTimestamp()) { + codecVersion = v0 + } + return utils.Err( s.writeBlocks(), - s.writeCurrentStakers(updateValidators, height), + s.writeCurrentStakers(updateValidators, height, codecVersion), s.writePendingStakers(), - s.WriteValidatorMetadata(s.currentValidatorList, s.currentSubnetValidatorList), // Must be called after writeCurrentStakers + s.WriteValidatorMetadata(s.currentValidatorList, s.currentSubnetValidatorList, codecVersion), // Must be called after writeCurrentStakers s.writeTXs(), s.writeRewardUTXOs(), s.writeUTXOs(), @@ -1944,7 +1969,7 @@ func (s *state) GetBlockIDAtHeight(height uint64) (ids.ID, error) { return blkID, nil } -func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error { +func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecVersion uint16) error { heightBytes := database.PackUInt64(height) rawNestedPublicKeyDiffDB := prefixdb.New(heightBytes, s.nestedValidatorPublicKeyDiffsDB) nestedPKDiffDB := linkeddb.NewDefault(rawNestedPublicKeyDiffDB) @@ -2003,17 +2028,19 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error // // Invariant: It's impossible for a delegator to have been // rewarded in the same block that the validator was added. + startTime := uint64(staker.StartTime.Unix()) metadata := &validatorMetadata{ txID: staker.TxID, lastUpdated: staker.StartTime, UpDuration: 0, - LastUpdated: uint64(staker.StartTime.Unix()), + LastUpdated: startTime, + StakerStartTime: startTime, PotentialReward: staker.PotentialReward, PotentialDelegateeReward: 0, } - metadataBytes, err := metadataCodec.Marshal(v0, metadata) + metadataBytes, err := metadataCodec.Marshal(codecVersion, metadata) if err != nil { return fmt.Errorf("failed to serialize current validator: %w", err) } @@ -2066,6 +2093,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64) error delegatorDB, weightDiff, validatorDiff, + codecVersion, ) if err != nil { return err @@ -2141,6 +2169,7 @@ func writeCurrentDelegatorDiff( currentDelegatorList linkeddb.LinkedDB, weightDiff *ValidatorWeightDiff, validatorDiff *diffValidator, + codecVersion uint16, ) error { addedDelegatorIterator := NewTreeIterator(validatorDiff.addedDelegators) defer addedDelegatorIterator.Release() @@ -2154,8 +2183,9 @@ func writeCurrentDelegatorDiff( metadata := &delegatorMetadata{ txID: staker.TxID, PotentialReward: staker.PotentialReward, + StakerStartTime: uint64(staker.StartTime.Unix()), } - if err := writeDelegatorMetadata(currentDelegatorList, metadata); err != nil { + if err := writeDelegatorMetadata(currentDelegatorList, metadata, codecVersion); err != nil { return fmt.Errorf("failed to write current delegator to list: %w", err) } } diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index 1d0e02938f1c..74d0413bb0f7 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -165,7 +165,9 @@ func newStateFromDB(require *require.Assertions, db database.Database) State { state, err := newState( db, metrics.Noop, - validators.NewManager(), + &config.Config{ + Validators: validators.NewManager(), + }, execCfg, &snow.Context{}, prometheus.NewRegistry(), diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index df3150e04bdd..f1311da8737e 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -132,7 +132,7 @@ func newEnvironment(t *testing.T, postBanff, postCortina bool) *environment { fx := defaultFx(clk, ctx.Log, isBootstrapped.Get()) rewards := reward.NewCalculator(config.RewardConfig) - baseState := defaultState(config.Validators, ctx, baseDB, rewards) + baseState := defaultState(config, ctx, baseDB, rewards) atomicUTXOs := avax.NewAtomicUTXOManager(ctx.SharedMemory, txs.Codec) uptimes := uptime.NewManager(baseState, clk) @@ -140,7 +140,7 @@ func newEnvironment(t *testing.T, postBanff, postCortina bool) *environment { txBuilder := builder.New( ctx, - &config, + config, clk, fx, baseState, @@ -149,7 +149,7 @@ func newEnvironment(t *testing.T, postBanff, postCortina bool) *environment { ) backend := Backend{ - Config: &config, + Config: config, Ctx: ctx, Clk: clk, Bootstrapped: &isBootstrapped, @@ -161,7 +161,7 @@ func newEnvironment(t *testing.T, postBanff, postCortina bool) *environment { env := &environment{ isBootstrapped: &isBootstrapped, - config: &config, + config: config, clk: clk, baseDB: baseDB, ctx: ctx, @@ -218,7 +218,7 @@ func addSubnet( } func defaultState( - validators validators.Manager, + cfg *config.Config, ctx *snow.Context, db database.Database, rewards reward.Calculator, @@ -229,7 +229,7 @@ func defaultState( db, genesisBytes, prometheus.NewRegistry(), - validators, + cfg, execCfg, ctx, metrics.Noop, @@ -280,7 +280,7 @@ func defaultCtx(db database.Database) (*snow.Context, *mutableSharedMemory) { return ctx, msm } -func defaultConfig(postBanff, postCortina bool) config.Config { +func defaultConfig(postBanff, postCortina bool) *config.Config { banffTime := mockable.MaxTime if postBanff { banffTime = defaultValidateEndTime.Add(-2 * time.Second) @@ -290,7 +290,7 @@ func defaultConfig(postBanff, postCortina bool) config.Config { cortinaTime = defaultValidateStartTime.Add(-2 * time.Second) } - return config.Config{ + return &config.Config{ Chains: chains.TestManager, UptimeLockedCalculator: uptime.NewLockedCalculator(), Validators: validators.NewManager(), diff --git a/vms/platformvm/validators/manager_benchmark_test.go b/vms/platformvm/validators/manager_benchmark_test.go index 155811d988ad..0664c085c942 100644 --- a/vms/platformvm/validators/manager_benchmark_test.go +++ b/vms/platformvm/validators/manager_benchmark_test.go @@ -112,7 +112,9 @@ func BenchmarkGetValidatorSet(b *testing.B) { db, genesisBytes, prometheus.NewRegistry(), - vdrs, + &config.Config{ + Validators: vdrs, + }, execConfig, &snow.Context{ NetworkID: constants.UnitTestID, diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 4c1e10c645d6..8b578c9f621a 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -139,7 +139,7 @@ func (vm *VM) Initialize( vm.db, genesisBytes, registerer, - vm.Config.Validators, + &vm.Config, execConfig, vm.ctx, vm.metrics, diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 80b38a06c234..5b50c9895622 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -648,7 +648,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { vm.db, nil, prometheus.NewRegistry(), - vm.Config.Validators, + &vm.Config, execCfg, vm.ctx, metrics.Noop, @@ -955,7 +955,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { vm.db, nil, prometheus.NewRegistry(), - vm.Config.Validators, + &vm.Config, execCfg, vm.ctx, metrics.Noop, From 512f342c3008cd60f4daacb9f900462372bc0f2e Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Thu, 14 Dec 2023 17:47:03 -0500 Subject: [PATCH 153/267] SDK Push Gossiper implementation (#2428) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Signed-off-by: Stephen Buttolph Co-authored-by: Stephen Buttolph --- go.mod | 2 +- go.sum | 4 +- network/p2p/gossip/gossip.go | 232 ++++++++++++++++++++---- network/p2p/gossip/gossip_test.go | 285 +++++++++++++++++++++++++----- network/p2p/gossip/gossipable.go | 3 +- network/p2p/gossip/handler.go | 133 ++++++++++---- network/p2p/gossip/test_gossip.go | 19 +- network/p2p/network_test.go | 7 +- proto/pb/sdk/sdk.pb.go | 75 +++++++- proto/sdk/sdk.proto | 4 + 10 files changed, 626 insertions(+), 138 deletions(-) diff --git a/go.mod b/go.mod index 15052ca3f366..bcc9c4a86703 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213002358-53424dd5480c + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213223840-6e78d609ed32 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index b74c5dbbb979..d49e45a92af9 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213002358-53424dd5480c h1:bWPdqoi+J6ztfVhEl7iexFSaKyaFlMpIltIMVTpXDQY= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213002358-53424dd5480c/go.mod h1:v8pqR8wC9VuyPTEbI6/wmflXPIAmUr6SUwEKP+hi9iU= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213223840-6e78d609ed32 h1:CZ1N++oMSL6yKV/FcCx/7/2cmpAk3rQse797Xz/6Ro0= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213223840-6e78d609ed32/go.mod h1:bHPGzEjcBOLIKGbik9ZzETOhHxnzdLyVX+Q/XvGmGeE= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index 05b46a0bd99a..f8c39e258fcc 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -5,6 +5,8 @@ package gossip import ( "context" + "fmt" + "sync" "time" "github.com/prometheus/client_golang/prometheus" @@ -17,13 +19,25 @@ import ( "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/proto/pb/sdk" "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/buffer" "github.com/ava-labs/avalanchego/utils/logging" ) +const ( + typeLabel = "type" + pushType = "push" + pullType = "pull" +) + var ( _ Gossiper = (*ValidatorGossiper)(nil) _ Gossiper = (*PullGossiper[testTx, *testTx])(nil) _ Gossiper = (*NoOpGossiper)(nil) + + _ Accumulator[*testTx] = (*PushGossiper[*testTx])(nil) + _ Accumulator[*testTx] = (*NoOpAccumulator[*testTx])(nil) + + metricLabels = []string{typeLabel} ) // Gossiper gossips Gossipables to other nodes @@ -32,6 +46,13 @@ type Gossiper interface { Gossip(ctx context.Context) error } +// Accumulator allows a caller to accumulate gossipables to be gossiped +type Accumulator[T Gossipable] interface { + Gossiper + // Add queues gossipables to be gossiped + Add(gossipables ...T) +} + // GossipableAny exists to help create non-nil pointers to a concrete Gossipable // ref: https://stackoverflow.com/questions/69573113/how-can-i-instantiate-a-non-nil-pointer-of-type-argument-with-generic-go type GossipableAny[T any] interface { @@ -47,6 +68,51 @@ type ValidatorGossiper struct { Validators p2p.ValidatorSet } +// Metrics that are tracked across a gossip protocol. A given protocol should +// only use a single instance of Metrics. +type Metrics struct { + sentCount *prometheus.CounterVec + sentBytes *prometheus.CounterVec + receivedCount *prometheus.CounterVec + receivedBytes *prometheus.CounterVec +} + +// NewMetrics returns a common set of metrics +func NewMetrics( + metrics prometheus.Registerer, + namespace string, +) (Metrics, error) { + m := Metrics{ + sentCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "gossip_sent_count", + Help: "amount of gossip sent (n)", + }, metricLabels), + sentBytes: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "gossip_sent_bytes", + Help: "amount of gossip sent (bytes)", + }, metricLabels), + receivedCount: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "gossip_received_count", + Help: "amount of gossip received (n)", + }, metricLabels), + receivedBytes: prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "gossip_received_bytes", + Help: "amount of gossip received (bytes)", + }, metricLabels), + } + err := utils.Err( + metrics.Register(m.sentCount), + metrics.Register(m.sentBytes), + metrics.Register(m.receivedCount), + metrics.Register(m.receivedBytes), + ) + return m, err +} + func (v ValidatorGossiper) Gossip(ctx context.Context) error { if !v.Validators.Has(ctx, v.NodeID) { return nil @@ -55,49 +121,32 @@ func (v ValidatorGossiper) Gossip(ctx context.Context) error { return v.Gossiper.Gossip(ctx) } -type Config struct { - Namespace string - PollSize int -} - func NewPullGossiper[T any, U GossipableAny[T]]( - config Config, log logging.Logger, set Set[U], client *p2p.Client, - metrics prometheus.Registerer, -) (*PullGossiper[T, U], error) { - p := &PullGossiper[T, U]{ - config: config, - log: log, - set: set, - client: client, - receivedN: prometheus.NewCounter(prometheus.CounterOpts{ - Namespace: config.Namespace, - Name: "gossip_received_n", - Help: "amount of gossip received (n)", - }), - receivedBytes: prometheus.NewCounter(prometheus.CounterOpts{ - Namespace: config.Namespace, - Name: "gossip_received_bytes", - Help: "amount of gossip received (bytes)", - }), + metrics Metrics, + pollSize int, +) *PullGossiper[T, U] { + return &PullGossiper[T, U]{ + log: log, + set: set, + client: client, + metrics: metrics, + pollSize: pollSize, + labels: prometheus.Labels{ + typeLabel: pullType, + }, } - - err := utils.Err( - metrics.Register(p.receivedN), - metrics.Register(p.receivedBytes), - ) - return p, err } type PullGossiper[T any, U GossipableAny[T]] struct { - config Config - log logging.Logger - set Set[U] - client *p2p.Client - receivedN prometheus.Counter - receivedBytes prometheus.Counter + log logging.Logger + set Set[U] + client *p2p.Client + metrics Metrics + pollSize int + labels prometheus.Labels } func (p *PullGossiper[_, _]) Gossip(ctx context.Context) error { @@ -115,7 +164,7 @@ func (p *PullGossiper[_, _]) Gossip(ctx context.Context) error { return err } - for i := 0; i < p.config.PollSize; i++ { + for i := 0; i < p.pollSize; i++ { if err := p.client.AppRequestAny(ctx, msgBytes, p.handleResponse); err != nil { return err } @@ -176,8 +225,107 @@ func (p *PullGossiper[T, U]) handleResponse( } } - p.receivedN.Add(float64(len(response.Gossip))) - p.receivedBytes.Add(float64(receivedBytes)) + receivedCountMetric, err := p.metrics.receivedCount.GetMetricWith(p.labels) + if err != nil { + p.log.Error("failed to get received count metric", zap.Error(err)) + return + } + + receivedBytesMetric, err := p.metrics.receivedBytes.GetMetricWith(p.labels) + if err != nil { + p.log.Error("failed to get received bytes metric", zap.Error(err)) + return + } + + receivedCountMetric.Add(float64(len(response.Gossip))) + receivedBytesMetric.Add(float64(receivedBytes)) +} + +// NewPushGossiper returns an instance of PushGossiper +func NewPushGossiper[T Gossipable](client *p2p.Client, metrics Metrics, targetGossipSize int) *PushGossiper[T] { + return &PushGossiper[T]{ + client: client, + metrics: metrics, + targetGossipSize: targetGossipSize, + labels: prometheus.Labels{ + typeLabel: pushType, + }, + pending: buffer.NewUnboundedDeque[T](0), + } +} + +// PushGossiper broadcasts gossip to peers randomly in the network +type PushGossiper[T Gossipable] struct { + client *p2p.Client + metrics Metrics + targetGossipSize int + + labels prometheus.Labels + + lock sync.Mutex + pending buffer.Deque[T] +} + +// Gossip flushes any queued gossipables +func (p *PushGossiper[T]) Gossip(ctx context.Context) error { + p.lock.Lock() + defer p.lock.Unlock() + + if p.pending.Len() == 0 { + return nil + } + + msg := &sdk.PushGossip{ + Gossip: make([][]byte, 0, p.pending.Len()), + } + + sentBytes := 0 + for sentBytes < p.targetGossipSize { + gossipable, ok := p.pending.PeekLeft() + if !ok { + break + } + + bytes, err := gossipable.Marshal() + if err != nil { + // remove this item so we don't get stuck in a loop + _, _ = p.pending.PopLeft() + return err + } + + msg.Gossip = append(msg.Gossip, bytes) + sentBytes += len(bytes) + p.pending.PopLeft() + } + + msgBytes, err := proto.Marshal(msg) + if err != nil { + return err + } + + sentCountMetric, err := p.metrics.sentCount.GetMetricWith(p.labels) + if err != nil { + return fmt.Errorf("failed to get sent count metric: %w", err) + } + + sentBytesMetric, err := p.metrics.sentBytes.GetMetricWith(p.labels) + if err != nil { + return fmt.Errorf("failed to get sent bytes metric: %w", err) + } + + sentCountMetric.Add(float64(len(msg.Gossip))) + sentBytesMetric.Add(float64(sentBytes)) + + return p.client.AppGossip(ctx, msgBytes) +} + +func (p *PushGossiper[T]) Add(gossipables ...T) { + p.lock.Lock() + defer p.lock.Unlock() + + for _, gossipable := range gossipables { + p.pending.PushRight(gossipable) + } } // Every calls [Gossip] every [frequency] amount of time. @@ -203,3 +351,11 @@ type NoOpGossiper struct{} func (NoOpGossiper) Gossip(context.Context) error { return nil } + +type NoOpAccumulator[T Gossipable] struct{} + +func (NoOpAccumulator[_]) Gossip(context.Context) error { + return nil +} + +func (NoOpAccumulator[T]) Add(...T) {} diff --git a/network/p2p/gossip/gossip_test.go b/network/p2p/gossip/gossip_test.go index a55cec20da59..5ccebba9756c 100644 --- a/network/p2p/gossip/gossip_test.go +++ b/network/p2p/gossip/gossip_test.go @@ -11,13 +11,19 @@ import ( "github.com/prometheus/client_golang/prometheus" + "golang.org/x/exp/maps" + + "google.golang.org/protobuf/proto" + "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network/p2p" + "github.com/ava-labs/avalanchego/proto/pb/sdk" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" ) var ( @@ -25,18 +31,14 @@ var ( _ Gossiper = (*testGossiper)(nil) ) -func TestGossiperShutdown(t *testing.T) { - require := require.New(t) - - metrics := prometheus.NewRegistry() - gossiper, err := NewPullGossiper[testTx]( - Config{}, +func TestGossiperShutdown(*testing.T) { + gossiper := NewPullGossiper[testTx]( logging.NoLog{}, nil, nil, - metrics, + Metrics{}, + 0, ) - require.NoError(err) ctx, cancel := context.WithCancel(context.Background()) wg := &sync.WaitGroup{} @@ -54,7 +56,7 @@ func TestGossiperShutdown(t *testing.T) { func TestGossiperGossip(t *testing.T) { tests := []struct { name string - config HandlerConfig + targetResponseSize int requester []*testTx // what we have responder []*testTx // what the peer we're requesting gossip from has expectedPossibleValues []*testTx // possible values we can have @@ -64,48 +66,38 @@ func TestGossiperGossip(t *testing.T) { name: "no gossip - no one knows anything", }, { - name: "no gossip - requester knows more than responder", - config: HandlerConfig{ - TargetResponseSize: 1024, - }, + name: "no gossip - requester knows more than responder", + targetResponseSize: 1024, requester: []*testTx{{id: ids.ID{0}}}, expectedPossibleValues: []*testTx{{id: ids.ID{0}}}, expectedLen: 1, }, { - name: "no gossip - requester knows everything responder knows", - config: HandlerConfig{ - TargetResponseSize: 1024, - }, + name: "no gossip - requester knows everything responder knows", + targetResponseSize: 1024, requester: []*testTx{{id: ids.ID{0}}}, responder: []*testTx{{id: ids.ID{0}}}, expectedPossibleValues: []*testTx{{id: ids.ID{0}}}, expectedLen: 1, }, { - name: "gossip - requester knows nothing", - config: HandlerConfig{ - TargetResponseSize: 1024, - }, + name: "gossip - requester knows nothing", + targetResponseSize: 1024, responder: []*testTx{{id: ids.ID{0}}}, expectedPossibleValues: []*testTx{{id: ids.ID{0}}}, expectedLen: 1, }, { - name: "gossip - requester knows less than responder", - config: HandlerConfig{ - TargetResponseSize: 1024, - }, + name: "gossip - requester knows less than responder", + targetResponseSize: 1024, requester: []*testTx{{id: ids.ID{0}}}, responder: []*testTx{{id: ids.ID{0}}, {id: ids.ID{1}}}, expectedPossibleValues: []*testTx{{id: ids.ID{0}}, {id: ids.ID{1}}}, expectedLen: 2, }, { - name: "gossip - target response size exceeded", - config: HandlerConfig{ - TargetResponseSize: 32, - }, + name: "gossip - target response size exceeded", + targetResponseSize: 32, responder: []*testTx{{id: ids.ID{0}}, {id: ids.ID{1}}, {id: ids.ID{2}}}, expectedPossibleValues: []*testTx{{id: ids.ID{0}}, {id: ids.ID{1}}, {id: ids.ID{2}}}, expectedLen: 2, @@ -125,15 +117,23 @@ func TestGossiperGossip(t *testing.T) { responseBloom, err := NewBloomFilter(1000, 0.01) require.NoError(err) - responseSet := testSet{ - set: set.Set[*testTx]{}, + responseSet := &testSet{ + txs: make(map[ids.ID]*testTx), bloom: responseBloom, } for _, item := range tt.responder { require.NoError(responseSet.Add(item)) } - handler, err := NewHandler[*testTx](responseSet, tt.config, prometheus.NewRegistry()) + metrics, err := NewMetrics(prometheus.NewRegistry(), "") + require.NoError(err) + handler := NewHandler[testTx, *testTx]( + logging.NoLog{}, + NoOpAccumulator[*testTx]{}, + responseSet, + metrics, + tt.targetResponseSize, + ) require.NoError(err) require.NoError(responseNetwork.AddHandler(0x0, handler)) @@ -147,8 +147,8 @@ func TestGossiperGossip(t *testing.T) { bloom, err := NewBloomFilter(1000, 0.01) require.NoError(err) - requestSet := testSet{ - set: set.Set[*testTx]{}, + requestSet := &testSet{ + txs: make(map[ids.ID]*testTx), bloom: bloom, } for _, item := range tt.requester { @@ -156,17 +156,14 @@ func TestGossiperGossip(t *testing.T) { } requestClient := requestNetwork.NewClient(0x0) - require.NoError(err) - config := Config{ - PollSize: 1, - } - gossiper, err := NewPullGossiper[testTx, *testTx]( - config, + require.NoError(err) + gossiper := NewPullGossiper[testTx, *testTx]( logging.NoLog{}, requestSet, requestClient, - prometheus.NewRegistry(), + metrics, + 1, ) require.NoError(err) received := set.Set[*testTx]{} @@ -178,8 +175,8 @@ func TestGossiperGossip(t *testing.T) { require.NoError(responseNetwork.AppRequest(ctx, ids.EmptyNodeID, 1, time.Time{}, <-requestSender.SentAppRequest)) require.NoError(requestNetwork.AppResponse(ctx, ids.EmptyNodeID, 1, <-responseSender.SentAppResponse)) - require.Len(requestSet.set, tt.expectedLen) - require.Subset(tt.expectedPossibleValues, requestSet.set.List()) + require.Len(requestSet.txs, tt.expectedLen) + require.Subset(tt.expectedPossibleValues, maps.Values(requestSet.txs)) // we should not receive anything that we already had before we // requested the gossip @@ -240,6 +237,208 @@ func TestValidatorGossiper(t *testing.T) { require.Equal(2, calls) } +// Tests that the outgoing gossip is equivalent to what was accumulated +func TestPushGossiper(t *testing.T) { + tests := []struct { + name string + cycles [][]*testTx + }{ + { + name: "single cycle", + cycles: [][]*testTx{ + { + &testTx{ + id: ids.ID{0}, + }, + &testTx{ + id: ids.ID{1}, + }, + &testTx{ + id: ids.ID{2}, + }, + }, + }, + }, + { + name: "multiple cycles", + cycles: [][]*testTx{ + { + &testTx{ + id: ids.ID{0}, + }, + }, + { + &testTx{ + id: ids.ID{1}, + }, + &testTx{ + id: ids.ID{2}, + }, + }, + { + &testTx{ + id: ids.ID{3}, + }, + &testTx{ + id: ids.ID{4}, + }, + &testTx{ + id: ids.ID{5}, + }, + }, + { + &testTx{ + id: ids.ID{6}, + }, + &testTx{ + id: ids.ID{7}, + }, + &testTx{ + id: ids.ID{8}, + }, + &testTx{ + id: ids.ID{9}, + }, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + ctx := context.Background() + + sender := &common.FakeSender{ + SentAppGossip: make(chan []byte, 1), + } + network, err := p2p.NewNetwork( + logging.NoLog{}, + sender, + prometheus.NewRegistry(), + "", + ) + require.NoError(err) + client := network.NewClient(0) + metrics, err := NewMetrics(prometheus.NewRegistry(), "") + require.NoError(err) + gossiper := NewPushGossiper[*testTx](client, metrics, units.MiB) + + for _, gossipables := range tt.cycles { + gossiper.Add(gossipables...) + require.NoError(gossiper.Gossip(ctx)) + + want := &sdk.PushGossip{ + Gossip: make([][]byte, 0, len(tt.cycles)), + } + + for _, gossipable := range gossipables { + bytes, err := gossipable.Marshal() + require.NoError(err) + + want.Gossip = append(want.Gossip, bytes) + } + + // remove the handler prefix + sentMsg := <-sender.SentAppGossip + got := &sdk.PushGossip{} + require.NoError(proto.Unmarshal(sentMsg[1:], got)) + + require.Equal(want.Gossip, got.Gossip) + } + }) + } +} + +// Tests that gossip to a peer should forward the gossip if it was not +// previously known +func TestPushGossipE2E(t *testing.T) { + require := require.New(t) + + // tx known by both the sender and the receiver which should not be + // forwarded + knownTx := &testTx{id: ids.GenerateTestID()} + + log := logging.NoLog{} + bloom, err := NewBloomFilter(100, 0.01) + require.NoError(err) + set := &testSet{ + txs: make(map[ids.ID]*testTx), + bloom: bloom, + } + require.NoError(set.Add(knownTx)) + + forwarder := &common.FakeSender{ + SentAppGossip: make(chan []byte, 1), + } + forwarderNetwork, err := p2p.NewNetwork(log, forwarder, prometheus.NewRegistry(), "") + require.NoError(err) + handlerID := uint64(123) + client := forwarderNetwork.NewClient(handlerID) + + metrics, err := NewMetrics(prometheus.NewRegistry(), "") + require.NoError(err) + forwarderGossiper := NewPushGossiper[*testTx](client, metrics, units.MiB) + + handler := NewHandler[testTx, *testTx]( + log, + forwarderGossiper, + set, + metrics, + 0, + ) + require.NoError(err) + require.NoError(forwarderNetwork.AddHandler(handlerID, handler)) + + issuer := &common.FakeSender{ + SentAppGossip: make(chan []byte, 1), + } + issuerNetwork, err := p2p.NewNetwork(log, issuer, prometheus.NewRegistry(), "") + require.NoError(err) + issuerClient := issuerNetwork.NewClient(handlerID) + require.NoError(err) + issuerGossiper := NewPushGossiper[*testTx](issuerClient, metrics, units.MiB) + + want := []*testTx{ + {id: ids.GenerateTestID()}, + {id: ids.GenerateTestID()}, + {id: ids.GenerateTestID()}, + } + + // gossip both some unseen txs and one the receiver already knows about + var gossiped []*testTx + gossiped = append(gossiped, want...) + gossiped = append(gossiped, knownTx) + + issuerGossiper.Add(gossiped...) + addedToSet := make([]*testTx, 0, len(want)) + set.onAdd = func(tx *testTx) { + addedToSet = append(addedToSet, tx) + } + + ctx := context.Background() + require.NoError(issuerGossiper.Gossip(ctx)) + + // make sure that we only add new txs someone gossips to us + require.NoError(forwarderNetwork.AppGossip(ctx, ids.EmptyNodeID, <-issuer.SentAppGossip)) + require.Equal(want, addedToSet) + + // make sure that we only forward txs we have not already seen before + forwardedBytes := <-forwarder.SentAppGossip + forwardedMsg := &sdk.PushGossip{} + require.NoError(proto.Unmarshal(forwardedBytes[1:], forwardedMsg)) + require.Len(forwardedMsg.Gossip, len(want)) + + gotForwarded := make([]*testTx, 0, len(addedToSet)) + for _, bytes := range forwardedMsg.Gossip { + tx := &testTx{} + require.NoError(tx.Unmarshal(bytes)) + gotForwarded = append(gotForwarded, tx) + } + + require.Equal(want, gotForwarded) +} + type testGossiper struct { gossipF func(ctx context.Context) error } diff --git a/network/p2p/gossip/gossipable.go b/network/p2p/gossip/gossipable.go index 84c37e2d6b84..d488e90e949c 100644 --- a/network/p2p/gossip/gossipable.go +++ b/network/p2p/gossip/gossipable.go @@ -14,7 +14,8 @@ type Gossipable interface { // Set holds a set of known Gossipable items type Set[T Gossipable] interface { - // Add adds a Gossipable to the set + // Add adds a Gossipable to the set. Returns an error if gossipable was not + // added. Add(gossipable T) error // Iterate iterates over elements until [f] returns false Iterate(f func(gossipable T) bool) diff --git a/network/p2p/gossip/handler.go b/network/p2p/gossip/handler.go index 695551f9dbc0..f1da62a03962 100644 --- a/network/p2p/gossip/handler.go +++ b/network/p2p/gossip/handler.go @@ -5,65 +5,58 @@ package gossip import ( "context" + "fmt" "time" bloomfilter "github.com/holiman/bloomfilter/v2" "github.com/prometheus/client_golang/prometheus" + "go.uber.org/zap" + "google.golang.org/protobuf/proto" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/proto/pb/sdk" - "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/logging" ) -var _ p2p.Handler = (*Handler[Gossipable])(nil) - -type HandlerConfig struct { - Namespace string - TargetResponseSize int -} +var _ p2p.Handler = (*Handler[testTx, *testTx])(nil) -func NewHandler[T Gossipable]( - set Set[T], - config HandlerConfig, - metrics prometheus.Registerer, -) (*Handler[T], error) { - h := &Handler[T]{ +func NewHandler[T any, U GossipableAny[T]]( + log logging.Logger, + accumulator Accumulator[U], + set Set[U], + metrics Metrics, + targetResponseSize int, +) *Handler[T, U] { + return &Handler[T, U]{ Handler: p2p.NoOpHandler{}, + log: log, + accumulator: accumulator, set: set, - targetResponseSize: config.TargetResponseSize, - sentN: prometheus.NewCounter(prometheus.CounterOpts{ - Namespace: config.Namespace, - Name: "gossip_sent_n", - Help: "amount of gossip sent (n)", - }), - sentBytes: prometheus.NewCounter(prometheus.CounterOpts{ - Namespace: config.Namespace, - Name: "gossip_sent_bytes", - Help: "amount of gossip sent (bytes)", - }), + metrics: metrics, + targetResponseSize: targetResponseSize, + pullLabels: prometheus.Labels{ + typeLabel: pullType, + }, } - - err := utils.Err( - metrics.Register(h.sentN), - metrics.Register(h.sentBytes), - ) - return h, err } -type Handler[T Gossipable] struct { +type Handler[T any, U GossipableAny[T]] struct { p2p.Handler - set Set[T] + accumulator Accumulator[U] + log logging.Logger + set Set[U] + metrics Metrics targetResponseSize int - sentN prometheus.Counter - sentBytes prometheus.Counter + pullLabels prometheus.Labels + pushLabels prometheus.Labels } -func (h Handler[T]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, requestBytes []byte) ([]byte, error) { +func (h Handler[_, U]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, requestBytes []byte) ([]byte, error) { request := &sdk.PullGossipRequest{} if err := proto.Unmarshal(requestBytes, request); err != nil { return nil, err @@ -84,7 +77,7 @@ func (h Handler[T]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, req responseSize := 0 gossipBytes := make([][]byte, 0) - h.set.Iterate(func(gossipable T) bool { + h.set.Iterate(func(gossipable U) bool { // filter out what the requesting peer already knows about if filter.Has(gossipable) { return true @@ -112,8 +105,72 @@ func (h Handler[T]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, req Gossip: gossipBytes, } - h.sentN.Add(float64(len(response.Gossip))) - h.sentBytes.Add(float64(responseSize)) + sentCountMetric, err := h.metrics.sentCount.GetMetricWith(h.pullLabels) + if err != nil { + return nil, fmt.Errorf("failed to get sent count metric: %w", err) + } + + sentBytesMetric, err := h.metrics.sentBytes.GetMetricWith(h.pullLabels) + if err != nil { + return nil, fmt.Errorf("failed to get sent bytes metric: %w", err) + } + + sentCountMetric.Add(float64(len(response.Gossip))) + sentBytesMetric.Add(float64(responseSize)) return proto.Marshal(response) } + +func (h Handler[T, U]) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { + msg := &sdk.PushGossip{} + if err := proto.Unmarshal(gossipBytes, msg); err != nil { + h.log.Debug("failed to unmarshal gossip", zap.Error(err)) + return + } + + receivedBytes := 0 + for _, bytes := range msg.Gossip { + receivedBytes += len(bytes) + gossipable := U(new(T)) + if err := gossipable.Unmarshal(bytes); err != nil { + h.log.Debug("failed to unmarshal gossip", + zap.Stringer("nodeID", nodeID), + zap.Error(err), + ) + continue + } + + if err := h.set.Add(gossipable); err != nil { + h.log.Debug( + "failed to add gossip to the known set", + zap.Stringer("nodeID", nodeID), + zap.Stringer("id", gossipable.GetID()), + zap.Error(err), + ) + continue + } + + // continue gossiping messages we have not seen to other peers + h.accumulator.Add(gossipable) + } + + if err := h.accumulator.Gossip(ctx); err != nil { + h.log.Error("failed to forward gossip", zap.Error(err)) + return + } + + receivedCountMetric, err := h.metrics.receivedCount.GetMetricWith(h.pushLabels) + if err != nil { + h.log.Error("failed to get received count metric", zap.Error(err)) + return + } + + receivedBytesMetric, err := h.metrics.receivedBytes.GetMetricWith(h.pushLabels) + if err != nil { + h.log.Error("failed to get received bytes metric", zap.Error(err)) + return + } + + receivedCountMetric.Add(float64(len(msg.Gossip))) + receivedBytesMetric.Add(float64(receivedBytes)) +} diff --git a/network/p2p/gossip/test_gossip.go b/network/p2p/gossip/test_gossip.go index ba114adf3774..8e87ba70da94 100644 --- a/network/p2p/gossip/test_gossip.go +++ b/network/p2p/gossip/test_gossip.go @@ -4,8 +4,9 @@ package gossip import ( + "fmt" + "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/set" ) var ( @@ -32,13 +33,17 @@ func (t *testTx) Unmarshal(bytes []byte) error { } type testSet struct { - set set.Set[*testTx] + txs map[ids.ID]*testTx bloom *BloomFilter onAdd func(tx *testTx) } -func (t testSet) Add(gossipable *testTx) error { - t.set.Add(gossipable) +func (t *testSet) Add(gossipable *testTx) error { + if _, ok := t.txs[gossipable.id]; ok { + return fmt.Errorf("%s already present", gossipable.id) + } + + t.txs[gossipable.id] = gossipable t.bloom.Add(gossipable) if t.onAdd != nil { t.onAdd(gossipable) @@ -47,15 +52,15 @@ func (t testSet) Add(gossipable *testTx) error { return nil } -func (t testSet) Iterate(f func(gossipable *testTx) bool) { - for tx := range t.set { +func (t *testSet) Iterate(f func(gossipable *testTx) bool) { + for _, tx := range t.txs { if !f(tx) { return } } } -func (t testSet) GetFilter() ([]byte, []byte, error) { +func (t *testSet) GetFilter() ([]byte, []byte, error) { bloom, err := t.bloom.Bloom.MarshalBinary() return bloom, t.bloom.Salt[:], err } diff --git a/network/p2p/network_test.go b/network/p2p/network_test.go index b8775c112d9c..ef42830db6ac 100644 --- a/network/p2p/network_test.go +++ b/network/p2p/network_test.go @@ -165,8 +165,11 @@ func TestAppRequestResponse(t *testing.T) { close(done) } - require.NoError(client.AppRequest(ctx, set.Of(wantNodeID), []byte("request"), callback)) - <-sender.SentAppRequest + want := []byte("request") + require.NoError(client.AppRequest(ctx, set.Of(wantNodeID), want, callback)) + got := <-sender.SentAppRequest + require.Equal(handlerPrefix, got[0]) + require.Equal(want, got[1:]) require.NoError(network.AppResponse(ctx, wantNodeID, 1, wantResponse)) <-done diff --git a/proto/pb/sdk/sdk.pb.go b/proto/pb/sdk/sdk.pb.go index 120974ee5976..b828c4026d96 100644 --- a/proto/pb/sdk/sdk.pb.go +++ b/proto/pb/sdk/sdk.pb.go @@ -122,6 +122,53 @@ func (x *PullGossipResponse) GetGossip() [][]byte { return nil } +type PushGossip struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Gossip [][]byte `protobuf:"bytes,1,rep,name=gossip,proto3" json:"gossip,omitempty"` +} + +func (x *PushGossip) Reset() { + *x = PushGossip{} + if protoimpl.UnsafeEnabled { + mi := &file_sdk_sdk_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushGossip) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushGossip) ProtoMessage() {} + +func (x *PushGossip) ProtoReflect() protoreflect.Message { + mi := &file_sdk_sdk_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PushGossip.ProtoReflect.Descriptor instead. +func (*PushGossip) Descriptor() ([]byte, []int) { + return file_sdk_sdk_proto_rawDescGZIP(), []int{2} +} + +func (x *PushGossip) GetGossip() [][]byte { + if x != nil { + return x.Gossip + } + return nil +} + var File_sdk_sdk_proto protoreflect.FileDescriptor var file_sdk_sdk_proto_rawDesc = []byte{ @@ -133,10 +180,13 @@ var file_sdk_sdk_proto_rawDesc = []byte{ 0x04, 0x73, 0x61, 0x6c, 0x74, 0x22, 0x2c, 0x0a, 0x12, 0x50, 0x75, 0x6c, 0x6c, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, - 0x73, 0x69, 0x70, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, - 0x73, 0x64, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x69, 0x70, 0x22, 0x24, 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x47, 0x6f, 0x73, 0x73, 0x69, + 0x70, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, + 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x64, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -151,10 +201,11 @@ func file_sdk_sdk_proto_rawDescGZIP() []byte { return file_sdk_sdk_proto_rawDescData } -var file_sdk_sdk_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_sdk_sdk_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_sdk_sdk_proto_goTypes = []interface{}{ (*PullGossipRequest)(nil), // 0: sdk.PullGossipRequest (*PullGossipResponse)(nil), // 1: sdk.PullGossipResponse + (*PushGossip)(nil), // 2: sdk.PushGossip } var file_sdk_sdk_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -194,6 +245,18 @@ func file_sdk_sdk_proto_init() { return nil } } + file_sdk_sdk_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushGossip); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -201,7 +264,7 @@ func file_sdk_sdk_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_sdk_sdk_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/sdk/sdk.proto b/proto/sdk/sdk.proto index 20bfca081856..6841cfb8b020 100644 --- a/proto/sdk/sdk.proto +++ b/proto/sdk/sdk.proto @@ -12,3 +12,7 @@ message PullGossipRequest { message PullGossipResponse { repeated bytes gossip = 1; } + +message PushGossip { + repeated bytes gossip = 1; +} From 8107f792ce2af22a66e360c1d5093b6a590595d6 Mon Sep 17 00:00:00 2001 From: marun Date: Thu, 14 Dec 2023 20:13:33 -0800 Subject: [PATCH 154/267] `tmpnet`: Move tmpnet/local to tmpnet package (#2457) Co-authored-by: aaronbuchwald --- scripts/tests.upgrade.sh | 11 +- tests/e2e/c/dynamic_fees.go | 8 +- tests/e2e/faultinjection/duplicate_node_id.go | 18 +- tests/e2e/p/interchain_workflow.go | 4 +- tests/e2e/p/staking_rewards.go | 8 +- tests/fixture/e2e/env.go | 17 +- tests/fixture/e2e/flags.go | 10 +- tests/fixture/e2e/helpers.go | 21 +- tests/fixture/tmpnet/README.md | 217 ++++++++++++- tests/fixture/tmpnet/cmd/main.go | 27 +- tests/fixture/tmpnet/config.go | 5 - .../tmpnet/{local/config.go => defaults.go} | 19 +- tests/fixture/tmpnet/interfaces.go | 28 -- tests/fixture/tmpnet/local/README.md | 219 ------------- tests/fixture/tmpnet/{local => }/network.go | 299 +++++++++--------- .../tmpnet/{local => }/network_test.go | 6 +- tests/fixture/tmpnet/{local => }/node.go | 103 +++--- tests/fixture/tmpnet/{local => }/node_test.go | 4 +- tests/fixture/tmpnet/{common.go => utils.go} | 14 +- tests/upgrade/upgrade_test.go | 7 +- 20 files changed, 483 insertions(+), 562 deletions(-) rename tests/fixture/tmpnet/{local/config.go => defaults.go} (77%) delete mode 100644 tests/fixture/tmpnet/interfaces.go delete mode 100644 tests/fixture/tmpnet/local/README.md rename tests/fixture/tmpnet/{local => }/network.go (65%) rename tests/fixture/tmpnet/{local => }/network_test.go (84%) rename tests/fixture/tmpnet/{local => }/node.go (72%) rename tests/fixture/tmpnet/{local => }/node_test.go (90%) rename tests/fixture/tmpnet/{common.go => utils.go} (72%) diff --git a/scripts/tests.upgrade.sh b/scripts/tests.upgrade.sh index 8b274180cd12..49c402da29a1 100755 --- a/scripts/tests.upgrade.sh +++ b/scripts/tests.upgrade.sh @@ -11,10 +11,13 @@ if ! [[ "$0" =~ scripts/tests.upgrade.sh ]]; then exit 255 fi -# 1.10.17 is the first version compatible with bls signing keys being -# included in the genesis. Attempting to upgrade from prior versions -# will result in nodes failing to boot due to the hash of the genesis -# not matching the hash of the committed genesis block. +# The AvalancheGo local network does not support long-lived +# backwards-compatible networks. When a breaking change is made to the +# local network, this flag must be updated to the last compatible +# version with the latest code. +# +# v1.10.17 includes the AWM activation on the C-Chain local network +# and the inclusion of BLS Public Keys in the network genesis. DEFAULT_VERSION="1.10.17" VERSION="${1:-${DEFAULT_VERSION}}" diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 6d106dc77fed..5e80573542b4 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -42,14 +42,14 @@ var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { privateNetwork := e2e.Env.NewPrivateNetwork() ginkgo.By("allocating a pre-funded key") - key := privateNetwork.GetConfig().PreFundedKeys[0] + key := privateNetwork.PreFundedKeys[0] ethAddress := evm.GetEthAddress(key) ginkgo.By("initializing a coreth client") - node := privateNetwork.GetNodes()[0] + node := privateNetwork.Nodes[0] nodeURI := tmpnet.NodeURI{ - NodeID: node.GetID(), - URI: node.GetProcessContext().URI, + NodeID: node.NodeID, + URI: node.URI, } ethClient := e2e.NewEthClient(nodeURI) diff --git a/tests/e2e/faultinjection/duplicate_node_id.go b/tests/e2e/faultinjection/duplicate_node_id.go index 9278c1bd5b8d..65a81a0a05eb 100644 --- a/tests/e2e/faultinjection/duplicate_node_id.go +++ b/tests/e2e/faultinjection/duplicate_node_id.go @@ -24,17 +24,16 @@ var _ = ginkgo.Describe("Duplicate node handling", func() { ginkgo.It("should ensure that a given Node ID (i.e. staking keypair) can be used at most once on a network", func() { network := e2e.Env.GetNetwork() - nodes := network.GetNodes() ginkgo.By("creating new node") node1 := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) e2e.WaitForHealthy(node1) ginkgo.By("checking that the new node is connected to its peers") - checkConnectedPeers(nodes, node1) + checkConnectedPeers(network.Nodes, node1) ginkgo.By("creating a second new node with the same staking keypair as the first new node") - node1Flags := node1.GetConfig().Flags + node1Flags := node1.Flags node2Flags := tmpnet.FlagsMap{ config.StakingTLSKeyContentKey: node1Flags[config.StakingTLSKeyContentKey], config.StakingCertContentKey: node1Flags[config.StakingCertContentKey], @@ -56,18 +55,18 @@ var _ = ginkgo.Describe("Duplicate node handling", func() { e2e.WaitForHealthy(node2) ginkgo.By("checking that the second new node is connected to its peers") - checkConnectedPeers(nodes, node2) + checkConnectedPeers(network.Nodes, node2) // A bootstrap check was already performed by the second node. }) }) // Check that a new node is connected to existing nodes and vice versa -func checkConnectedPeers(existingNodes []tmpnet.Node, newNode tmpnet.Node) { +func checkConnectedPeers(existingNodes []*tmpnet.Node, newNode *tmpnet.Node) { require := require.New(ginkgo.GinkgoT()) // Collect the node ids of the new node's peers - infoClient := info.NewClient(newNode.GetProcessContext().URI) + infoClient := info.NewClient(newNode.URI) peers, err := infoClient.Peers(e2e.DefaultContext()) require.NoError(err) peerIDs := set.NewSet[ids.NodeID](len(existingNodes)) @@ -75,18 +74,17 @@ func checkConnectedPeers(existingNodes []tmpnet.Node, newNode tmpnet.Node) { peerIDs.Add(peer.ID) } - newNodeID := newNode.GetID() for _, existingNode := range existingNodes { // Check that the existing node is a peer of the new node - require.True(peerIDs.Contains(existingNode.GetID())) + require.True(peerIDs.Contains(existingNode.NodeID)) // Check that the new node is a peer - infoClient := info.NewClient(existingNode.GetProcessContext().URI) + infoClient := info.NewClient(existingNode.URI) peers, err := infoClient.Peers(e2e.DefaultContext()) require.NoError(err) isPeer := false for _, peer := range peers { - if peer.ID == newNodeID { + if peer.ID == newNode.NodeID { isPeer = true break } diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 678f9b5cc204..755312ae8160 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -43,7 +43,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL network := e2e.Env.GetNetwork() ginkgo.By("checking that the network has a compatible minimum stake duration", func() { - minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) + minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) }) @@ -91,7 +91,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL e2e.WaitForHealthy(node) ginkgo.By("retrieving new node's id and pop") - infoClient := info.NewClient(node.GetProcessContext().URI) + infoClient := info.NewClient(node.URI) nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) require.NoError(err) diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index ce6990b236a1..c8ae29805ebf 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -42,7 +42,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { network := e2e.Env.GetNetwork() ginkgo.By("checking that the network has a compatible minimum stake duration", func() { - minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) + minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) }) @@ -94,16 +94,16 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { pWallet := baseWallet.P() ginkgo.By("retrieving alpha node id and pop") - alphaInfoClient := info.NewClient(alphaNode.GetProcessContext().URI) + alphaInfoClient := info.NewClient(alphaNode.URI) alphaNodeID, alphaPOP, err := alphaInfoClient.GetNodeID(e2e.DefaultContext()) require.NoError(err) ginkgo.By("retrieving beta node id and pop") - betaInfoClient := info.NewClient(betaNode.GetProcessContext().URI) + betaInfoClient := info.NewClient(betaNode.URI) betaNodeID, betaPOP, err := betaInfoClient.GetNodeID(e2e.DefaultContext()) require.NoError(err) - pvmClient := platformvm.NewClient(alphaNode.GetProcessContext().URI) + pvmClient := platformvm.NewClient(alphaNode.URI) const ( delegationPercent = 0.10 // 10% diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index 3cd77ecb5c4c..c50a2a7aace2 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture" "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet/local" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -60,14 +59,14 @@ func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { networkDir := flagVars.NetworkDir() // Load or create a test network - var network *local.LocalNetwork + var network *tmpnet.Network if len(networkDir) > 0 { var err error - network, err = local.ReadNetwork(networkDir) + network, err = tmpnet.ReadNetwork(networkDir) require.NoError(err) tests.Outf("{{yellow}}Using an existing network configured at %s{{/}}\n", network.Dir) } else { - network = StartLocalNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir) + network = StartNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir) } uris := network.GetURIs() @@ -97,8 +96,8 @@ func (te *TestEnvironment) GetRandomNodeURI() tmpnet.NodeURI { } // Retrieve the network to target for testing. -func (te *TestEnvironment) GetNetwork() tmpnet.Network { - network, err := local.ReadNetwork(te.NetworkDir) +func (te *TestEnvironment) GetNetwork() *tmpnet.Network { + network, err := tmpnet.ReadNetwork(te.NetworkDir) te.require.NoError(err) return network } @@ -123,9 +122,9 @@ func (te *TestEnvironment) NewKeychain(count int) *secp256k1fx.Keychain { } // Create a new private network that is not shared with other tests. -func (te *TestEnvironment) NewPrivateNetwork() tmpnet.Network { +func (te *TestEnvironment) NewPrivateNetwork() *tmpnet.Network { // Load the shared network to retrieve its path and exec path - sharedNetwork, err := local.ReadNetwork(te.NetworkDir) + sharedNetwork, err := tmpnet.ReadNetwork(te.NetworkDir) te.require.NoError(err) // The private networks dir is under the shared network dir to ensure it @@ -133,5 +132,5 @@ func (te *TestEnvironment) NewPrivateNetwork() tmpnet.Network { privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName) te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute)) - return StartLocalNetwork(sharedNetwork.ExecPath, privateNetworksDir) + return StartNetwork(sharedNetwork.ExecPath, privateNetworksDir) } diff --git a/tests/fixture/e2e/flags.go b/tests/fixture/e2e/flags.go index 23952b5dcd91..b1354473fe86 100644 --- a/tests/fixture/e2e/flags.go +++ b/tests/fixture/e2e/flags.go @@ -8,7 +8,7 @@ import ( "fmt" "os" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet/local" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" ) type FlagVars struct { @@ -24,7 +24,7 @@ func (v *FlagVars) NetworkDir() string { if len(v.networkDir) > 0 { return v.networkDir } - return os.Getenv(local.NetworkDirEnvName) + return os.Getenv(tmpnet.NetworkDirEnvName) } func (v *FlagVars) AvalancheGoExecPath() string { @@ -40,14 +40,14 @@ func RegisterFlags() *FlagVars { flag.StringVar( &vars.avalancheGoExecPath, "avalanchego-path", - os.Getenv(local.AvalancheGoPathEnvName), - fmt.Sprintf("avalanchego executable path (required if not using an existing network). Also possible to configure via the %s env variable.", local.AvalancheGoPathEnvName), + os.Getenv(tmpnet.AvalancheGoPathEnvName), + fmt.Sprintf("avalanchego executable path (required if not using an existing network). Also possible to configure via the %s env variable.", tmpnet.AvalancheGoPathEnvName), ) flag.StringVar( &vars.networkDir, "network-dir", "", - fmt.Sprintf("[optional] the dir containing the configuration of an existing network to target for testing. Will only be used if --use-existing-network is specified. Also possible to configure via the %s env variable.", local.NetworkDirEnvName), + fmt.Sprintf("[optional] the dir containing the configuration of an existing network to target for testing. Will only be used if --use-existing-network is specified. Also possible to configure via the %s env variable.", tmpnet.NetworkDirEnvName), ) flag.BoolVar( &vars.useExistingNetwork, diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index c5776e546389..36555bae598c 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet/local" "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary" @@ -128,7 +127,7 @@ func Eventually(condition func() bool, waitFor time.Duration, tick time.Duration // Add an ephemeral node that is only intended to be used by a single test. Its ID and // URI are not intended to be returned from the Network instance to minimize // accessibility from other tests. -func AddEphemeralNode(network tmpnet.Network, flags tmpnet.FlagsMap) tmpnet.Node { +func AddEphemeralNode(network *tmpnet.Network, flags tmpnet.FlagsMap) *tmpnet.Node { require := require.New(ginkgo.GinkgoT()) node, err := network.AddEphemeralNode(ginkgo.GinkgoWriter, flags) @@ -137,7 +136,7 @@ func AddEphemeralNode(network tmpnet.Network, flags tmpnet.FlagsMap) tmpnet.Node // Ensure node is stopped on teardown. It's configuration is not removed to enable // collection in CI to aid in troubleshooting failures. ginkgo.DeferCleanup(func() { - tests.Outf("Shutting down ephemeral node %s\n", node.GetID()) + tests.Outf("Shutting down ephemeral node %s\n", node.NodeID) require.NoError(node.Stop()) }) @@ -145,7 +144,7 @@ func AddEphemeralNode(network tmpnet.Network, flags tmpnet.FlagsMap) tmpnet.Node } // Wait for the given node to report healthy. -func WaitForHealthy(node tmpnet.Node) { +func WaitForHealthy(node *tmpnet.Node) { // Need to use explicit context (vs DefaultContext()) to support use with DeferCleanup ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) defer cancel() @@ -197,7 +196,7 @@ func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { } // Verify that a new node can bootstrap into the network. -func CheckBootstrapIsPossible(network tmpnet.Network) { +func CheckBootstrapIsPossible(network *tmpnet.Network) { require := require.New(ginkgo.GinkgoT()) if len(os.Getenv(SkipBootstrapChecksEnvName)) > 0 { @@ -214,23 +213,23 @@ func CheckBootstrapIsPossible(network tmpnet.Network) { require.NoError(err) defer func() { - tests.Outf("Shutting down ephemeral node %s\n", node.GetID()) + tests.Outf("Shutting down ephemeral node %s\n", node.NodeID) require.NoError(node.Stop()) }() WaitForHealthy(node) } -// Start a local test-managed network with the provided avalanchego binary. -func StartLocalNetwork(avalancheGoExecPath string, networkDir string) *local.LocalNetwork { +// Start a temporary network with the provided avalanchego binary. +func StartNetwork(avalancheGoExecPath string, networkDir string) *tmpnet.Network { require := require.New(ginkgo.GinkgoT()) - network, err := local.StartNetwork( + network, err := tmpnet.StartNetwork( DefaultContext(), ginkgo.GinkgoWriter, networkDir, - &local.LocalNetwork{ - LocalConfig: local.LocalConfig{ + &tmpnet.Network{ + NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ ExecPath: avalancheGoExecPath, }, }, diff --git a/tests/fixture/tmpnet/README.md b/tests/fixture/tmpnet/README.md index ca48d553105e..15688417990d 100644 --- a/tests/fixture/tmpnet/README.md +++ b/tests/fixture/tmpnet/README.md @@ -1,11 +1,11 @@ # tmpnet (temporary network fixture) -This package contains configuration and interfaces that are -independent of a given orchestration mechanism -(e.g. [local](local/README.md)). The intent is to enable tests to be -written against the interfaces defined in this package and for -implementation-specific details of test network orchestration to be -limited to test setup and teardown. +This package implements a simple orchestrator for the avalanchego +nodes of a temporary network. Configuration is stored on disk, and +nodes run as independent processes whose process details are also +written to disk. Using the filesystem to store configuration and +process details allows for the `tmpnetctl` cli and e2e test fixture to +orchestrate the same temporary networks without the use of an rpc daemon. ## What's in a name? @@ -18,3 +18,208 @@ To avoid confusion, the name was changed to `tmpnet` and its cli networks it deploys are likely to live for a limited duration in support of the development and testing of avalanchego and its related repositories. + +## Package details + +The functionality in this package is grouped by logical purpose into +the following non-test files: + +| Filename | Types | Purpose | +|:------------|:--------|:----------------------------------------------| +| defaults.go | | Default configuration | +| network.go | Network | Network-level orchestration and configuration | +| node.go | Node | Node-level orchestration and configuration | +| util.go | | Shared utility functions | + +## Usage + +### Via tmpnetctl + +A temporary network can be managed by the `tmpnetctl` cli tool: + +```bash +# From the root of the avalanchego repo + +# Build the tmpnetctl binary +$ ./scripts/build_tmpnetctl.sh + +# Start a new network +$ ./build/tmpnetctl start-network --avalanchego-path=/path/to/avalanchego +... +Started network 1000 @ /home/me/.tmpnet/networks/1000 + +Configure tmpnetctl to target this network by default with one of the following statements: + - source /home/me/.tmpnet/networks/1000/network.env + - export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/1000 + - export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/latest + +# Stop the network +$ ./build/tmpnetctl stop-network --network-dir=/path/to/network +``` + +Note the export of the path ending in `latest`. This is a symlink that +is set to the last network created by `tmpnetctl start-network`. Setting +the `TMPNET_NETWORK_DIR` env var to this symlink ensures that +`tmpnetctl` commands and e2e execution with +`--use-existing-network` will target the most recently deployed temporary +network. + +### Via code + +A temporary network can be managed in code: + +```golang +network, _ := tmpnet.StartNetwork( + ctx, // Context used to limit duration of waiting for network health + ginkgo.GinkgoWriter, // Writer to report progress of network start + "", // Use default root dir (~/.tmpnet) + &tmpnet.Network{ + DefaultRuntime: tmpnet.NodeRuntimeConfig{ + ExecPath: "/path/to/avalanchego", // Defining the avalanchego exec path is required + }, + }, + 5, // Number of initial validating nodes + 50, // Number of pre-funded keys to create +) + +uris := network.GetURIs() + +// Use URIs to interact with the network + +// Stop all nodes in the network +network.Stop() +``` + +If non-default node behavior is required, the `Network` instance +supplied to `StartNetwork()` can be initialized with explicit node +configuration and by supplying a nodeCount argument of `0`: + +```golang +network, _ := tmpnet.StartNetwork( + ctx, + ginkgo.GinkgoWriter, + "", + &tmpnet.Network{ + DefaultRuntime: tmpnet.NodeRuntimeConfig{ + ExecPath: "/path/to/avalanchego", + }, + Nodes: []*Node{ + { // node1 configuration is customized + Flags: FlagsMap{ // Any and all node flags can be configured here + config.DataDirKey: "/custom/path/to/node/data", + } + }, + }, + {}, // node2 uses default configuration + {}, // node3 uses default configuration + {}, // node4 uses default configuration + {}, // node5 uses default configuration + }, + 0, // Node count must be zero when setting node config + 50, +) +``` + +Further examples of code-based usage are located in the [e2e +tests](../../e2e/e2e_test.go). + +## Networking configuration + +By default, nodes in a temporary network will be started with staking and +API ports set to `0` to ensure that ports will be dynamically +chosen. The tmpnet fixture discovers the ports used by a given node +by reading the `[base-data-dir]/process.json` file written by +avalanchego on node start. The use of dynamic ports supports testing +with many temporary networks without having to manually select compatible +port ranges. + +## Configuration on disk + +A temporary network relies on configuration written to disk in the following structure: + +``` +HOME +└── .tmpnet // Root path for the temporary network fixture + └── networks // Default parent directory for temporary networks + └── 1000 // The networkID is used to name the network dir and starts at 1000 + ├── NodeID-37E8UK3x2YFsHE3RdALmfWcppcZ1eTuj9 // The ID of a node is the name of its data dir + │ ├── chainData + │ │ └── ... + │ ├── config.json // Node flags + │ ├── db + │ │ └── ... + │ ├── logs + │ │ └── ... + │ ├── plugins + │ │ └── ... + │ └── process.json // Node process details (PID, API URI, staking address) + ├── chains + │ └── C + │ └── config.json // C-Chain config for all nodes + ├── defaults.json // Default flags and configuration for network + ├── genesis.json // Genesis for all nodes + ├── network.env // Sets network dir env to simplify use of network + └── ephemeral // Parent directory for ephemeral nodes (e.g. created by tests) + └─ NodeID-FdxnAvr4jK9XXAwsYZPgWAHW2QnwSZ // Data dir for an ephemeral node + └── ... + +``` + +### Default flags and configuration + +The default avalanchego node flags (e.g. `--staking-port=`) and +default configuration like the avalanchego path are stored at +`[network-dir]/defaults.json`. The value for a given defaulted flag +will be set on initial and subsequently added nodes that do not supply +values for a given defaulted flag. + +### Genesis + +The genesis file is stored at `[network-dir]/genesis.json` and +referenced by default by all nodes in the network. The genesis file +content will be generated with reasonable defaults if not +supplied. Each node in the network can override the default by setting +an explicit value for `--genesis-file` or `--genesis-file-content`. + +### C-Chain config + +The C-Chain config for a temporary network is stored at +`[network-dir]/chains/C/config.json` and referenced by default by all +nodes in the network. The C-Chain config will be generated with +reasonable defaults if not supplied. Each node in the network can +override the default by setting an explicit value for +`--chain-config-dir` and ensuring the C-Chain config file exists at +`[chain-config-dir]/C/config.json`. + +TODO(marun) Enable configuration of X-Chain and P-Chain. + +### Network env + +A shell script that sets the `TMPNET_NETWORK_DIR` env var to the +path of the network is stored at `[network-dir]/network.env`. Sourcing +this file (i.e. `source network.env`) in a shell will configure ginkgo +e2e and the `tmpnetctl` cli to target the network path specified in +the env var. + +### Node configuration + +The data dir for a node is set by default to +`[network-path]/[node-id]`. A node can be configured to use a +non-default path by explicitly setting the `--data-dir` +flag. + +#### Flags + +All flags used to configure a node are written to +`[network-path]/[node-id]/config.json` so that a node can be +configured with only a single argument: +`--config-file=/path/to/config.json`. This simplifies node launch and +ensures all parameters used to launch a node can be modified by +editing the config file. + +#### Process details + +The process details of a node are written by avalanchego to +`[base-data-dir]/process.json`. The file contains the PID of the node +process, the URI of the node's API, and the address other nodes can +use to bootstrap themselves (aka staking address). diff --git a/tests/fixture/tmpnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go index e58bb7213b36..0fe8435bb49e 100644 --- a/tests/fixture/tmpnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -14,15 +14,14 @@ import ( "github.com/spf13/cobra" "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet/local" "github.com/ava-labs/avalanchego/version" ) const cliVersion = "0.0.1" var ( - errAvalancheGoRequired = fmt.Errorf("--avalanchego-path or %s are required", local.AvalancheGoPathEnvName) - errNetworkDirRequired = fmt.Errorf("--network-dir or %s are required", local.NetworkDirEnvName) + errAvalancheGoRequired = fmt.Errorf("--avalanchego-path or %s are required", tmpnet.AvalancheGoPathEnvName) + errNetworkDirRequired = fmt.Errorf("--network-dir or %s are required", tmpnet.NetworkDirEnvName) ) func main() { @@ -53,7 +52,7 @@ func main() { ) startNetworkCmd := &cobra.Command{ Use: "start-network", - Short: "Start a new local network", + Short: "Start a new temporary network", RunE: func(*cobra.Command, []string) error { if len(execPath) == 0 { return errAvalancheGoRequired @@ -61,14 +60,14 @@ func main() { // Root dir will be defaulted on start if not provided - network := &local.LocalNetwork{ - LocalConfig: local.LocalConfig{ + network := &tmpnet.Network{ + NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ ExecPath: execPath, }, } - ctx, cancel := context.WithTimeout(context.Background(), local.DefaultNetworkStartTimeout) + ctx, cancel := context.WithTimeout(context.Background(), tmpnet.DefaultNetworkStartTimeout) defer cancel() - network, err := local.StartNetwork(ctx, os.Stdout, rootDir, network, int(nodeCount), int(preFundedKeyCount)) + network, err := tmpnet.StartNetwork(ctx, os.Stdout, rootDir, network, int(nodeCount), int(preFundedKeyCount)) if err != nil { return err } @@ -87,13 +86,13 @@ func main() { fmt.Fprintf(os.Stdout, "\nConfigure tmpnetctl to target this network by default with one of the following statements:") fmt.Fprintf(os.Stdout, "\n - source %s\n", network.EnvFilePath()) fmt.Fprintf(os.Stdout, " - %s\n", network.EnvFileContents()) - fmt.Fprintf(os.Stdout, " - export %s=%s\n", local.NetworkDirEnvName, latestSymlinkPath) + fmt.Fprintf(os.Stdout, " - export %s=%s\n", tmpnet.NetworkDirEnvName, latestSymlinkPath) return nil }, } - startNetworkCmd.PersistentFlags().StringVar(&rootDir, "root-dir", os.Getenv(local.RootDirEnvName), "The path to the root directory for local networks") - startNetworkCmd.PersistentFlags().StringVar(&execPath, "avalanchego-path", os.Getenv(local.AvalancheGoPathEnvName), "The path to an avalanchego binary") + startNetworkCmd.PersistentFlags().StringVar(&rootDir, "root-dir", os.Getenv(tmpnet.RootDirEnvName), "The path to the root directory for temporary networks") + startNetworkCmd.PersistentFlags().StringVar(&execPath, "avalanchego-path", os.Getenv(tmpnet.AvalancheGoPathEnvName), "The path to an avalanchego binary") startNetworkCmd.PersistentFlags().Uint8Var(&nodeCount, "node-count", tmpnet.DefaultNodeCount, "Number of nodes the network should initially consist of") startNetworkCmd.PersistentFlags().Uint8Var(&preFundedKeyCount, "pre-funded-key-count", tmpnet.DefaultPreFundedKeyCount, "Number of pre-funded keys the network should start with") rootCmd.AddCommand(startNetworkCmd) @@ -101,19 +100,19 @@ func main() { var networkDir string stopNetworkCmd := &cobra.Command{ Use: "stop-network", - Short: "Stop a local network", + Short: "Stop a temporary network", RunE: func(*cobra.Command, []string) error { if len(networkDir) == 0 { return errNetworkDirRequired } - if err := local.StopNetwork(networkDir); err != nil { + if err := tmpnet.StopNetwork(networkDir); err != nil { return err } fmt.Fprintf(os.Stdout, "Stopped network configured at: %s\n", networkDir) return nil }, } - stopNetworkCmd.PersistentFlags().StringVar(&networkDir, "network-dir", os.Getenv(local.NetworkDirEnvName), "The path to the configuration directory of a local network") + stopNetworkCmd.PersistentFlags().StringVar(&networkDir, "network-dir", os.Getenv(tmpnet.NetworkDirEnvName), "The path to the configuration directory of a temporary network") rootCmd.AddCommand(stopNetworkCmd) if err := rootCmd.Execute(); err != nil { diff --git a/tests/fixture/tmpnet/config.go b/tests/fixture/tmpnet/config.go index 03a8487f67cc..90a6c7bda04a 100644 --- a/tests/fixture/tmpnet/config.go +++ b/tests/fixture/tmpnet/config.go @@ -113,11 +113,6 @@ func ReadFlagsMap(path string, description string) (*FlagsMap, error) { return flagsMap, nil } -// Marshal to json with default prefix and indent. -func DefaultJSONMarshal(v interface{}) ([]byte, error) { - return json.MarshalIndent(v, "", " ") -} - // NetworkConfig defines configuration shared or // common to all nodes in a given network. type NetworkConfig struct { diff --git a/tests/fixture/tmpnet/local/config.go b/tests/fixture/tmpnet/defaults.go similarity index 77% rename from tests/fixture/tmpnet/local/config.go rename to tests/fixture/tmpnet/defaults.go index 70ef9a443185..c8b5c42c13d2 100644 --- a/tests/fixture/tmpnet/local/config.go +++ b/tests/fixture/tmpnet/defaults.go @@ -1,18 +1,17 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package local +package tmpnet import ( "time" "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" ) const ( // Constants defining the names of shell variables whose value can - // configure local network orchestration. + // configure temporary network orchestration. AvalancheGoPathEnvName = "AVALANCHEGO_PATH" NetworkDirEnvName = "TMPNET_NETWORK_DIR" RootDirEnvName = "TMPNET_ROOT_DIR" @@ -22,10 +21,10 @@ const ( DefaultNodeStopTimeout = 5 * time.Second ) -// A set of flags appropriate for local testing. -func LocalFlags() tmpnet.FlagsMap { +// A set of flags appropriate for testing. +func DefaultFlags() FlagsMap { // Supply only non-default configuration to ensure that default values will be used. - return tmpnet.FlagsMap{ + return FlagsMap{ config.NetworkPeerListGossipFreqKey: "250ms", config.NetworkMaxReconnectDelayKey: "1s", config.PublicIPKey: "127.0.0.1", @@ -37,16 +36,16 @@ func LocalFlags() tmpnet.FlagsMap { config.IndexEnabledKey: true, config.LogDisplayLevelKey: "INFO", config.LogLevelKey: "DEBUG", - config.MinStakeDurationKey: tmpnet.DefaultMinStakeDuration.String(), + config.MinStakeDurationKey: DefaultMinStakeDuration.String(), } } -// C-Chain config for local testing. -func LocalCChainConfig() tmpnet.FlagsMap { +// C-Chain config for testing. +func DefaultCChainConfig() FlagsMap { // Supply only non-default configuration to ensure that default // values will be used. Available C-Chain configuration options are // defined in the `github.com/ava-labs/coreth/evm` package. - return tmpnet.FlagsMap{ + return FlagsMap{ "log-level": "trace", } } diff --git a/tests/fixture/tmpnet/interfaces.go b/tests/fixture/tmpnet/interfaces.go deleted file mode 100644 index 2fd03cbc2a98..000000000000 --- a/tests/fixture/tmpnet/interfaces.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package tmpnet - -import ( - "context" - "io" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/node" -) - -// Defines network capabilities supportable regardless of how a network is orchestrated. -type Network interface { - GetConfig() NetworkConfig - GetNodes() []Node - AddEphemeralNode(w io.Writer, flags FlagsMap) (Node, error) -} - -// Defines node capabilities supportable regardless of how a network is orchestrated. -type Node interface { - GetID() ids.NodeID - GetConfig() NodeConfig - GetProcessContext() node.NodeProcessContext - IsHealthy(ctx context.Context) (bool, error) - Stop() error -} diff --git a/tests/fixture/tmpnet/local/README.md b/tests/fixture/tmpnet/local/README.md deleted file mode 100644 index 91af35a9b805..000000000000 --- a/tests/fixture/tmpnet/local/README.md +++ /dev/null @@ -1,219 +0,0 @@ -# Local network orchestration - -This package implements a simple orchestrator for the avalanchego -nodes of a local network. Configuration is stored on disk, and nodes -run as independent processes whose process details are also written to -disk. Using the filesystem to store configuration and process details -allows for the `tmpnetctl` cli and e2e test fixture to orchestrate -the same local networks without the use of an rpc daemon. - -## Package details - -The functionality in this package is grouped by logical purpose into -the following non-test files: - -| Filename | Types | Purpose | -|:-----------|:-------------------|:----------------------------------------------| -| config.go | | Common configuration | -| network.go | LocalNetwork | Network-level orchestration and configuration | -| node.go | Local{Config,Node} | Node-level orchestration and configuration | - - -This package depends on its parent package for implementation-agnostic -network and node configuration. Only configuration and code specific -to orchestrating local networks belongs in this package to ensure that -other orchestration implementations can reuse the shared configuration -abstractions. - -## Usage - -### Via tmpnetctl - -A local network can be managed by the `tmpnetctl` cli tool: - -```bash -# From the root of the avalanchego repo - -# Build the tmpnetctl binary -$ ./scripts/build_tmpnetctl.sh - -# Start a new network -$ ./build/tmpnetctl start-network --avalanchego-path=/path/to/avalanchego -... -Started network 1000 @ /home/me/.tmpnet/networks/1000 - -Configure tmpnetctl to target this network by default with one of the following statements: - - source /home/me/.tmpnet/networks/1000/network.env - - export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/1000 - - export TMPNET_NETWORK_DIR=/home/me/.tmpnet/networks/latest - -# Stop the network -$ ./build/tmpnetctl stop-network --network-dir=/path/to/network -``` - -Note the export of the path ending in `latest`. This is a symlink that -is set to the last network created by `tmpnetctl start-network`. Setting -the `TMPNET_NETWORK_DIR` env var to this symlink ensures that -`tmpnetctl` commands and e2e execution with -`--use-existing-network` will target the most recently deployed local -network. - -### Via code - -A local network can be managed in code: - -```golang -network, _ := local.StartNetwork( - ctx, // Context used to limit duration of waiting for network health - ginkgo.GinkgoWriter, // Writer to report progress of network start - "", // Use default root dir (~/.tmpnet) - &local.LocalNetwork{ - LocalConfig: local.LocalConfig{ - ExecPath: "/path/to/avalanchego", // Defining the avalanchego exec path is required - }, - }, - 5, // Number of initial validating nodes - 50, // Number of pre-funded keys to create -) - -uris := network.GetURIs() - -// Use URIs to interact with the network - -// Stop all nodes in the network -network.Stop() -``` - -If non-default node behavior is required, the `LocalNetwork` instance -supplied to `StartNetwork()` can be initialized with explicit node -configuration and by supplying a nodeCount argument of `0`: - -```golang -network, _ := local.StartNetwork( - ctx, - ginkgo.GinkgoWriter, - "", - &local.LocalNetwork{ - LocalConfig: local.LocalConfig{ - ExecPath: "/path/to/avalanchego", - }, - Nodes: []*LocalNode{ - { // node1 configuration is customized - Flags: FlagsMap{ // Any and all node flags can be configured here - config.DataDirKey: "/custom/path/to/node/data", - } - }, - }, - {}, // node2 uses default configuration - {}, // node3 uses default configuration - {}, // node4 uses default configuration - {}, // node5 uses default configuration - }, - 0, // Node count must be zero when setting node config - 50, -) -``` - -Further examples of code-based usage are located in the [e2e -tests](../../../e2e/e2e_test.go). - -## Networking configuration - -By default, nodes in a local network will be started with staking and -API ports set to `0` to ensure that ports will be dynamically -chosen. The tmpnet fixture discovers the ports used by a given node -by reading the `[base-data-dir]/process.json` file written by -avalanchego on node start. The use of dynamic ports supports testing -with many local networks without having to manually select compatible -port ranges. - -## Configuration on disk - -A local network relies on configuration written to disk in the following structure: - -``` -HOME -└── .tmpnet // Root path for the temporary network fixture - └── networks // Default parent directory for local networks - └── 1000 // The networkID is used to name the network dir and starts at 1000 - ├── NodeID-37E8UK3x2YFsHE3RdALmfWcppcZ1eTuj9 // The ID of a node is the name of its data dir - │ ├── chainData - │ │ └── ... - │ ├── config.json // Node flags - │ ├── db - │ │ └── ... - │ ├── logs - │ │ └── ... - │ ├── plugins - │ │ └── ... - │ └── process.json // Node process details (PID, API URI, staking address) - ├── chains - │ └── C - │ └── config.json // C-Chain config for all nodes - ├── defaults.json // Default flags and configuration for network - ├── genesis.json // Genesis for all nodes - ├── network.env // Sets network dir env to simplify use of network - └── ephemeral // Parent directory for ephemeral nodes (e.g. created by tests) - └─ NodeID-FdxnAvr4jK9XXAwsYZPgWAHW2QnwSZ // Data dir for an ephemeral node - └── ... - -``` - -### Default flags and configuration - -The default avalanchego node flags (e.g. `--staking-port=`) and -default configuration like the avalanchego path are stored at -`[network-dir]/defaults.json`. The value for a given defaulted flag -will be set on initial and subsequently added nodes that do not supply -values for a given defaulted flag. - -### Genesis - -The genesis file is stored at `[network-dir]/genesis.json` and -referenced by default by all nodes in the network. The genesis file -content will be generated with reasonable defaults if not -supplied. Each node in the network can override the default by setting -an explicit value for `--genesis-file` or `--genesis-file-content`. - -### C-Chain config - -The C-Chain config for a local network is stored at -`[network-dir]/chains/C/config.json` and referenced by default by all -nodes in the network. The C-Chain config will be generated with -reasonable defaults if not supplied. Each node in the network can -override the default by setting an explicit value for -`--chain-config-dir` and ensuring the C-Chain config file exists at -`[chain-config-dir]/C/config.json`. - -TODO(marun) Enable configuration of X-Chain and P-Chain. - -### Network env - -A shell script that sets the `TMPNET_NETWORK_DIR` env var to the -path of the network is stored at `[network-dir]/network.env`. Sourcing -this file (i.e. `source network.env`) in a shell will configure ginkgo -e2e and the `tmpnetctl` cli to target the network path specified in -the env var. - -### Node configuration - -The data dir for a node is set by default to -`[network-path]/[node-id]`. A node can be configured to use a -non-default path by explicitly setting the `--data-dir` -flag. - -#### Flags - -All flags used to configure a node are written to -`[network-path]/[node-id]/config.json` so that a node can be -configured with only a single argument: -`--config-file=/path/to/config.json`. This simplifies node launch and -ensures all parameters used to launch a node can be modified by -editing the config file. - -#### Process details - -The process details of a node are written by avalanchego to -`[base-data-dir]/process.json`. The file contains the PID of the node -process, the URI of the node's API, and the address other nodes can -use to bootstrap themselves (aka staking address). diff --git a/tests/fixture/tmpnet/local/network.go b/tests/fixture/tmpnet/network.go similarity index 65% rename from tests/fixture/tmpnet/local/network.go rename to tests/fixture/tmpnet/network.go index 4d0fd4ed8a4d..9c7eb976979d 100644 --- a/tests/fixture/tmpnet/local/network.go +++ b/tests/fixture/tmpnet/network.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package local +package tmpnet import ( "context" @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/formatting/address" @@ -37,10 +36,10 @@ const ( ) var ( - errInvalidNodeCount = errors.New("failed to populate local network config: non-zero node count is only valid for a network without nodes") - errInvalidKeyCount = errors.New("failed to populate local network config: non-zero key count is only valid for a network without keys") - errLocalNetworkDirNotSet = errors.New("local network directory not set - has Create() been called?") - errInvalidNetworkDir = errors.New("failed to write local network: invalid network directory") + errInvalidNodeCount = errors.New("failed to populate network config: non-zero node count is only valid for a network without nodes") + errInvalidKeyCount = errors.New("failed to populate network config: non-zero key count is only valid for a network without keys") + errNetworkDirNotSet = errors.New("network directory not set - has Create() been called?") + errInvalidNetworkDir = errors.New("failed to write network: invalid network directory") errMissingBootstrapNodes = errors.New("failed to add node due to missing bootstrap nodes") ) @@ -83,39 +82,25 @@ func FindNextNetworkID(rootDir string) (uint32, string, error) { } } -// Defines the configuration required for a local network (i.e. one composed of local processes). -type LocalNetwork struct { - tmpnet.NetworkConfig - LocalConfig +// Defines the configuration required for a tempoary network +type Network struct { + NetworkConfig + NodeRuntimeConfig - // Nodes with local configuration - Nodes []*LocalNode + // Nodes comprising the network + Nodes []*Node // Path where network configuration will be stored Dir string } -// Returns the configuration of the network in backend-agnostic form. -func (ln *LocalNetwork) GetConfig() tmpnet.NetworkConfig { - return ln.NetworkConfig -} - -// Returns the nodes of the network in backend-agnostic form. -func (ln *LocalNetwork) GetNodes() []tmpnet.Node { - nodes := make([]tmpnet.Node, 0, len(ln.Nodes)) - for _, node := range ln.Nodes { - nodes = append(nodes, node) - } - return nodes -} - // Adds a backend-agnostic ephemeral node to the network -func (ln *LocalNetwork) AddEphemeralNode(w io.Writer, flags tmpnet.FlagsMap) (tmpnet.Node, error) { +func (n *Network) AddEphemeralNode(w io.Writer, flags FlagsMap) (*Node, error) { if flags == nil { - flags = tmpnet.FlagsMap{} + flags = FlagsMap{} } - return ln.AddLocalNode(w, &LocalNode{ - NodeConfig: tmpnet.NodeConfig{ + return n.AddNode(w, &Node{ + NodeConfig: NodeConfig{ Flags: flags, }, }, true /* isEphemeral */) @@ -127,11 +112,11 @@ func StartNetwork( ctx context.Context, w io.Writer, rootDir string, - network *LocalNetwork, + network *Network, nodeCount int, keyCount int, -) (*LocalNetwork, error) { - if _, err := fmt.Fprintf(w, "Preparing configuration for new local network with %s\n", network.ExecPath); err != nil { +) (*Network, error) { + if _, err := fmt.Fprintf(w, "Preparing configuration for new temporary network with %s\n", network.ExecPath); err != nil { return nil, err } @@ -178,7 +163,7 @@ func StartNetwork( // nodes know where to write their configuration. network.Dir = networkDir - if err := network.PopulateLocalNetworkConfig(networkID, nodeCount, keyCount); err != nil { + if err := network.PopulateNetworkConfig(networkID, nodeCount, keyCount); err != nil { return nil, err } @@ -204,10 +189,10 @@ func StartNetwork( } // Read a network from the provided directory. -func ReadNetwork(dir string) (*LocalNetwork, error) { - network := &LocalNetwork{Dir: dir} +func ReadNetwork(dir string) (*Network, error) { + network := &Network{Dir: dir} if err := network.ReadAll(); err != nil { - return nil, fmt.Errorf("failed to read local network: %w", err) + return nil, fmt.Errorf("failed to read network: %w", err) } return network, nil } @@ -222,34 +207,34 @@ func StopNetwork(dir string) error { } // Ensure the network has the configuration it needs to start. -func (ln *LocalNetwork) PopulateLocalNetworkConfig(networkID uint32, nodeCount int, keyCount int) error { - if len(ln.Nodes) > 0 && nodeCount > 0 { +func (n *Network) PopulateNetworkConfig(networkID uint32, nodeCount int, keyCount int) error { + if len(n.Nodes) > 0 && nodeCount > 0 { return errInvalidNodeCount } - if len(ln.PreFundedKeys) > 0 && keyCount > 0 { + if len(n.PreFundedKeys) > 0 && keyCount > 0 { return errInvalidKeyCount } if nodeCount > 0 { // Add the specified number of nodes - nodes := make([]*LocalNode, 0, nodeCount) + nodes := make([]*Node, 0, nodeCount) for i := 0; i < nodeCount; i++ { - nodes = append(nodes, NewLocalNode("")) + nodes = append(nodes, NewNode("")) } - ln.Nodes = nodes + n.Nodes = nodes } // Ensure each node has keys and an associated node ID. This // ensures the availability of node IDs and proofs of possession // for genesis generation. - for _, node := range ln.Nodes { + for _, node := range n.Nodes { if err := node.EnsureKeys(); err != nil { return err } } // Assume all the initial nodes are stakers - initialStakers, err := stakersForNodes(networkID, ln.Nodes) + initialStakers, err := stakersForNodes(networkID, n.Nodes) if err != nil { return err } @@ -264,27 +249,27 @@ func (ln *LocalNetwork) PopulateLocalNetworkConfig(networkID uint32, nodeCount i } keys = append(keys, key) } - ln.PreFundedKeys = keys + n.PreFundedKeys = keys } - if err := ln.EnsureGenesis(networkID, initialStakers); err != nil { + if err := n.EnsureGenesis(networkID, initialStakers); err != nil { return err } - if ln.CChainConfig == nil { - ln.CChainConfig = LocalCChainConfig() + if n.CChainConfig == nil { + n.CChainConfig = DefaultCChainConfig() } // Default flags need to be set in advance of node config // population to ensure correct node configuration. - if ln.DefaultFlags == nil { - ln.DefaultFlags = LocalFlags() + if n.DefaultFlags == nil { + n.DefaultFlags = DefaultFlags() } - for _, node := range ln.Nodes { + for _, node := range n.Nodes { // Ensure the node is configured for use with the network and // knows where to write its configuration. - if err := ln.PopulateNodeConfig(node, ln.Dir); err != nil { + if err := n.PopulateNodeConfig(node, n.Dir); err != nil { return err } } @@ -295,18 +280,18 @@ func (ln *LocalNetwork) PopulateLocalNetworkConfig(networkID uint32, nodeCount i // Ensure the provided node has the configuration it needs to start. If the data dir is // not set, it will be defaulted to [nodeParentDir]/[node ID]. Requires that the // network has valid genesis data. -func (ln *LocalNetwork) PopulateNodeConfig(node *LocalNode, nodeParentDir string) error { +func (n *Network) PopulateNodeConfig(node *Node, nodeParentDir string) error { flags := node.Flags // Set values common to all nodes - flags.SetDefaults(ln.DefaultFlags) - flags.SetDefaults(tmpnet.FlagsMap{ - config.GenesisFileKey: ln.GetGenesisPath(), - config.ChainConfigDirKey: ln.GetChainConfigDir(), + flags.SetDefaults(n.DefaultFlags) + flags.SetDefaults(FlagsMap{ + config.GenesisFileKey: n.GetGenesisPath(), + config.ChainConfigDirKey: n.GetChainConfigDir(), }) // Convert the network id to a string to ensure consistency in JSON round-tripping. - flags[config.NetworkNameKey] = strconv.FormatUint(uint64(ln.Genesis.NetworkID), 10) + flags[config.NetworkNameKey] = strconv.FormatUint(uint64(n.Genesis.NetworkID), 10) // Ensure keys are added if necessary if err := node.EnsureKeys(); err != nil { @@ -325,13 +310,13 @@ func (ln *LocalNetwork) PopulateNodeConfig(node *LocalNode, nodeParentDir string } // Starts a network for the first time -func (ln *LocalNetwork) Start(w io.Writer) error { - if len(ln.Dir) == 0 { - return errLocalNetworkDirNotSet +func (n *Network) Start(w io.Writer) error { + if len(n.Dir) == 0 { + return errNetworkDirNotSet } // Ensure configuration on disk is current - if err := ln.WriteAll(); err != nil { + if err := n.WriteAll(); err != nil { return err } @@ -344,11 +329,11 @@ func (ln *LocalNetwork) Start(w io.Writer) error { // 3rd node: 1st and 2nd nodes // ... // - bootstrapIDs := make([]string, 0, len(ln.Nodes)) - bootstrapIPs := make([]string, 0, len(ln.Nodes)) + bootstrapIDs := make([]string, 0, len(n.Nodes)) + bootstrapIPs := make([]string, 0, len(n.Nodes)) // Configure networking and start each node - for _, node := range ln.Nodes { + for _, node := range n.Nodes { // Update network configuration node.SetNetworkingConfigDefaults(0, 0, bootstrapIDs, bootstrapIPs) @@ -362,7 +347,7 @@ func (ln *LocalNetwork) Start(w io.Writer) error { // its staking port. The network will start faster with this // synchronization due to the avoidance of exponential backoff // if a node tries to connect to a beacon that is not ready. - if err := node.Start(w, ln.ExecPath); err != nil { + if err := node.Start(w, n.ExecPath); err != nil { return err } @@ -375,19 +360,19 @@ func (ln *LocalNetwork) Start(w io.Writer) error { } // Wait until all nodes in the network are healthy. -func (ln *LocalNetwork) WaitForHealthy(ctx context.Context, w io.Writer) error { +func (n *Network) WaitForHealthy(ctx context.Context, w io.Writer) error { ticker := time.NewTicker(networkHealthCheckInterval) defer ticker.Stop() - healthyNodes := set.NewSet[ids.NodeID](len(ln.Nodes)) - for healthyNodes.Len() < len(ln.Nodes) { - for _, node := range ln.Nodes { + healthyNodes := set.NewSet[ids.NodeID](len(n.Nodes)) + for healthyNodes.Len() < len(n.Nodes) { + for _, node := range n.Nodes { if healthyNodes.Contains(node.NodeID) { continue } healthy, err := node.IsHealthy(ctx) - if err != nil && !errors.Is(err, tmpnet.ErrNotRunning) { + if err != nil && !errors.Is(err, ErrNotRunning) { return err } if !healthy { @@ -411,14 +396,14 @@ func (ln *LocalNetwork) WaitForHealthy(ctx context.Context, w io.Writer) error { // Retrieve API URIs for all running primary validator nodes. URIs for // ephemeral nodes are not returned. -func (ln *LocalNetwork) GetURIs() []tmpnet.NodeURI { - uris := make([]tmpnet.NodeURI, 0, len(ln.Nodes)) - for _, node := range ln.Nodes { +func (n *Network) GetURIs() []NodeURI { + uris := make([]NodeURI, 0, len(n.Nodes)) + for _, node := range n.Nodes { // Only append URIs that are not empty. A node may have an // empty URI if it was not running at the time // node.ReadProcessContext() was called. if len(node.URI) > 0 { - uris = append(uris, tmpnet.NodeURI{ + uris = append(uris, NodeURI{ NodeID: node.NodeID, URI: node.URI, }) @@ -428,10 +413,10 @@ func (ln *LocalNetwork) GetURIs() []tmpnet.NodeURI { } // Stop all nodes in the network. -func (ln *LocalNetwork) Stop() error { +func (n *Network) Stop() error { var errs []error // Assume the nodes are loaded and the pids are current - for _, node := range ln.Nodes { + for _, node := range n.Nodes { if err := node.Stop(); err != nil { errs = append(errs, fmt.Errorf("failed to stop node %s: %w", node.NodeID, err)) } @@ -442,12 +427,12 @@ func (ln *LocalNetwork) Stop() error { return nil } -func (ln *LocalNetwork) GetGenesisPath() string { - return filepath.Join(ln.Dir, "genesis.json") +func (n *Network) GetGenesisPath() string { + return filepath.Join(n.Dir, "genesis.json") } -func (ln *LocalNetwork) ReadGenesis() error { - bytes, err := os.ReadFile(ln.GetGenesisPath()) +func (n *Network) ReadGenesis() error { + bytes, err := os.ReadFile(n.GetGenesisPath()) if err != nil { return fmt.Errorf("failed to read genesis: %w", err) } @@ -455,107 +440,107 @@ func (ln *LocalNetwork) ReadGenesis() error { if err := json.Unmarshal(bytes, &genesis); err != nil { return fmt.Errorf("failed to unmarshal genesis: %w", err) } - ln.Genesis = &genesis + n.Genesis = &genesis return nil } -func (ln *LocalNetwork) WriteGenesis() error { - bytes, err := tmpnet.DefaultJSONMarshal(ln.Genesis) +func (n *Network) WriteGenesis() error { + bytes, err := DefaultJSONMarshal(n.Genesis) if err != nil { return fmt.Errorf("failed to marshal genesis: %w", err) } - if err := os.WriteFile(ln.GetGenesisPath(), bytes, perms.ReadWrite); err != nil { + if err := os.WriteFile(n.GetGenesisPath(), bytes, perms.ReadWrite); err != nil { return fmt.Errorf("failed to write genesis: %w", err) } return nil } -func (ln *LocalNetwork) GetChainConfigDir() string { - return filepath.Join(ln.Dir, "chains") +func (n *Network) GetChainConfigDir() string { + return filepath.Join(n.Dir, "chains") } -func (ln *LocalNetwork) GetCChainConfigPath() string { - return filepath.Join(ln.GetChainConfigDir(), "C", "config.json") +func (n *Network) GetCChainConfigPath() string { + return filepath.Join(n.GetChainConfigDir(), "C", "config.json") } -func (ln *LocalNetwork) ReadCChainConfig() error { - chainConfig, err := tmpnet.ReadFlagsMap(ln.GetCChainConfigPath(), "C-Chain config") +func (n *Network) ReadCChainConfig() error { + chainConfig, err := ReadFlagsMap(n.GetCChainConfigPath(), "C-Chain config") if err != nil { return err } - ln.CChainConfig = *chainConfig + n.CChainConfig = *chainConfig return nil } -func (ln *LocalNetwork) WriteCChainConfig() error { - path := ln.GetCChainConfigPath() +func (n *Network) WriteCChainConfig() error { + path := n.GetCChainConfigPath() dir := filepath.Dir(path) if err := os.MkdirAll(dir, perms.ReadWriteExecute); err != nil { return fmt.Errorf("failed to create C-Chain config dir: %w", err) } - return ln.CChainConfig.Write(path, "C-Chain config") + return n.CChainConfig.Write(path, "C-Chain config") } -// Used to marshal/unmarshal persistent local network defaults. -type localDefaults struct { - Flags tmpnet.FlagsMap +// Used to marshal/unmarshal persistent network defaults. +type networkDefaults struct { + Flags FlagsMap ExecPath string PreFundedKeys []*secp256k1.PrivateKey } -func (ln *LocalNetwork) GetDefaultsPath() string { - return filepath.Join(ln.Dir, "defaults.json") +func (n *Network) GetDefaultsPath() string { + return filepath.Join(n.Dir, "defaults.json") } -func (ln *LocalNetwork) ReadDefaults() error { - bytes, err := os.ReadFile(ln.GetDefaultsPath()) +func (n *Network) ReadDefaults() error { + bytes, err := os.ReadFile(n.GetDefaultsPath()) if err != nil { return fmt.Errorf("failed to read defaults: %w", err) } - defaults := localDefaults{} + defaults := networkDefaults{} if err := json.Unmarshal(bytes, &defaults); err != nil { return fmt.Errorf("failed to unmarshal defaults: %w", err) } - ln.DefaultFlags = defaults.Flags - ln.ExecPath = defaults.ExecPath - ln.PreFundedKeys = defaults.PreFundedKeys + n.DefaultFlags = defaults.Flags + n.ExecPath = defaults.ExecPath + n.PreFundedKeys = defaults.PreFundedKeys return nil } -func (ln *LocalNetwork) WriteDefaults() error { - defaults := localDefaults{ - Flags: ln.DefaultFlags, - ExecPath: ln.ExecPath, - PreFundedKeys: ln.PreFundedKeys, +func (n *Network) WriteDefaults() error { + defaults := networkDefaults{ + Flags: n.DefaultFlags, + ExecPath: n.ExecPath, + PreFundedKeys: n.PreFundedKeys, } - bytes, err := tmpnet.DefaultJSONMarshal(defaults) + bytes, err := DefaultJSONMarshal(defaults) if err != nil { return fmt.Errorf("failed to marshal defaults: %w", err) } - if err := os.WriteFile(ln.GetDefaultsPath(), bytes, perms.ReadWrite); err != nil { + if err := os.WriteFile(n.GetDefaultsPath(), bytes, perms.ReadWrite); err != nil { return fmt.Errorf("failed to write defaults: %w", err) } return nil } -func (ln *LocalNetwork) EnvFilePath() string { - return filepath.Join(ln.Dir, "network.env") +func (n *Network) EnvFilePath() string { + return filepath.Join(n.Dir, "network.env") } -func (ln *LocalNetwork) EnvFileContents() string { - return fmt.Sprintf("export %s=%s", NetworkDirEnvName, ln.Dir) +func (n *Network) EnvFileContents() string { + return fmt.Sprintf("export %s=%s", NetworkDirEnvName, n.Dir) } // Write an env file that sets the network dir env when sourced. -func (ln *LocalNetwork) WriteEnvFile() error { - if err := os.WriteFile(ln.EnvFilePath(), []byte(ln.EnvFileContents()), perms.ReadWrite); err != nil { - return fmt.Errorf("failed to write local network env file: %w", err) +func (n *Network) WriteEnvFile() error { + if err := os.WriteFile(n.EnvFilePath(), []byte(n.EnvFileContents()), perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write network env file: %w", err) } return nil } -func (ln *LocalNetwork) WriteNodes() error { - for _, node := range ln.Nodes { +func (n *Network) WriteNodes() error { + for _, node := range n.Nodes { if err := node.WriteConfig(); err != nil { return err } @@ -564,42 +549,42 @@ func (ln *LocalNetwork) WriteNodes() error { } // Write network configuration to disk. -func (ln *LocalNetwork) WriteAll() error { - if len(ln.Dir) == 0 { +func (n *Network) WriteAll() error { + if len(n.Dir) == 0 { return errInvalidNetworkDir } - if err := ln.WriteGenesis(); err != nil { + if err := n.WriteGenesis(); err != nil { return err } - if err := ln.WriteCChainConfig(); err != nil { + if err := n.WriteCChainConfig(); err != nil { return err } - if err := ln.WriteDefaults(); err != nil { + if err := n.WriteDefaults(); err != nil { return err } - if err := ln.WriteEnvFile(); err != nil { + if err := n.WriteEnvFile(); err != nil { return err } - return ln.WriteNodes() + return n.WriteNodes() } // Read network configuration from disk. -func (ln *LocalNetwork) ReadConfig() error { - if err := ln.ReadGenesis(); err != nil { +func (n *Network) ReadConfig() error { + if err := n.ReadGenesis(); err != nil { return err } - if err := ln.ReadCChainConfig(); err != nil { + if err := n.ReadCChainConfig(); err != nil { return err } - return ln.ReadDefaults() + return n.ReadDefaults() } // Read node configuration and process context from disk. -func (ln *LocalNetwork) ReadNodes() error { - nodes := []*LocalNode{} +func (n *Network) ReadNodes() error { + nodes := []*Node{} // Node configuration / process context is stored in child directories - entries, err := os.ReadDir(ln.Dir) + entries, err := os.ReadDir(n.Dir) if err != nil { return fmt.Errorf("failed to read network path: %w", err) } @@ -608,10 +593,10 @@ func (ln *LocalNetwork) ReadNodes() error { continue } - nodeDir := filepath.Join(ln.Dir, entry.Name()) + nodeDir := filepath.Join(n.Dir, entry.Name()) node, err := ReadNode(nodeDir) if errors.Is(err, os.ErrNotExist) { - // If no config file exists, assume this is not the path of a local node + // If no config file exists, assume this is not the path of a node continue } else if err != nil { return err @@ -620,30 +605,30 @@ func (ln *LocalNetwork) ReadNodes() error { nodes = append(nodes, node) } - ln.Nodes = nodes + n.Nodes = nodes return nil } // Read network and node configuration from disk. -func (ln *LocalNetwork) ReadAll() error { - if err := ln.ReadConfig(); err != nil { +func (n *Network) ReadAll() error { + if err := n.ReadConfig(); err != nil { return err } - return ln.ReadNodes() + return n.ReadNodes() } -func (ln *LocalNetwork) AddLocalNode(w io.Writer, node *LocalNode, isEphemeral bool) (*LocalNode, error) { +func (n *Network) AddNode(w io.Writer, node *Node, isEphemeral bool) (*Node, error) { // Assume network configuration has been written to disk and is current in memory if node == nil { // Set an empty data dir so that PopulateNodeConfig will know // to set the default of `[network dir]/[node id]`. - node = NewLocalNode("") + node = NewNode("") } // Default to a data dir of [network-dir]/[node-ID] - nodeParentDir := ln.Dir + nodeParentDir := n.Dir if isEphemeral { // For an ephemeral node, default to a data dir of [network-dir]/[ephemeral-dir]/[node-ID] // to provide a clear separation between nodes that are expected to expose stable API @@ -653,14 +638,14 @@ func (ln *LocalNetwork) AddLocalNode(w io.Writer, node *LocalNode, isEphemeral b // The data for an ephemeral node is still stored in the file tree rooted at the network // dir to ensure that recursively archiving the network dir in CI will collect all node // data used for a test run. - nodeParentDir = filepath.Join(ln.Dir, defaultEphemeralDirName) + nodeParentDir = filepath.Join(n.Dir, defaultEphemeralDirName) } - if err := ln.PopulateNodeConfig(node, nodeParentDir); err != nil { + if err := n.PopulateNodeConfig(node, nodeParentDir); err != nil { return nil, err } - bootstrapIPs, bootstrapIDs, err := ln.GetBootstrapIPsAndIDs() + bootstrapIPs, bootstrapIDs, err := n.GetBootstrapIPsAndIDs() if err != nil { return nil, err } @@ -676,7 +661,7 @@ func (ln *LocalNetwork) AddLocalNode(w io.Writer, node *LocalNode, isEphemeral b return nil, err } - err = node.Start(w, ln.ExecPath) + err = node.Start(w, n.ExecPath) if err != nil { // Attempt to stop an unhealthy node to provide some assurance to the caller // that an error condition will not result in a lingering process. @@ -690,16 +675,16 @@ func (ln *LocalNetwork) AddLocalNode(w io.Writer, node *LocalNode, isEphemeral b return node, nil } -func (ln *LocalNetwork) GetBootstrapIPsAndIDs() ([]string, []string, error) { +func (n *Network) GetBootstrapIPsAndIDs() ([]string, []string, error) { // Collect staking addresses of running nodes for use in bootstrapping a node - if err := ln.ReadNodes(); err != nil { - return nil, nil, fmt.Errorf("failed to read local network nodes: %w", err) + if err := n.ReadNodes(); err != nil { + return nil, nil, fmt.Errorf("failed to read network nodes: %w", err) } var ( - bootstrapIPs = make([]string, 0, len(ln.Nodes)) - bootstrapIDs = make([]string, 0, len(ln.Nodes)) + bootstrapIPs = make([]string, 0, len(n.Nodes)) + bootstrapIDs = make([]string, 0, len(n.Nodes)) ) - for _, node := range ln.Nodes { + for _, node := range n.Nodes { if len(node.StakingAddress) == 0 { // Node is not running continue @@ -717,7 +702,7 @@ func (ln *LocalNetwork) GetBootstrapIPsAndIDs() ([]string, []string, error) { } // Returns staker configuration for the given set of nodes. -func stakersForNodes(networkID uint32, nodes []*LocalNode) ([]genesis.UnparsedStaker, error) { +func stakersForNodes(networkID uint32, nodes []*Node) ([]genesis.UnparsedStaker, error) { // Give staking rewards for initial validators to a random address. Any testing of staking rewards // will be easier to perform with nodes other than the initial validators since the timing of // staking can be more easily controlled. diff --git a/tests/fixture/tmpnet/local/network_test.go b/tests/fixture/tmpnet/network_test.go similarity index 84% rename from tests/fixture/tmpnet/local/network_test.go rename to tests/fixture/tmpnet/network_test.go index 3893c9e51db4..7955fa4fd622 100644 --- a/tests/fixture/tmpnet/local/network_test.go +++ b/tests/fixture/tmpnet/network_test.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package local +package tmpnet import ( "testing" @@ -14,8 +14,8 @@ func TestNetworkSerialization(t *testing.T) { tmpDir := t.TempDir() - network := &LocalNetwork{Dir: tmpDir} - require.NoError(network.PopulateLocalNetworkConfig(1337, 1, 1)) + network := &Network{Dir: tmpDir} + require.NoError(network.PopulateNetworkConfig(1337, 1, 1)) require.NoError(network.WriteAll()) loadedNetwork, err := ReadNetwork(tmpDir) diff --git a/tests/fixture/tmpnet/local/node.go b/tests/fixture/tmpnet/node.go similarity index 72% rename from tests/fixture/tmpnet/local/node.go rename to tests/fixture/tmpnet/node.go index 908d3fd5f474..64ca8f11802f 100644 --- a/tests/fixture/tmpnet/local/node.go +++ b/tests/fixture/tmpnet/node.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package local +package tmpnet import ( "context" @@ -21,88 +21,69 @@ import ( "github.com/ava-labs/avalanchego/api/health" "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/node" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" "github.com/ava-labs/avalanchego/utils/perms" ) -var errNodeAlreadyRunning = errors.New("failed to start local node: node is already running") +var errNodeAlreadyRunning = errors.New("failed to start node: node is already running") -// Defines local-specific node configuration. Supports setting default -// and node-specific values. +// Defines configuration to execute a node. // // TODO(marun) Support persisting this configuration per-node when // node restart is implemented. Currently it can be supplied for node // start but won't survive restart. -type LocalConfig struct { +type NodeRuntimeConfig struct { // Path to avalanchego binary ExecPath string } -// Stores the configuration and process details of a node in a local network. -type LocalNode struct { - tmpnet.NodeConfig - LocalConfig +// Stores the configuration and process details of a node in a temporary network. +type Node struct { + NodeConfig + NodeRuntimeConfig node.NodeProcessContext // Configuration is intended to be stored at the path identified in NodeConfig.Flags[config.DataDirKey] } -func NewLocalNode(dataDir string) *LocalNode { - return &LocalNode{ - NodeConfig: tmpnet.NodeConfig{ - Flags: tmpnet.FlagsMap{ +func NewNode(dataDir string) *Node { + return &Node{ + NodeConfig: NodeConfig{ + Flags: FlagsMap{ config.DataDirKey: dataDir, }, }, } } -// Attempt to read configuration and process details for a local node +// Attempt to read configuration and process details for a node // from the specified directory. -func ReadNode(dataDir string) (*LocalNode, error) { - node := NewLocalNode(dataDir) +func ReadNode(dataDir string) (*Node, error) { + node := NewNode(dataDir) if _, err := os.Stat(node.GetConfigPath()); err != nil { - return nil, fmt.Errorf("failed to read local node config file: %w", err) + return nil, fmt.Errorf("failed to read node config file: %w", err) } return node, node.ReadAll() } -// Retrieve the ID of the node. The returned value may be nil if the -// node configuration has not yet been populated or read. -func (n *LocalNode) GetID() ids.NodeID { - return n.NodeConfig.NodeID -} - -// Retrieve backend-agnostic node configuration. -func (n *LocalNode) GetConfig() tmpnet.NodeConfig { - return n.NodeConfig -} - -// Retrieve backend-agnostic process details. -func (n *LocalNode) GetProcessContext() node.NodeProcessContext { - return n.NodeProcessContext -} - -func (n *LocalNode) GetDataDir() string { +func (n *Node) GetDataDir() string { return cast.ToString(n.Flags[config.DataDirKey]) } -func (n *LocalNode) GetConfigPath() string { +func (n *Node) GetConfigPath() string { return filepath.Join(n.GetDataDir(), "config.json") } -func (n *LocalNode) ReadConfig() error { +func (n *Node) ReadConfig() error { bytes, err := os.ReadFile(n.GetConfigPath()) if err != nil { - return fmt.Errorf("failed to read local node config: %w", err) + return fmt.Errorf("failed to read node config: %w", err) } - flags := tmpnet.FlagsMap{} + flags := FlagsMap{} if err := json.Unmarshal(bytes, &flags); err != nil { - return fmt.Errorf("failed to unmarshal local node config: %w", err) + return fmt.Errorf("failed to unmarshal node config: %w", err) } - config := tmpnet.NodeConfig{Flags: flags} + config := NodeConfig{Flags: flags} if err := config.EnsureNodeID(); err != nil { return err } @@ -110,27 +91,27 @@ func (n *LocalNode) ReadConfig() error { return nil } -func (n *LocalNode) WriteConfig() error { +func (n *Node) WriteConfig() error { if err := os.MkdirAll(n.GetDataDir(), perms.ReadWriteExecute); err != nil { return fmt.Errorf("failed to create node dir: %w", err) } - bytes, err := tmpnet.DefaultJSONMarshal(n.Flags) + bytes, err := DefaultJSONMarshal(n.Flags) if err != nil { - return fmt.Errorf("failed to marshal local node config: %w", err) + return fmt.Errorf("failed to marshal node config: %w", err) } if err := os.WriteFile(n.GetConfigPath(), bytes, perms.ReadWrite); err != nil { - return fmt.Errorf("failed to write local node config: %w", err) + return fmt.Errorf("failed to write node config: %w", err) } return nil } -func (n *LocalNode) GetProcessContextPath() string { +func (n *Node) GetProcessContextPath() string { return filepath.Join(n.GetDataDir(), config.DefaultProcessContextFilename) } -func (n *LocalNode) ReadProcessContext() error { +func (n *Node) ReadProcessContext() error { path := n.GetProcessContextPath() if _, err := os.Stat(path); errors.Is(err, fs.ErrNotExist) { // The absence of the process context file indicates the node is not running @@ -140,28 +121,28 @@ func (n *LocalNode) ReadProcessContext() error { bytes, err := os.ReadFile(path) if err != nil { - return fmt.Errorf("failed to read local node process context: %w", err) + return fmt.Errorf("failed to read node process context: %w", err) } processContext := node.NodeProcessContext{} if err := json.Unmarshal(bytes, &processContext); err != nil { - return fmt.Errorf("failed to unmarshal local node process context: %w", err) + return fmt.Errorf("failed to unmarshal node process context: %w", err) } n.NodeProcessContext = processContext return nil } -func (n *LocalNode) ReadAll() error { +func (n *Node) ReadAll() error { if err := n.ReadConfig(); err != nil { return err } return n.ReadProcessContext() } -func (n *LocalNode) Start(w io.Writer, defaultExecPath string) error { +func (n *Node) Start(w io.Writer, defaultExecPath string) error { // Avoid attempting to start an already running node. proc, err := n.GetProcess() if err != nil { - return fmt.Errorf("failed to start local node: %w", err) + return fmt.Errorf("failed to start node: %w", err) } if proc != nil { return errNodeAlreadyRunning @@ -208,7 +189,7 @@ func (n *LocalNode) Start(w io.Writer, defaultExecPath string) error { // found in a reasonable amount of time, the node is unlikely to have // started successfully. if err := n.WaitForProcessContext(context.Background()); err != nil { - return fmt.Errorf("failed to start local node: %w", err) + return fmt.Errorf("failed to start node: %w", err) } _, err = fmt.Fprintf(w, "Started %s\n", nodeDescription) @@ -218,7 +199,7 @@ func (n *LocalNode) Start(w io.Writer, defaultExecPath string) error { // Retrieve the node process if it is running. As part of determining // process liveness, the node's process context will be refreshed if // live or cleared if not running. -func (n *LocalNode) GetProcess() (*os.Process, error) { +func (n *Node) GetProcess() (*os.Process, error) { // Read the process context to ensure freshness. The node may have // stopped or been restarted since last read. if err := n.ReadProcessContext(); err != nil { @@ -251,7 +232,7 @@ func (n *LocalNode) GetProcess() (*os.Process, error) { // Signals the node process to stop and waits for the node process to // stop running. -func (n *LocalNode) Stop() error { +func (n *Node) Stop() error { proc, err := n.GetProcess() if err != nil { return fmt.Errorf("failed to retrieve process to stop: %w", err) @@ -265,7 +246,7 @@ func (n *LocalNode) Stop() error { } // Wait for the node process to stop - ticker := time.NewTicker(tmpnet.DefaultNodeTickerInterval) + ticker := time.NewTicker(DefaultNodeTickerInterval) defer ticker.Stop() ctx, cancel := context.WithTimeout(context.Background(), DefaultNodeStopTimeout) defer cancel() @@ -286,7 +267,7 @@ func (n *LocalNode) Stop() error { } } -func (n *LocalNode) IsHealthy(ctx context.Context) (bool, error) { +func (n *Node) IsHealthy(ctx context.Context) (bool, error) { // Check that the node process is running as a precondition for // checking health. GetProcess will also ensure that the node's // API URI is current. @@ -295,7 +276,7 @@ func (n *LocalNode) IsHealthy(ctx context.Context) (bool, error) { return false, fmt.Errorf("failed to determine process status: %w", err) } if proc == nil { - return false, tmpnet.ErrNotRunning + return false, ErrNotRunning } // Check that the node is reporting healthy @@ -320,8 +301,8 @@ func (n *LocalNode) IsHealthy(ctx context.Context) (bool, error) { return false, fmt.Errorf("failed to query node health: %w", err) } -func (n *LocalNode) WaitForProcessContext(ctx context.Context) error { - ticker := time.NewTicker(tmpnet.DefaultNodeTickerInterval) +func (n *Node) WaitForProcessContext(ctx context.Context) error { + ticker := time.NewTicker(DefaultNodeTickerInterval) defer ticker.Stop() ctx, cancel := context.WithTimeout(ctx, DefaultNodeInitTimeout) diff --git a/tests/fixture/tmpnet/local/node_test.go b/tests/fixture/tmpnet/node_test.go similarity index 90% rename from tests/fixture/tmpnet/local/node_test.go rename to tests/fixture/tmpnet/node_test.go index 64cd77928a4d..ab060105804a 100644 --- a/tests/fixture/tmpnet/local/node_test.go +++ b/tests/fixture/tmpnet/node_test.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package local +package tmpnet import ( "testing" @@ -14,7 +14,7 @@ func TestNodeSerialization(t *testing.T) { tmpDir := t.TempDir() - node := NewLocalNode(tmpDir) + node := NewNode(tmpDir) require.NoError(node.EnsureKeys()) require.NoError(node.WriteConfig()) diff --git a/tests/fixture/tmpnet/common.go b/tests/fixture/tmpnet/utils.go similarity index 72% rename from tests/fixture/tmpnet/common.go rename to tests/fixture/tmpnet/utils.go index 4b0281f45242..b8508c3880e2 100644 --- a/tests/fixture/tmpnet/common.go +++ b/tests/fixture/tmpnet/utils.go @@ -5,6 +5,7 @@ package tmpnet import ( "context" + "encoding/json" "errors" "fmt" "time" @@ -17,9 +18,9 @@ const ( var ErrNotRunning = errors.New("not running") // WaitForHealthy blocks until Node.IsHealthy returns true or an error (including context timeout) is observed. -func WaitForHealthy(ctx context.Context, node Node) error { +func WaitForHealthy(ctx context.Context, node *Node) error { if _, ok := ctx.Deadline(); !ok { - return fmt.Errorf("unable to wait for health for node %q with a context without a deadline", node.GetID()) + return fmt.Errorf("unable to wait for health for node %q with a context without a deadline", node.NodeID) } ticker := time.NewTicker(DefaultNodeTickerInterval) defer ticker.Stop() @@ -27,7 +28,7 @@ func WaitForHealthy(ctx context.Context, node Node) error { for { healthy, err := node.IsHealthy(ctx) if err != nil && !errors.Is(err, ErrNotRunning) { - return fmt.Errorf("failed to wait for health of node %q: %w", node.GetID(), err) + return fmt.Errorf("failed to wait for health of node %q: %w", node.NodeID, err) } if healthy { return nil @@ -35,8 +36,13 @@ func WaitForHealthy(ctx context.Context, node Node) error { select { case <-ctx.Done(): - return fmt.Errorf("failed to wait for health of node %q before timeout: %w", node.GetID(), ctx.Err()) + return fmt.Errorf("failed to wait for health of node %q before timeout: %w", node.NodeID, ctx.Err()) case <-ticker.C: } } } + +// Marshal to json with default prefix and indent. +func DefaultJSONMarshal(v interface{}) ([]byte, error) { + return json.MarshalIndent(v, "", " ") +} diff --git a/tests/upgrade/upgrade_test.go b/tests/upgrade/upgrade_test.go index 97a57a34b6a0..0f65c0202385 100644 --- a/tests/upgrade/upgrade_test.go +++ b/tests/upgrade/upgrade_test.go @@ -48,12 +48,11 @@ var _ = ginkgo.Describe("[Upgrade]", func() { require := require.New(ginkgo.GinkgoT()) ginkgo.It("can upgrade versions", func() { - // TODO(marun) How many nodes should the target network have to best validate upgrade? - network := e2e.StartLocalNetwork(avalancheGoExecPath, e2e.DefaultNetworkDir) + network := e2e.StartNetwork(avalancheGoExecPath, e2e.DefaultNetworkDir) ginkgo.By(fmt.Sprintf("restarting all nodes with %q binary", avalancheGoExecPathToUpgradeTo)) for _, node := range network.Nodes { - ginkgo.By(fmt.Sprintf("restarting node %q with %q binary", node.GetID(), avalancheGoExecPathToUpgradeTo)) + ginkgo.By(fmt.Sprintf("restarting node %q with %q binary", node.NodeID, avalancheGoExecPathToUpgradeTo)) require.NoError(node.Stop()) // A node must start with sufficient bootstrap nodes to represent a quorum. Since the node's current @@ -73,7 +72,7 @@ var _ = ginkgo.Describe("[Upgrade]", func() { node.ExecPath = avalancheGoExecPathToUpgradeTo require.NoError(node.Start(ginkgo.GinkgoWriter, "" /* defaultExecPath */)) - ginkgo.By(fmt.Sprintf("waiting for node %q to report healthy after restart", node.GetID())) + ginkgo.By(fmt.Sprintf("waiting for node %q to report healthy after restart", node.NodeID)) e2e.WaitForHealthy(node) } From 8c47e3faad1e35749367215f7847a62afd2defea Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 15 Dec 2023 12:07:00 -0500 Subject: [PATCH 155/267] `merkledb` -- make tests use time as randomness seed (#2470) --- x/sync/client.go | 3 ++- x/sync/client_test.go | 52 +++++++++---------------------------------- 2 files changed, 12 insertions(+), 43 deletions(-) diff --git a/x/sync/client.go b/x/sync/client.go index 6605a5089935..ad79e35f7e71 100644 --- a/x/sync/client.go +++ b/x/sync/client.go @@ -36,6 +36,7 @@ var ( _ Client = (*client)(nil) errInvalidRangeProof = errors.New("failed to verify range proof") + errInvalidChangeProof = errors.New("failed to verify change proof") errTooManyKeys = errors.New("response contains more than requested keys") errTooManyBytes = errors.New("response contains more than requested bytes") errUnexpectedChangeProofResponse = errors.New("unexpected response type") @@ -149,7 +150,7 @@ func (c *client) GetChangeProof( endKey, endRoot, ); err != nil { - return nil, fmt.Errorf("%w due to %w", errInvalidRangeProof, err) + return nil, fmt.Errorf("%w due to %w", errInvalidChangeProof, err) } return &merkledb.ChangeOrRangeProof{ diff --git a/x/sync/client_test.go b/x/sync/client_test.go index 0c71ccb52e75..8f4f9173b5d9 100644 --- a/x/sync/client_test.go +++ b/x/sync/client_test.go @@ -159,13 +159,9 @@ func sendRangeProofRequest( } func TestGetRangeProof(t *testing.T) { - // TODO use time as random seed instead of 1 - // once we move to go 1.20 which allows for - // joining multiple errors with %w. Right now, - // for some of these tests, we may get different - // errors based on randomness but we can only - // assert one error. - r := rand.New(rand.NewSource(1)) // #nosec G404 + now := time.Now().UnixNano() + t.Logf("seed: %d", now) + r := rand.New(rand.NewSource(now)) // #nosec G404 smallTrieKeyCount := defaultRequestKeyLimit smallTrieDB, _, err := generateTrieWithMinKeyLen(t, r, smallTrieKeyCount, 1) @@ -280,19 +276,7 @@ func TestGetRangeProof(t *testing.T) { response.StartProof = proof.StartProof response.EndProof = proof.EndProof }, - expectedErr: merkledb.ErrInvalidProof, - }, - "removed last key in response": { - db: largeTrieDB, - request: &pb.SyncGetRangeProofRequest{ - RootHash: largeTrieRoot[:], - KeyLimit: defaultRequestKeyLimit, - BytesLimit: defaultRequestByteSizeLimit, - }, - modifyResponse: func(response *merkledb.RangeProof) { - response.KeyValues = response.KeyValues[:len(response.KeyValues)-2] - }, - expectedErr: merkledb.ErrProofNodeNotForKey, + expectedErr: errInvalidRangeProof, }, "removed key from middle of response": { db: largeTrieDB, @@ -319,7 +303,7 @@ func TestGetRangeProof(t *testing.T) { }, expectedErr: merkledb.ErrNoEndProof, }, - "end proof nodes removed": { + "end proof removed": { db: largeTrieDB, request: &pb.SyncGetRangeProofRequest{ RootHash: largeTrieRoot[:], @@ -503,13 +487,9 @@ func sendChangeProofRequest( } func TestGetChangeProof(t *testing.T) { - // TODO use time as random seed instead of 1 - // once we move to go 1.20 which allows for - // joining multiple errors with %w. Right now, - // for some of these tests, we may get different - // errors based on randomness but we can only - // assert one error. - r := rand.New(rand.NewSource(1)) // #nosec G404 + now := time.Now().UnixNano() + t.Logf("seed: %d", now) + r := rand.New(rand.NewSource(now)) // #nosec G404 serverDB, err := merkledb.New( context.Background(), @@ -625,19 +605,7 @@ func TestGetChangeProof(t *testing.T) { modifyChangeProofResponse: func(response *merkledb.ChangeProof) { response.KeyChanges = response.KeyChanges[1:] }, - expectedErr: merkledb.ErrInvalidProof, - }, - "removed last key in response": { - request: &pb.SyncGetChangeProofRequest{ - StartRootHash: startRoot[:], - EndRootHash: endRoot[:], - KeyLimit: defaultRequestKeyLimit, - BytesLimit: defaultRequestByteSizeLimit, - }, - modifyChangeProofResponse: func(response *merkledb.ChangeProof) { - response.KeyChanges = response.KeyChanges[:len(response.KeyChanges)-2] - }, - expectedErr: merkledb.ErrProofNodeNotForKey, + expectedErr: errInvalidChangeProof, }, "removed key from middle of response": { request: &pb.SyncGetChangeProofRequest{ @@ -677,7 +645,7 @@ func TestGetChangeProof(t *testing.T) { modifyRangeProofResponse: func(response *merkledb.RangeProof) { response.KeyValues = response.KeyValues[1:] }, - expectedErr: merkledb.ErrInvalidProof, + expectedErr: errInvalidRangeProof, expectRangeProof: true, }, } From 2dcce4c78ab36cc964109022ffd19d9a5624a645 Mon Sep 17 00:00:00 2001 From: marun Date: Fri, 15 Dec 2023 09:38:55 -0800 Subject: [PATCH 156/267] `tmpnet`: Break config.go up into coherent parts (#2462) --- tests/fixture/e2e/env.go | 2 +- tests/fixture/tmpnet/README.md | 14 +- tests/fixture/tmpnet/config.go | 423 ------------------------------ tests/fixture/tmpnet/defaults.go | 9 + tests/fixture/tmpnet/flags.go | 69 +++++ tests/fixture/tmpnet/genesis.go | 193 ++++++++++++++ tests/fixture/tmpnet/network.go | 75 ++---- tests/fixture/tmpnet/node.go | 168 +++++++++++- tests/fixture/tmpnet/node_test.go | 24 -- tests/fixture/tmpnet/utils.go | 37 +++ 10 files changed, 493 insertions(+), 521 deletions(-) delete mode 100644 tests/fixture/tmpnet/config.go create mode 100644 tests/fixture/tmpnet/flags.go create mode 100644 tests/fixture/tmpnet/genesis.go delete mode 100644 tests/fixture/tmpnet/node_test.go diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index c50a2a7aace2..8c7733fa41a7 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -69,7 +69,7 @@ func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { network = StartNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir) } - uris := network.GetURIs() + uris := tmpnet.GetNodeURIs(network.Nodes) require.NotEmpty(uris, "network contains no nodes") tests.Outf("{{green}}network URIs: {{/}} %+v\n", uris) diff --git a/tests/fixture/tmpnet/README.md b/tests/fixture/tmpnet/README.md index 15688417990d..dfe430ea10a0 100644 --- a/tests/fixture/tmpnet/README.md +++ b/tests/fixture/tmpnet/README.md @@ -24,12 +24,14 @@ repositories. The functionality in this package is grouped by logical purpose into the following non-test files: -| Filename | Types | Purpose | -|:------------|:--------|:----------------------------------------------| -| defaults.go | | Default configuration | -| network.go | Network | Network-level orchestration and configuration | -| node.go | Node | Node-level orchestration and configuration | -| util.go | | Shared utility functions | +| Filename | Types | Purpose | +|:------------------|:------------|:-----------------------------------------------| +| defaults.go | | Defines common default configuration | +| flags.go | FlagsMap | Simplifies configuration of avalanchego flags | +| genesis.go | | Creates test genesis | +| network.go | Network | Orchestrates and configures temporary networks | +| node.go | Node | Orchestrates and configures nodes | +| utils.go | | Defines shared utility functions | ## Usage diff --git a/tests/fixture/tmpnet/config.go b/tests/fixture/tmpnet/config.go deleted file mode 100644 index 90a6c7bda04a..000000000000 --- a/tests/fixture/tmpnet/config.go +++ /dev/null @@ -1,423 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package tmpnet - -import ( - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "math/big" - "os" - "strings" - "time" - - "github.com/spf13/cast" - - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/staking" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/formatting/address" - "github.com/ava-labs/avalanchego/utils/perms" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/platformvm/signer" -) - -const ( - DefaultNodeCount = 2 // Minimum required to ensure connectivity-based health checks will pass - DefaultPreFundedKeyCount = 50 - - DefaultGasLimit = uint64(100_000_000) // Gas limit is arbitrary - - // Arbitrarily large amount of AVAX to fund keys on the X-Chain for testing - DefaultPreFundedKeyXChainAmount = 30 * units.MegaAvax - - // A short min stake duration enables testing of staking logic. - DefaultMinStakeDuration = time.Second -) - -var ( - // Arbitrarily large amount of AVAX (10^12) to fund keys on the C-Chain for testing - DefaultPreFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) - - errNoKeysForGenesis = errors.New("failed to generate genesis: no keys to fund") - errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID") - errMissingStakersForGenesis = errors.New("no genesis stakers provided") - errMissingBalancesForGenesis = errors.New("no genesis balances given") - errMissingTLSKeyForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingTLSKeyContentKey) - errMissingCertForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingCertContentKey) - errInvalidKeypair = fmt.Errorf("%q and %q must be provided together or not at all", config.StakingTLSKeyContentKey, config.StakingCertContentKey) -) - -// Defines a mapping of flag keys to values intended to be supplied to -// an invocation of an AvalancheGo node. -type FlagsMap map[string]interface{} - -// SetDefaults ensures the effectiveness of flag overrides by only -// setting values supplied in the defaults map that are not already -// explicitly set. -func (f FlagsMap) SetDefaults(defaults FlagsMap) { - for key, value := range defaults { - if _, ok := f[key]; !ok { - f[key] = value - } - } -} - -// GetStringVal simplifies retrieving a map value as a string. -func (f FlagsMap) GetStringVal(key string) (string, error) { - rawVal, ok := f[key] - if !ok { - return "", nil - } - - val, err := cast.ToStringE(rawVal) - if err != nil { - return "", fmt.Errorf("failed to cast value for %q: %w", key, err) - } - return val, nil -} - -// Write simplifies writing a FlagsMap to the provided path. The -// description is used in error messages. -func (f FlagsMap) Write(path string, description string) error { - bytes, err := DefaultJSONMarshal(f) - if err != nil { - return fmt.Errorf("failed to marshal %s: %w", description, err) - } - if err := os.WriteFile(path, bytes, perms.ReadWrite); err != nil { - return fmt.Errorf("failed to write %s: %w", description, err) - } - return nil -} - -// Utility function simplifying construction of a FlagsMap from a file. -func ReadFlagsMap(path string, description string) (*FlagsMap, error) { - bytes, err := os.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("failed to read %s: %w", description, err) - } - flagsMap := &FlagsMap{} - if err := json.Unmarshal(bytes, flagsMap); err != nil { - return nil, fmt.Errorf("failed to unmarshal %s: %w", description, err) - } - return flagsMap, nil -} - -// NetworkConfig defines configuration shared or -// common to all nodes in a given network. -type NetworkConfig struct { - Genesis *genesis.UnparsedConfig - CChainConfig FlagsMap - DefaultFlags FlagsMap - PreFundedKeys []*secp256k1.PrivateKey -} - -// Ensure genesis is generated if not already present. -func (c *NetworkConfig) EnsureGenesis(networkID uint32, initialStakers []genesis.UnparsedStaker) error { - if c.Genesis != nil { - return nil - } - - if len(c.PreFundedKeys) == 0 { - return errNoKeysForGenesis - } - - // Ensure pre-funded keys have arbitrary large balances on both chains to support testing - xChainBalances := make(XChainBalanceMap, len(c.PreFundedKeys)) - cChainBalances := make(core.GenesisAlloc, len(c.PreFundedKeys)) - for _, key := range c.PreFundedKeys { - xChainBalances[key.Address()] = DefaultPreFundedKeyXChainAmount - cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - Balance: DefaultPreFundedKeyCChainAmount, - } - } - - genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, initialStakers) - if err != nil { - return err - } - - c.Genesis = genesis - return nil -} - -// NodeURI associates a node ID with its API URI. -type NodeURI struct { - NodeID ids.NodeID - URI string -} - -// NodeConfig defines configuration for an AvalancheGo node. -type NodeConfig struct { - NodeID ids.NodeID - Flags FlagsMap -} - -func NewNodeConfig() *NodeConfig { - return &NodeConfig{ - Flags: FlagsMap{}, - } -} - -// Convenience method for setting networking flags. -func (nc *NodeConfig) SetNetworkingConfigDefaults( - httpPort uint16, - stakingPort uint16, - bootstrapIDs []string, - bootstrapIPs []string, -) { - nc.Flags.SetDefaults(FlagsMap{ - config.HTTPPortKey: httpPort, - config.StakingPortKey: stakingPort, - config.BootstrapIDsKey: strings.Join(bootstrapIDs, ","), - config.BootstrapIPsKey: strings.Join(bootstrapIPs, ","), - }) -} - -// Ensures staking and signing keys are generated if not already present and -// that the node ID (derived from the staking keypair) is set. -func (nc *NodeConfig) EnsureKeys() error { - if err := nc.EnsureBLSSigningKey(); err != nil { - return err - } - if err := nc.EnsureStakingKeypair(); err != nil { - return err - } - // Once a staking keypair is guaranteed it is safe to derive the node ID - return nc.EnsureNodeID() -} - -// Derives the nodes proof-of-possession. Requires the node to have a -// BLS signing key. -func (nc *NodeConfig) GetProofOfPossession() (*signer.ProofOfPossession, error) { - signingKey, err := nc.Flags.GetStringVal(config.StakingSignerKeyContentKey) - if err != nil { - return nil, err - } - signingKeyBytes, err := base64.StdEncoding.DecodeString(signingKey) - if err != nil { - return nil, err - } - secretKey, err := bls.SecretKeyFromBytes(signingKeyBytes) - if err != nil { - return nil, err - } - return signer.NewProofOfPossession(secretKey), nil -} - -// Ensures a BLS signing key is generated if not already present. -func (nc *NodeConfig) EnsureBLSSigningKey() error { - // Attempt to retrieve an existing key - existingKey, err := nc.Flags.GetStringVal(config.StakingSignerKeyContentKey) - if err != nil { - return err - } - if len(existingKey) > 0 { - // Nothing to do - return nil - } - - // Generate a new signing key - newKey, err := bls.NewSecretKey() - if err != nil { - return fmt.Errorf("failed to generate staking signer key: %w", err) - } - nc.Flags[config.StakingSignerKeyContentKey] = base64.StdEncoding.EncodeToString(bls.SerializeSecretKey(newKey)) - return nil -} - -// Ensures a staking keypair is generated if not already present. -func (nc *NodeConfig) EnsureStakingKeypair() error { - keyKey := config.StakingTLSKeyContentKey - certKey := config.StakingCertContentKey - - key, err := nc.Flags.GetStringVal(keyKey) - if err != nil { - return err - } - - cert, err := nc.Flags.GetStringVal(certKey) - if err != nil { - return err - } - - if len(key) == 0 && len(cert) == 0 { - // Generate new keypair - tlsCertBytes, tlsKeyBytes, err := staking.NewCertAndKeyBytes() - if err != nil { - return fmt.Errorf("failed to generate staking keypair: %w", err) - } - nc.Flags[keyKey] = base64.StdEncoding.EncodeToString(tlsKeyBytes) - nc.Flags[certKey] = base64.StdEncoding.EncodeToString(tlsCertBytes) - } else if len(key) == 0 || len(cert) == 0 { - // Only one of key and cert was provided - return errInvalidKeypair - } - - err = nc.EnsureNodeID() - if err != nil { - return fmt.Errorf("failed to derive a node ID: %w", err) - } - - return nil -} - -// Attempt to derive the node ID from the node configuration. -func (nc *NodeConfig) EnsureNodeID() error { - keyKey := config.StakingTLSKeyContentKey - certKey := config.StakingCertContentKey - - key, err := nc.Flags.GetStringVal(keyKey) - if err != nil { - return err - } - if len(key) == 0 { - return errMissingTLSKeyForNodeID - } - keyBytes, err := base64.StdEncoding.DecodeString(key) - if err != nil { - return fmt.Errorf("failed to ensure node ID: failed to base64 decode value for %q: %w", keyKey, err) - } - - cert, err := nc.Flags.GetStringVal(certKey) - if err != nil { - return err - } - if len(cert) == 0 { - return errMissingCertForNodeID - } - certBytes, err := base64.StdEncoding.DecodeString(cert) - if err != nil { - return fmt.Errorf("failed to ensure node ID: failed to base64 decode value for %q: %w", certKey, err) - } - - tlsCert, err := staking.LoadTLSCertFromBytes(keyBytes, certBytes) - if err != nil { - return fmt.Errorf("failed to ensure node ID: failed to load tls cert: %w", err) - } - stakingCert := staking.CertificateFromX509(tlsCert.Leaf) - nc.NodeID = ids.NodeIDFromCert(stakingCert) - - return nil -} - -// Helper type to simplify configuring X-Chain genesis balances -type XChainBalanceMap map[ids.ShortID]uint64 - -// Create a genesis struct valid for bootstrapping a test -// network. Note that many of the genesis fields (e.g. reward -// addresses) are randomly generated or hard-coded. -func NewTestGenesis( - networkID uint32, - xChainBalances XChainBalanceMap, - cChainBalances core.GenesisAlloc, - initialStakers []genesis.UnparsedStaker, -) (*genesis.UnparsedConfig, error) { - // Validate inputs - switch networkID { - case constants.TestnetID, constants.MainnetID, constants.LocalID: - return nil, errInvalidNetworkIDForGenesis - } - if len(initialStakers) == 0 { - return nil, errMissingStakersForGenesis - } - if len(xChainBalances) == 0 || len(cChainBalances) == 0 { - return nil, errMissingBalancesForGenesis - } - - // Address that controls stake doesn't matter -- generate it randomly - stakeAddress, err := address.Format( - "X", - constants.GetHRP(networkID), - ids.GenerateTestShortID().Bytes(), - ) - if err != nil { - return nil, fmt.Errorf("failed to format stake address: %w", err) - } - - // Ensure the total stake allows a MegaAvax per staker - totalStake := uint64(len(initialStakers)) * units.MegaAvax - - // The eth address is only needed to link pre-mainnet assets. Until that capability - // becomes necessary for testing, use a bogus address. - // - // Reference: https://github.com/ava-labs/avalanchego/issues/1365#issuecomment-1511508767 - ethAddress := "0x0000000000000000000000000000000000000000" - - now := time.Now() - - config := &genesis.UnparsedConfig{ - NetworkID: networkID, - Allocations: []genesis.UnparsedAllocation{ - { - ETHAddr: ethAddress, - AVAXAddr: stakeAddress, - InitialAmount: 0, - UnlockSchedule: []genesis.LockedAmount{ // Provides stake to validators - { - Amount: totalStake, - Locktime: uint64(now.Add(7 * 24 * time.Hour).Unix()), // 1 Week - }, - }, - }, - }, - StartTime: uint64(now.Unix()), - InitialStakedFunds: []string{stakeAddress}, - InitialStakeDuration: 365 * 24 * 60 * 60, // 1 year - InitialStakeDurationOffset: 90 * 60, // 90 minutes - Message: "hello avalanche!", - InitialStakers: initialStakers, - } - - // Set X-Chain balances - for xChainAddress, balance := range xChainBalances { - avaxAddr, err := address.Format("X", constants.GetHRP(networkID), xChainAddress[:]) - if err != nil { - return nil, fmt.Errorf("failed to format X-Chain address: %w", err) - } - config.Allocations = append( - config.Allocations, - genesis.UnparsedAllocation{ - ETHAddr: ethAddress, - AVAXAddr: avaxAddr, - InitialAmount: balance, - UnlockSchedule: []genesis.LockedAmount{ - { - Amount: 20 * units.MegaAvax, - }, - { - Amount: totalStake, - Locktime: uint64(now.Add(7 * 24 * time.Hour).Unix()), // 1 Week - }, - }, - }, - ) - } - - // Define C-Chain genesis - cChainGenesis := &core.Genesis{ - Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - }, - Difficulty: big.NewInt(0), // Difficulty is a mandatory field - GasLimit: DefaultGasLimit, - Alloc: cChainBalances, - } - cChainGenesisBytes, err := json.Marshal(cChainGenesis) - if err != nil { - return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - } - config.CChainGenesis = string(cChainGenesisBytes) - - return config, nil -} diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index c8b5c42c13d2..1ca62e26bd4f 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -19,6 +19,15 @@ const ( DefaultNetworkStartTimeout = 2 * time.Minute DefaultNodeInitTimeout = 10 * time.Second DefaultNodeStopTimeout = 5 * time.Second + + // Minimum required to ensure connectivity-based health checks will pass + DefaultNodeCount = 2 + + // Arbitrary number of pre-funded keys to create by default + DefaultPreFundedKeyCount = 50 + + // A short minimum stake duration enables testing of staking logic. + DefaultMinStakeDuration = time.Second ) // A set of flags appropriate for testing. diff --git a/tests/fixture/tmpnet/flags.go b/tests/fixture/tmpnet/flags.go new file mode 100644 index 000000000000..556bfbec961e --- /dev/null +++ b/tests/fixture/tmpnet/flags.go @@ -0,0 +1,69 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package tmpnet + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/spf13/cast" + + "github.com/ava-labs/avalanchego/utils/perms" +) + +// Defines a mapping of flag keys to values intended to be supplied to +// an invocation of an AvalancheGo node. +type FlagsMap map[string]interface{} + +// Utility function simplifying construction of a FlagsMap from a file. +func ReadFlagsMap(path string, description string) (*FlagsMap, error) { + bytes, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("failed to read %s: %w", description, err) + } + flagsMap := &FlagsMap{} + if err := json.Unmarshal(bytes, flagsMap); err != nil { + return nil, fmt.Errorf("failed to unmarshal %s: %w", description, err) + } + return flagsMap, nil +} + +// SetDefaults ensures the effectiveness of flag overrides by only +// setting values supplied in the defaults map that are not already +// explicitly set. +func (f FlagsMap) SetDefaults(defaults FlagsMap) { + for key, value := range defaults { + if _, ok := f[key]; !ok { + f[key] = value + } + } +} + +// GetStringVal simplifies retrieving a map value as a string. +func (f FlagsMap) GetStringVal(key string) (string, error) { + rawVal, ok := f[key] + if !ok { + return "", nil + } + + val, err := cast.ToStringE(rawVal) + if err != nil { + return "", fmt.Errorf("failed to cast value for %q: %w", key, err) + } + return val, nil +} + +// Write simplifies writing a FlagsMap to the provided path. The +// description is used in error messages. +func (f FlagsMap) Write(path string, description string) error { + bytes, err := DefaultJSONMarshal(f) + if err != nil { + return fmt.Errorf("failed to marshal %s: %w", description, err) + } + if err := os.WriteFile(path, bytes, perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write %s: %w", description, err) + } + return nil +} diff --git a/tests/fixture/tmpnet/genesis.go b/tests/fixture/tmpnet/genesis.go new file mode 100644 index 000000000000..5ee605702482 --- /dev/null +++ b/tests/fixture/tmpnet/genesis.go @@ -0,0 +1,193 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package tmpnet + +import ( + "encoding/json" + "errors" + "fmt" + "math/big" + "time" + + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/formatting/address" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" +) + +const ( + defaultGasLimit = uint64(100_000_000) // Gas limit is arbitrary + + // Arbitrarily large amount of AVAX to fund keys on the X-Chain for testing + defaultFundedKeyXChainAmount = 30 * units.MegaAvax +) + +var ( + // Arbitrarily large amount of AVAX (10^12) to fund keys on the C-Chain for testing + defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) + + errNoKeysForGenesis = errors.New("no keys to fund for genesis") + errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID for genesis") + errMissingStakersForGenesis = errors.New("no stakers provided for genesis") +) + +// Helper type to simplify configuring X-Chain genesis balances +type XChainBalanceMap map[ids.ShortID]uint64 + +// Create a genesis struct valid for bootstrapping a test +// network. Note that many of the genesis fields (e.g. reward +// addresses) are randomly generated or hard-coded. +func NewTestGenesis( + networkID uint32, + nodes []*Node, + keysToFund []*secp256k1.PrivateKey, +) (*genesis.UnparsedConfig, error) { + // Validate inputs + switch networkID { + case constants.TestnetID, constants.MainnetID, constants.LocalID: + return nil, errInvalidNetworkIDForGenesis + } + if len(nodes) == 0 { + return nil, errMissingStakersForGenesis + } + if len(keysToFund) == 0 { + return nil, errNoKeysForGenesis + } + + initialStakers, err := stakersForNodes(networkID, nodes) + if err != nil { + return nil, fmt.Errorf("failed to configure stakers for nodes: %w", err) + } + + // Address that controls stake doesn't matter -- generate it randomly + stakeAddress, err := address.Format( + "X", + constants.GetHRP(networkID), + ids.GenerateTestShortID().Bytes(), + ) + if err != nil { + return nil, fmt.Errorf("failed to format stake address: %w", err) + } + + // Ensure the total stake allows a MegaAvax per staker + totalStake := uint64(len(initialStakers)) * units.MegaAvax + + // The eth address is only needed to link pre-mainnet assets. Until that capability + // becomes necessary for testing, use a bogus address. + // + // Reference: https://github.com/ava-labs/avalanchego/issues/1365#issuecomment-1511508767 + ethAddress := "0x0000000000000000000000000000000000000000" + + now := time.Now() + + config := &genesis.UnparsedConfig{ + NetworkID: networkID, + Allocations: []genesis.UnparsedAllocation{ + { + ETHAddr: ethAddress, + AVAXAddr: stakeAddress, + InitialAmount: 0, + UnlockSchedule: []genesis.LockedAmount{ // Provides stake to validators + { + Amount: totalStake, + Locktime: uint64(now.Add(7 * 24 * time.Hour).Unix()), // 1 Week + }, + }, + }, + }, + StartTime: uint64(now.Unix()), + InitialStakedFunds: []string{stakeAddress}, + InitialStakeDuration: 365 * 24 * 60 * 60, // 1 year + InitialStakeDurationOffset: 90 * 60, // 90 minutes + Message: "hello avalanche!", + InitialStakers: initialStakers, + } + + // Ensure pre-funded keys have arbitrary large balances on both chains to support testing + xChainBalances := make(XChainBalanceMap, len(keysToFund)) + cChainBalances := make(core.GenesisAlloc, len(keysToFund)) + for _, key := range keysToFund { + xChainBalances[key.Address()] = defaultFundedKeyXChainAmount + cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + Balance: defaultFundedKeyCChainAmount, + } + } + + // Set X-Chain balances + for xChainAddress, balance := range xChainBalances { + avaxAddr, err := address.Format("X", constants.GetHRP(networkID), xChainAddress[:]) + if err != nil { + return nil, fmt.Errorf("failed to format X-Chain address: %w", err) + } + config.Allocations = append( + config.Allocations, + genesis.UnparsedAllocation{ + ETHAddr: ethAddress, + AVAXAddr: avaxAddr, + InitialAmount: balance, + UnlockSchedule: []genesis.LockedAmount{ + { + Amount: 20 * units.MegaAvax, + }, + { + Amount: totalStake, + Locktime: uint64(now.Add(7 * 24 * time.Hour).Unix()), // 1 Week + }, + }, + }, + ) + } + + // Define C-Chain genesis + cChainGenesis := &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + }, + Difficulty: big.NewInt(0), // Difficulty is a mandatory field + GasLimit: defaultGasLimit, + Alloc: cChainBalances, + } + cChainGenesisBytes, err := json.Marshal(cChainGenesis) + if err != nil { + return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + } + config.CChainGenesis = string(cChainGenesisBytes) + + return config, nil +} + +// Returns staker configuration for the given set of nodes. +func stakersForNodes(networkID uint32, nodes []*Node) ([]genesis.UnparsedStaker, error) { + // Give staking rewards for initial validators to a random address. Any testing of staking rewards + // will be easier to perform with nodes other than the initial validators since the timing of + // staking can be more easily controlled. + rewardAddr, err := address.Format("X", constants.GetHRP(networkID), ids.GenerateTestShortID().Bytes()) + if err != nil { + return nil, fmt.Errorf("failed to format reward address: %w", err) + } + + // Configure provided nodes as initial stakers + initialStakers := make([]genesis.UnparsedStaker, len(nodes)) + for i, node := range nodes { + pop, err := node.GetProofOfPossession() + if err != nil { + return nil, fmt.Errorf("failed to derive proof of possession for node %s: %w", node.NodeID, err) + } + initialStakers[i] = genesis.UnparsedStaker{ + NodeID: node.NodeID, + RewardAddress: rewardAddr, + DelegationFee: .01 * reward.PercentDenominator, + Signer: pop, + } + } + + return initialStakers, nil +} diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 9c7eb976979d..11b0128df3bb 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -20,10 +20,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" ) const ( @@ -84,9 +82,13 @@ func FindNextNetworkID(rootDir string) (uint32, string, error) { // Defines the configuration required for a tempoary network type Network struct { - NetworkConfig NodeRuntimeConfig + Genesis *genesis.UnparsedConfig + CChainConfig FlagsMap + DefaultFlags FlagsMap + PreFundedKeys []*secp256k1.PrivateKey + // Nodes comprising the network Nodes []*Node @@ -100,9 +102,7 @@ func (n *Network) AddEphemeralNode(w io.Writer, flags FlagsMap) (*Node, error) { flags = FlagsMap{} } return n.AddNode(w, &Node{ - NodeConfig: NodeConfig{ - Flags: flags, - }, + Flags: flags, }, true /* isEphemeral */) } @@ -233,27 +233,20 @@ func (n *Network) PopulateNetworkConfig(networkID uint32, nodeCount int, keyCoun } } - // Assume all the initial nodes are stakers - initialStakers, err := stakersForNodes(networkID, n.Nodes) - if err != nil { - return err - } - if keyCount > 0 { - // Ensure there are keys for genesis generation to fund - keys := make([]*secp256k1.PrivateKey, 0, keyCount) - for i := 0; i < keyCount; i++ { - key, err := secp256k1.NewPrivateKey() - if err != nil { - return fmt.Errorf("failed to generate private key: %w", err) - } - keys = append(keys, key) + keys, err := NewPrivateKeys(keyCount) + if err != nil { + return err } n.PreFundedKeys = keys } - if err := n.EnsureGenesis(networkID, initialStakers); err != nil { - return err + if n.Genesis == nil { + genesis, err := NewTestGenesis(networkID, n.Nodes, n.PreFundedKeys) + if err != nil { + return err + } + n.Genesis = genesis } if n.CChainConfig == nil { @@ -335,7 +328,7 @@ func (n *Network) Start(w io.Writer) error { // Configure networking and start each node for _, node := range n.Nodes { // Update network configuration - node.SetNetworkingConfigDefaults(0, 0, bootstrapIDs, bootstrapIPs) + node.SetNetworkingConfig(bootstrapIDs, bootstrapIPs) // Write configuration to disk in preparation for node start if err := node.WriteConfig(); err != nil { @@ -649,13 +642,7 @@ func (n *Network) AddNode(w io.Writer, node *Node, isEphemeral bool) (*Node, err if err != nil { return nil, err } - - var ( - // Use dynamic port allocation. - httpPort uint16 = 0 - stakingPort uint16 = 0 - ) - node.SetNetworkingConfigDefaults(httpPort, stakingPort, bootstrapIDs, bootstrapIPs) + node.SetNetworkingConfig(bootstrapIDs, bootstrapIPs) if err := node.WriteConfig(); err != nil { return nil, err @@ -700,31 +687,3 @@ func (n *Network) GetBootstrapIPsAndIDs() ([]string, []string, error) { return bootstrapIPs, bootstrapIDs, nil } - -// Returns staker configuration for the given set of nodes. -func stakersForNodes(networkID uint32, nodes []*Node) ([]genesis.UnparsedStaker, error) { - // Give staking rewards for initial validators to a random address. Any testing of staking rewards - // will be easier to perform with nodes other than the initial validators since the timing of - // staking can be more easily controlled. - rewardAddr, err := address.Format("X", constants.GetHRP(networkID), ids.GenerateTestShortID().Bytes()) - if err != nil { - return nil, fmt.Errorf("failed to format reward address: %w", err) - } - - // Configure provided nodes as initial stakers - initialStakers := make([]genesis.UnparsedStaker, len(nodes)) - for i, node := range nodes { - pop, err := node.GetProofOfPossession() - if err != nil { - return nil, fmt.Errorf("failed to derive proof of possession: %w", err) - } - initialStakers[i] = genesis.UnparsedStaker{ - NodeID: node.NodeID, - RewardAddress: rewardAddr, - DelegationFee: .01 * reward.PercentDenominator, - Signer: pop, - } - } - - return initialStakers, nil -} diff --git a/tests/fixture/tmpnet/node.go b/tests/fixture/tmpnet/node.go index 64ca8f11802f..0bd18cc65ae9 100644 --- a/tests/fixture/tmpnet/node.go +++ b/tests/fixture/tmpnet/node.go @@ -5,6 +5,7 @@ package tmpnet import ( "context" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -14,6 +15,7 @@ import ( "os" "os/exec" "path/filepath" + "strings" "syscall" "time" @@ -21,11 +23,20 @@ import ( "github.com/ava-labs/avalanchego/api/health" "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/node" + "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/perms" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) -var errNodeAlreadyRunning = errors.New("failed to start node: node is already running") +var ( + errNodeAlreadyRunning = errors.New("failed to start node: node is already running") + errMissingTLSKeyForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingTLSKeyContentKey) + errMissingCertForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingCertContentKey) + errInvalidKeypair = fmt.Errorf("%q and %q must be provided together or not at all", config.StakingTLSKeyContentKey, config.StakingCertContentKey) +) // Defines configuration to execute a node. // @@ -39,19 +50,19 @@ type NodeRuntimeConfig struct { // Stores the configuration and process details of a node in a temporary network. type Node struct { - NodeConfig NodeRuntimeConfig node.NodeProcessContext + NodeID ids.NodeID + Flags FlagsMap + // Configuration is intended to be stored at the path identified in NodeConfig.Flags[config.DataDirKey] } func NewNode(dataDir string) *Node { return &Node{ - NodeConfig: NodeConfig{ - Flags: FlagsMap{ - config.DataDirKey: dataDir, - }, + Flags: FlagsMap{ + config.DataDirKey: dataDir, }, } } @@ -83,11 +94,10 @@ func (n *Node) ReadConfig() error { if err := json.Unmarshal(bytes, &flags); err != nil { return fmt.Errorf("failed to unmarshal node config: %w", err) } - config := NodeConfig{Flags: flags} - if err := config.EnsureNodeID(); err != nil { + n.Flags = flags + if err := n.EnsureNodeID(); err != nil { return err } - n.NodeConfig = config return nil } @@ -321,3 +331,143 @@ func (n *Node) WaitForProcessContext(ctx context.Context) error { } return nil } + +// Convenience method for setting networking flags. +func (n *Node) SetNetworkingConfig(bootstrapIDs []string, bootstrapIPs []string) { + var ( + // Use dynamic port allocation. + httpPort uint16 = 0 + stakingPort uint16 = 0 + ) + n.Flags[config.HTTPPortKey] = httpPort + n.Flags[config.StakingPortKey] = stakingPort + n.Flags[config.BootstrapIDsKey] = strings.Join(bootstrapIDs, ",") + n.Flags[config.BootstrapIPsKey] = strings.Join(bootstrapIPs, ",") +} + +// Ensures staking and signing keys are generated if not already present and +// that the node ID (derived from the staking keypair) is set. +func (n *Node) EnsureKeys() error { + if err := n.EnsureBLSSigningKey(); err != nil { + return err + } + if err := n.EnsureStakingKeypair(); err != nil { + return err + } + // Once a staking keypair is guaranteed it is safe to derive the node ID + return n.EnsureNodeID() +} + +// Derives the nodes proof-of-possession. Requires the node to have a +// BLS signing key. +func (n *Node) GetProofOfPossession() (*signer.ProofOfPossession, error) { + signingKey, err := n.Flags.GetStringVal(config.StakingSignerKeyContentKey) + if err != nil { + return nil, err + } + signingKeyBytes, err := base64.StdEncoding.DecodeString(signingKey) + if err != nil { + return nil, err + } + secretKey, err := bls.SecretKeyFromBytes(signingKeyBytes) + if err != nil { + return nil, err + } + return signer.NewProofOfPossession(secretKey), nil +} + +// Ensures a BLS signing key is generated if not already present. +func (n *Node) EnsureBLSSigningKey() error { + // Attempt to retrieve an existing key + existingKey, err := n.Flags.GetStringVal(config.StakingSignerKeyContentKey) + if err != nil { + return err + } + if len(existingKey) > 0 { + // Nothing to do + return nil + } + + // Generate a new signing key + newKey, err := bls.NewSecretKey() + if err != nil { + return fmt.Errorf("failed to generate staking signer key: %w", err) + } + n.Flags[config.StakingSignerKeyContentKey] = base64.StdEncoding.EncodeToString(bls.SerializeSecretKey(newKey)) + return nil +} + +// Ensures a staking keypair is generated if not already present. +func (n *Node) EnsureStakingKeypair() error { + keyKey := config.StakingTLSKeyContentKey + certKey := config.StakingCertContentKey + + key, err := n.Flags.GetStringVal(keyKey) + if err != nil { + return err + } + + cert, err := n.Flags.GetStringVal(certKey) + if err != nil { + return err + } + + if len(key) == 0 && len(cert) == 0 { + // Generate new keypair + tlsCertBytes, tlsKeyBytes, err := staking.NewCertAndKeyBytes() + if err != nil { + return fmt.Errorf("failed to generate staking keypair: %w", err) + } + n.Flags[keyKey] = base64.StdEncoding.EncodeToString(tlsKeyBytes) + n.Flags[certKey] = base64.StdEncoding.EncodeToString(tlsCertBytes) + } else if len(key) == 0 || len(cert) == 0 { + // Only one of key and cert was provided + return errInvalidKeypair + } + + err = n.EnsureNodeID() + if err != nil { + return fmt.Errorf("failed to derive a node ID: %w", err) + } + + return nil +} + +// Attempt to derive the node ID from the node configuration. +func (n *Node) EnsureNodeID() error { + keyKey := config.StakingTLSKeyContentKey + certKey := config.StakingCertContentKey + + key, err := n.Flags.GetStringVal(keyKey) + if err != nil { + return err + } + if len(key) == 0 { + return errMissingTLSKeyForNodeID + } + keyBytes, err := base64.StdEncoding.DecodeString(key) + if err != nil { + return fmt.Errorf("failed to ensure node ID: failed to base64 decode value for %q: %w", keyKey, err) + } + + cert, err := n.Flags.GetStringVal(certKey) + if err != nil { + return err + } + if len(cert) == 0 { + return errMissingCertForNodeID + } + certBytes, err := base64.StdEncoding.DecodeString(cert) + if err != nil { + return fmt.Errorf("failed to ensure node ID: failed to base64 decode value for %q: %w", certKey, err) + } + + tlsCert, err := staking.LoadTLSCertFromBytes(keyBytes, certBytes) + if err != nil { + return fmt.Errorf("failed to ensure node ID: failed to load tls cert: %w", err) + } + stakingCert := staking.CertificateFromX509(tlsCert.Leaf) + n.NodeID = ids.NodeIDFromCert(stakingCert) + + return nil +} diff --git a/tests/fixture/tmpnet/node_test.go b/tests/fixture/tmpnet/node_test.go deleted file mode 100644 index ab060105804a..000000000000 --- a/tests/fixture/tmpnet/node_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package tmpnet - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNodeSerialization(t *testing.T) { - require := require.New(t) - - tmpDir := t.TempDir() - - node := NewNode(tmpDir) - require.NoError(node.EnsureKeys()) - require.NoError(node.WriteConfig()) - - loadedNode, err := ReadNode(tmpDir) - require.NoError(err) - require.Equal(node, loadedNode) -} diff --git a/tests/fixture/tmpnet/utils.go b/tests/fixture/tmpnet/utils.go index b8508c3880e2..fd0bc64427f3 100644 --- a/tests/fixture/tmpnet/utils.go +++ b/tests/fixture/tmpnet/utils.go @@ -9,6 +9,9 @@ import ( "errors" "fmt" "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" ) const ( @@ -42,7 +45,41 @@ func WaitForHealthy(ctx context.Context, node *Node) error { } } +// NodeURI associates a node ID with its API URI. +type NodeURI struct { + NodeID ids.NodeID + URI string +} + +func GetNodeURIs(nodes []*Node) []NodeURI { + uris := make([]NodeURI, 0, len(nodes)) + for _, node := range nodes { + // Only append URIs that are not empty. A node may have an + // empty URI if it is not currently running. + if len(node.URI) > 0 { + uris = append(uris, NodeURI{ + NodeID: node.NodeID, + URI: node.URI, + }) + } + } + return uris +} + // Marshal to json with default prefix and indent. func DefaultJSONMarshal(v interface{}) ([]byte, error) { return json.MarshalIndent(v, "", " ") } + +// Helper simplifying creation of a set of private keys +func NewPrivateKeys(keyCount int) ([]*secp256k1.PrivateKey, error) { + keys := make([]*secp256k1.PrivateKey, 0, keyCount) + for i := 0; i < keyCount; i++ { + key, err := secp256k1.NewPrivateKey() + if err != nil { + return nil, fmt.Errorf("failed to generate private key: %w", err) + } + keys = append(keys, key) + } + return keys, nil +} From 5ce35ce8bff94fa8cc18d455b9d8cd03ac2e699e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 15 Dec 2023 16:20:55 -0700 Subject: [PATCH 157/267] Drop Pending Stakers 4 - minimal UT infra cleanup (#2332) Co-authored-by: Stephen Buttolph Co-authored-by: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> --- vms/platformvm/service_test.go | 38 ++-- .../txs/executor/advance_time_test.go | 64 +++--- .../txs/executor/create_chain_test.go | 10 +- .../txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/export_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 14 +- vms/platformvm/txs/executor/import_test.go | 2 +- .../txs/executor/proposal_tx_executor_test.go | 37 ++-- .../txs/executor/reward_validator_test.go | 12 +- .../executor/staker_tx_verification_test.go | 125 +++++++---- .../txs/executor/standard_tx_executor_test.go | 199 ++++++++++-------- vms/platformvm/txs/validator_test.go | 2 +- vms/platformvm/vm_regression_test.go | 41 ++-- vms/platformvm/vm_test.go | 199 ++++++++++++------ 14 files changed, 454 insertions(+), 293 deletions(-) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index f5e61a9e4e72..d6d96e66df41 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -73,7 +73,7 @@ var ( ) func defaultService(t *testing.T) (*Service, *mutableSharedMemory) { - vm, _, mutableSharedMemory := defaultVM(t) + vm, _, mutableSharedMemory := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() ks := keystore.New(logging.NoLog{}, memdb.New()) @@ -400,7 +400,7 @@ func TestGetBalance(t *testing.T) { // Ensure GetStake is correct for each of the genesis validators genesis, _ := defaultGenesis(t) - for _, utxo := range genesis.UTXOs { + for idx, utxo := range genesis.UTXOs { request := GetBalanceRequest{ Addresses: []string{ fmt.Sprintf("P-%s", utxo.Address), @@ -409,9 +409,14 @@ func TestGetBalance(t *testing.T) { reply := GetBalanceResponse{} require.NoError(service.GetBalance(nil, &request, &reply)) - - require.Equal(json.Uint64(defaultBalance), reply.Balance) - require.Equal(json.Uint64(defaultBalance), reply.Unlocked) + balance := defaultBalance + if idx == 0 { + // we use the first key to fund a subnet creation in [defaultGenesis]. + // As such we need to account for the subnet creation fee + balance = defaultBalance - service.vm.Config.GetCreateSubnetTxFee(service.vm.clock.Time()) + } + require.Equal(json.Uint64(balance), reply.Balance) + require.Equal(json.Uint64(balance), reply.Unlocked) require.Equal(json.Uint64(0), reply.LockedStakeable) require.Equal(json.Uint64(0), reply.LockedNotStakeable) } @@ -495,11 +500,12 @@ func TestGetStake(t *testing.T) { // Add a delegator stakeAmount := service.vm.MinDelegatorStake + 12345 delegatorNodeID := genesisNodeIDs[0] - delegatorEndTime := uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix()) + delegatorStartTime := defaultValidateStartTime + delegatorEndTime := defaultGenesisTime.Add(defaultMinStakingDuration) tx, err := service.vm.txBuilder.NewAddDelegatorTx( stakeAmount, - uint64(defaultGenesisTime.Unix()), - delegatorEndTime, + uint64(delegatorStartTime.Unix()), + uint64(delegatorEndTime.Unix()), delegatorNodeID, ids.GenerateTestShortID(), []*secp256k1.PrivateKey{keys[0]}, @@ -511,7 +517,7 @@ func TestGetStake(t *testing.T) { staker, err := state.NewCurrentStaker( tx.ID(), addDelTx, - addDelTx.StartTime(), + delegatorStartTime, 0, ) require.NoError(err) @@ -629,15 +635,15 @@ func TestGetCurrentValidators(t *testing.T) { // Add a delegator stakeAmount := service.vm.MinDelegatorStake + 12345 validatorNodeID := genesisNodeIDs[1] - delegatorStartTime := uint64(defaultValidateStartTime.Unix()) - delegatorEndTime := uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix()) + delegatorStartTime := defaultValidateStartTime + delegatorEndTime := delegatorStartTime.Add(defaultMinStakingDuration) service.vm.ctx.Lock.Lock() delTx, err := service.vm.txBuilder.NewAddDelegatorTx( stakeAmount, - delegatorStartTime, - delegatorEndTime, + uint64(delegatorStartTime.Unix()), + uint64(delegatorEndTime.Unix()), validatorNodeID, ids.GenerateTestShortID(), []*secp256k1.PrivateKey{keys[0]}, @@ -649,7 +655,7 @@ func TestGetCurrentValidators(t *testing.T) { staker, err := state.NewCurrentStaker( delTx.ID(), addDelTx, - addDelTx.StartTime(), + delegatorStartTime, 0, ) require.NoError(err) @@ -691,8 +697,8 @@ func TestGetCurrentValidators(t *testing.T) { require.Len(*innerVdr.Delegators, 1) delegator := (*innerVdr.Delegators)[0] require.Equal(delegator.NodeID, innerVdr.NodeID) - require.Equal(uint64(delegator.StartTime), delegatorStartTime) - require.Equal(uint64(delegator.EndTime), delegatorEndTime) + require.Equal(int64(delegator.StartTime), delegatorStartTime.Unix()) + require.Equal(int64(delegator.EndTime), delegatorEndTime.Unix()) require.Equal(uint64(delegator.Weight), stakeAmount) } require.True(found) diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index ad87af9a7fed..24e5746b6047 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -24,7 +24,7 @@ import ( // for the primary network func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -33,10 +33,16 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { // Case: Timestamp is after next validator start time // Add a pending validator - pendingValidatorStartTime := defaultGenesisTime.Add(1 * time.Second) + pendingValidatorStartTime := defaultValidateStartTime.Add(1 * time.Second) pendingValidatorEndTime := pendingValidatorStartTime.Add(defaultMinStakingDuration) nodeID := ids.GenerateTestNodeID() - addPendingValidatorTx, err := addPendingValidator(env, pendingValidatorStartTime, pendingValidatorEndTime, nodeID, []*secp256k1.PrivateKey{preFundedKeys[0]}) + addPendingValidatorTx, err := addPendingValidator( + env, + pendingValidatorStartTime, + pendingValidatorEndTime, + nodeID, + []*secp256k1.PrivateKey{preFundedKeys[0]}, + ) require.NoError(err) tx, err := env.txBuilder.NewAdvanceTimeTx(pendingValidatorStartTime) @@ -83,12 +89,12 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { // Ensure semantic verification fails when proposed timestamp is at or before current timestamp func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() - tx, err := env.txBuilder.NewAdvanceTimeTx(defaultGenesisTime) + tx, err := env.txBuilder.NewAdvanceTimeTx(env.state.GetTimestamp()) require.NoError(err) onCommitState, err := state.NewDiff(lastAcceptedID, env) @@ -110,12 +116,12 @@ func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { // Ensure semantic verification fails when proposed timestamp is after next validator set change time func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() // Case: Timestamp is after next validator start time // Add a pending validator - pendingValidatorStartTime := defaultGenesisTime.Add(1 * time.Second) + pendingValidatorStartTime := defaultValidateStartTime.Add(1 * time.Second) pendingValidatorEndTime := pendingValidatorStartTime.Add(defaultMinStakingDuration) nodeID := ids.GenerateTestNodeID() _, err := addPendingValidator(env, pendingValidatorStartTime, pendingValidatorEndTime, nodeID, []*secp256k1.PrivateKey{preFundedKeys[0]}) @@ -144,7 +150,7 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { require.NoError(shutdownEnvironment(env)) // Case: Timestamp is after next validator end time - env = newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env = newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -207,8 +213,8 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { // Staker5: |--------------------| staker1 := staker{ nodeID: ids.GenerateTestNodeID(), - startTime: defaultGenesisTime.Add(1 * time.Minute), - endTime: defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute), + startTime: defaultValidateStartTime.Add(1 * time.Minute), + endTime: defaultValidateStartTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute), } staker2 := staker{ nodeID: ids.GenerateTestNodeID(), @@ -346,7 +352,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -451,7 +457,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { // is after the new timestamp func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -555,7 +561,7 @@ func TestTrackedSubnet(t *testing.T) { for _, tracked := range []bool{true, false} { t.Run(fmt.Sprintf("tracked %t", tracked), func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -570,8 +576,8 @@ func TestTrackedSubnet(t *testing.T) { // Add a subnet validator to the staker set subnetValidatorNodeID := genesisNodeIDs[0] - subnetVdr1StartTime := defaultGenesisTime.Add(1 * time.Minute) - subnetVdr1EndTime := defaultGenesisTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) + subnetVdr1StartTime := defaultValidateStartTime.Add(1 * time.Minute) + subnetVdr1EndTime := defaultValidateStartTime.Add(10 * defaultMinStakingDuration).Add(1 * time.Minute) tx, err := env.txBuilder.NewAddSubnetValidatorTx( 1, // Weight uint64(subnetVdr1StartTime.Unix()), // Start time @@ -625,7 +631,7 @@ func TestTrackedSubnet(t *testing.T) { func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -634,7 +640,7 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { // Case: Timestamp is after next validator start time // Add a pending validator - pendingValidatorStartTime := defaultGenesisTime.Add(1 * time.Second) + pendingValidatorStartTime := defaultValidateStartTime.Add(1 * time.Second) pendingValidatorEndTime := pendingValidatorStartTime.Add(defaultMaxStakingDuration) nodeID := ids.GenerateTestNodeID() _, err := addPendingValidator( @@ -732,7 +738,7 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -741,7 +747,7 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { // Case: Timestamp is after next validator start time // Add a pending validator - pendingValidatorStartTime := defaultGenesisTime.Add(1 * time.Second) + pendingValidatorStartTime := defaultValidateStartTime.Add(1 * time.Second) pendingValidatorEndTime := pendingValidatorStartTime.Add(defaultMinStakingDuration) nodeID := ids.GenerateTestNodeID() _, err := addPendingValidator(env, pendingValidatorStartTime, pendingValidatorEndTime, nodeID, []*secp256k1.PrivateKey{preFundedKeys[0]}) @@ -829,15 +835,15 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { // Test method InitiallyPrefersCommit func TestAdvanceTimeTxInitiallyPrefersCommit(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) }() - env.clk.Set(defaultGenesisTime) // VM's clock reads the genesis time + now := env.clk.Time() // Proposed advancing timestamp to 1 second after sync bound - tx, err := env.txBuilder.NewAdvanceTimeTx(defaultGenesisTime.Add(SyncBound)) + tx, err := env.txBuilder.NewAdvanceTimeTx(now.Add(SyncBound)) require.NoError(err) onCommitState, err := state.NewDiff(lastAcceptedID, env) @@ -859,16 +865,19 @@ func TestAdvanceTimeTxInitiallyPrefersCommit(t *testing.T) { func TestAdvanceTimeTxAfterBanff(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) }() env.clk.Set(defaultGenesisTime) // VM's clock reads the genesis time - env.config.BanffTime = defaultGenesisTime.Add(SyncBound) + upgradeTime := env.clk.Time().Add(SyncBound) + env.config.BanffTime = upgradeTime + env.config.CortinaTime = upgradeTime + env.config.DurangoTime = upgradeTime // Proposed advancing timestamp to the banff timestamp - tx, err := env.txBuilder.NewAdvanceTimeTx(defaultGenesisTime.Add(SyncBound)) + tx, err := env.txBuilder.NewAdvanceTimeTx(upgradeTime) require.NoError(err) onCommitState, err := state.NewDiff(lastAcceptedID, env) @@ -890,13 +899,14 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { // Ensure marshaling/unmarshaling works func TestAdvanceTimeTxUnmarshal(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) }() - tx, err := env.txBuilder.NewAdvanceTimeTx(defaultGenesisTime) + chainTime := env.state.GetTimestamp() + tx, err := env.txBuilder.NewAdvanceTimeTx(chainTime.Add(time.Second)) require.NoError(err) bytes, err := txs.Codec.Marshal(txs.Version, tx) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 72315d3c4dd5..4fa960002a00 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -25,7 +25,7 @@ import ( // Ensure Execute fails when there are not enough control sigs func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -60,7 +60,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { // Ensure Execute fails when an incorrect control signature is given func TestCreateChainTxWrongControlSig(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -102,7 +102,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { // its validator set doesn't exist func TestCreateChainTxNoSuchSubnet(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -136,7 +136,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { // Ensure valid tx passes semanticVerify func TestCreateChainTxValid(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -195,7 +195,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.config.ApricotPhase3Time = ap3Time defer func() { diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 182e28ae83c9..bd1912915f70 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -49,7 +49,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.config.ApricotPhase3Time = ap3Time env.ctx.Lock.Lock() defer func() { diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index 380b3dd5a489..73f625603904 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -15,7 +15,7 @@ import ( ) func TestNewExportTx(t *testing.T) { - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(t, shutdownEnvironment(env)) diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index f1311da8737e..1aced0dcbad5 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -119,12 +119,12 @@ func (e *environment) SetState(blkID ids.ID, chainState state.Chain) { e.states[blkID] = chainState } -func newEnvironment(t *testing.T, postBanff, postCortina bool) *environment { +func newEnvironment(t *testing.T, postBanff, postCortina, postDurango bool) *environment { var isBootstrapped utils.Atomic[bool] isBootstrapped.Set(true) - config := defaultConfig(postBanff, postCortina) - clk := defaultClock(postBanff || postCortina) + config := defaultConfig(postBanff, postCortina, postDurango) + clk := defaultClock(postBanff || postCortina || postDurango) baseDB := versiondb.New(memdb.New()) ctx, msm := defaultCtx(baseDB) @@ -215,6 +215,7 @@ func addSubnet( stateDiff.AddTx(testSubnet1, status.Committed) require.NoError(stateDiff.Apply(env.state)) + require.NoError(env.state.Commit()) } func defaultState( @@ -280,7 +281,7 @@ func defaultCtx(db database.Database) (*snow.Context, *mutableSharedMemory) { return ctx, msm } -func defaultConfig(postBanff, postCortina bool) *config.Config { +func defaultConfig(postBanff, postCortina, postDurango bool) *config.Config { banffTime := mockable.MaxTime if postBanff { banffTime = defaultValidateEndTime.Add(-2 * time.Second) @@ -289,6 +290,10 @@ func defaultConfig(postBanff, postCortina bool) *config.Config { if postCortina { cortinaTime = defaultValidateStartTime.Add(-2 * time.Second) } + durangoTime := mockable.MaxTime + if postDurango { + durangoTime = defaultValidateStartTime.Add(-2 * time.Second) + } return &config.Config{ Chains: chains.TestManager, @@ -312,6 +317,7 @@ func defaultConfig(postBanff, postCortina bool) *config.Config { ApricotPhase5Time: defaultValidateEndTime, BanffTime: banffTime, CortinaTime: cortinaTime, + DurangoTime: durangoTime, } } diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 3d78429cf906..e35eda20dbba 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -22,7 +22,7 @@ import ( ) func TestNewImportTx(t *testing.T) { - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) defer func() { require.NoError(t, shutdownEnvironment(env)) }() diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index cf05193983b5..eef480f744c9 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -91,7 +91,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { require.NoError(t, target.state.Commit()) } - dummyH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + dummyH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) currentTimestamp := dummyH.state.GetTimestamp() type test struct { @@ -245,7 +245,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { require := require.New(t) - freshTH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + freshTH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) freshTH.config.ApricotPhase3Time = tt.AP3Time defer func() { require.NoError(shutdownEnvironment(freshTH)) @@ -286,7 +286,7 @@ func TestProposalTxExecuteAddDelegator(t *testing.T) { func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -358,7 +358,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Add a validator to pending validator set of primary network // Starts validating primary network 10 seconds after genesis pendingDSValidatorID := ids.GenerateTestNodeID() - dsStartTime := defaultGenesisTime.Add(10 * time.Second) + dsStartTime := defaultValidateStartTime.Add(10 * time.Second) dsEndTime := dsStartTime.Add(5 * defaultMinStakingDuration) addDSTx, err := env.txBuilder.NewAddValidatorTx( @@ -510,7 +510,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Case: Proposed validator start validating at/before current timestamp // First, advance the timestamp - newTimestamp := defaultGenesisTime.Add(2 * time.Second) + newTimestamp := defaultValidateStartTime.Add(2 * time.Second) env.state.SetTimestamp(newTimestamp) { @@ -542,7 +542,7 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { } // reset the timestamp - env.state.SetTimestamp(defaultGenesisTime) + env.state.SetTimestamp(defaultValidateStartTime) // Case: Proposed validator already validating the subnet // First, add validator as validator of subnet @@ -607,9 +607,9 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Too few signatures tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultGenesisTime.Unix())+1, // start time - uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix())+1, // end time + defaultWeight, // weight + uint64(defaultValidateStartTime.Unix())+1, // start time + uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix())+1, // end time nodeID, // node ID testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[2]}, @@ -643,9 +643,9 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { { // Case: Control Signature from invalid key (keys[3] is not a control key) tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultGenesisTime.Unix())+1, // start time - uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix())+1, // end time + defaultWeight, // weight + uint64(defaultValidateStartTime.Unix())+1, // start time + uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix())+1, // end time nodeID, // node ID testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], preFundedKeys[1]}, @@ -678,9 +678,9 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { // Case: Proposed validator in pending validator set for subnet // First, add validator to pending validator set of subnet tx, err := env.txBuilder.NewAddSubnetValidatorTx( - defaultWeight, // weight - uint64(defaultGenesisTime.Unix())+1, // start time - uint64(defaultGenesisTime.Add(defaultMinStakingDuration).Unix())+1, // end time + defaultWeight, // weight + uint64(defaultValidateStartTime.Unix())+1, // start time + uint64(defaultValidateStartTime.Add(defaultMinStakingDuration).Unix())+1, // end time nodeID, // node ID testSubnet1.ID(), // subnet ID []*secp256k1.PrivateKey{testSubnet1ControlKeys[0], testSubnet1ControlKeys[1]}, @@ -721,19 +721,20 @@ func TestProposalTxExecuteAddSubnetValidator(t *testing.T) { func TestProposalTxExecuteAddValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) }() nodeID := ids.GenerateTestNodeID() + chainTime := env.state.GetTimestamp() { // Case: Validator's start time too early tx, err := env.txBuilder.NewAddValidatorTx( env.config.MinValidatorStake, - uint64(defaultValidateStartTime.Unix()), + uint64(chainTime.Unix()), uint64(defaultValidateEndTime.Unix()), nodeID, ids.ShortEmpty, @@ -823,7 +824,7 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { { // Case: Validator in pending validator set of primary network - startTime := defaultGenesisTime.Add(1 * time.Second) + startTime := defaultValidateStartTime.Add(1 * time.Second) tx, err := env.txBuilder.NewAddValidatorTx( env.config.MinValidatorStake, // stake amount uint64(startTime.Unix()), // start time diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 4060bbbb9497..488423c47a07 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -25,7 +25,7 @@ import ( func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() @@ -128,7 +128,7 @@ func TestRewardValidatorTxExecuteOnCommit(t *testing.T) { func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() @@ -225,7 +225,7 @@ func TestRewardValidatorTxExecuteOnAbort(t *testing.T) { func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() @@ -349,7 +349,7 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/) + env := newEnvironment(t, true /*postBanff*/, true /*postCortina*/, true /*postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() @@ -568,7 +568,7 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/) + env := newEnvironment(t, true /*postBanff*/, true /*postCortina*/, true /*postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() @@ -730,7 +730,7 @@ func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t * func TestRewardDelegatorTxExecuteOnAbort(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index aa8953c8f22e..f0da597939b9 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -37,6 +37,12 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { } var ( + // in the following tests we set the fork time for forks we want active + // to activeForkTime, which is ensured to be before any other time related + // quantity (based on now) + activeForkTime = time.Unix(0, 0) + now = time.Now().Truncate(time.Second) // after activeForkTime + subnetID = ids.GenerateTestID() customAssetID = ids.GenerateTestID() unsignedTransformTx = &txs.TransformSubnetTx{ @@ -52,6 +58,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { Creds: []verify.Verifiable{}, } // This tx already passed syntactic verification. + startTime = now.Add(time.Second) + endTime = startTime.Add(time.Second * time.Duration(unsignedTransformTx.MinStakeDuration)) verifiedTx = txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{ SyntacticallyVerified: true, @@ -64,8 +72,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, Validator: txs.Validator{ NodeID: ids.GenerateTestNodeID(), - Start: 1, - End: 1 + uint64(unsignedTransformTx.MinStakeDuration), + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), Wght: unsignedTransformTx.MinValidatorStake, }, Subnet: subnetID, @@ -99,6 +107,9 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { backendF: func(*gomock.Controller) *Backend { return &Backend{ Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, } }, stateF: func(*gomock.Controller) state.Chain { @@ -116,7 +127,10 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { name: "not bootstrapped", backendF: func(*gomock.Controller) *Backend { return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: &utils.Atomic[bool]{}, } }, @@ -137,7 +151,11 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + CortinaTime: activeForkTime, + DurangoTime: mockable.MaxTime, + }, Bootstrapped: bootstrapped, } }, @@ -160,13 +178,16 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: bootstrapped, } }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + state.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -186,13 +207,16 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: bootstrapped, } }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + state.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -212,13 +236,16 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: bootstrapped, } }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + state.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -239,13 +266,16 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: bootstrapped, } }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + state.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -256,9 +286,9 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { tx := verifiedTx // Note that this copies [verifiedTx] tx.Validator.Wght = unsignedTransformTx.MaxValidatorStake tx.DelegationShares = unsignedTransformTx.MinDelegationFee + // Note the duration is 1 less than the minimum - tx.Validator.Start = 1 - tx.Validator.End = uint64(unsignedTransformTx.MinStakeDuration) + tx.Validator.End = tx.Validator.Start + uint64(unsignedTransformTx.MinStakeDuration) - 1 return &tx }, expectedErr: ErrStakeTooShort, @@ -269,13 +299,16 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: bootstrapped, } }, stateF: func(ctrl *gomock.Controller) state.Chain { state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + state.EXPECT().GetTimestamp().Return(time.Unix(1, 0)) // chain time is after fork activation since time.Unix(1, 0).After(activeForkTime) state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) return state }, @@ -286,9 +319,9 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { tx := verifiedTx // Note that this copies [verifiedTx] tx.Validator.Wght = unsignedTransformTx.MaxValidatorStake tx.DelegationShares = unsignedTransformTx.MinDelegationFee + // Note the duration is more than the maximum - tx.Validator.Start = 1 - tx.Validator.End = 2 + uint64(unsignedTransformTx.MaxStakeDuration) + tx.Validator.End = tx.Validator.Start + uint64(unsignedTransformTx.MaxStakeDuration) + 1 return &tx }, expectedErr: ErrStakeTooLong, @@ -299,15 +332,18 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: bootstrapped, } }, stateF: func(ctrl *gomock.Controller) state.Chain { - state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) - state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) - return state + mockState := state.NewMockChain(ctrl) + mockState.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) + return mockState }, sTxF: func() *txs.Tx { return &verifiedSignedTx @@ -331,17 +367,20 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: bootstrapped, } }, stateF: func(ctrl *gomock.Controller) state.Chain { - state := state.NewMockChain(ctrl) - state.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) - state.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) + mockState := state.NewMockChain(ctrl) + mockState.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) // State says validator exists - state.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, nil) - return state + mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, nil) + return mockState }, sTxF: func() *txs.Tx { return &verifiedSignedTx @@ -357,20 +396,22 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: snow.DefaultContextTest(), + Config: &config.Config{ + DurangoTime: activeForkTime, // activate latest fork + }, Bootstrapped: bootstrapped, } }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + mockState.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) // Validator time isn't subset of primary network validator time primaryNetworkVdr := &state.Staker{ - StartTime: verifiedTx.StartTime().Add(time.Second), - EndTime: verifiedTx.EndTime(), + EndTime: verifiedTx.EndTime().Add(-1 * time.Second), } mockState.EXPECT().GetCurrentValidator(constants.PrimaryNetworkID, verifiedTx.NodeID()).Return(primaryNetworkVdr, nil) return mockState @@ -403,6 +444,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { FlowChecker: flowChecker, Config: &config.Config{ AddSubnetValidatorFee: 1, + DurangoTime: activeForkTime, // activate latest fork, }, Ctx: snow.DefaultContextTest(), Bootstrapped: bootstrapped, @@ -410,13 +452,12 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + mockState.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) primaryNetworkVdr := &state.Staker{ - StartTime: verifiedTx.StartTime(), - EndTime: verifiedTx.EndTime(), + EndTime: mockable.MaxTime, } mockState.EXPECT().GetCurrentValidator(constants.PrimaryNetworkID, verifiedTx.NodeID()).Return(primaryNetworkVdr, nil) return mockState @@ -448,6 +489,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { return &Backend{ FlowChecker: flowChecker, Config: &config.Config{ + CortinaTime: activeForkTime, + DurangoTime: mockable.MaxTime, AddSubnetValidatorFee: 1, }, Ctx: snow.DefaultContextTest(), @@ -456,7 +499,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + mockState.EXPECT().GetTimestamp().Return(now) // chain time is Cortina fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) @@ -473,7 +516,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { txF: func() *txs.AddPermissionlessValidatorTx { // Note this copies [verifiedTx] tx := verifiedTx - tx.Validator.Start = uint64(MaxFutureStartTime.Seconds()) + 1 + tx.Validator.Start = uint64(now.Add(MaxFutureStartTime).Add(time.Second).Unix()) tx.Validator.End = tx.Validator.Start + uint64(unsignedTransformTx.MinStakeDuration) return &tx }, @@ -499,6 +542,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { FlowChecker: flowChecker, Config: &config.Config{ AddSubnetValidatorFee: 1, + DurangoTime: activeForkTime, // activate latest fork, }, Ctx: snow.DefaultContextTest(), Bootstrapped: bootstrapped, @@ -506,13 +550,12 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(time.Unix(0, 0)) + mockState.EXPECT().GetTimestamp().Return(now) // chain time is after Durango fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) primaryNetworkVdr := &state.Staker{ - StartTime: time.Unix(0, 0), - EndTime: mockable.MaxTime, + EndTime: mockable.MaxTime, } mockState.EXPECT().GetCurrentValidator(constants.PrimaryNetworkID, verifiedTx.NodeID()).Return(primaryNetworkVdr, nil) return mockState diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index d545c07d0a45..19ca07604ccf 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -41,14 +41,14 @@ var errTest = errors.New("non-nil error") func TestStandardTxExecutorAddValidatorTxEmptyID(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) }() chainTime := env.state.GetTimestamp() - startTime := defaultGenesisTime.Add(1 * time.Second) + startTime := defaultValidateStartTime.Add(1 * time.Second) tests := []struct { banffTime time.Time @@ -102,19 +102,19 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { nodeID := genesisNodeIDs[0] newValidatorID := ids.GenerateTestNodeID() - newValidatorStartTime := uint64(defaultValidateStartTime.Add(5 * time.Second).Unix()) - newValidatorEndTime := uint64(defaultValidateEndTime.Add(-5 * time.Second).Unix()) + newValidatorStartTime := defaultValidateStartTime.Add(5 * time.Second) + newValidatorEndTime := defaultValidateEndTime.Add(-5 * time.Second) // [addMinStakeValidator] adds a new validator to the primary network's // pending validator set with the minimum staking amount addMinStakeValidator := func(target *environment) { tx, err := target.txBuilder.NewAddValidatorTx( - target.config.MinValidatorStake, // stake amount - newValidatorStartTime, // start time - newValidatorEndTime, // end time - newValidatorID, // node ID - rewardAddress, // Reward Address - reward.PercentDenominator, // Shares + target.config.MinValidatorStake, // stake amount + uint64(newValidatorStartTime.Unix()), // start time + uint64(newValidatorEndTime.Unix()), // end time + newValidatorID, // node ID + rewardAddress, // Reward Address + reward.PercentDenominator, // Shares []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, ) @@ -124,7 +124,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { staker, err := state.NewCurrentStaker( tx.ID(), addValTx, - addValTx.StartTime(), + newValidatorStartTime, 0, ) require.NoError(t, err) @@ -139,12 +139,12 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { // pending validator set with the maximum staking amount addMaxStakeValidator := func(target *environment) { tx, err := target.txBuilder.NewAddValidatorTx( - target.config.MaxValidatorStake, // stake amount - newValidatorStartTime, // start time - newValidatorEndTime, // end time - newValidatorID, // node ID - rewardAddress, // Reward Address - reward.PercentDenominator, // Shared + target.config.MaxValidatorStake, // stake amount + uint64(newValidatorStartTime.Unix()), // start time + uint64(newValidatorEndTime.Unix()), // end time + newValidatorID, // node ID + rewardAddress, // Reward Address + reward.PercentDenominator, // Shared []*secp256k1.PrivateKey{preFundedKeys[0]}, ids.ShortEmpty, ) @@ -154,7 +154,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { staker, err := state.NewCurrentStaker( tx.ID(), addValTx, - addValTx.StartTime(), + newValidatorStartTime, 0, ) require.NoError(t, err) @@ -165,14 +165,14 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { require.NoError(t, target.state.Commit()) } - dummyH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + dummyH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) currentTimestamp := dummyH.state.GetTimestamp() type test struct { description string stakeAmount uint64 - startTime uint64 - endTime uint64 + startTime time.Time + endTime time.Time nodeID ids.NodeID rewardAddress ids.ShortID feeKeys []*secp256k1.PrivateKey @@ -186,8 +186,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { { description: "validator stops validating earlier than delegator", stakeAmount: dummyH.config.MinDelegatorStake, - startTime: uint64(defaultValidateStartTime.Unix()) + 1, - endTime: uint64(defaultValidateEndTime.Unix()) + 1, + startTime: defaultValidateStartTime.Add(time.Second), + endTime: defaultValidateEndTime.Add(time.Second), nodeID: nodeID, rewardAddress: rewardAddress, feeKeys: []*secp256k1.PrivateKey{preFundedKeys[0]}, @@ -199,8 +199,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { { description: fmt.Sprintf("delegator should not be added more than (%s) in the future", MaxFutureStartTime), stakeAmount: dummyH.config.MinDelegatorStake, - startTime: uint64(currentTimestamp.Add(MaxFutureStartTime + time.Second).Unix()), - endTime: uint64(currentTimestamp.Add(MaxFutureStartTime + defaultMinStakingDuration + time.Second).Unix()), + startTime: currentTimestamp.Add(MaxFutureStartTime + time.Second), + endTime: currentTimestamp.Add(MaxFutureStartTime + defaultMinStakingDuration + time.Second), nodeID: nodeID, rewardAddress: rewardAddress, feeKeys: []*secp256k1.PrivateKey{preFundedKeys[0]}, @@ -212,8 +212,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { { description: "validator not in the current or pending validator sets", stakeAmount: dummyH.config.MinDelegatorStake, - startTime: uint64(defaultValidateStartTime.Add(5 * time.Second).Unix()), - endTime: uint64(defaultValidateEndTime.Add(-5 * time.Second).Unix()), + startTime: defaultValidateStartTime.Add(5 * time.Second), + endTime: defaultValidateEndTime.Add(-5 * time.Second), nodeID: newValidatorID, rewardAddress: rewardAddress, feeKeys: []*secp256k1.PrivateKey{preFundedKeys[0]}, @@ -225,7 +225,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { { description: "delegator starts before validator", stakeAmount: dummyH.config.MinDelegatorStake, - startTime: newValidatorStartTime - 1, // start validating subnet before primary network + startTime: newValidatorStartTime.Add(-1 * time.Second), // start validating subnet before primary network endTime: newValidatorEndTime, nodeID: newValidatorID, rewardAddress: rewardAddress, @@ -239,7 +239,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { description: "delegator stops before validator", stakeAmount: dummyH.config.MinDelegatorStake, startTime: newValidatorStartTime, - endTime: newValidatorEndTime + 1, // stop validating subnet after stopping validating primary network + endTime: newValidatorEndTime.Add(time.Second), // stop validating subnet after stopping validating primary network nodeID: newValidatorID, rewardAddress: rewardAddress, feeKeys: []*secp256k1.PrivateKey{preFundedKeys[0]}, @@ -264,8 +264,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { { description: "starts delegating at current timestamp", stakeAmount: dummyH.config.MinDelegatorStake, // weight - startTime: uint64(currentTimestamp.Unix()), // start time - endTime: uint64(defaultValidateEndTime.Unix()), // end time + startTime: currentTimestamp, // start time + endTime: defaultValidateEndTime, // end time nodeID: nodeID, // node ID rewardAddress: rewardAddress, // Reward Address feeKeys: []*secp256k1.PrivateKey{preFundedKeys[0]}, // tx fee payer @@ -276,12 +276,12 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { }, { description: "tx fee paying key has no funds", - stakeAmount: dummyH.config.MinDelegatorStake, // weight - startTime: uint64(defaultValidateStartTime.Unix()) + 1, // start time - endTime: uint64(defaultValidateEndTime.Unix()), // end time - nodeID: nodeID, // node ID - rewardAddress: rewardAddress, // Reward Address - feeKeys: []*secp256k1.PrivateKey{preFundedKeys[1]}, // tx fee payer + stakeAmount: dummyH.config.MinDelegatorStake, // weight + startTime: defaultValidateStartTime.Add(time.Second), // start time + endTime: defaultValidateEndTime, // end time + nodeID: nodeID, // node ID + rewardAddress: rewardAddress, // Reward Address + feeKeys: []*secp256k1.PrivateKey{preFundedKeys[1]}, // tx fee payer setup: func(target *environment) { // Remove all UTXOs owned by keys[1] utxoIDs, err := target.state.UTXOIDs( preFundedKeys[1].PublicKey().Address().Bytes(), @@ -330,7 +330,7 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { for _, tt := range tests { t.Run(tt.description, func(t *testing.T) { require := require.New(t) - freshTH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + freshTH := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) freshTH.config.ApricotPhase3Time = tt.AP3Time defer func() { require.NoError(shutdownEnvironment(freshTH)) @@ -338,8 +338,8 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { tx, err := freshTH.txBuilder.NewAddDelegatorTx( tt.stakeAmount, - tt.startTime, - tt.endTime, + uint64(tt.startTime.Unix()), + uint64(tt.endTime.Unix()), tt.nodeID, tt.rewardAddress, tt.feeKeys, @@ -378,14 +378,13 @@ func TestStandardTxExecutorAddDelegator(t *testing.T) { func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) }() nodeID := genesisNodeIDs[0] - env.config.BanffTime = env.state.GetTimestamp() { // Case: Proposed validator currently validating primary network @@ -806,9 +805,9 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { } } -func TestStandardTxExecutorAddValidator(t *testing.T) { +func TestStandardTxExecutorBanffAddValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -816,8 +815,6 @@ func TestStandardTxExecutorAddValidator(t *testing.T) { nodeID := ids.GenerateTestNodeID() - env.config.BanffTime = env.state.GetTimestamp() - { // Case: Validator's start time too early tx, err := env.txBuilder.NewAddValidatorTx( @@ -872,7 +869,7 @@ func TestStandardTxExecutorAddValidator(t *testing.T) { { // Case: Validator in current validator set of primary network - startTime := defaultGenesisTime.Add(1 * time.Second) + startTime := defaultValidateStartTime.Add(1 * time.Second) tx, err := env.txBuilder.NewAddValidatorTx( env.config.MinValidatorStake, // stake amount uint64(startTime.Unix()), // start time @@ -911,7 +908,7 @@ func TestStandardTxExecutorAddValidator(t *testing.T) { { // Case: Validator in pending validator set of primary network - startTime := defaultGenesisTime.Add(1 * time.Second) + startTime := defaultValidateStartTime.Add(1 * time.Second) tx, err := env.txBuilder.NewAddValidatorTx( env.config.MinValidatorStake, // stake amount uint64(startTime.Unix()), // start time @@ -947,7 +944,7 @@ func TestStandardTxExecutorAddValidator(t *testing.T) { { // Case: Validator doesn't have enough tokens to cover stake amount - startTime := defaultGenesisTime.Add(1 * time.Second) + startTime := defaultValidateStartTime.Add(1 * time.Second) tx, err := env.txBuilder.NewAddValidatorTx( // create the tx env.config.MinValidatorStake, uint64(startTime.Unix()), @@ -1044,13 +1041,13 @@ func newRemoveSubnetValidatorTx(t *testing.T) (*txs.RemoveSubnetValidatorTx, *tx // mock implementations that can be used in tests // for verifying RemoveSubnetValidatorTx. type removeSubnetValidatorTxVerifyEnv struct { - banffTime time.Time - fx *fx.MockFx - flowChecker *utxo.MockVerifier - unsignedTx *txs.RemoveSubnetValidatorTx - tx *txs.Tx - state *state.MockDiff - staker *state.Staker + latestForkTime time.Time + fx *fx.MockFx + flowChecker *utxo.MockVerifier + unsignedTx *txs.RemoveSubnetValidatorTx + tx *txs.Tx + state *state.MockDiff + staker *state.Staker } // Returns mock implementations that can be used in tests @@ -1064,12 +1061,12 @@ func newValidRemoveSubnetValidatorTxVerifyEnv(t *testing.T, ctrl *gomock.Control unsignedTx, tx := newRemoveSubnetValidatorTx(t) mockState := state.NewMockDiff(ctrl) return removeSubnetValidatorTxVerifyEnv{ - banffTime: now, - fx: mockFx, - flowChecker: mockFlowChecker, - unsignedTx: unsignedTx, - tx: tx, - state: mockState, + latestForkTime: now, + fx: mockFx, + flowChecker: mockFlowChecker, + unsignedTx: unsignedTx, + tx: tx, + state: mockState, staker: &state.Staker{ TxID: ids.GenerateTestID(), NodeID: ids.GenerateTestNodeID(), @@ -1105,7 +1102,9 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1130,7 +1129,9 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1155,7 +1156,9 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1183,7 +1186,9 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1209,7 +1214,9 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1234,7 +1241,9 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1261,7 +1270,9 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1291,7 +1302,9 @@ func TestStandardExecutorRemoveSubnetValidatorTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1395,13 +1408,13 @@ func newTransformSubnetTx(t *testing.T) (*txs.TransformSubnetTx, *txs.Tx) { // mock implementations that can be used in tests // for verifying TransformSubnetTx. type transformSubnetTxVerifyEnv struct { - banffTime time.Time - fx *fx.MockFx - flowChecker *utxo.MockVerifier - unsignedTx *txs.TransformSubnetTx - tx *txs.Tx - state *state.MockDiff - staker *state.Staker + latestForkTime time.Time + fx *fx.MockFx + flowChecker *utxo.MockVerifier + unsignedTx *txs.TransformSubnetTx + tx *txs.Tx + state *state.MockDiff + staker *state.Staker } // Returns mock implementations that can be used in tests @@ -1415,12 +1428,12 @@ func newValidTransformSubnetTxVerifyEnv(t *testing.T, ctrl *gomock.Controller) t unsignedTx, tx := newTransformSubnetTx(t) mockState := state.NewMockDiff(ctrl) return transformSubnetTxVerifyEnv{ - banffTime: now, - fx: mockFx, - flowChecker: mockFlowChecker, - unsignedTx: unsignedTx, - tx: tx, - state: mockState, + latestForkTime: now, + fx: mockFx, + flowChecker: mockFlowChecker, + unsignedTx: unsignedTx, + tx: tx, + state: mockState, staker: &state.Staker{ TxID: ids.GenerateTestID(), NodeID: ids.GenerateTestNodeID(), @@ -1446,7 +1459,9 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1470,7 +1485,9 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, }, Bootstrapped: &utils.Atomic[bool]{}, Fx: env.fx, @@ -1495,7 +1512,9 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, MaxStakeDuration: math.MaxInt64, }, Bootstrapped: &utils.Atomic[bool]{}, @@ -1526,7 +1545,9 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, MaxStakeDuration: math.MaxInt64, }, Bootstrapped: &utils.Atomic[bool]{}, @@ -1562,7 +1583,9 @@ func TestStandardExecutorTransformSubnetTx(t *testing.T) { e := &StandardTxExecutor{ Backend: &Backend{ Config: &config.Config{ - BanffTime: env.banffTime, + BanffTime: env.latestForkTime, + CortinaTime: env.latestForkTime, + DurangoTime: env.latestForkTime, MaxStakeDuration: math.MaxInt64, }, Bootstrapped: &utils.Atomic[bool]{}, diff --git a/vms/platformvm/txs/validator_test.go b/vms/platformvm/txs/validator_test.go index fbef50981a14..b51873ad4ee4 100644 --- a/vms/platformvm/txs/validator_test.go +++ b/vms/platformvm/txs/validator_test.go @@ -36,7 +36,7 @@ func TestBoundedBy(t *testing.T) { End: bEndTime, Wght: defaultWeight, } - require.False(BoundedBy(a.StartTime(), b.EndTime(), b.StartTime(), b.EndTime())) + require.False(BoundedBy(a.StartTime(), a.EndTime(), b.StartTime(), b.EndTime())) require.False(BoundedBy(b.StartTime(), b.EndTime(), a.StartTime(), a.EndTime())) // case 2: a starts, b starts, a finishes, b finishes diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 5b50c9895622..00290385a972 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -28,6 +28,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -45,7 +46,7 @@ import ( func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -167,7 +168,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { } func TestAddDelegatorTxHeapCorruption(t *testing.T) { - validatorStartTime := banffForkTime.Add(executor.SyncBound).Add(1 * time.Second) + validatorStartTime := latestForkTime.Add(executor.SyncBound).Add(1 * time.Second) validatorEndTime := validatorStartTime.Add(360 * 24 * time.Hour) validatorStake := defaultMaxValidatorStake / 5 @@ -205,7 +206,7 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, apricotPhase3) vm.ApricotPhase3Time = test.ap3Time vm.ctx.Lock.Lock() @@ -352,7 +353,9 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: banffForkTime, + BanffTime: latestForkTime, + CortinaTime: mockable.MaxTime, + DurangoTime: mockable.MaxTime, }} ctx := defaultContext(t) @@ -379,8 +382,8 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { vm.ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) // set time to post Banff fork - vm.clock.Set(banffForkTime.Add(time.Second)) - vm.state.SetTimestamp(banffForkTime.Add(time.Second)) + vm.clock.Set(latestForkTime.Add(time.Second)) + vm.state.SetTimestamp(latestForkTime.Add(time.Second)) key0 := keys[0] key1 := keys[1] @@ -463,7 +466,7 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { require := require.New(t) - vm, baseDB, mutableSharedMemory := defaultVM(t) + vm, baseDB, mutableSharedMemory := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -672,7 +675,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { require := require.New(t) - vm, baseDB, mutableSharedMemory := defaultVM(t) + vm, baseDB, mutableSharedMemory := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -988,7 +991,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -1116,7 +1119,7 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require := require.New(t) - validatorStartTime := banffForkTime.Add(executor.SyncBound).Add(1 * time.Second) + validatorStartTime := latestForkTime.Add(executor.SyncBound).Add(1 * time.Second) validatorEndTime := validatorStartTime.Add(360 * 24 * time.Hour) validatorStake := defaultMaxValidatorStake / 5 @@ -1128,7 +1131,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { delegator2EndTime := delegator2StartTime.Add(3 * defaultMinStakingDuration) delegator2Stake := defaultMaxValidatorStake - validatorStake - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { @@ -1210,10 +1213,10 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t *testing.T) { require := require.New(t) - validatorStartTime := banffForkTime.Add(executor.SyncBound).Add(1 * time.Second) + validatorStartTime := latestForkTime.Add(executor.SyncBound).Add(1 * time.Second) validatorEndTime := validatorStartTime.Add(360 * 24 * time.Hour) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { @@ -1328,10 +1331,10 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *testing.T) { require := require.New(t) - validatorStartTime := banffForkTime.Add(executor.SyncBound).Add(1 * time.Second) + validatorStartTime := latestForkTime.Add(executor.SyncBound).Add(1 * time.Second) validatorEndTime := validatorStartTime.Add(360 * 24 * time.Hour) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { @@ -1432,7 +1435,7 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { // setup require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -1714,7 +1717,7 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { // setup require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -1874,7 +1877,7 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { // setup require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -2085,7 +2088,7 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { // setup require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index a74e6266bd07..59df851a5bc3 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "errors" + "fmt" "testing" "time" @@ -47,6 +48,7 @@ import ( "github.com/ava-labs/avalanchego/utils/resource" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/timer" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -68,7 +70,19 @@ import ( txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" ) -const defaultWeight uint64 = 10000 +type activeFork uint8 + +const ( + apricotPhase3 activeFork = iota + apricotPhase5 + banffFork + cortinaFork + durangoFork + + latestFork activeFork = durangoFork + + defaultWeight uint64 = 10000 +) var ( defaultMinStakingDuration = 24 * time.Hour @@ -95,20 +109,17 @@ var ( // time that genesis validators stop validating defaultValidateEndTime = defaultValidateStartTime.Add(10 * defaultMinStakingDuration) - banffForkTime = defaultValidateEndTime.Add(-5 * defaultMinStakingDuration) + latestForkTime = defaultGenesisTime.Add(time.Second) // each key controls an address that has [defaultBalance] AVAX at genesis keys = secp256k1.TestKeys() // Node IDs of genesis validators. Initialized in init function - genesisNodeIDs []ids.NodeID - - defaultMinValidatorStake = 5 * units.MilliAvax - defaultMaxValidatorStake = 500 * units.MilliAvax + genesisNodeIDs []ids.NodeID defaultMinDelegatorStake = 1 * units.MilliAvax - - // amount all genesis validators have in defaultVM - defaultBalance = 100 * defaultMinValidatorStake + defaultMinValidatorStake = 5 * defaultMinDelegatorStake + defaultMaxValidatorStake = 100 * defaultMinValidatorStake + defaultBalance = 2 * defaultMaxValidatorStake // amount all genesis validators have in defaultVM // subnet that exists at genesis in defaultVM // Its controlKeys are keys[0], keys[1], keys[2] @@ -304,8 +315,37 @@ func BuildGenesisTestWithArgs(t *testing.T, args *api.BuildGenesisArgs) (*api.Bu return &buildGenesisArgs, genesisBytes } -func defaultVM(t *testing.T) (*VM, database.Database, *mutableSharedMemory) { +func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableSharedMemory) { require := require.New(t) + var ( + apricotPhase3Time = mockable.MaxTime + apricotPhase5Time = mockable.MaxTime + banffTime = mockable.MaxTime + cortinaTime = mockable.MaxTime + durangoTime = mockable.MaxTime + ) + + // always reset latestForkTime (a package level variable) + // to ensure test independence + latestForkTime = defaultGenesisTime.Add(time.Second) + switch fork { + case durangoFork: + durangoTime = latestForkTime + fallthrough + case cortinaFork: + cortinaTime = latestForkTime + fallthrough + case banffFork: + banffTime = latestForkTime + fallthrough + case apricotPhase5: + apricotPhase5Time = latestForkTime + fallthrough + case apricotPhase3: + apricotPhase3Time = latestForkTime + default: + require.NoError(fmt.Errorf("unhandled fork %d", fork)) + } vm := &VM{Config: config.Config{ Chains: chains.TestManager, @@ -322,16 +362,18 @@ func defaultVM(t *testing.T) (*VM, database.Database, *mutableSharedMemory) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - ApricotPhase3Time: defaultValidateEndTime, - ApricotPhase5Time: defaultValidateEndTime, - BanffTime: banffForkTime, + ApricotPhase3Time: apricotPhase3Time, + ApricotPhase5Time: apricotPhase5Time, + BanffTime: banffTime, + CortinaTime: cortinaTime, + DurangoTime: durangoTime, }} db := memdb.New() chainDB := prefixdb.New([]byte{0}, db) atomicDB := prefixdb.New([]byte{1}, db) - vm.clock.Set(banffForkTime.Add(time.Second)) + vm.clock.Set(latestForkTime) msgChan := make(chan common.Message, 1) ctx := defaultContext(t) @@ -362,6 +404,9 @@ func defaultVM(t *testing.T) (*VM, database.Database, *mutableSharedMemory) { appSender, )) + // align chain time and local clock + vm.state.SetTimestamp(vm.clock.Time()) + require.NoError(vm.SetState(context.Background(), snow.NormalOp)) // Create a subnet and store it in testSubnet1 @@ -389,7 +434,7 @@ func defaultVM(t *testing.T) (*VM, database.Database, *mutableSharedMemory) { // Ensure genesis state is parsed from bytes and stored correctly func TestGenesis(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -425,7 +470,7 @@ func TestGenesis(t *testing.T) { require.NoError(err) require.Equal(utxo.Address, addr) - require.Equal(uint64(utxo.Amount)-vm.TxFee, out.Amount()) + require.Equal(uint64(utxo.Amount)-vm.CreateSubnetTxFee, out.Amount()) } } @@ -445,17 +490,19 @@ func TestGenesis(t *testing.T) { // accept proposal to add validator to primary network func TestAddValidatorCommit(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) vm.ctx.Lock.Unlock() }() - startTime := vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) - endTime := startTime.Add(defaultMinStakingDuration) - nodeID := ids.GenerateTestNodeID() - rewardAddress := ids.GenerateTestShortID() + var ( + startTime = vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) + endTime = startTime.Add(defaultMinStakingDuration) + nodeID = ids.GenerateTestNodeID() + rewardAddress = ids.GenerateTestShortID() + ) // create valid tx tx, err := vm.txBuilder.NewAddValidatorTx( @@ -491,7 +538,7 @@ func TestAddValidatorCommit(t *testing.T) { // verify invalid attempt to add validator to primary network func TestInvalidAddValidatorCommit(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -544,17 +591,19 @@ func TestInvalidAddValidatorCommit(t *testing.T) { // Reject attempt to add validator to primary network func TestAddValidatorReject(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) vm.ctx.Lock.Unlock() }() - startTime := vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) - endTime := startTime.Add(defaultMinStakingDuration) - nodeID := ids.GenerateTestNodeID() - rewardAddress := ids.GenerateTestShortID() + var ( + startTime = vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) + endTime = startTime.Add(defaultMinStakingDuration) + nodeID = ids.GenerateTestNodeID() + rewardAddress = ids.GenerateTestShortID() + ) // create valid tx tx, err := vm.txBuilder.NewAddValidatorTx( @@ -588,7 +637,7 @@ func TestAddValidatorReject(t *testing.T) { // Reject proposal to add validator to primary network func TestAddValidatorInvalidNotReissued(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -598,7 +647,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { // Use nodeID that is already in the genesis repeatNodeID := genesisNodeIDs[0] - startTime := banffForkTime.Add(txexecutor.SyncBound).Add(1 * time.Second) + startTime := latestForkTime.Add(txexecutor.SyncBound).Add(1 * time.Second) endTime := startTime.Add(defaultMinStakingDuration) // create valid tx @@ -622,16 +671,18 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { // Accept proposal to add validator to subnet func TestAddSubnetValidatorAccept(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) vm.ctx.Lock.Unlock() }() - startTime := vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) - endTime := startTime.Add(defaultMinStakingDuration) - nodeID := genesisNodeIDs[0] + var ( + startTime = vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) + endTime = startTime.Add(defaultMinStakingDuration) + nodeID = genesisNodeIDs[0] + ) // create valid tx // note that [startTime, endTime] is a subset of time that keys[0] @@ -668,16 +719,18 @@ func TestAddSubnetValidatorAccept(t *testing.T) { // Reject proposal to add validator to subnet func TestAddSubnetValidatorReject(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) vm.ctx.Lock.Unlock() }() - startTime := vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) - endTime := startTime.Add(defaultMinStakingDuration) - nodeID := genesisNodeIDs[0] + var ( + startTime = vm.clock.Time().Add(txexecutor.SyncBound).Add(1 * time.Second) + endTime = startTime.Add(defaultMinStakingDuration) + nodeID = genesisNodeIDs[0] + ) // create valid tx // note that [startTime, endTime] is a subset of time that keys[0] @@ -713,7 +766,7 @@ func TestAddSubnetValidatorReject(t *testing.T) { // Test case where primary network validator rewarded func TestRewardValidatorAccept(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -784,7 +837,7 @@ func TestRewardValidatorAccept(t *testing.T) { // Test case where primary network validator not rewarded func TestRewardValidatorReject(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -857,7 +910,7 @@ func TestRewardValidatorReject(t *testing.T) { // Ensure BuildBlock errors when there is no block to build func TestUnneededBuildBlock(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -870,7 +923,7 @@ func TestUnneededBuildBlock(t *testing.T) { // test acceptance of proposal to create a new chain func TestCreateChain(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -921,7 +974,7 @@ func TestCreateChain(t *testing.T) { // 4) Advance timestamp to validator's end time (removing validator from current) func TestCreateSubnet(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -942,7 +995,7 @@ func TestCreateSubnet(t *testing.T) { require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) - // should contain proposal to create subnet + // should contain the CreateSubnetTx blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -1031,7 +1084,7 @@ func TestCreateSubnet(t *testing.T) { // test asset import func TestAtomicImport(t *testing.T) { require := require.New(t) - vm, baseDB, mutableSharedMemory := defaultVM(t) + vm, baseDB, mutableSharedMemory := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -1118,7 +1171,7 @@ func TestAtomicImport(t *testing.T) { // test optimistic asset import func TestOptimisticAtomicImport(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, apricotPhase3) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -1189,7 +1242,9 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: banffForkTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, }} firstCtx := defaultContext(t) @@ -1199,7 +1254,7 @@ func TestRestartFullyAccepted(t *testing.T) { m := atomic.NewMemory(atomicDB) firstCtx.SharedMemory = m.NewSharedMemory(firstCtx.ChainID) - initialClkTime := banffForkTime.Add(time.Second) + initialClkTime := latestForkTime.Add(time.Second) firstVM.clock.Set(initialClkTime) firstCtx.Lock.Lock() @@ -1272,7 +1327,9 @@ func TestRestartFullyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: banffForkTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, }} secondCtx := defaultContext(t) @@ -1322,10 +1379,12 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: banffForkTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, }} - initialClkTime := banffForkTime.Add(time.Second) + initialClkTime := latestForkTime.Add(time.Second) vm.clock.Set(initialClkTime) ctx := defaultContext(t) @@ -1661,10 +1720,12 @@ func TestUnverifiedParent(t *testing.T) { MinStakeDuration: defaultMinStakingDuration, MaxStakeDuration: defaultMaxStakingDuration, RewardConfig: defaultRewardConfig, - BanffTime: banffForkTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, }} - initialClkTime := banffForkTime.Add(time.Second) + initialClkTime := latestForkTime.Add(time.Second) vm.clock.Set(initialClkTime) ctx := defaultContext(t) ctx.Lock.Lock() @@ -1758,7 +1819,7 @@ func TestUnverifiedParent(t *testing.T) { } func TestMaxStakeAmount(t *testing.T) { - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(t, vm.Shutdown(context.Background())) @@ -1809,6 +1870,7 @@ func TestMaxStakeAmount(t *testing.T) { func TestUptimeDisallowedWithRestart(t *testing.T) { require := require.New(t) + latestForkTime = defaultValidateStartTime.Add(defaultMinStakingDuration) _, genesisBytes := defaultGenesis(t) db := memdb.New() @@ -1820,7 +1882,9 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: banffForkTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, }} firstCtx := defaultContext(t) @@ -1839,7 +1903,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { nil, )) - initialClkTime := defaultValidateStartTime + initialClkTime := latestForkTime.Add(time.Second) firstVM.clock.Set(initialClkTime) // Set VM state to NormalOp, to start tracking validators' uptime @@ -1848,7 +1912,8 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { // Fast forward clock so that validators meet 20% uptime required for reward durationForReward := defaultValidateEndTime.Sub(defaultValidateStartTime) * firstUptimePercentage / 100 - firstVM.clock.Set(defaultValidateStartTime.Add(durationForReward)) + vmStopTime := defaultValidateStartTime.Add(durationForReward) + firstVM.clock.Set(vmStopTime) // Shutdown VM to stop all genesis validator uptime. // At this point they have been validating for the 20% uptime needed to be rewarded @@ -1863,7 +1928,9 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { UptimePercentage: secondUptimePercentage / 100., Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: banffForkTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, }} secondCtx := defaultContext(t) @@ -1890,8 +1957,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { nil, )) - // set clock to the time we switched firstVM off - secondVM.clock.Set(defaultValidateStartTime.Add(durationForReward)) + secondVM.clock.Set(vmStopTime) // Set VM state to NormalOp, to start tracking validators' uptime require.NoError(secondVM.SetState(context.Background(), snow.Bootstrapping)) @@ -1951,6 +2017,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { require := require.New(t) + latestForkTime = defaultValidateStartTime.Add(defaultMinStakingDuration) _, genesisBytes := defaultGenesis(t) db := memdb.New() @@ -1960,7 +2027,9 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { RewardConfig: defaultRewardConfig, Validators: validators.NewManager(), UptimeLockedCalculator: uptime.NewLockedCalculator(), - BanffTime: banffForkTime, + BanffTime: latestForkTime, + CortinaTime: latestForkTime, + DurangoTime: latestForkTime, }} ctx := defaultContext(t) @@ -1989,7 +2058,7 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { ctx.Lock.Unlock() }() - initialClkTime := defaultValidateStartTime + initialClkTime := latestForkTime.Add(time.Second) vm.clock.Set(initialClkTime) // Set VM state to NormalOp, to start tracking validators' uptime @@ -2051,10 +2120,10 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { require := require.New(t) - validatorStartTime := banffForkTime.Add(txexecutor.SyncBound).Add(1 * time.Second) + validatorStartTime := latestForkTime.Add(txexecutor.SyncBound).Add(1 * time.Second) validatorEndTime := validatorStartTime.Add(360 * 24 * time.Hour) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { @@ -2150,7 +2219,7 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { func TestTransferSubnetOwnershipTx(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -2225,7 +2294,7 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { func TestBaseTx(t *testing.T) { require := require.New(t) - vm, _, _ := defaultVM(t) + vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) From 83c95a5464d2af6ba374c6c66c0119dce94fd32a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 15 Dec 2023 19:02:29 -0700 Subject: [PATCH 158/267] ProposerVM Extend windows 2- extend windowing (#2401) Co-authored-by: Stephen Buttolph --- chains/manager.go | 2 + scripts/mocks.mockgen.txt | 1 + snow/validators/test_state.go | 2 +- utils/sampler/rand_test.go | 20 ++ vms/proposervm/batched_vm_test.go | 55 ++- vms/proposervm/block.go | 176 ++++++++-- vms/proposervm/block_test.go | 104 +++++- vms/proposervm/config.go | 7 + vms/proposervm/post_fork_block_test.go | 220 ++++++++++-- vms/proposervm/post_fork_option_test.go | 40 ++- vms/proposervm/pre_fork_block_test.go | 60 +++- vms/proposervm/proposer/mock_windower.go | 30 ++ vms/proposervm/proposer/windower.go | 214 +++++++++--- vms/proposervm/proposer/windower_test.go | 382 +++++++++++++++++---- vms/proposervm/scheduler/mock_scheduler.go | 74 ++++ vms/proposervm/state_syncable_vm_test.go | 9 +- vms/proposervm/vm.go | 83 ++++- vms/proposervm/vm_byzantine_test.go | 38 +- vms/proposervm/vm_regression_test.go | 3 +- vms/proposervm/vm_test.go | 178 ++++++++-- 20 files changed, 1445 insertions(+), 253 deletions(-) create mode 100644 vms/proposervm/scheduler/mock_scheduler.go diff --git a/chains/manager.go b/chains/manager.go index 86da6811c41a..43160e136f7c 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -771,6 +771,7 @@ func (m *manager) createAvalancheChain( vmWrappedInsideProposerVM, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, + DurangoTime: version.GetDurangoTime(m.NetworkID), MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, @@ -1116,6 +1117,7 @@ func (m *manager) createSnowmanChain( vm, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, + DurangoTime: version.GetDurangoTime(m.NetworkID), MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 714c3b5932e4..97b0eb8f799e 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -37,6 +37,7 @@ github.com/ava-labs/avalanchego/vms/platformvm/txs/builder=Builder=vms/platformv github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool=Mempool=vms/platformvm/txs/mempool/mock_mempool.go github.com/ava-labs/avalanchego/vms/platformvm/utxo=Verifier=vms/platformvm/utxo/mock_verifier.go github.com/ava-labs/avalanchego/vms/proposervm/proposer=Windower=vms/proposervm/proposer/mock_windower.go +github.com/ava-labs/avalanchego/vms/proposervm/scheduler=Scheduler=vms/proposervm/scheduler/mock_scheduler.go github.com/ava-labs/avalanchego/vms/proposervm/state=State=vms/proposervm/state/mock_state.go github.com/ava-labs/avalanchego/vms/proposervm=PostForkBlock=vms/proposervm/mock_post_fork_block.go github.com/ava-labs/avalanchego/vms/registry=VMGetter=vms/registry/mock_vm_getter.go diff --git a/snow/validators/test_state.go b/snow/validators/test_state.go index b27e6d972613..eb6af391a1d8 100644 --- a/snow/validators/test_state.go +++ b/snow/validators/test_state.go @@ -23,7 +23,7 @@ var ( var _ State = (*TestState)(nil) type TestState struct { - T *testing.T + T testing.TB CantGetMinimumHeight, CantGetCurrentHeight, diff --git a/utils/sampler/rand_test.go b/utils/sampler/rand_test.go index 362093a695ac..e822d5876cbf 100644 --- a/utils/sampler/rand_test.go +++ b/utils/sampler/rand_test.go @@ -12,6 +12,8 @@ import ( "github.com/stretchr/testify/require" "github.com/thepudds/fzgen/fuzzer" + + "gonum.org/v1/gonum/mathext/prng" ) type testSource struct { @@ -208,3 +210,21 @@ func FuzzRNG(f *testing.F) { require.Len(stdSource.nums, len(source.nums)) }) } + +func BenchmarkSeed32(b *testing.B) { + source := prng.NewMT19937() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + source.Seed(0) + } +} + +func BenchmarkSeed64(b *testing.B) { + source := prng.NewMT19937_64() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + source.Seed(0) + } +} diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index b95a321f9ddf..9934e8f13811 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -23,13 +23,16 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/timer/mockable" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) func TestCoreVMNotRemote(t *testing.T) { // if coreVM is not remote VM, a specific error is returned require := require.New(t) - _, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -54,7 +57,11 @@ func TestCoreVMNotRemote(t *testing.T) { func TestGetAncestorsPreForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -200,7 +207,11 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { func TestGetAncestorsPostForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -224,7 +235,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk1.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk1.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk1, 0)) coreBlk2 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -244,7 +255,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk2.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk2.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk2, 0)) coreBlk3 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -355,10 +366,12 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { preForkTime = currentTime.Add(5 * time.Minute) forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) + + durangoTime = forkTime ) // enable ProBlks in next future - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -442,7 +455,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { // prepare build of next block require.NoError(builtBlk3.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk3.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk3, builtBlk3.(*postForkBlock).PChainHeight())) coreBlk4 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -556,7 +569,11 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { func TestBatchedParseBlockPreForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -674,7 +691,11 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -698,7 +719,7 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk1.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk1.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk1, 0)) coreBlk2 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -718,7 +739,7 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk2.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk2.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk2, builtBlk2.(*postForkBlock).PChainHeight())) coreBlk3 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -786,10 +807,12 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { preForkTime = currentTime.Add(5 * time.Minute) forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) + + durangoTime = forkTime ) // enable ProBlks in next future - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -873,7 +896,7 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { // prepare build of next block require.NoError(builtBlk3.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk3.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk3, builtBlk3.(*postForkBlock).PChainHeight())) coreBlk4 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -949,7 +972,8 @@ type TestRemoteProposerVM struct { func initTestRemoteProposerVM( t *testing.T, - activationTime time.Time, + activationTime, + durangoTime time.Time, ) ( TestRemoteProposerVM, *VM, @@ -1015,6 +1039,7 @@ func initTestRemoteProposerVM( coreVM, Config{ ActivationTime: activationTime, + DurangoTime: durangoTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index fdea5464edb8..94969a048caa 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -35,6 +35,7 @@ var ( errPChainHeightNotReached = errors.New("block P-chain height larger than current P-chain height") errTimeTooAdvanced = errors.New("time is too far advanced") errProposerWindowNotStarted = errors.New("proposer window hasn't started") + errUnexpectedProposer = errors.New("unexpected proposer for current window") errProposersNotActivated = errors.New("proposers haven't been activated yet") errPChainHeightTooLow = errors.New("block P-chain height is too low") ) @@ -141,13 +142,23 @@ func (p *postForkCommonComponents) Verify( ) } - delay, err := p.verifyBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) - if err != nil { - return err + // After Durango, we never allow unsigned blocks. + shouldHaveProposer := true + if p.vm.IsDurangoActivated(parentTimestamp) { + err := p.verifyPostDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) + if err != nil { + return err + } + } else { + delay, err := p.verifyPreDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) + if err != nil { + return err + } + + shouldHaveProposer = delay < proposer.MaxVerifyDelay } // Verify the signature of the node - shouldHaveProposer := delay < proposer.MaxVerifyDelay if err := child.SignedBlock.Verify(shouldHaveProposer, p.vm.ctx.ChainID); err != nil { return err } @@ -193,13 +204,25 @@ func (p *postForkCommonComponents) buildChild( return nil, err } - shouldBuildUnsignedBlock, err := p.shouldBuildUnsignedBlock( - ctx, - parentID, - parentTimestamp, - parentPChainHeight, - newTimestamp, - ) + // After Durango, we never allow unsigned blocks. + shouldBuildUnsignedBlock := false + if p.vm.IsDurangoActivated(parentTimestamp) { + err = p.shouldBuildBlockPostDurango( + ctx, + parentID, + parentTimestamp, + parentPChainHeight, + newTimestamp, + ) + } else { + shouldBuildUnsignedBlock, err = p.shouldBuildUnsignedBlockPreDurango( + ctx, + parentID, + parentTimestamp, + parentPChainHeight, + newTimestamp, + ) + } if err != nil { return nil, err } @@ -304,7 +327,7 @@ func verifyIsNotOracleBlock(ctx context.Context, b snowman.Block) error { } } -func (p *postForkCommonComponents) verifyBlockDelay( +func (p *postForkCommonComponents) verifyPreDurangoBlockDelay( ctx context.Context, parentTimestamp time.Time, parentPChainHeight uint64, @@ -315,8 +338,19 @@ func (p *postForkCommonComponents) verifyBlockDelay( childHeight = blk.Height() proposerID = blk.Proposer() ) - minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) + minDelay, err := p.vm.Windower.Delay( + ctx, + childHeight, + parentPChainHeight, + proposerID, + proposer.MaxVerifyWindows, + ) if err != nil { + p.vm.ctx.Log.Error("unexpected block verification failure", + zap.String("reason", "failed to calculate required timestamp delay"), + zap.Stringer("blkID", blk.ID()), + zap.Error(err), + ) return 0, err } @@ -328,7 +362,105 @@ func (p *postForkCommonComponents) verifyBlockDelay( return delay, nil } -func (p *postForkCommonComponents) shouldBuildUnsignedBlock( +func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( + ctx context.Context, + parentTimestamp time.Time, + parentPChainHeight uint64, + blk *postForkBlock, +) error { + var ( + blkTimestamp = blk.Timestamp() + blkHeight = blk.Height() + proposerID = blk.Proposer() + ) + + expectedProposerID, err := p.vm.Windower.ExpectedProposer( + ctx, + blkHeight, + parentPChainHeight, + proposer.TimeToSlot(parentTimestamp, blkTimestamp), + ) + if err != nil { + p.vm.ctx.Log.Error("unexpected block verification failure", + zap.String("reason", "failed to calculate expected proposer"), + zap.Stringer("blkID", blk.ID()), + zap.Error(err), + ) + return err + } + if expectedProposerID != proposerID { + return errUnexpectedProposer + } + + return nil +} + +func (p *postForkCommonComponents) shouldBuildBlockPostDurango( + ctx context.Context, + parentID ids.ID, + parentTimestamp time.Time, + parentPChainHeight uint64, + newTimestamp time.Time, +) error { + parentHeight := p.innerBlk.Height() + currentSlot := proposer.TimeToSlot(parentTimestamp, newTimestamp) + expectedProposerID, err := p.vm.Windower.ExpectedProposer( + ctx, + parentHeight+1, + parentPChainHeight, + currentSlot, + ) + if err != nil { + p.vm.ctx.Log.Error("unexpected build block failure", + zap.String("reason", "failed to calculate expected proposer"), + zap.Stringer("parentID", parentID), + zap.Error(err), + ) + return err + } + if expectedProposerID == p.vm.ctx.NodeID { + return nil + } + + // It's not our turn to propose a block yet. This is likely caused by having + // previously notified the consensus engine to attempt to build a block on + // top of a block that is no longer the preferred block. + p.vm.ctx.Log.Debug("build block dropped", + zap.Time("parentTimestamp", parentTimestamp), + zap.Time("blockTimestamp", newTimestamp), + zap.Uint64("slot", currentSlot), + zap.Stringer("expectedProposer", expectedProposerID), + ) + + // We need to reschedule the block builder to the next time we can try to + // build a block. + // + // TODO: After Durango activates, restructure this logic to separate + // updating the scheduler from verifying the proposerID. + nextStartTime, err := p.vm.getPostDurangoSlotTime( + ctx, + parentHeight+1, + parentPChainHeight, + currentSlot+1, // We know we aren't the proposer for the current slot + parentTimestamp, + ) + if err != nil { + p.vm.ctx.Log.Error("failed to reset block builder scheduler", + zap.String("reason", "failed to calculate expected proposer"), + zap.Stringer("parentID", parentID), + zap.Error(err), + ) + return err + } + p.vm.Scheduler.SetBuildBlockTime(nextStartTime) + + // In case the inner VM only issued one pendingTxs message, we should + // attempt to re-handle that once it is our turn to build the block. + p.vm.notifyInnerBlockReady() + return errProposerWindowNotStarted +} + +func (p *postForkCommonComponents) shouldBuildUnsignedBlockPreDurango( ctx context.Context, parentID ids.ID, parentTimestamp time.Time, @@ -354,24 +486,22 @@ func (p *postForkCommonComponents) shouldBuildUnsignedBlock( } if delay >= minDelay { - // it's time for this node to propose a block. It'll be signed or unsigned - // depending on the delay + // it's time for this node to propose a block. It'll be signed or + // unsigned depending on the delay return delay >= proposer.MaxVerifyDelay, nil } - // It's not our turn to propose a block yet. This is likely caused - // by having previously notified the consensus engine to attempt to - // build a block on top of a block that is no longer the preferred - // block. + // It's not our turn to propose a block yet. This is likely caused by having + // previously notified the consensus engine to attempt to build a block on + // top of a block that is no longer the preferred block. p.vm.ctx.Log.Debug("build block dropped", zap.Time("parentTimestamp", parentTimestamp), zap.Duration("minDelay", minDelay), zap.Time("blockTimestamp", newTimestamp), ) - // In case the inner VM only issued one pendingTxs message, we - // should attempt to re-handle that once it is our turn to build the - // block. + // In case the inner VM only issued one pendingTxs message, we should + // attempt to re-handle that once it is our turn to build the block. p.vm.notifyInnerBlockReady() return false, errProposerWindowNotStarted } diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 35bd959a6679..8297e3681b2c 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -25,7 +25,9 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" + "github.com/ava-labs/avalanchego/vms/proposervm/scheduler" ) // Assert that when the underlying VM implements ChainVMWithBuildBlockContext @@ -37,15 +39,17 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { ctrl := gomock.NewController(t) var ( + nodeID = ids.GenerateTestNodeID() pChainHeight uint64 = 1337 parentID = ids.GenerateTestID() parentTimestamp = time.Now().Truncate(time.Second) + parentHeight uint64 = 1234 blkID = ids.GenerateTestID() ) innerBlk := snowman.NewMockBlock(ctrl) innerBlk.EXPECT().ID().Return(blkID).AnyTimes() - innerBlk.EXPECT().Height().Return(pChainHeight - 1).AnyTimes() + innerBlk.EXPECT().Height().Return(parentHeight + 1).AnyTimes() builtBlk := snowman.NewMockBlock(ctrl) builtBlk.EXPECT().Bytes().Return([]byte{1, 2, 3}).AnyTimes() @@ -62,19 +66,21 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() windower := proposer.NewMockWindower(ctrl) - windower.EXPECT().Delay(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(time.Duration(0), nil).AnyTimes() + windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nodeID, nil).AnyTimes() pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) vm := &VM{ Config: Config{ ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, ChainVM: innerVM, blockBuilderVM: innerBlockBuilderVM, ctx: &snow.Context{ + NodeID: nodeID, ValidatorState: vdrState, Log: logging.NoLog{}, }, @@ -97,11 +103,15 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require.Equal(builtBlk, gotChild.(*postForkBlock).innerBlk) } -func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { +func TestPreDurangoValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() @@ -230,11 +240,15 @@ func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { } } -func TestNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { +func TestPreDurangoNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() @@ -358,3 +372,81 @@ func TestNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require.Equal(ids.EmptyNodeID, childBlk.(*postForkBlock).Proposer()) // unsigned so no proposer } } + +// We consider cases where this node is not current proposer (may be scheduled in the next future or not). +// We check that scheduler is called nonetheless, to be able to process innerVM block requests +func TestPostDurangoBuildChildResetScheduler(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + var ( + thisNodeID = ids.GenerateTestNodeID() + selectedProposer = ids.GenerateTestNodeID() + pChainHeight uint64 = 1337 + parentID = ids.GenerateTestID() + parentTimestamp = time.Now().Truncate(time.Second) + now = parentTimestamp.Add(12 * time.Second) + parentHeight uint64 = 1234 + ) + + innerBlk := snowman.NewMockBlock(ctrl) + innerBlk.EXPECT().Height().Return(parentHeight + 1).AnyTimes() + + vdrState := validators.NewMockState(ctrl) + vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() + + windower := proposer.NewMockWindower(ctrl) + windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(selectedProposer, nil).AnyTimes() // return a proposer different from thisNode, to check whether scheduler is reset + + scheduler := scheduler.NewMockScheduler(ctrl) + + pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(err) + vm := &VM{ + Config: Config{ + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), + StakingCertLeaf: &staking.Certificate{}, + StakingLeafSigner: pk, + }, + ChainVM: mocks.NewMockChainVM(ctrl), + ctx: &snow.Context{ + NodeID: thisNodeID, + ValidatorState: vdrState, + Log: logging.NoLog{}, + }, + Windower: windower, + Scheduler: scheduler, + } + vm.Clock.Set(now) + + blk := &postForkCommonComponents{ + innerBlk: innerBlk, + vm: vm, + } + + delays := []time.Duration{ + proposer.MaxLookAheadWindow - time.Minute, + proposer.MaxLookAheadWindow, + proposer.MaxLookAheadWindow + time.Minute, + } + + for _, delay := range delays { + windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(delay, nil).Times(1) + + // we mock the scheduler setting the exact time we expect it to be reset + // to + expectedSchedulerTime := parentTimestamp.Add(delay) + scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).Times(1) + + _, err = blk.buildChild( + context.Background(), + parentID, + parentTimestamp, + pChainHeight-1, + ) + require.ErrorIs(err, errProposerWindowNotStarted) + } +} diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go index 96645c9489a8..6e4ed9576925 100644 --- a/vms/proposervm/config.go +++ b/vms/proposervm/config.go @@ -14,6 +14,9 @@ type Config struct { // Time at which proposerVM activates its congestion control mechanism ActivationTime time.Time + // Durango fork activation time + DurangoTime time.Time + // Minimal P-chain height referenced upon block building MinimumPChainHeight uint64 @@ -30,3 +33,7 @@ type Config struct { // Block certificate StakingCertLeaf *staking.Certificate } + +func (c *Config) IsDurangoActivated(timestamp time.Time) bool { + return !timestamp.Before(c.DurangoTime) +} diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index c0b3850b243f..4e4a35bf0761 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -39,7 +40,11 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { require.Equal(snowman.ErrNotOracle, err) // setup - _, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -92,10 +97,14 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { } // ProposerBlock.Verify tests section -func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { +func TestBlockVerify_PostForkBlock_PreDurango_ParentChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime // pre Durango + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -192,10 +201,123 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { } } +func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { + require := require.New(t) + + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime // post Durango + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + defer func() { + require.NoError(proVM.Shutdown(context.Background())) + }() + + pChainHeight := uint64(100) + valState.GetCurrentHeightF = func(context.Context) (uint64, error) { + return pChainHeight, nil + } + + parentCoreBlk := &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: ids.Empty.Prefix(1111), + StatusV: choices.Processing, + }, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + } + coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { + return parentCoreBlk, nil + } + coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { + switch blkID { + case coreGenBlk.ID(): + return coreGenBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil + default: + return nil, database.ErrNotFound + } + } + coreVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { + switch { + case bytes.Equal(b, coreGenBlk.Bytes()): + return coreGenBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil + default: + return nil, errUnknownBlock + } + } + + parentBlk, err := proVM.BuildBlock(context.Background()) + require.NoError(err) + + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) + + childCoreBlk := &snowman.TestBlock{ + ParentV: parentCoreBlk.ID(), + BytesV: []byte{2}, + HeightV: parentCoreBlk.Height() + 1, + } + childBlk := postForkBlock{ + postForkCommonComponents: postForkCommonComponents{ + vm: proVM, + innerBlk: childCoreBlk, + status: choices.Processing, + }, + } + + require.NoError(waitForProposerWindow(proVM, parentBlk, parentBlk.(*postForkBlock).PChainHeight())) + + { + // child block referring unknown parent does not verify + childSlb, err := block.Build( + ids.Empty, // refer unknown parent + proVM.Time(), + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, database.ErrNotFound) + } + + { + // child block referring known parent does verify + childSlb, err := block.Build( + parentBlk.ID(), + proVM.Time(), + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + + require.NoError(err) + childBlk.SignedBlock = childSlb + + proVM.Set(childSlb.Timestamp()) + require.NoError(childBlk.Verify(context.Background())) + } +} + func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -412,7 +534,11 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -467,10 +593,8 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { // set VM to be ready to build next block. We set it to generate unsigned blocks // for simplicity. - nextTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) - proVM.Set(nextTime) - parentBlkPChainHeight := parentBlk.(*postForkBlock).PChainHeight() + require.NoError(waitForProposerWindow(proVM, parentBlk, parentBlkPChainHeight)) childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -478,6 +602,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { StatusV: choices.Processing, }, ParentV: parentCoreBlk.ID(), + HeightV: parentBlk.Height() + 1, BytesV: []byte{2}, } childBlk := postForkBlock{ @@ -490,11 +615,14 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { { // child P-Chain height must not precede parent P-Chain height - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - nextTime, + proVM.Time(), parentBlkPChainHeight-1, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) require.NoError(err) childBlk.SignedBlock = childSlb @@ -505,11 +633,14 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { { // child P-Chain height can be equal to parent P-Chain height - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - nextTime, + proVM.Time(), parentBlkPChainHeight, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) require.NoError(err) childBlk.SignedBlock = childSlb @@ -519,11 +650,14 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { { // child P-Chain height may follow parent P-Chain height - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - nextTime, - parentBlkPChainHeight+1, + proVM.Time(), + parentBlkPChainHeight, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) require.NoError(err) childBlk.SignedBlock = childSlb @@ -534,11 +668,14 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) { // block P-Chain height can be equal to current P-Chain height - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - nextTime, + proVM.Time(), currPChainHeight, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) require.NoError(err) childBlk.SignedBlock = childSlb @@ -548,11 +685,14 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { { // block P-Chain height cannot be at higher than current P-Chain height - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - nextTime, + proVM.Time(), currPChainHeight*2, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) require.NoError(err) childBlk.SignedBlock = childSlb @@ -565,7 +705,11 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -761,7 +905,11 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify a block once (in this test by building it). // Show that other verify call would not call coreBlk.Verify() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -824,7 +972,11 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) // setup - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -887,7 +1039,11 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -934,7 +1090,11 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -966,7 +1126,11 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1080,7 +1244,11 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 5) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 5) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index febecc1843d0..26000f59ba33 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -36,7 +36,11 @@ func (tob TestOptionsBlock) Options(context.Context) ([2]snowman.Block, error) { func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -138,6 +142,7 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return childCoreBlk, nil } + require.NoError(waitForProposerWindow(proVM, opts[0], postForkOracleBlk.PChainHeight())) proChild, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -150,7 +155,11 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { require := require.New(t) // Verify an option once; then show that another verify call would not call coreBlk.Verify() - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -251,7 +260,11 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -360,7 +373,11 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -461,7 +478,11 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { require := require.New(t) // Verify an option once; then show that another verify call would not call coreBlk.Verify() - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -545,7 +566,11 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { func TestOptionTimestampValidity(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoTime, 0) coreOracleBlkID := ids.GenerateTestID() coreOracleBlk := &TestOptionsBlock{ @@ -653,7 +678,8 @@ func TestOptionTimestampValidity(t *testing.T) { proVM = New( coreVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 35efbbaeaaa4..42dfe14789f5 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -50,7 +50,11 @@ func TestOracle_PreForkBlkImplementsInterface(t *testing.T) { func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -138,8 +142,11 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -232,8 +239,11 @@ func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -308,8 +318,11 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -439,8 +452,11 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { func TestBlockVerify_BlocksBuiltOnPostForkGenesis(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(-1 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(-1 * time.Second) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(activationTime) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -481,7 +497,11 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) // setup - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -539,7 +559,11 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -570,8 +594,11 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -661,8 +688,11 @@ func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index 3e7375326429..7df10ee28bcf 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -54,6 +54,36 @@ func (mr *MockWindowerMockRecorder) Delay(arg0, arg1, arg2, arg3, arg4 interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delay", reflect.TypeOf((*MockWindower)(nil).Delay), arg0, arg1, arg2, arg3, arg4) } +// ExpectedProposer mocks base method. +func (m *MockWindower) ExpectedProposer(arg0 context.Context, arg1, arg2, arg3 uint64) (ids.NodeID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExpectedProposer", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(ids.NodeID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExpectedProposer indicates an expected call of ExpectedProposer. +func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExpectedProposer", reflect.TypeOf((*MockWindower)(nil).ExpectedProposer), arg0, arg1, arg2, arg3) +} + +// MinDelayForProposer mocks base method. +func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint64, arg3 ids.NodeID, arg4 uint64) (time.Duration, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MinDelayForProposer", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(time.Duration) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MinDelayForProposer indicates an expected call of MinDelayForProposer. +func (mr *MockWindowerMockRecorder) MinDelayForProposer(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinDelayForProposer", reflect.TypeOf((*MockWindower)(nil).MinDelayForProposer), arg0, arg1, arg2, arg3, arg4) +} + // Proposers mocks base method. func (m *MockWindower) Proposers(arg0 context.Context, arg1, arg2 uint64, arg3 int) ([]ids.NodeID, error) { m.ctrl.T.Helper() diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 9abfbcfd60d4..6903db785e29 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -5,6 +5,9 @@ package proposer import ( "context" + "errors" + "fmt" + "math/bits" "time" "gonum.org/v1/gonum/mathext/prng" @@ -26,31 +29,66 @@ const ( MaxBuildWindows = 60 MaxBuildDelay = MaxBuildWindows * WindowDuration // 5 minutes + + MaxLookAheadSlots = 720 + MaxLookAheadWindow = MaxLookAheadSlots * WindowDuration // 1 hour ) -var _ Windower = (*windower)(nil) +var ( + _ Windower = (*windower)(nil) + + ErrNoProposersAvailable = errors.New("no proposers available") +) type Windower interface { - // Proposers returns the proposer list for building a block at [chainHeight] + // Proposers returns the proposer list for building a block at [blockHeight] // when the validator set is defined at [pChainHeight]. The list is returned // in order. The minimum delay of a validator is the index they appear times // [WindowDuration]. Proposers( ctx context.Context, - chainHeight, + blockHeight, pChainHeight uint64, maxWindows int, ) ([]ids.NodeID, error) + // Delay returns the amount of time that [validatorID] must wait before - // building a block at [chainHeight] when the validator set is defined at + // building a block at [blockHeight] when the validator set is defined at // [pChainHeight]. Delay( ctx context.Context, - chainHeight, + blockHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int, ) (time.Duration, error) + + // In the Post-Durango windowing scheme, every validator active at + // [pChainHeight] gets specific slots it can propose in (instead of being + // able to propose from a given time on as it happens Pre-Durango). + // [ExpectedProposer] calculates which nodeID is scheduled to propose a + // block of height [blockHeight] at [slot]. + ExpectedProposer( + ctx context.Context, + blockHeight, + pChainHeight, + slot uint64, + ) (ids.NodeID, error) + + // In the Post-Durango windowing scheme, every validator active at + // [pChainHeight] gets specific slots it can propose in (instead of being + // able to propose from a given time on as it happens Pre-Durango). + // [MinDelayForProposer] specifies how long [nodeID] needs to wait for its + // slot to start. Delay is specified as starting from slot zero start. + // (which is parent timestamp). For efficiency reasons, we cap the slot + // search to [MaxLookAheadSlots]. + MinDelayForProposer( + ctx context.Context, + blockHeight, + pChainHeight uint64, + nodeID ids.NodeID, + startSlot uint64, + ) (time.Duration, error) } // windower interfaces with P-Chain and it is responsible for calculating the @@ -70,53 +108,26 @@ func New(state validators.State, subnetID, chainID ids.ID) Windower { } } -func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { - // get the validator set by the p-chain height - validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) +func (w *windower) Proposers(ctx context.Context, blockHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { + // Note: The 32-bit prng is used here for legacy reasons. All other usages + // of a prng in this file should use the 64-bit version. + source := prng.NewMT19937() + sampler, validators, err := w.makeSampler(ctx, pChainHeight, source) if err != nil { return nil, err } - // convert the map of validators to a slice - validators := make([]validatorData, 0, len(validatorsMap)) - weight := uint64(0) - for k, v := range validatorsMap { - validators = append(validators, validatorData{ - id: k, - weight: v.Weight, - }) - newWeight, err := math.Add64(weight, v.Weight) + var totalWeight uint64 + for _, validator := range validators { + totalWeight, err = math.Add64(totalWeight, validator.weight) if err != nil { return nil, err } - weight = newWeight } - // canonically sort validators - // Note: validators are sorted by ID, sorting by weight would not create a - // canonically sorted list - utils.Sort(validators) - - // convert the slice of validators to a slice of weights - validatorWeights := make([]uint64, len(validators)) - for i, v := range validators { - validatorWeights[i] = v.weight - } - - seed := chainHeight ^ w.chainSource - - source := prng.NewMT19937() - source.Seed(seed) - sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) - if err := sampler.Initialize(validatorWeights); err != nil { - return nil, err - } - - numToSample := maxWindows - if weight < uint64(numToSample) { - numToSample = int(weight) - } + source.Seed(w.chainSource ^ blockHeight) + numToSample := int(math.Min(uint64(maxWindows), totalWeight)) indices, err := sampler.Sample(numToSample) if err != nil { return nil, err @@ -129,12 +140,12 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint return nodeIDs, nil } -func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int) (time.Duration, error) { +func (w *windower) Delay(ctx context.Context, blockHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int) (time.Duration, error) { if validatorID == ids.EmptyNodeID { return time.Duration(maxWindows) * WindowDuration, nil } - proposers, err := w.Proposers(ctx, chainHeight, pChainHeight, maxWindows) + proposers, err := w.Proposers(ctx, blockHeight, pChainHeight, maxWindows) if err != nil { return 0, err } @@ -148,3 +159,118 @@ func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, } return delay, nil } + +func (w *windower) ExpectedProposer( + ctx context.Context, + blockHeight, + pChainHeight, + slot uint64, +) (ids.NodeID, error) { + source := prng.NewMT19937_64() + sampler, validators, err := w.makeSampler(ctx, pChainHeight, source) + if err != nil { + return ids.EmptyNodeID, err + } + + return w.expectedProposer( + validators, + source, + sampler, + blockHeight, + slot, + ) +} + +func (w *windower) MinDelayForProposer( + ctx context.Context, + blockHeight, + pChainHeight uint64, + nodeID ids.NodeID, + startSlot uint64, +) (time.Duration, error) { + source := prng.NewMT19937_64() + sampler, validators, err := w.makeSampler(ctx, pChainHeight, source) + if err != nil { + return 0, err + } + + maxSlot := startSlot + MaxLookAheadSlots + for slot := startSlot; slot < maxSlot; slot++ { + expectedNodeID, err := w.expectedProposer( + validators, + source, + sampler, + blockHeight, + slot, + ) + if err != nil { + return 0, err + } + + if expectedNodeID == nodeID { + return time.Duration(slot) * WindowDuration, nil + } + } + + // no slots scheduled for the max window we inspect. Return max delay + return time.Duration(maxSlot) * WindowDuration, nil +} + +func (w *windower) makeSampler( + ctx context.Context, + pChainHeight uint64, + source sampler.Source, +) (sampler.WeightedWithoutReplacement, []validatorData, error) { + // Get the canconical representation of the validator set at the provided + // p-chain height. + validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) + if err != nil { + return nil, nil, err + } + + validators := make([]validatorData, 0, len(validatorsMap)) + for k, v := range validatorsMap { + validators = append(validators, validatorData{ + id: k, + weight: v.Weight, + }) + } + + // Note: validators are sorted by ID. Sorting by weight would not create a + // canonically sorted list. + utils.Sort(validators) + + weights := make([]uint64, len(validators)) + for i, validator := range validators { + weights[i] = validator.weight + } + + sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) + return sampler, validators, sampler.Initialize(weights) +} + +func (w *windower) expectedProposer( + validators []validatorData, + source *prng.MT19937_64, + sampler sampler.WeightedWithoutReplacement, + blockHeight, + slot uint64, +) (ids.NodeID, error) { + // Slot is reversed to utilize a different state space in the seed than the + // height. If the slot was not reversed the state space would collide; + // biasing the seed generation. For example, without reversing the slot + // height=0 and slot=1 would equal height=1 and slot=0. + source.Seed(w.chainSource ^ blockHeight ^ bits.Reverse64(slot)) + indices, err := sampler.Sample(1) + if err != nil { + return ids.EmptyNodeID, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) + } + return validators[indices[0]].id, nil +} + +func TimeToSlot(start, now time.Time) uint64 { + if now.Before(start) { + return 0 + } + return uint64(now.Sub(start) / WindowDuration) +} diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 854c7b737213..bf8786b8b735 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -5,6 +5,7 @@ package proposer import ( "context" + "math" "math/rand" "testing" "time" @@ -13,41 +14,41 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) + +var ( + subnetID = ids.GenerateTestID() + randomChainID = ids.GenerateTestID() + fixedChainID = ids.ID{0, 2} ) func TestWindowerNoValidators(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.GenerateTestID() - chainID = ids.GenerateTestID() - nodeID = ids.GenerateTestNodeID() - ) - - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - return nil, nil - }, - } - - w := New(vdrState, subnetID, chainID) + _, vdrState := makeValidators(t, 0) + w := New(vdrState, subnetID, randomChainID) var ( chainHeight uint64 = 1 pChainHeight uint64 = 0 + nodeID = ids.GenerateTestNodeID() + slot uint64 = 1 ) delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) require.NoError(err) require.Zero(delay) + + expectedProposer, err := w.ExpectedProposer(context.Background(), chainHeight, pChainHeight, slot) + require.ErrorIs(err, ErrNoProposersAvailable) + require.Equal(ids.EmptyNodeID, expectedProposer) } func TestWindowerRepeatedValidator(t *testing.T) { require := require.New(t) var ( - subnetID = ids.GenerateTestID() - chainID = ids.GenerateTestID() validatorID = ids.GenerateTestNodeID() nonValidatorID = ids.GenerateTestNodeID() ) @@ -64,7 +65,7 @@ func TestWindowerRepeatedValidator(t *testing.T) { }, } - w := New(vdrState, subnetID, chainID) + w := New(vdrState, subnetID, randomChainID) validatorDelay, err := w.Delay(context.Background(), 1, 0, validatorID, MaxVerifyWindows) require.NoError(err) @@ -78,30 +79,8 @@ func TestWindowerRepeatedValidator(t *testing.T) { func TestDelayChangeByHeight(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.ID{0, 1} - chainID = ids.ID{0, 2} - ) - - validatorIDs := make([]ids.NodeID, MaxVerifyWindows) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - - w := New(vdrState, subnetID, chainID) + validatorIDs, vdrState := makeValidators(t, MaxVerifyWindows) + w := New(vdrState, subnetID, fixedChainID) expectedDelays1 := []time.Duration{ 2 * WindowDuration, @@ -137,8 +116,6 @@ func TestDelayChangeByHeight(t *testing.T) { func TestDelayChangeByChain(t *testing.T) { require := require.New(t) - subnetID := ids.ID{0, 1} - source := rand.NewSource(int64(0)) rng := rand.New(source) // #nosec G404 @@ -150,24 +127,7 @@ func TestDelayChangeByChain(t *testing.T) { _, err = rng.Read(chainID1[:]) require.NoError(err) - validatorIDs := make([]ids.NodeID, MaxVerifyWindows) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - + validatorIDs, vdrState := makeValidators(t, MaxVerifyWindows) w0 := New(vdrState, subnetID, chainID0) w1 := New(vdrState, subnetID, chainID1) @@ -201,3 +161,303 @@ func TestDelayChangeByChain(t *testing.T) { require.Equal(expectedDelay, validatorDelay) } } + +func TestExpectedProposerChangeByHeight(t *testing.T) { + require := require.New(t) + + validatorIDs, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) + + var ( + dummyCtx = context.Background() + pChainHeight uint64 = 0 + slot uint64 = 0 + ) + + expectedProposers := map[uint64]ids.NodeID{ + 1: validatorIDs[2], + 2: validatorIDs[1], + } + + for chainHeight, expectedProposerID := range expectedProposers { + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) + require.NoError(err) + require.Equal(expectedProposerID, proposerID) + } +} + +func TestExpectedProposerChangeByChain(t *testing.T) { + require := require.New(t) + + source := rand.NewSource(int64(0)) + rng := rand.New(source) // #nosec G404 + + chainID0 := ids.ID{} + _, err := rng.Read(chainID0[:]) + require.NoError(err) + + chainID1 := ids.ID{} + _, err = rng.Read(chainID1[:]) + require.NoError(err) + + validatorIDs, vdrState := makeValidators(t, 10) + + var ( + dummyCtx = context.Background() + chainHeight uint64 = 1 + pChainHeight uint64 = 0 + slot uint64 = 0 + ) + + expectedProposers := map[ids.ID]ids.NodeID{ + chainID0: validatorIDs[5], + chainID1: validatorIDs[3], + } + + for chainID, expectedProposerID := range expectedProposers { + w := New(vdrState, subnetID, chainID) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) + require.NoError(err) + require.Equal(expectedProposerID, proposerID) + } +} + +func TestExpectedProposerChangeBySlot(t *testing.T) { + require := require.New(t) + + validatorIDs, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) + + var ( + dummyCtx = context.Background() + chainHeight uint64 = 1 + pChainHeight uint64 = 0 + ) + + proposers := []ids.NodeID{ + validatorIDs[2], + validatorIDs[0], + validatorIDs[9], + validatorIDs[7], + validatorIDs[0], + validatorIDs[3], + validatorIDs[3], + validatorIDs[3], + validatorIDs[3], + validatorIDs[3], + validatorIDs[4], + validatorIDs[0], + validatorIDs[6], + validatorIDs[3], + validatorIDs[2], + validatorIDs[1], + validatorIDs[6], + validatorIDs[0], + validatorIDs[5], + validatorIDs[1], + validatorIDs[9], + validatorIDs[6], + validatorIDs[0], + validatorIDs[8], + } + expectedProposers := map[uint64]ids.NodeID{ + MaxLookAheadSlots: validatorIDs[4], + MaxLookAheadSlots + 1: validatorIDs[6], + } + for slot, expectedProposerID := range proposers { + expectedProposers[uint64(slot)] = expectedProposerID + } + + for slot, expectedProposerID := range expectedProposers { + actualProposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) + require.NoError(err) + require.Equal(expectedProposerID, actualProposerID) + } +} + +func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { + require := require.New(t) + + _, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) + + var ( + dummyCtx = context.Background() + chainHeight uint64 = 1 + pChainHeight uint64 = 0 + ) + + for slot := uint64(0); slot < 3*MaxLookAheadSlots; slot++ { + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) + require.NoError(err) + + // proposerID is the scheduled proposer. It should start with the + // expected delay + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, proposerID, slot) + require.NoError(err) + require.Equal(time.Duration(slot)*WindowDuration, delay) + } +} + +func TestMinDelayForProposer(t *testing.T) { + require := require.New(t) + + validatorIDs, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) + + var ( + dummyCtx = context.Background() + chainHeight uint64 = 1 + pChainHeight uint64 = 0 + slot uint64 = 0 + ) + + expectedDelays := map[ids.NodeID]time.Duration{ + validatorIDs[0]: 1 * WindowDuration, + validatorIDs[1]: 15 * WindowDuration, + validatorIDs[2]: 0 * WindowDuration, + validatorIDs[3]: 5 * WindowDuration, + validatorIDs[4]: 10 * WindowDuration, + validatorIDs[5]: 18 * WindowDuration, + validatorIDs[6]: 12 * WindowDuration, + validatorIDs[7]: 3 * WindowDuration, + validatorIDs[8]: 23 * WindowDuration, + validatorIDs[9]: 2 * WindowDuration, + ids.GenerateTestNodeID(): MaxLookAheadWindow, + } + + for nodeID, expectedDelay := range expectedDelays { + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, nodeID, slot) + require.NoError(err) + require.Equal(expectedDelay, delay) + } +} + +func BenchmarkMinDelayForProposer(b *testing.B) { + require := require.New(b) + + _, vdrState := makeValidators(b, 10) + w := New(vdrState, subnetID, fixedChainID) + + var ( + dummyCtx = context.Background() + pChainHeight uint64 = 0 + chainHeight uint64 = 1 + nodeID = ids.GenerateTestNodeID() // Ensure to exhaust the search + slot uint64 = 0 + ) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, nodeID, slot) + require.NoError(err) + } +} + +func TestTimeToSlot(t *testing.T) { + parentTime := time.Now() + tests := []struct { + timeOffset time.Duration + expectedSlot uint64 + }{ + { + timeOffset: -WindowDuration, + expectedSlot: 0, + }, + { + timeOffset: -time.Second, + expectedSlot: 0, + }, + { + timeOffset: 0, + expectedSlot: 0, + }, + { + timeOffset: WindowDuration, + expectedSlot: 1, + }, + { + timeOffset: 2 * WindowDuration, + expectedSlot: 2, + }, + } + for _, test := range tests { + t.Run(test.timeOffset.String(), func(t *testing.T) { + slot := TimeToSlot(parentTime, parentTime.Add(test.timeOffset)) + require.Equal(t, test.expectedSlot, slot) + }) + } +} + +// Ensure that the proposer distribution is within 3 standard deviations of the +// expected value assuming a truly random binomial distribution. +func TestProposerDistribution(t *testing.T) { + require := require.New(t) + + validatorIDs, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) + + var ( + dummyCtx = context.Background() + pChainHeight uint64 = 0 + numChainHeights uint64 = 100 + numSlots uint64 = 100 + ) + + proposerFrequency := make(map[ids.NodeID]int) + for _, validatorID := range validatorIDs { + // Initialize the map to 0s to include validators that are never sampled + // in the analysis. + proposerFrequency[validatorID] = 0 + } + for chainHeight := uint64(0); chainHeight < numChainHeights; chainHeight++ { + for slot := uint64(0); slot < numSlots; slot++ { + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) + require.NoError(err) + proposerFrequency[proposerID]++ + } + } + + var ( + totalNumberOfSamples = numChainHeights * numSlots + probabilityOfBeingSampled = 1 / float64(len(validatorIDs)) + expectedNumberOfSamples = uint64(probabilityOfBeingSampled * float64(totalNumberOfSamples)) + variance = float64(totalNumberOfSamples) * probabilityOfBeingSampled * (1 - probabilityOfBeingSampled) + stdDeviation = math.Sqrt(variance) + maxDeviation uint64 + ) + for _, sampled := range proposerFrequency { + maxDeviation = safemath.Max( + maxDeviation, + safemath.AbsDiff( + uint64(sampled), + expectedNumberOfSamples, + ), + ) + } + + maxSTDDeviation := float64(maxDeviation) / stdDeviation + require.Less(maxSTDDeviation, 3.) +} + +func makeValidators(t testing.TB, count int) ([]ids.NodeID, *validators.TestState) { + validatorIDs := make([]ids.NodeID, count) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, + } + return validatorIDs, vdrState +} diff --git a/vms/proposervm/scheduler/mock_scheduler.go b/vms/proposervm/scheduler/mock_scheduler.go new file mode 100644 index 000000000000..bb4c19b941f1 --- /dev/null +++ b/vms/proposervm/scheduler/mock_scheduler.go @@ -0,0 +1,74 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ava-labs/avalanchego/vms/proposervm/scheduler (interfaces: Scheduler) + +// Package scheduler is a generated GoMock package. +package scheduler + +import ( + reflect "reflect" + time "time" + + gomock "go.uber.org/mock/gomock" +) + +// MockScheduler is a mock of Scheduler interface. +type MockScheduler struct { + ctrl *gomock.Controller + recorder *MockSchedulerMockRecorder +} + +// MockSchedulerMockRecorder is the mock recorder for MockScheduler. +type MockSchedulerMockRecorder struct { + mock *MockScheduler +} + +// NewMockScheduler creates a new mock instance. +func NewMockScheduler(ctrl *gomock.Controller) *MockScheduler { + mock := &MockScheduler{ctrl: ctrl} + mock.recorder = &MockSchedulerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockScheduler) EXPECT() *MockSchedulerMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockScheduler) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockSchedulerMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockScheduler)(nil).Close)) +} + +// Dispatch mocks base method. +func (m *MockScheduler) Dispatch(arg0 time.Time) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Dispatch", arg0) +} + +// Dispatch indicates an expected call of Dispatch. +func (mr *MockSchedulerMockRecorder) Dispatch(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Dispatch", reflect.TypeOf((*MockScheduler)(nil).Dispatch), arg0) +} + +// SetBuildBlockTime mocks base method. +func (m *MockScheduler) SetBuildBlockTime(arg0 time.Time) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetBuildBlockTime", arg0) +} + +// SetBuildBlockTime indicates an expected call of SetBuildBlockTime. +func (mr *MockSchedulerMockRecorder) SetBuildBlockTime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBuildBlockTime", reflect.TypeOf((*MockScheduler)(nil).SetBuildBlockTime), arg0) +} diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 31695ec9876e..0a4ba6d3bfe1 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -71,7 +71,8 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { vm := New( innerVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -601,7 +602,11 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { require := require.New(t) // Note: by default proVM is built such that heightIndex will be considered complete - coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index ae9afe6562cd..2963739ef990 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -333,18 +333,59 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { return err } - // reset scheduler - minDelay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) + var ( + childBlockHeight = blk.Height() + 1 + parentTimestamp = blk.Timestamp() + nextStartTime time.Time + ) + if vm.IsDurangoActivated(parentTimestamp) { + currentTime := vm.Clock.Time().Truncate(time.Second) + nextStartTime, err = vm.getPostDurangoSlotTime( + ctx, + childBlockHeight, + pChainHeight, + proposer.TimeToSlot(parentTimestamp, currentTime), + parentTimestamp, + ) + } else { + nextStartTime, err = vm.getPreDurangoSlotTime( + ctx, + childBlockHeight, + pChainHeight, + parentTimestamp, + ) + } if err != nil { vm.ctx.Log.Debug("failed to fetch the expected delay", zap.Error(err), ) + // A nil error is returned here because it is possible that // bootstrapping caused the last accepted block to move past the latest // P-chain height. This will cause building blocks to return an error // until the P-chain's height has advanced. return nil } + vm.Scheduler.SetBuildBlockTime(nextStartTime) + + vm.ctx.Log.Debug("set preference", + zap.Stringer("blkID", blk.ID()), + zap.Time("blockTimestamp", parentTimestamp), + zap.Time("nextStartTime", nextStartTime), + ) + return nil +} + +func (vm *VM) getPreDurangoSlotTime( + ctx context.Context, + blkHeight, + pChainHeight uint64, + parentTimestamp time.Time, +) (time.Time, error) { + delay, err := vm.Windower.Delay(ctx, blkHeight, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) + if err != nil { + return time.Time{}, err + } // Note: The P-chain does not currently try to target any block time. It // notifies the consensus engine as soon as a new block may be built. To @@ -352,18 +393,36 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { // validators can specify. This delay may be an issue for high performance, // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. - minDelay = math.Max(minDelay, vm.MinBlkDelay) - - preferredTime := blk.Timestamp() - nextStartTime := preferredTime.Add(minDelay) - vm.Scheduler.SetBuildBlockTime(nextStartTime) + delay = math.Max(delay, vm.MinBlkDelay) + return parentTimestamp.Add(delay), nil +} - vm.ctx.Log.Debug("set preference", - zap.Stringer("blkID", blk.ID()), - zap.Time("blockTimestamp", preferredTime), - zap.Time("nextStartTime", nextStartTime), +func (vm *VM) getPostDurangoSlotTime( + ctx context.Context, + blkHeight, + pChainHeight, + slot uint64, + parentTimestamp time.Time, +) (time.Time, error) { + delay, err := vm.Windower.MinDelayForProposer( + ctx, + blkHeight, + pChainHeight, + vm.ctx.NodeID, + slot, ) - return nil + if err != nil { + return time.Time{}, err + } + + // Note: The P-chain does not currently try to target any block time. It + // notifies the consensus engine as soon as a new block may be built. To + // avoid fast runs of blocks there is an additional minimum delay that + // validators can specify. This delay may be an issue for high performance, + // custom VMs. Until the P-chain is modified to target a specific block + // time, ProposerMinBlockDelay can be configured in the subnet config. + delay = math.Max(delay, vm.MinBlkDelay) + return parentTimestamp.Add(delay), err } func (vm *VM) LastAccepted(ctx context.Context) (ids.ID, error) { diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index 5b6c29ee6a63..fcb230156c96 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -32,8 +32,11 @@ import ( func TestInvalidByzantineProposerParent(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) // enable ProBlks - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -100,7 +103,11 @@ func TestInvalidByzantineProposerParent(t *testing.T) { func TestInvalidByzantineProposerOracleParent(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -205,8 +212,11 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { func TestInvalidByzantineProposerPreForkParent(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) // enable ProBlks - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -292,7 +302,11 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -388,7 +402,11 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { func TestBlockVerify_InvalidPostForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -568,7 +586,11 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { func TestGetBlock_MutatedSignature(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index fba3f5974332..d8b6ea195001 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -47,7 +47,8 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test proVM := New( innerVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index b716a6fa3c3d..97216d9c0905 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -74,6 +74,7 @@ func init() { func initTestProposerVM( t *testing.T, proBlkStartTime time.Time, + durangoTime time.Time, minPChainHeight uint64, ) ( *fullVM, @@ -136,6 +137,7 @@ func initTestProposerVM( coreVM, Config{ ActivationTime: proBlkStartTime, + DurangoTime: durangoTime, MinimumPChainHeight: minPChainHeight, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -215,13 +217,44 @@ func initTestProposerVM( return coreVM, valState, proVM, coreGenBlk, db } +func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) error { + var ( + ctx = context.Background() + childBlockHeight = chainTip.Height() + 1 + parentTimestamp = chainTip.Timestamp() + ) + + for { + slot := proposer.TimeToSlot(parentTimestamp, vm.Clock.Time().Truncate(time.Second)) + delay, err := vm.MinDelayForProposer( + ctx, + childBlockHeight, + pchainHeight, + vm.ctx.NodeID, + slot, + ) + if err != nil { + return err + } + + vm.Clock.Set(parentTimestamp.Add(delay)) + if delay < proposer.MaxLookAheadWindow { + return nil + } + } +} + // VM.BuildBlock tests section func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { require := require.New(t) // given the same core block, BuildBlock returns the same proposer block - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -253,7 +286,11 @@ func TestBuildBlockIsIdempotent(t *testing.T) { require := require.New(t) // given the same core block, BuildBlock returns the same proposer block - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -287,7 +324,11 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { require := require.New(t) // setup - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -320,7 +361,11 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -401,7 +446,7 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { return coreBlk3, nil } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proVM, proBlk2, proBlk2.(*postForkBlock).PChainHeight())) builtBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -412,7 +457,11 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -493,7 +542,7 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { return coreBlk3, nil } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proVM, proBlk2, proBlk2.(*postForkBlock).PChainHeight())) blk, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -505,7 +554,11 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { require := require.New(t) - coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -543,7 +596,11 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { require := require.New(t) - coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -615,7 +672,11 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -681,7 +742,11 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { func TestPreFork_Initialize(t *testing.T) { require := require.New(t) - _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -700,7 +765,11 @@ func TestPreFork_Initialize(t *testing.T) { func TestPreFork_BuildBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -737,8 +806,11 @@ func TestPreFork_BuildBlock(t *testing.T) { func TestPreFork_ParseBlock(t *testing.T) { require := require.New(t) - // setup - coreVM, _, proVM, _, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -773,7 +845,11 @@ func TestPreFork_ParseBlock(t *testing.T) { func TestPreFork_SetPreference(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -874,6 +950,7 @@ func TestExpiredBuildBlock(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1045,7 +1122,11 @@ func (b *wrappedBlock) Verify(ctx context.Context) error { func TestInnerBlockDeduplication(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // disable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1219,6 +1300,7 @@ func TestInnerVMRollback(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1308,6 +1390,7 @@ func TestInnerVMRollback(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1345,7 +1428,11 @@ func TestInnerVMRollback(t *testing.T) { func TestBuildBlockDuringWindow(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1446,8 +1533,11 @@ func TestBuildBlockDuringWindow(t *testing.T) { func TestTwoForks_OneIsAccepted(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1540,8 +1630,11 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { func TestTooFarAdvanced(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1631,7 +1724,11 @@ func TestTooFarAdvanced(t *testing.T) { func TestTwoOptions_OneIsAccepted(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1705,7 +1802,11 @@ func TestTwoOptions_OneIsAccepted(t *testing.T) { func TestLaggedPChainHeight(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1795,7 +1896,8 @@ func TestRejectedHeightNotIndexed(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2004,7 +2106,8 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2169,7 +2272,8 @@ func TestVMInnerBlkCache(t *testing.T) { vm := New( innerVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2269,8 +2373,11 @@ func TestVMInnerBlkCache(t *testing.T) { func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2345,8 +2452,11 @@ func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoTime = activationTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2400,7 +2510,8 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { vm := New( innerVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2613,7 +2724,8 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2714,6 +2826,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, @@ -2758,6 +2871,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: newNumHistoricalBlocks, From 21fe5033d59869b70535209e626069ea46842696 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 16 Dec 2023 17:25:29 -0500 Subject: [PATCH 159/267] Support json marshalling txs returned from the wallet (#2494) --- wallet/chain/c/builder.go | 10 +++++ wallet/chain/c/context.go | 21 +++++++++- wallet/chain/p/builder.go | 70 +++++++++++++++++++++----------- wallet/chain/p/context.go | 17 ++++++++ wallet/chain/x/builder.go | 49 +++++++++++++++++----- wallet/chain/x/context.go | 23 ++++++++++- wallet/chain/x/signer_visitor.go | 3 ++ 7 files changed, 156 insertions(+), 37 deletions(-) diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index d2d088e88a53..81fcf3aa896a 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -201,6 +201,7 @@ func (b *builder) NewImportTx( importedInputs = append(importedInputs, &avax.TransferableInput{ UTXOID: utxo.UTXOID, Asset: utxo.Asset, + FxID: secp256k1fx.ID, In: &secp256k1fx.TransferInput{ Amt: amount, Input: secp256k1fx.Input{ @@ -267,6 +268,7 @@ func (b *builder) NewExportTx( for i, output := range outputs { exportedOutputs[i] = &avax.TransferableOutput{ Asset: avax.Asset{ID: avaxAssetID}, + FxID: secp256k1fx.ID, Out: output, } @@ -376,6 +378,14 @@ func (b *builder) NewExportTx( utils.Sort(inputs) tx.Ins = inputs + + snowCtx, err := newSnowContext(b.backend) + if err != nil { + return nil, err + } + for _, out := range tx.ExportedOutputs { + out.InitCtx(snowCtx) + } return tx, nil } diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index d506b42f81fa..b9cd41cb5667 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -8,9 +8,14 @@ import ( "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/avm" ) +const Alias = "C" + var _ Context = (*context)(nil) type Context interface { @@ -41,7 +46,7 @@ func NewContextFromClients( return nil, err } - chainID, err := infoClient.GetBlockchainID(ctx, "C") + chainID, err := infoClient.GetBlockchainID(ctx, Alias) if err != nil { return nil, err } @@ -81,3 +86,17 @@ func (c *context) BlockchainID() ids.ID { func (c *context) AVAXAssetID() ids.ID { return c.avaxAssetID } + +func newSnowContext(c Context) (*snow.Context, error) { + chainID := c.BlockchainID() + lookup := ids.NewAliaser() + return &snow.Context{ + NetworkID: c.NetworkID(), + SubnetID: constants.PrimaryNetworkID, + ChainID: chainID, + CChainID: chainID, + AVAXAssetID: c.AVAXAssetID(), + Log: logging.NoLog{}, + BCLookup: lookup, + }, lookup.Alias(chainID, Alias) +} diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index f890790dad26..6b3b11254cd7 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -311,7 +311,7 @@ func (b *builder) NewBaseTx( outputs = append(outputs, changeOutputs...) avax.SortTransferableOutputs(outputs, txs.Codec) // sort the outputs - return &txs.CreateSubnetTx{ + tx := &txs.CreateSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -320,7 +320,8 @@ func (b *builder) NewBaseTx( Memo: ops.Memo(), }}, Owner: &secp256k1fx.OutputOwners{}, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewAddValidatorTx( @@ -343,7 +344,7 @@ func (b *builder) NewAddValidatorTx( } utils.Sort(rewardsOwner.Addrs) - return &txs.AddValidatorTx{ + tx := &txs.AddValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -355,7 +356,8 @@ func (b *builder) NewAddValidatorTx( StakeOuts: stakeOutputs, RewardsOwner: rewardsOwner, DelegationShares: shares, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewAddSubnetValidatorTx( @@ -377,7 +379,7 @@ func (b *builder) NewAddSubnetValidatorTx( return nil, err } - return &txs.AddSubnetValidatorTx{ + tx := &txs.AddSubnetValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -387,7 +389,8 @@ func (b *builder) NewAddSubnetValidatorTx( }}, SubnetValidator: *vdr, SubnetAuth: subnetAuth, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewRemoveSubnetValidatorTx( @@ -410,7 +413,7 @@ func (b *builder) NewRemoveSubnetValidatorTx( return nil, err } - return &txs.RemoveSubnetValidatorTx{ + tx := &txs.RemoveSubnetValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -421,7 +424,8 @@ func (b *builder) NewRemoveSubnetValidatorTx( Subnet: subnetID, NodeID: nodeID, SubnetAuth: subnetAuth, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewAddDelegatorTx( @@ -443,7 +447,7 @@ func (b *builder) NewAddDelegatorTx( } utils.Sort(rewardsOwner.Addrs) - return &txs.AddDelegatorTx{ + tx := &txs.AddDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -454,7 +458,8 @@ func (b *builder) NewAddDelegatorTx( Validator: *vdr, StakeOuts: stakeOutputs, DelegationRewardsOwner: rewardsOwner, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewCreateChainTx( @@ -481,7 +486,7 @@ func (b *builder) NewCreateChainTx( } utils.Sort(fxIDs) - return &txs.CreateChainTx{ + tx := &txs.CreateChainTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -495,7 +500,8 @@ func (b *builder) NewCreateChainTx( FxIDs: fxIDs, GenesisData: genesis, SubnetAuth: subnetAuth, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewCreateSubnetTx( @@ -513,7 +519,7 @@ func (b *builder) NewCreateSubnetTx( } utils.Sort(owner.Addrs) - return &txs.CreateSubnetTx{ + tx := &txs.CreateSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -522,7 +528,8 @@ func (b *builder) NewCreateSubnetTx( Memo: ops.Memo(), }}, Owner: owner, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewImportTx( @@ -618,7 +625,7 @@ func (b *builder) NewImportTx( } avax.SortTransferableOutputs(outputs, txs.Codec) // sort imported outputs - return &txs.ImportTx{ + tx := &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -628,7 +635,8 @@ func (b *builder) NewImportTx( }}, SourceChain: sourceChainID, ImportedInputs: importedInputs, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewExportTx( @@ -656,7 +664,7 @@ func (b *builder) NewExportTx( } avax.SortTransferableOutputs(outputs, txs.Codec) // sort exported outputs - return &txs.ExportTx{ + tx := &txs.ExportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -666,7 +674,8 @@ func (b *builder) NewExportTx( }}, DestinationChain: chainID, ExportedOutputs: outputs, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewTransformSubnetTx( @@ -702,7 +711,7 @@ func (b *builder) NewTransformSubnetTx( return nil, err } - return &txs.TransformSubnetTx{ + tx := &txs.TransformSubnetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -725,7 +734,8 @@ func (b *builder) NewTransformSubnetTx( MaxValidatorWeightFactor: maxValidatorWeightFactor, UptimeRequirement: uptimeRequirement, SubnetAuth: subnetAuth, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewAddPermissionlessValidatorTx( @@ -755,7 +765,7 @@ func (b *builder) NewAddPermissionlessValidatorTx( utils.Sort(validationRewardsOwner.Addrs) utils.Sort(delegationRewardsOwner.Addrs) - return &txs.AddPermissionlessValidatorTx{ + tx := &txs.AddPermissionlessValidatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -770,7 +780,8 @@ func (b *builder) NewAddPermissionlessValidatorTx( ValidatorRewardsOwner: validationRewardsOwner, DelegatorRewardsOwner: delegationRewardsOwner, DelegationShares: shares, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewAddPermissionlessDelegatorTx( @@ -796,7 +807,7 @@ func (b *builder) NewAddPermissionlessDelegatorTx( } utils.Sort(rewardsOwner.Addrs) - return &txs.AddPermissionlessDelegatorTx{ + tx := &txs.AddPermissionlessDelegatorTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: constants.PlatformChainID, @@ -808,7 +819,8 @@ func (b *builder) NewAddPermissionlessDelegatorTx( Subnet: vdr.Subnet, StakeOuts: stakeOutputs, DelegationRewardsOwner: rewardsOwner, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) getBalance( @@ -1117,3 +1129,13 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se SigIndices: inputSigIndices, }, nil } + +func (b *builder) initCtx(tx txs.UnsignedTx) error { + ctx, err := newSnowContext(b.backend) + if err != nil { + return err + } + + tx.InitCtx(ctx) + return nil +} diff --git a/wallet/chain/p/context.go b/wallet/chain/p/context.go index 75bcdb19e7f2..9c3ba67d0dc7 100644 --- a/wallet/chain/p/context.go +++ b/wallet/chain/p/context.go @@ -8,9 +8,14 @@ import ( "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/avm" ) +const Alias = "P" + var _ Context = (*context)(nil) type Context interface { @@ -144,3 +149,15 @@ func (c *context) AddSubnetValidatorFee() uint64 { func (c *context) AddSubnetDelegatorFee() uint64 { return c.addSubnetDelegatorFee } + +func newSnowContext(c Context) (*snow.Context, error) { + lookup := ids.NewAliaser() + return &snow.Context{ + NetworkID: c.NetworkID(), + SubnetID: constants.PrimaryNetworkID, + ChainID: constants.PlatformChainID, + AVAXAssetID: c.AVAXAssetID(), + Log: logging.NoLog{}, + BCLookup: lookup, + }, lookup.Alias(constants.PlatformChainID, Alias) +} diff --git a/wallet/chain/x/builder.go b/wallet/chain/x/builder.go index 0b639a7776ad..d7af2b62aa25 100644 --- a/wallet/chain/x/builder.go +++ b/wallet/chain/x/builder.go @@ -26,6 +26,12 @@ var ( errNoChangeAddress = errors.New("no possible change address") errInsufficientFunds = errors.New("insufficient funds") + fxIndexToID = map[uint32]ids.ID{ + 0: secp256k1fx.ID, + 1: nftfx.ID, + 2: propertyfx.ID, + } + _ Builder = (*builder)(nil) ) @@ -213,13 +219,14 @@ func (b *builder) NewBaseTx( outputs = append(outputs, changeOutputs...) avax.SortTransferableOutputs(outputs, Parser.Codec()) // sort the outputs - return &txs.BaseTx{BaseTx: avax.BaseTx{ + tx := &txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: b.backend.BlockchainID(), Ins: inputs, Outs: outputs, Memo: ops.Memo(), - }}, nil + }} + return tx, b.initCtx(tx) } func (b *builder) NewCreateAssetTx( @@ -243,12 +250,14 @@ func (b *builder) NewCreateAssetTx( for fxIndex, outs := range initialState { state := &txs.InitialState{ FxIndex: fxIndex, + FxID: fxIndexToID[fxIndex], Outs: outs, } state.Sort(codec) // sort the outputs states = append(states, state) } + utils.Sort(states) // sort the initial states tx := &txs.CreateAssetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), @@ -262,8 +271,7 @@ func (b *builder) NewCreateAssetTx( Denomination: denomination, States: states, } - utils.Sort(tx.States) // sort the initial states - return tx, nil + return tx, b.initCtx(tx) } func (b *builder) NewOperationTx( @@ -280,7 +288,7 @@ func (b *builder) NewOperationTx( } txs.SortOperations(operations, Parser.Codec()) - return &txs.OperationTx{ + tx := &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: b.backend.BlockchainID(), @@ -289,7 +297,8 @@ func (b *builder) NewOperationTx( Memo: ops.Memo(), }}, Ops: operations, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewOperationTxMintFT( @@ -380,6 +389,7 @@ func (b *builder) NewImportTx( importedInputs = append(importedInputs, &avax.TransferableInput{ UTXOID: utxo.UTXOID, Asset: utxo.Asset, + FxID: secp256k1fx.ID, In: &secp256k1fx.TransferInput{ Amt: out.Amt, Input: secp256k1fx.Input{ @@ -428,6 +438,7 @@ func (b *builder) NewImportTx( for assetID, amount := range importedAmounts { outputs = append(outputs, &avax.TransferableOutput{ Asset: avax.Asset{ID: assetID}, + FxID: secp256k1fx.ID, Out: &secp256k1fx.TransferOutput{ Amt: amount, OutputOwners: *to, @@ -436,7 +447,7 @@ func (b *builder) NewImportTx( } avax.SortTransferableOutputs(outputs, Parser.Codec()) - return &txs.ImportTx{ + tx := &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: b.backend.BlockchainID(), @@ -446,7 +457,8 @@ func (b *builder) NewImportTx( }}, SourceChain: chainID, ImportedIns: importedInputs, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) NewExportTx( @@ -473,7 +485,7 @@ func (b *builder) NewExportTx( } avax.SortTransferableOutputs(outputs, Parser.Codec()) - return &txs.ExportTx{ + tx := &txs.ExportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), BlockchainID: b.backend.BlockchainID(), @@ -483,7 +495,8 @@ func (b *builder) NewExportTx( }}, DestinationChain: chainID, ExportedOuts: outputs, - }, nil + } + return tx, b.initCtx(tx) } func (b *builder) getBalance( @@ -578,6 +591,7 @@ func (b *builder) spend( inputs = append(inputs, &avax.TransferableInput{ UTXOID: utxo.UTXOID, Asset: utxo.Asset, + FxID: secp256k1fx.ID, In: &secp256k1fx.TransferInput{ Amt: out.Amt, Input: secp256k1fx.Input{ @@ -596,6 +610,7 @@ func (b *builder) spend( // This input had extra value, so some of it must be returned outputs = append(outputs, &avax.TransferableOutput{ Asset: utxo.Asset, + FxID: secp256k1fx.ID, Out: &secp256k1fx.TransferOutput{ Amt: remainingAmount, OutputOwners: *changeOwner, @@ -656,6 +671,7 @@ func (b *builder) mintFTs( operations = append(operations, &txs.Operation{ Asset: utxo.Asset, UTXOIDs: []*avax.UTXOID{&utxo.UTXOID}, + FxID: secp256k1fx.ID, Op: &secp256k1fx.MintOperation{ MintInput: secp256k1fx.Input{ SigIndices: inputSigIndices, @@ -719,6 +735,7 @@ func (b *builder) mintNFTs( UTXOIDs: []*avax.UTXOID{ &utxo.UTXOID, }, + FxID: nftfx.ID, Op: &nftfx.MintOperation{ MintInput: secp256k1fx.Input{ SigIndices: inputSigIndices, @@ -775,6 +792,7 @@ func (b *builder) mintProperty( UTXOIDs: []*avax.UTXOID{ &utxo.UTXOID, }, + FxID: propertyfx.ID, Op: &propertyfx.MintOperation{ MintInput: secp256k1fx.Input{ SigIndices: inputSigIndices, @@ -831,6 +849,7 @@ func (b *builder) burnProperty( UTXOIDs: []*avax.UTXOID{ &utxo.UTXOID, }, + FxID: propertyfx.ID, Op: &propertyfx.BurnOperation{ Input: secp256k1fx.Input{ SigIndices: inputSigIndices, @@ -847,3 +866,13 @@ func (b *builder) burnProperty( } return operations, nil } + +func (b *builder) initCtx(tx txs.UnsignedTx) error { + ctx, err := newSnowContext(b.backend) + if err != nil { + return err + } + + tx.InitCtx(ctx) + return nil +} diff --git a/wallet/chain/x/context.go b/wallet/chain/x/context.go index bdabe2d925b5..064080253eb6 100644 --- a/wallet/chain/x/context.go +++ b/wallet/chain/x/context.go @@ -8,9 +8,14 @@ import ( "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/avm" ) +const Alias = "X" + var _ Context = (*context)(nil) type Context interface { @@ -31,7 +36,7 @@ type context struct { func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { infoClient := info.NewClient(uri) - xChainClient := avm.NewClient(uri, "X") + xChainClient := avm.NewClient(uri, Alias) return NewContextFromClients(ctx, infoClient, xChainClient) } @@ -45,7 +50,7 @@ func NewContextFromClients( return nil, err } - chainID, err := infoClient.GetBlockchainID(ctx, "X") + chainID, err := infoClient.GetBlockchainID(ctx, Alias) if err != nil { return nil, err } @@ -104,3 +109,17 @@ func (c *context) BaseTxFee() uint64 { func (c *context) CreateAssetTxFee() uint64 { return c.createAssetTxFee } + +func newSnowContext(c Context) (*snow.Context, error) { + chainID := c.BlockchainID() + lookup := ids.NewAliaser() + return &snow.Context{ + NetworkID: c.NetworkID(), + SubnetID: constants.PrimaryNetworkID, + ChainID: chainID, + XChainID: chainID, + AVAXAssetID: c.AVAXAssetID(), + Log: logging.NoLog{}, + BCLookup: lookup, + }, lookup.Alias(chainID, Alias) +} diff --git a/wallet/chain/x/signer_visitor.go b/wallet/chain/x/signer_visitor.go index 11e611b8134e..35b0bd668224 100644 --- a/wallet/chain/x/signer_visitor.go +++ b/wallet/chain/x/signer_visitor.go @@ -245,10 +245,13 @@ func sign(tx *txs.Tx, creds []verify.Verifiable, txSigners [][]keychain.Signer) var cred *secp256k1fx.Credential switch credImpl := credIntf.(type) { case *secp256k1fx.Credential: + fxCred.FxID = secp256k1fx.ID cred = credImpl case *nftfx.Credential: + fxCred.FxID = nftfx.ID cred = &credImpl.Credential case *propertyfx.Credential: + fxCred.FxID = propertyfx.ID cred = &credImpl.Credential default: return errUnknownCredentialType From 331a5bcd4942ca650dc263ebbe68f163719d38ea Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 17 Dec 2023 00:25:56 -0500 Subject: [PATCH 160/267] Avoid escaping to improve readability (#2496) --- api/auth/auth.go | 2 +- ids/id.go | 2 +- ids/id_test.go | 22 +- ids/node_id.go | 2 +- ids/node_id_test.go | 32 ++- ids/short.go | 2 +- node/overridden_manager_test.go | 12 +- snow/choices/status.go | 17 +- snow/consensus/snowball/parameters.go | 30 +-- snow/consensus/snowball/tree_test.go | 290 +++++++++++++------------- snow/validators/manager_test.go | 12 +- snow/validators/set_test.go | 6 +- tests/fixture/tmpnet/cmd/main.go | 4 +- utils/bag/bag_test.go | 4 +- utils/crypto/secp256k1/secp256k1.go | 2 +- utils/formatting/encoding.go | 2 +- utils/json/float32.go | 2 +- utils/json/float64.go | 2 +- utils/json/uint16.go | 2 +- utils/json/uint32.go | 2 +- utils/json/uint64.go | 2 +- utils/json/uint8.go | 2 +- utils/logging/sanitize.go | 4 +- 23 files changed, 237 insertions(+), 220 deletions(-) diff --git a/api/auth/auth.go b/api/auth/auth.go index 0f78192cb111..a9869fe3ea23 100644 --- a/api/auth/auth.go +++ b/api/auth/auth.go @@ -41,7 +41,7 @@ const ( var ( errNoToken = errors.New("auth token not provided") errAuthHeaderNotParsable = fmt.Errorf( - "couldn't parse auth token. Header \"%s\" should be \"%sTOKEN.GOES.HERE\"", + `couldn't parse auth token. Header "%s" should be "%sTOKEN.GOES.HERE"`, headerKey, headerValStart, ) diff --git a/ids/id.go b/ids/id.go index 6e5aed7876fd..dc22ff0200ae 100644 --- a/ids/id.go +++ b/ids/id.go @@ -51,7 +51,7 @@ func (id ID) MarshalJSON() ([]byte, error) { if err != nil { return nil, err } - return []byte("\"" + str + "\""), nil + return []byte(`"` + str + `"`), nil } func (id *ID) UnmarshalJSON(b []byte) error { diff --git a/ids/id_test.go b/ids/id_test.go index 3197e7843697..af12bc78f714 100644 --- a/ids/id_test.go +++ b/ids/id_test.go @@ -102,11 +102,16 @@ func TestIDMarshalJSON(t *testing.T) { out []byte err error }{ - {"ID{}", ID{}, []byte("\"11111111111111111111111111111111LpoYY\""), nil}, { - "ID(\"ava labs\")", + "ID{}", + ID{}, + []byte(`"11111111111111111111111111111111LpoYY"`), + nil, + }, + { + `ID("ava labs")`, ID{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}, - []byte("\"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7\""), + []byte(`"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7"`), nil, }, } @@ -128,10 +133,15 @@ func TestIDUnmarshalJSON(t *testing.T) { out ID err error }{ - {"ID{}", []byte("null"), ID{}, nil}, { - "ID(\"ava labs\")", - []byte("\"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7\""), + "ID{}", + []byte("null"), + ID{}, + nil, + }, + { + `ID("ava labs")`, + []byte(`"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7"`), ID{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}, nil, }, diff --git a/ids/node_id.go b/ids/node_id.go index a20b00d24462..f2ce6d9acfb7 100644 --- a/ids/node_id.go +++ b/ids/node_id.go @@ -37,7 +37,7 @@ func (id NodeID) Bytes() []byte { } func (id NodeID) MarshalJSON() ([]byte, error) { - return []byte("\"" + id.String() + "\""), nil + return []byte(`"` + id.String() + `"`), nil } func (id NodeID) MarshalText() ([]byte, error) { diff --git a/ids/node_id_test.go b/ids/node_id_test.go index f3c11a452d24..4aac5875b104 100644 --- a/ids/node_id_test.go +++ b/ids/node_id_test.go @@ -68,11 +68,16 @@ func TestNodeIDMarshalJSON(t *testing.T) { out []byte err error }{ - {"NodeID{}", NodeID{}, []byte("\"NodeID-111111111111111111116DBWJs\""), nil}, { - "ID(\"ava labs\")", + "NodeID{}", + NodeID{}, + []byte(`"NodeID-111111111111111111116DBWJs"`), + nil, + }, + { + `ID("ava labs")`, NodeID{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}, - []byte("\"NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz\""), + []byte(`"NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz"`), nil, }, } @@ -94,40 +99,45 @@ func TestNodeIDUnmarshalJSON(t *testing.T) { out NodeID expectedErr error }{ - {"NodeID{}", []byte("null"), NodeID{}, nil}, { - "NodeID(\"ava labs\")", - []byte("\"NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz\""), + "NodeID{}", + []byte("null"), + NodeID{}, + nil, + }, + { + `NodeID("ava labs")`, + []byte(`"NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz"`), NodeID{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}, nil, }, { "missing start quote", - []byte("NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz\""), + []byte(`NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz"`), NodeID{}, errMissingQuotes, }, { "missing end quote", - []byte("\"NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz"), + []byte(`"NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz`), NodeID{}, errMissingQuotes, }, { "NodeID-", - []byte("\"NodeID-\""), + []byte(`"NodeID-"`), NodeID{}, errShortNodeID, }, { "NodeID-1", - []byte("\"NodeID-1\""), + []byte(`"NodeID-1"`), NodeID{}, cb58.ErrMissingChecksum, }, { "NodeID-9tLMkeWFhWXd8QZc4rSiS5meuVXF5kRsz1", - []byte("\"NodeID-1\""), + []byte(`"NodeID-1"`), NodeID{}, cb58.ErrMissingChecksum, }, diff --git a/ids/short.go b/ids/short.go index b19e0420690d..8de2a43828b8 100644 --- a/ids/short.go +++ b/ids/short.go @@ -54,7 +54,7 @@ func (id ShortID) MarshalJSON() ([]byte, error) { if err != nil { return nil, err } - return []byte("\"" + str + "\""), nil + return []byte(`"` + str + `"`), nil } func (id *ShortID) UnmarshalJSON(b []byte) error { diff --git a/node/overridden_manager_test.go b/node/overridden_manager_test.go index 79f03579a5d0..80dfabe10552 100644 --- a/node/overridden_manager_test.go +++ b/node/overridden_manager_test.go @@ -64,12 +64,12 @@ func TestOverriddenString(t *testing.T) { require.NoError(m.AddStaker(subnetID1, nodeID1, nil, ids.Empty, 1)) om := newOverriddenManager(subnetID0, m) - expected := "Overridden Validator Manager (SubnetID = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES): Validator Manager: (Size = 2)\n" + - " Subnet[TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES]: Validator Set: (Size = 2, Weight = 9223372036854775807)\n" + - " Validator[0]: NodeID-111111111111111111116DBWJs, 1\n" + - " Validator[1]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 9223372036854775806\n" + - " Subnet[2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w]: Validator Set: (Size = 1, Weight = 1)\n" + - " Validator[0]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 1" + expected := `Overridden Validator Manager (SubnetID = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES): Validator Manager: (Size = 2) + Subnet[TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES]: Validator Set: (Size = 2, Weight = 9223372036854775807) + Validator[0]: NodeID-111111111111111111116DBWJs, 1 + Validator[1]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 9223372036854775806 + Subnet[2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w]: Validator Set: (Size = 1, Weight = 1) + Validator[0]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 1` result := om.String() require.Equal(expected, result) } diff --git a/snow/choices/status.go b/snow/choices/status.go index 255356b73960..9a8d410cf005 100644 --- a/snow/choices/status.go +++ b/snow/choices/status.go @@ -29,22 +29,19 @@ func (s Status) MarshalJSON() ([]byte, error) { if err := s.Valid(); err != nil { return nil, err } - return []byte("\"" + s.String() + "\""), nil + return []byte(`"` + s.String() + `"`), nil } func (s *Status) UnmarshalJSON(b []byte) error { - str := string(b) - if str == "null" { - return nil - } - switch str { - case "\"Unknown\"": + switch string(b) { + case "null": + case `"Unknown"`: *s = Unknown - case "\"Processing\"": + case `"Processing"`: *s = Processing - case "\"Rejected\"": + case `"Rejected"`: *s = Rejected - case "\"Accepted\"": + case `"Accepted"`: *s = Accepted default: return errUnknownStatus diff --git a/snow/consensus/snowball/parameters.go b/snow/consensus/snowball/parameters.go index 29bb0ba9e215..00f6d5bb95c4 100644 --- a/snow/consensus/snowball/parameters.go +++ b/snow/consensus/snowball/parameters.go @@ -17,21 +17,21 @@ const ( // 1 means MinPercentConnected = 1 (fully connected). MinPercentConnectedBuffer = .2 - errMsg = "" + - `__________ .___` + "\n" + - `\______ \____________ __| _/__.__.` + "\n" + - ` | | _/\_ __ \__ \ / __ < | |` + "\n" + - ` | | \ | | \// __ \_/ /_/ |\___ |` + "\n" + - ` |______ / |__| (____ /\____ |/ ____|` + "\n" + - ` \/ \/ \/\/` + "\n" + - "\n" + - ` 🏆 🏆 🏆 🏆 🏆 🏆 🏆` + "\n" + - ` ________ ________ ________________` + "\n" + - ` / _____/ \_____ \ / _ \__ ___/` + "\n" + - `/ \ ___ / | \ / /_\ \| |` + "\n" + - `\ \_\ \/ | \/ | \ |` + "\n" + - ` \______ /\_______ /\____|__ /____|` + "\n" + - ` \/ \/ \/` + "\n" + errMsg = `__________ .___ +\______ \____________ __| _/__.__. + | | _/\_ __ \__ \ / __ < | | + | | \ | | \// __ \_/ /_/ |\___ | + |______ / |__| (____ /\____ |/ ____| + \/ \/ \/\/ + + 🏆 🏆 🏆 🏆 🏆 🏆 🏆 + ________ ________ ________________ + / _____/ \_____ \ / _ \__ ___/ +/ \ ___ / | \ / /_\ \| | +\ \_\ \/ | \/ | \ | + \______ /\_______ /\____|__ /____| + \/ \/ \/ +` ) var ( diff --git a/snow/consensus/snowball/tree_test.go b/snow/consensus/snowball/tree_test.go index 39252ea01624..9d96c53bd7d5 100644 --- a/snow/consensus/snowball/tree_test.go +++ b/snow/consensus/snowball/tree_test.go @@ -148,8 +148,8 @@ func TestSnowballLastBinary(t *testing.T) { // Should do nothing tree.Add(one) - expected := "SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [0, 255)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 255" + expected := `SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [0, 255) + SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 255` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -159,8 +159,8 @@ func TestSnowballLastBinary(t *testing.T) { require.Equal(one, tree.Preference()) require.False(tree.Finalized()) - expected = "SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [0, 255)\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 255" + expected = `SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [0, 255) + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 255` require.Equal(expected, tree.String()) require.True(tree.RecordPoll(oneBag)) @@ -191,12 +191,12 @@ func TestSnowballAddPreviouslyRejected(t *testing.T) { tree.Add(four) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 2)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 2) + SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -206,11 +206,11 @@ func TestSnowballAddPreviouslyRejected(t *testing.T) { require.True(tree.RecordPoll(zeroBag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -219,11 +219,11 @@ func TestSnowballAddPreviouslyRejected(t *testing.T) { tree.Add(two) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -247,9 +247,9 @@ func TestSnowballNewUnary(t *testing.T) { tree.Add(one) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -259,9 +259,9 @@ func TestSnowballNewUnary(t *testing.T) { require.True(tree.RecordPoll(oneBag)) { - expected := "SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256) + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(one, tree.Preference()) require.False(tree.Finalized()) @@ -270,9 +270,9 @@ func TestSnowballNewUnary(t *testing.T) { require.True(tree.RecordPoll(oneBag)) { - expected := "SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 2, SF(Confidence = 2, Finalized = false, SL(Preference = 1))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)\n" + - " SB(PreferenceStrength = 2, SF(Confidence = 2, Finalized = true)) Bits = [1, 256)" + expected := `SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 2, SF(Confidence = 2, Finalized = false, SL(Preference = 1))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256) + SB(PreferenceStrength = 2, SF(Confidence = 2, Finalized = true)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(one, tree.Preference()) require.False(tree.Finalized()) @@ -298,13 +298,13 @@ func TestSnowballTransitiveReset(t *testing.T) { tree.Add(eight) { - expected := "SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [0, 1)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 1\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 3)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 3\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)" + expected := `SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [0, 1) + SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 1 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 3) + SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 3 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -314,13 +314,13 @@ func TestSnowballTransitiveReset(t *testing.T) { require.True(tree.RecordPoll(zeroBag)) { - expected := "SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [0, 1)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [2, 3)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 3\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [4, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)" + expected := `SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [0, 1) + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [2, 3) + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 3 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [4, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -330,13 +330,13 @@ func TestSnowballTransitiveReset(t *testing.T) { require.False(tree.RecordPoll(emptyBag)) { - expected := "SB(PreferenceStrength = 1, SF(Confidence = 0, Finalized = false)) Bits = [0, 1)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [2, 3)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 3\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [4, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)" + expected := `SB(PreferenceStrength = 1, SF(Confidence = 0, Finalized = false)) Bits = [0, 1) + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [2, 3) + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 3 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = false)) Bits = [4, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -345,13 +345,13 @@ func TestSnowballTransitiveReset(t *testing.T) { require.True(tree.RecordPoll(zeroBag)) { - expected := "SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = false)) Bits = [0, 1)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1\n" + - " SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = false)) Bits = [2, 3)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 3\n" + - " SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = false)) Bits = [4, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)" + expected := `SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = false)) Bits = [0, 1) + SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1 + SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = false)) Bits = [2, 3) + SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 3 + SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = false)) Bits = [4, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [4, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)` require.Equal(expected, tree.String()) require.Equal(zero, tree.Preference()) require.False(tree.Finalized()) @@ -491,11 +491,11 @@ func TestSnowballAddRejected(t *testing.T) { require.True(tree.RecordPoll(c0010Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 2\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 2 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0010, tree.Preference()) require.False(tree.Finalized()) @@ -504,11 +504,11 @@ func TestSnowballAddRejected(t *testing.T) { tree.Add(c0101) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 2\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 2 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0010, tree.Preference()) require.False(tree.Finalized()) @@ -540,11 +540,11 @@ func TestSnowballResetChild(t *testing.T) { require.True(tree.RecordPoll(c0000Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -554,11 +554,11 @@ func TestSnowballResetChild(t *testing.T) { require.False(tree.RecordPoll(emptyBag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -567,11 +567,11 @@ func TestSnowballResetChild(t *testing.T) { require.True(tree.RecordPoll(c0000Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1\n" + - " SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = true)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 1 + SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = true)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -603,11 +603,11 @@ func TestSnowballResetSibling(t *testing.T) { require.True(tree.RecordPoll(c0100Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 1\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 1 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0100, tree.Preference()) require.False(tree.Finalized()) @@ -617,11 +617,11 @@ func TestSnowballResetSibling(t *testing.T) { require.True(tree.RecordPoll(c1000Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 0\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 1\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 0 + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 1 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [2, 256) + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0100, tree.Preference()) require.False(tree.Finalized()) @@ -630,11 +630,11 @@ func TestSnowballResetSibling(t *testing.T) { require.True(tree.RecordPoll(c0100Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 2, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 1\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = true)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 2, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 2, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 1 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 2, SF(Confidence = 1, Finalized = true)) Bits = [2, 256) + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0100, tree.Preference()) require.False(tree.Finalized()) @@ -701,9 +701,9 @@ func TestSnowballFineGrained(t *testing.T) { tree.Add(c1100) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -712,11 +712,11 @@ func TestSnowballFineGrained(t *testing.T) { tree.Add(c1000) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 1))) Bit = 1\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256) + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 1))) Bit = 1 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -725,14 +725,14 @@ func TestSnowballFineGrained(t *testing.T) { tree.Add(c0010) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 2)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 1))) Bit = 1\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 2) + SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 1))) Bit = 1 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -742,13 +742,13 @@ func TestSnowballFineGrained(t *testing.T) { require.True(tree.RecordPoll(c0000Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 1))) Bit = 1\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(Preference = 1, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 1))) Bit = 1 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [2, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -758,9 +758,9 @@ func TestSnowballFineGrained(t *testing.T) { require.True(tree.RecordPoll(c0010Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 2\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 1, SF(Confidence = 1, Finalized = false, SL(Preference = 1))) Bit = 2 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -849,9 +849,9 @@ func TestSnowballFilterBinaryChildren(t *testing.T) { tree.Add(c1000) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -860,12 +860,12 @@ func TestSnowballFilterBinaryChildren(t *testing.T) { tree.Add(c0010) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 2)\n" + - " SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 2) + SB(Preference = 0, PreferenceStrength[0] = 0, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -875,11 +875,11 @@ func TestSnowballFilterBinaryChildren(t *testing.T) { require.True(tree.RecordPoll(c0000Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -888,11 +888,11 @@ func TestSnowballFilterBinaryChildren(t *testing.T) { tree.Add(c0100) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0\n" + - " SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 0 + SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 1, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [1, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) @@ -902,9 +902,9 @@ func TestSnowballFilterBinaryChildren(t *testing.T) { require.True(tree.RecordPoll(c0100Bag)) { - expected := "SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 2\n" + - " SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256)\n" + - " SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)" + expected := `SB(Preference = 0, PreferenceStrength[0] = 1, PreferenceStrength[1] = 0, SF(Confidence = 0, Finalized = false, SL(Preference = 0))) Bit = 2 + SB(PreferenceStrength = 1, SF(Confidence = 1, Finalized = true)) Bits = [3, 256) + SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [3, 256)` require.Equal(expected, tree.String()) require.Equal(c0000, tree.Preference()) require.False(tree.Finalized()) diff --git a/snow/validators/manager_test.go b/snow/validators/manager_test.go index f93ab719e18a..1e6fb4a3abb8 100644 --- a/snow/validators/manager_test.go +++ b/snow/validators/manager_test.go @@ -398,12 +398,12 @@ func TestString(t *testing.T) { require.NoError(m.AddStaker(subnetID0, nodeID1, nil, ids.Empty, math.MaxInt64-1)) require.NoError(m.AddStaker(subnetID1, nodeID1, nil, ids.Empty, 1)) - expected := "Validator Manager: (Size = 2)\n" + - " Subnet[TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES]: Validator Set: (Size = 2, Weight = 9223372036854775807)\n" + - " Validator[0]: NodeID-111111111111111111116DBWJs, 1\n" + - " Validator[1]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 9223372036854775806\n" + - " Subnet[2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w]: Validator Set: (Size = 1, Weight = 1)\n" + - " Validator[0]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 1" + expected := `Validator Manager: (Size = 2) + Subnet[TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES]: Validator Set: (Size = 2, Weight = 9223372036854775807) + Validator[0]: NodeID-111111111111111111116DBWJs, 1 + Validator[1]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 9223372036854775806 + Subnet[2mcwQKiD8VEspmMJpL1dc7okQQ5dDVAWeCBZ7FWBFAbxpv3t7w]: Validator Set: (Size = 1, Weight = 1) + Validator[0]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 1` result := m.String() require.Equal(expected, result) } diff --git a/snow/validators/set_test.go b/snow/validators/set_test.go index 0067a520b5a9..f11a6f92c727 100644 --- a/snow/validators/set_test.go +++ b/snow/validators/set_test.go @@ -342,9 +342,9 @@ func TestSetString(t *testing.T) { require.NoError(s.Add(nodeID1, nil, ids.Empty, math.MaxInt64-1)) - expected := "Validator Set: (Size = 2, Weight = 9223372036854775807)\n" + - " Validator[0]: NodeID-111111111111111111116DBWJs, 1\n" + - " Validator[1]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 9223372036854775806" + expected := `Validator Set: (Size = 2, Weight = 9223372036854775807) + Validator[0]: NodeID-111111111111111111116DBWJs, 1 + Validator[1]: NodeID-QLbz7JHiBTspS962RLKV8GndWFwdYhk6V, 9223372036854775806` result := s.String() require.Equal(expected, result) } diff --git a/tests/fixture/tmpnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go index 0fe8435bb49e..6e0a87e272a2 100644 --- a/tests/fixture/tmpnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -83,8 +83,8 @@ func main() { return err } - fmt.Fprintf(os.Stdout, "\nConfigure tmpnetctl to target this network by default with one of the following statements:") - fmt.Fprintf(os.Stdout, "\n - source %s\n", network.EnvFilePath()) + fmt.Fprintf(os.Stdout, "\nConfigure tmpnetctl to target this network by default with one of the following statements:\n") + fmt.Fprintf(os.Stdout, " - source %s\n", network.EnvFilePath()) fmt.Fprintf(os.Stdout, " - %s\n", network.EnvFileContents()) fmt.Fprintf(os.Stdout, " - export %s=%s\n", tmpnet.NetworkDirEnvName, latestSymlinkPath) diff --git a/utils/bag/bag_test.go b/utils/bag/bag_test.go index 1a42486560a6..ffbda6379c77 100644 --- a/utils/bag/bag_test.go +++ b/utils/bag/bag_test.go @@ -201,8 +201,8 @@ func TestBagString(t *testing.T) { bag.AddCount(elt0, 1337) - expected := "Bag[int]: (Size = 1337)\n" + - " 123: 1337" + expected := `Bag[int]: (Size = 1337) + 123: 1337` require.Equal(t, expected, bag.String()) } diff --git a/utils/crypto/secp256k1/secp256k1.go b/utils/crypto/secp256k1/secp256k1.go index 022cce2861a0..733cee732d74 100644 --- a/utils/crypto/secp256k1/secp256k1.go +++ b/utils/crypto/secp256k1/secp256k1.go @@ -220,7 +220,7 @@ func (k *PrivateKey) String() string { } func (k *PrivateKey) MarshalJSON() ([]byte, error) { - return []byte("\"" + k.String() + "\""), nil + return []byte(`"` + k.String() + `"`), nil } func (k *PrivateKey) MarshalText() ([]byte, error) { diff --git a/utils/formatting/encoding.go b/utils/formatting/encoding.go index 20ab4df30157..b80c82779810 100644 --- a/utils/formatting/encoding.go +++ b/utils/formatting/encoding.go @@ -69,7 +69,7 @@ func (enc Encoding) MarshalJSON() ([]byte, error) { if !enc.valid() { return nil, errInvalidEncoding } - return []byte("\"" + enc.String() + "\""), nil + return []byte(`"` + enc.String() + `"`), nil } func (enc *Encoding) UnmarshalJSON(b []byte) error { diff --git a/utils/json/float32.go b/utils/json/float32.go index a20ee2bde525..26694b090b68 100644 --- a/utils/json/float32.go +++ b/utils/json/float32.go @@ -8,7 +8,7 @@ import "strconv" type Float32 float32 func (f Float32) MarshalJSON() ([]byte, error) { - return []byte("\"" + strconv.FormatFloat(float64(f), byte('f'), 4, 32) + "\""), nil + return []byte(`"` + strconv.FormatFloat(float64(f), byte('f'), 4, 32) + `"`), nil } func (f *Float32) UnmarshalJSON(b []byte) error { diff --git a/utils/json/float64.go b/utils/json/float64.go index 4d31459ecf19..8467fbf94745 100644 --- a/utils/json/float64.go +++ b/utils/json/float64.go @@ -8,7 +8,7 @@ import "strconv" type Float64 float64 func (f Float64) MarshalJSON() ([]byte, error) { - return []byte("\"" + strconv.FormatFloat(float64(f), byte('f'), 4, 64) + "\""), nil + return []byte(`"` + strconv.FormatFloat(float64(f), byte('f'), 4, 64) + `"`), nil } func (f *Float64) UnmarshalJSON(b []byte) error { diff --git a/utils/json/uint16.go b/utils/json/uint16.go index c2c8b6da378a..ae537ab2c9fb 100644 --- a/utils/json/uint16.go +++ b/utils/json/uint16.go @@ -8,7 +8,7 @@ import "strconv" type Uint16 uint16 func (u Uint16) MarshalJSON() ([]byte, error) { - return []byte("\"" + strconv.FormatUint(uint64(u), 10) + "\""), nil + return []byte(`"` + strconv.FormatUint(uint64(u), 10) + `"`), nil } func (u *Uint16) UnmarshalJSON(b []byte) error { diff --git a/utils/json/uint32.go b/utils/json/uint32.go index 0bd0f28544d1..c367051b2938 100644 --- a/utils/json/uint32.go +++ b/utils/json/uint32.go @@ -8,7 +8,7 @@ import "strconv" type Uint32 uint32 func (u Uint32) MarshalJSON() ([]byte, error) { - return []byte("\"" + strconv.FormatUint(uint64(u), 10) + "\""), nil + return []byte(`"` + strconv.FormatUint(uint64(u), 10) + `"`), nil } func (u *Uint32) UnmarshalJSON(b []byte) error { diff --git a/utils/json/uint64.go b/utils/json/uint64.go index ba3189039d67..c28229024284 100644 --- a/utils/json/uint64.go +++ b/utils/json/uint64.go @@ -8,7 +8,7 @@ import "strconv" type Uint64 uint64 func (u Uint64) MarshalJSON() ([]byte, error) { - return []byte("\"" + strconv.FormatUint(uint64(u), 10) + "\""), nil + return []byte(`"` + strconv.FormatUint(uint64(u), 10) + `"`), nil } func (u *Uint64) UnmarshalJSON(b []byte) error { diff --git a/utils/json/uint8.go b/utils/json/uint8.go index c43f2786daf6..c4a34bdb2074 100644 --- a/utils/json/uint8.go +++ b/utils/json/uint8.go @@ -8,7 +8,7 @@ import "strconv" type Uint8 uint8 func (u Uint8) MarshalJSON() ([]byte, error) { - return []byte("\"" + strconv.FormatUint(uint64(u), 10) + "\""), nil + return []byte(`"` + strconv.FormatUint(uint64(u), 10) + `"`), nil } func (u *Uint8) UnmarshalJSON(b []byte) error { diff --git a/utils/logging/sanitize.go b/utils/logging/sanitize.go index 05b24ff96be2..c4fdf7124fdd 100644 --- a/utils/logging/sanitize.go +++ b/utils/logging/sanitize.go @@ -12,7 +12,7 @@ import ( type sanitizedString string func (s sanitizedString) String() string { - return strings.ReplaceAll(string(s), "\n", "\\n") + return strings.ReplaceAll(string(s), "\n", `\n`) } // UserString constructs a field with the given key and the value stripped of @@ -29,7 +29,7 @@ func (s sanitizedStrings) String() string { if i != 0 { _, _ = strs.WriteString(", ") } - _, _ = strs.WriteString(strings.ReplaceAll(str, "\n", "\\n")) + _, _ = strs.WriteString(strings.ReplaceAll(str, "\n", `\n`)) } return strs.String() } From 443055051cf54083f4ae27c60193fb882bffe82b Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 17 Dec 2023 14:52:49 -0500 Subject: [PATCH 161/267] Allow OutputOwners to be json marshalled without InitCtx (#2495) --- vms/secp256k1fx/output_owners.go | 21 +++++++++------------ vms/secp256k1fx/output_owners_test.go | 17 +++-------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/vms/secp256k1fx/output_owners.go b/vms/secp256k1fx/output_owners.go index 1c252bd54e6d..c0bb243f4b6e 100644 --- a/vms/secp256k1fx/output_owners.go +++ b/vms/secp256k1fx/output_owners.go @@ -21,7 +21,6 @@ var ( ErrOutputUnspendable = errors.New("output is unspendable") ErrOutputUnoptimized = errors.New("output representation should be optimized") ErrAddrsNotSortedUnique = errors.New("addresses not sorted and unique") - ErrMarshal = errors.New("cannot marshal without ctx") ) type OutputOwners struct { @@ -37,8 +36,8 @@ type OutputOwners struct { ctx *snow.Context } -// InitCtx assigns the OutputOwners.ctx object to given [ctx] object -// Must be called at least once for MarshalJSON to work successfully +// InitCtx allows addresses to be formatted into their human readable format +// during json marshalling. func (out *OutputOwners) InitCtx(ctx *snow.Context) { out.ctx = ctx } @@ -59,14 +58,7 @@ func (out *OutputOwners) MarshalJSON() ([]byte, error) { // Fields returns JSON keys in a map that can be used with marshal JSON // to serialize OutputOwners struct func (out *OutputOwners) Fields() (map[string]interface{}, error) { - addrsLen := len(out.Addrs) - - // we need out.ctx to do this, if its absent, throw error - if addrsLen > 0 && out.ctx == nil { - return nil, ErrMarshal - } - - addresses := make([]string, addrsLen) + addresses := make([]string, len(out.Addrs)) for i, addr := range out.Addrs { // for each [addr] in [Addrs] we attempt to format it given // the [out.ctx] object @@ -138,8 +130,13 @@ func (out *OutputOwners) Sort() { } // formatAddress formats a given [addr] into human readable format using -// [ChainID] and [NetworkID] from the provided [ctx]. +// [ChainID] and [NetworkID] if a non-nil [ctx] is provided. If [ctx] is not +// provided, the address will be returned in cb58 format. func formatAddress(ctx *snow.Context, addr ids.ShortID) (string, error) { + if ctx == nil { + return addr.String(), nil + } + chainIDAlias, err := ctx.BCLookup.PrimaryAlias(ctx.ChainID) if err != nil { return "", err diff --git a/vms/secp256k1fx/output_owners_test.go b/vms/secp256k1fx/output_owners_test.go index b09e28bea923..97741e6b6f3d 100644 --- a/vms/secp256k1fx/output_owners_test.go +++ b/vms/secp256k1fx/output_owners_test.go @@ -149,31 +149,20 @@ func TestOutputOwnerEquals(t *testing.T) { } } -func TestMarshalJSONRequiresCtxWhenAddrsArePresent(t *testing.T) { +func TestMarshalJSONDoesNotRequireCtx(t *testing.T) { require := require.New(t) out := &OutputOwners{ Threshold: 1, + Locktime: 2, Addrs: []ids.ShortID{ {1}, {0}, }, } - _, err := out.MarshalJSON() - require.ErrorIs(err, ErrMarshal) -} - -func TestMarshalJSONDoesNotRequireCtxWhenAddrsAreAbsent(t *testing.T) { - require := require.New(t) - out := &OutputOwners{ - Threshold: 1, - Locktime: 2, - Addrs: []ids.ShortID{}, - } - b, err := out.MarshalJSON() require.NoError(err) jsonData := string(b) - require.Equal(jsonData, "{\"addresses\":[],\"locktime\":2,\"threshold\":1}") + require.Equal(jsonData, `{"addresses":["6HgC8KRBEhXYbF4riJyJFLSHt37UNuRt","111111111111111111116DBWJs"],"locktime":2,"threshold":1}`) } From aa764bb9684f74c09be2e81d443a9832a369e0b6 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 18 Dec 2023 16:00:17 -0700 Subject: [PATCH 162/267] Drop Pending Stakers 5 - validated PostDurango StakerTxs (#2314) Co-authored-by: Stephen Buttolph Co-authored-by: dhrubabasu <7675102+dhrubabasu@users.noreply.github.com> --- tests/e2e/p/interchain_workflow.go | 17 +- tests/e2e/p/permissionless_subnets.go | 9 +- tests/e2e/p/staking_rewards.go | 73 ++++---- tests/e2e/p/workflow.go | 6 +- tests/fixture/e2e/helpers.go | 6 - vms/platformvm/block/builder/builder_test.go | 95 ++++++++-- .../block/executor/proposal_block_test.go | 31 +--- vms/platformvm/state/state.go | 9 +- .../txs/executor/advance_time_test.go | 24 +-- .../txs/executor/create_chain_test.go | 10 +- .../txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/export_test.go | 2 +- .../txs/executor/proposal_tx_executor_test.go | 7 +- .../txs/executor/reward_validator_test.go | 4 +- .../txs/executor/staker_tx_verification.go | 163 +++++++++++------- .../staker_tx_verification_helpers.go | 8 +- .../executor/staker_tx_verification_test.go | 17 +- .../txs/executor/standard_tx_executor.go | 60 ++++++- .../txs/executor/standard_tx_executor_test.go | 47 ++++- vms/platformvm/txs/validator.go | 5 - vms/platformvm/validator_set_property_test.go | 21 +-- vms/platformvm/vm_regression_test.go | 12 +- vms/platformvm/vm_test.go | 32 +--- 23 files changed, 392 insertions(+), 268 deletions(-) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 755312ae8160..64caab902531 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -95,13 +95,9 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) require.NoError(err) + // Adding a validator should not break interchain transfer. + endTime := time.Now().Add(30 * time.Second) ginkgo.By("adding the new node as a validator", func() { - startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - // Validation duration doesn't actually matter to this - // test - it is only ensuring that adding a validator - // doesn't break interchain transfer. - endTime := startTime.Add(30 * time.Second) - rewardKey, err := secp256k1.NewPrivateKey() require.NoError(err) @@ -114,7 +110,6 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: nodeID, - Start: uint64(startTime.Unix()), End: uint64(endTime.Unix()), Wght: weight, }, @@ -136,13 +131,8 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL require.NoError(err) }) + // Adding a delegator should not break interchain transfer. ginkgo.By("adding a delegator to the new node", func() { - startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - // Delegation duration doesn't actually matter to this - // test - it is only ensuring that adding a delegator - // doesn't break interchain transfer. - endTime := startTime.Add(15 * time.Second) - rewardKey, err := secp256k1.NewPrivateKey() require.NoError(err) @@ -150,7 +140,6 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: nodeID, - Start: uint64(startTime.Unix()), End: uint64(endTime.Unix()), Wght: weight, }, diff --git a/tests/e2e/p/permissionless_subnets.go b/tests/e2e/p/permissionless_subnets.go index 0521306b9b40..566e36aa6178 100644 --- a/tests/e2e/p/permissionless_subnets.go +++ b/tests/e2e/p/permissionless_subnets.go @@ -134,14 +134,13 @@ var _ = e2e.DescribePChain("[Permissionless Subnets]", func() { require.NoError(err) }) - validatorStartTime := time.Now().Add(time.Minute) + endTime := time.Now().Add(time.Minute) ginkgo.By("add permissionless validator", func() { _, err := pWallet.IssueAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: validatorID, - Start: uint64(validatorStartTime.Unix()), - End: uint64(validatorStartTime.Add(5 * time.Second).Unix()), + End: uint64(endTime.Unix()), Wght: 25 * units.MegaAvax, }, Subnet: subnetID, @@ -156,14 +155,12 @@ var _ = e2e.DescribePChain("[Permissionless Subnets]", func() { require.NoError(err) }) - delegatorStartTime := validatorStartTime ginkgo.By("add permissionless delegator", func() { _, err := pWallet.IssueAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: validatorID, - Start: uint64(delegatorStartTime.Unix()), - End: uint64(delegatorStartTime.Add(5 * time.Second).Unix()), + End: uint64(endTime.Unix()), Wght: 25 * units.MegaAvax, }, Subnet: subnetID, diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index c8ae29805ebf..2ede58b53832 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -31,8 +31,8 @@ import ( ) const ( - delegationPeriod = 15 * time.Second - validationPeriod = 30 * time.Second + targetDelegationPeriod = 15 * time.Second + targetValidationPeriod = 30 * time.Second ) var _ = ginkgo.Describe("[Staking Rewards]", func() { @@ -58,6 +58,16 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { ginkgo.By("waiting until beta node is healthy") e2e.WaitForHealthy(betaNode) + ginkgo.By("retrieving alpha node id and pop") + alphaInfoClient := info.NewClient(alphaNode.URI) + alphaNodeID, alphaPOP, err := alphaInfoClient.GetNodeID(e2e.DefaultContext()) + require.NoError(err) + + ginkgo.By("retrieving beta node id and pop") + betaInfoClient := info.NewClient(betaNode.URI) + betaNodeID, betaPOP, err := betaInfoClient.GetNodeID(e2e.DefaultContext()) + require.NoError(err) + ginkgo.By("generating reward keys") alphaValidationRewardKey, err := secp256k1.NewPrivateKey() @@ -89,43 +99,34 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { keychain := secp256k1fx.NewKeychain(rewardKeys...) fundedKey := e2e.Env.AllocatePreFundedKey() keychain.Add(fundedKey) - nodeURI := e2e.Env.GetRandomNodeURI() + nodeURI := tmpnet.NodeURI{ + NodeID: alphaNodeID, + URI: alphaNode.URI, + } baseWallet := e2e.NewWallet(keychain, nodeURI) pWallet := baseWallet.P() - ginkgo.By("retrieving alpha node id and pop") - alphaInfoClient := info.NewClient(alphaNode.URI) - alphaNodeID, alphaPOP, err := alphaInfoClient.GetNodeID(e2e.DefaultContext()) - require.NoError(err) - - ginkgo.By("retrieving beta node id and pop") - betaInfoClient := info.NewClient(betaNode.URI) - betaNodeID, betaPOP, err := betaInfoClient.GetNodeID(e2e.DefaultContext()) - require.NoError(err) - - pvmClient := platformvm.NewClient(alphaNode.URI) - const ( delegationPercent = 0.10 // 10% delegationShare = reward.PercentDenominator * delegationPercent weight = 2_000 * units.Avax ) + pvmClient := platformvm.NewClient(alphaNode.URI) + ginkgo.By("retrieving supply before inserting validators") supplyAtValidatorsStart, _, err := pvmClient.GetCurrentSupply(e2e.DefaultContext(), constants.PrimaryNetworkID) require.NoError(err) - alphaValidatorStartTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - alphaValidatorEndTime := alphaValidatorStartTime.Add(validationPeriod) - tests.Outf("alpha node validation period starting at: %v\n", alphaValidatorStartTime) + alphaValidatorsEndTime := time.Now().Add(targetValidationPeriod) + tests.Outf("alpha node validation period ending at: %v\n", alphaValidatorsEndTime) ginkgo.By("adding alpha node as a validator", func() { _, err := pWallet.IssueAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: alphaNodeID, - Start: uint64(alphaValidatorStartTime.Unix()), - End: uint64(alphaValidatorEndTime.Unix()), + End: uint64(alphaValidatorsEndTime.Unix()), Wght: weight, }, Subnet: constants.PrimaryNetworkID, @@ -146,16 +147,14 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { require.NoError(err) }) - betaValidatorStartTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - betaValidatorEndTime := betaValidatorStartTime.Add(validationPeriod) - tests.Outf("beta node validation period starting at: %v\n", betaValidatorStartTime) + betaValidatorEndTime := time.Now().Add(targetValidationPeriod) + tests.Outf("beta node validation period ending at: %v\n", betaValidatorEndTime) ginkgo.By("adding beta node as a validator", func() { _, err := pWallet.IssueAddPermissionlessValidatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: betaNodeID, - Start: uint64(betaValidatorStartTime.Unix()), End: uint64(betaValidatorEndTime.Unix()), Wght: weight, }, @@ -181,16 +180,15 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { supplyAtDelegatorsStart, _, err := pvmClient.GetCurrentSupply(e2e.DefaultContext(), constants.PrimaryNetworkID) require.NoError(err) - gammaDelegatorStartTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - tests.Outf("gamma delegation period starting at: %v\n", gammaDelegatorStartTime) + gammaDelegatorEndTime := time.Now().Add(targetDelegationPeriod) + tests.Outf("gamma delegation period ending at: %v\n", gammaDelegatorEndTime) ginkgo.By("adding gamma as delegator to the alpha node", func() { _, err := pWallet.IssueAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: alphaNodeID, - Start: uint64(gammaDelegatorStartTime.Unix()), - End: uint64(gammaDelegatorStartTime.Add(delegationPeriod).Unix()), + End: uint64(gammaDelegatorEndTime.Unix()), Wght: weight, }, Subnet: constants.PrimaryNetworkID, @@ -205,16 +203,15 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { require.NoError(err) }) - deltaDelegatorStartTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - tests.Outf("delta delegation period starting at: %v\n", deltaDelegatorStartTime) + deltaDelegatorEndTime := time.Now().Add(targetDelegationPeriod) + tests.Outf("delta delegation period ending at: %v\n", deltaDelegatorEndTime) ginkgo.By("adding delta as delegator to the beta node", func() { _, err := pWallet.IssueAddPermissionlessDelegatorTx( &txs.SubnetValidator{ Validator: txs.Validator{ NodeID: betaNodeID, - Start: uint64(deltaDelegatorStartTime.Unix()), - End: uint64(deltaDelegatorStartTime.Add(delegationPeriod).Unix()), + End: uint64(deltaDelegatorEndTime.Unix()), Wght: weight, }, Subnet: constants.PrimaryNetworkID, @@ -232,6 +229,14 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { ginkgo.By("stopping beta node to prevent it and its delegator from receiving a validation reward") require.NoError(betaNode.Stop()) + ginkgo.By("retrieving staking periods from the chain") + data, err := pvmClient.GetCurrentValidators(e2e.DefaultContext(), constants.PlatformChainID, []ids.NodeID{alphaNodeID}) + require.NoError(err) + require.Len(data, 1) + actualAlphaValidationPeriod := time.Duration(data[0].EndTime-data[0].StartTime) * time.Second + delegatorData := data[0].Delegators[0] + actualGammaDelegationPeriod := time.Duration(delegatorData.EndTime-delegatorData.StartTime) * time.Second + ginkgo.By("waiting until all validation periods are over") // The beta validator was the last added and so has the latest end time. The // delegation periods are shorter than the validation periods. @@ -279,8 +284,8 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { ginkgo.By("determining expected validation and delegation rewards") calculator := reward.NewCalculator(rewardConfig) - expectedValidationReward := calculator.Calculate(validationPeriod, weight, supplyAtValidatorsStart) - potentialDelegationReward := calculator.Calculate(delegationPeriod, weight, supplyAtDelegatorsStart) + expectedValidationReward := calculator.Calculate(actualAlphaValidationPeriod, weight, supplyAtValidatorsStart) + potentialDelegationReward := calculator.Calculate(actualGammaDelegationPeriod, weight, supplyAtDelegatorsStart) expectedDelegationFee, expectedDelegatorReward := reward.Split(potentialDelegationReward, delegationShare) ginkgo.By("checking expected rewards against actual rewards") diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 8cc7c109d3a4..12410f1eeb54 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -68,9 +68,6 @@ var _ = e2e.DescribePChain("[Workflow]", func() { require.NoError(err) require.GreaterOrEqual(pBalance, minBalance) }) - // create validator data - validatorStartTimeDiff := 30 * time.Second - vdrStartTime := time.Now().Add(validatorStartTimeDiff) // Use a random node ID to ensure that repeated test runs // will succeed against a network that persists across runs. @@ -79,8 +76,7 @@ var _ = e2e.DescribePChain("[Workflow]", func() { vdr := &txs.Validator{ NodeID: validatorID, - Start: uint64(vdrStartTime.Unix()), - End: uint64(vdrStartTime.Add(72 * time.Hour).Unix()), + End: uint64(time.Now().Add(72 * time.Hour).Unix()), Wght: minValStake, } rewardOwner := &secp256k1fx.OutputOwners{ diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 36555bae598c..7df75ad85cf7 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -44,11 +43,6 @@ const ( // development. SkipBootstrapChecksEnvName = "E2E_SKIP_BOOTSTRAP_CHECKS" - // Validator start time must be a minimum of SyncBound from the - // current time for validator addition to succeed, and adding 20 - // seconds provides a buffer in case of any delay in processing. - DefaultValidatorStartTimeDiff = executor.SyncBound + 20*time.Second - DefaultGasLimit = uint64(21000) // Standard gas limit // An empty string prompts the use of the default path which ensures a diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 4b683bf9e1e3..1de7f77af15e 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -135,20 +135,8 @@ func TestBuildBlockShouldReward(t *testing.T) { require.NoError(blk.Accept(context.Background())) require.True(env.blkManager.SetPreference(blk.ID())) - // Validator should now be pending - staker, err := env.state.GetPendingValidator(constants.PrimaryNetworkID, nodeID) - require.NoError(err) - require.Equal(txID, staker.TxID) - - // Move it from pending to current - env.backend.Clk.Set(validatorStartTime) - blk, err = env.Builder.BuildBlock(context.Background()) - require.NoError(err) - require.NoError(blk.Verify(context.Background())) - require.NoError(blk.Accept(context.Background())) - require.True(env.blkManager.SetPreference(blk.ID())) - - staker, err = env.state.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) + // Validator should now be current + staker, err := env.state.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) require.NoError(err) require.Equal(txID, staker.TxID) @@ -298,6 +286,10 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { env.ctx.Lock.Unlock() }() + // The [StartTime] in a staker tx is only validated pre-Durango. + // TODO: Delete this test post-Durango activation. + env.config.DurangoTime = mockable.MaxTime + var ( now = env.backend.Clk.Time() defaultValidatorStake = 100 * units.MilliAvax @@ -384,6 +376,81 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { require.ErrorIs(tx3DropReason, txexecutor.ErrFutureStakeTime) } +func TestBuildBlockInvalidStakingDurations(t *testing.T) { + require := require.New(t) + + env := newEnvironment(t) + env.ctx.Lock.Lock() + defer func() { + require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() + }() + + // Post-Durango, [StartTime] is no longer validated. Staking durations are + // based on the current chain timestamp and must be validated. + env.config.DurangoTime = time.Time{} + + var ( + now = env.backend.Clk.Time() + defaultValidatorStake = 100 * units.MilliAvax + + // Add a validator ending in [MaxStakeDuration] + validatorEndTime = now.Add(env.config.MaxStakeDuration) + ) + + tx1, err := env.txBuilder.NewAddValidatorTx( + defaultValidatorStake, + uint64(now.Unix()), + uint64(validatorEndTime.Unix()), + ids.GenerateTestNodeID(), + preFundedKeys[0].PublicKey().Address(), + reward.PercentDenominator, + []*secp256k1.PrivateKey{preFundedKeys[0]}, + preFundedKeys[0].PublicKey().Address(), + ) + require.NoError(err) + require.NoError(env.mempool.Add(tx1)) + tx1ID := tx1.ID() + require.True(env.mempool.Has(tx1ID)) + + // Add a validator ending past [MaxStakeDuration] + validator2EndTime := now.Add(env.config.MaxStakeDuration + time.Second) + + tx2, err := env.txBuilder.NewAddValidatorTx( + defaultValidatorStake, + uint64(now.Unix()), + uint64(validator2EndTime.Unix()), + ids.GenerateTestNodeID(), + preFundedKeys[2].PublicKey().Address(), + reward.PercentDenominator, + []*secp256k1.PrivateKey{preFundedKeys[2]}, + preFundedKeys[2].PublicKey().Address(), + ) + require.NoError(err) + require.NoError(env.mempool.Add(tx2)) + tx2ID := tx2.ID() + require.True(env.mempool.Has(tx2ID)) + + // Only tx1 should be in a built block since [MaxStakeDuration] is satisfied. + blkIntf, err := env.Builder.BuildBlock(context.Background()) + require.NoError(err) + + require.IsType(&blockexecutor.Block{}, blkIntf) + blk := blkIntf.(*blockexecutor.Block) + require.Len(blk.Txs(), 1) + require.Equal(tx1ID, blk.Txs()[0].ID()) + + // Mempool should have none of the txs + require.False(env.mempool.Has(tx1ID)) + require.False(env.mempool.Has(tx2ID)) + + // Only tx2 should be dropped + require.NoError(env.mempool.GetDropReason(tx1ID)) + + tx2DropReason := env.mempool.GetDropReason(tx2ID) + require.ErrorIs(tx2DropReason, txexecutor.ErrStakeTooLong) +} + func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { require := require.New(t) diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 610fdef0cc87..45f4afe7c9e6 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -1389,33 +1389,8 @@ func TestAddValidatorProposalBlock(t *testing.T) { require.NoError(blk.Accept(context.Background())) require.True(env.blkManager.SetPreference(statelessBlk.ID())) - // Should be pending - staker, err := env.state.GetPendingValidator(constants.PrimaryNetworkID, nodeID) - require.NoError(err) - require.NotNil(staker) - - // Promote validator from pending to current - env.clk.Set(validatorStartTime) - now = env.clk.Time() - - preferredID = env.blkManager.Preferred() - preferred, err = env.blkManager.GetStatelessBlock(preferredID) - require.NoError(err) - - statelessBlk, err = block.NewBanffStandardBlock( - now, - preferredID, - preferred.Height()+1, - nil, - ) - require.NoError(err) - blk = env.blkManager.NewBlock(statelessBlk) - require.NoError(blk.Verify(context.Background())) - require.NoError(blk.Accept(context.Background())) - require.True(env.blkManager.SetPreference(statelessBlk.ID())) - // Should be current - staker, err = env.state.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) + staker, err := env.state.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) require.NoError(err) require.NotNil(staker) @@ -1495,8 +1470,8 @@ func TestAddValidatorProposalBlock(t *testing.T) { require.NoError(blk.Accept(context.Background())) require.NoError(commitBlk.Accept(context.Background())) - // Should be pending - staker, err = env.state.GetPendingValidator(constants.PrimaryNetworkID, nodeID) + // Should be current + staker, err = env.state.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) require.NoError(err) require.NotNil(staker) diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 6b981ab7b675..b6f0218128ce 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1332,7 +1332,10 @@ func (s *state) syncGenesis(genesisBlk block.Block, genesis *genesis.Genesis) er } stakeAmount := validatorTx.Weight() - stakeDuration := validatorTx.EndTime().Sub(validatorTx.StartTime()) + // Note: We use [StartTime()] here because genesis transactions are + // guaranteed to be pre-Durango activation. + startTime := validatorTx.StartTime() + stakeDuration := validatorTx.EndTime().Sub(startTime) currentSupply, err := s.GetCurrentSupply(constants.PrimaryNetworkID) if err != nil { return err @@ -1348,9 +1351,7 @@ func (s *state) syncGenesis(genesisBlk block.Block, genesis *genesis.Genesis) er return err } - // Note: We use [StartTime()] here because genesis transactions are - // guaranteed to be pre-Durango activation. - staker, err := NewCurrentStaker(vdrTx.ID(), validatorTx, validatorTx.StartTime(), potentialReward) + staker, err := NewCurrentStaker(vdrTx.ID(), validatorTx, startTime, potentialReward) if err != nil { return err } diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 24e5746b6047..55cc49e4350b 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -24,7 +24,7 @@ import ( // for the primary network func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -89,7 +89,7 @@ func TestAdvanceTimeTxUpdatePrimaryNetworkStakers(t *testing.T) { // Ensure semantic verification fails when proposed timestamp is at or before current timestamp func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() @@ -116,7 +116,7 @@ func TestAdvanceTimeTxTimestampTooEarly(t *testing.T) { // Ensure semantic verification fails when proposed timestamp is after next validator set change time func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() // Case: Timestamp is after next validator start time @@ -150,7 +150,7 @@ func TestAdvanceTimeTxTimestampTooLate(t *testing.T) { require.NoError(shutdownEnvironment(env)) // Case: Timestamp is after next validator end time - env = newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env = newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -352,7 +352,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -457,7 +457,7 @@ func TestAdvanceTimeTxUpdateStakers(t *testing.T) { // is after the new timestamp func TestAdvanceTimeTxRemoveSubnetValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -561,7 +561,7 @@ func TestTrackedSubnet(t *testing.T) { for _, tracked := range []bool{true, false} { t.Run(fmt.Sprintf("tracked %t", tracked), func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -631,7 +631,7 @@ func TestTrackedSubnet(t *testing.T) { func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -738,7 +738,7 @@ func TestAdvanceTimeTxDelegatorStakerWeight(t *testing.T) { func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -835,7 +835,7 @@ func TestAdvanceTimeTxDelegatorStakers(t *testing.T) { // Test method InitiallyPrefersCommit func TestAdvanceTimeTxInitiallyPrefersCommit(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -865,7 +865,7 @@ func TestAdvanceTimeTxInitiallyPrefersCommit(t *testing.T) { func TestAdvanceTimeTxAfterBanff(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -899,7 +899,7 @@ func TestAdvanceTimeTxAfterBanff(t *testing.T) { // Ensure marshaling/unmarshaling works func TestAdvanceTimeTxUnmarshal(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index 4fa960002a00..ab733337bf63 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -25,7 +25,7 @@ import ( // Ensure Execute fails when there are not enough control sigs func TestCreateChainTxInsufficientControlSigs(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -60,7 +60,7 @@ func TestCreateChainTxInsufficientControlSigs(t *testing.T) { // Ensure Execute fails when an incorrect control signature is given func TestCreateChainTxWrongControlSig(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -102,7 +102,7 @@ func TestCreateChainTxWrongControlSig(t *testing.T) { // its validator set doesn't exist func TestCreateChainTxNoSuchSubnet(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -136,7 +136,7 @@ func TestCreateChainTxNoSuchSubnet(t *testing.T) { // Ensure valid tx passes semanticVerify func TestCreateChainTxValid(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -195,7 +195,7 @@ func TestCreateChainTxAP3FeeChange(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.config.ApricotPhase3Time = ap3Time defer func() { diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index bd1912915f70..8b33f2a7734a 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -49,7 +49,7 @@ func TestCreateSubnetTxAP3FeeChange(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.config.ApricotPhase3Time = ap3Time env.ctx.Lock.Lock() defer func() { diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index 73f625603904..ebc64e1ecd1f 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -15,7 +15,7 @@ import ( ) func TestNewExportTx(t *testing.T) { - env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(t, shutdownEnvironment(env)) diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index eef480f744c9..13ed27e7c5b2 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -837,9 +837,12 @@ func TestProposalTxExecuteAddValidator(t *testing.T) { ) require.NoError(err) - staker, err := state.NewPendingStaker( + addValTx := tx.Unsigned.(*txs.AddValidatorTx) + staker, err := state.NewCurrentStaker( tx.ID(), - tx.Unsigned.(*txs.AddValidatorTx), + addValTx, + addValTx.StartTime(), + 0, ) require.NoError(err) diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 488423c47a07..71c3e93f330e 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -349,7 +349,7 @@ func TestRewardDelegatorTxExecuteOnCommitPreDelegateeDeferral(t *testing.T) { func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*postBanff*/, true /*postCortina*/, true /*postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/, false /*=postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() @@ -568,7 +568,7 @@ func TestRewardDelegatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { func TestRewardDelegatorTxAndValidatorTxExecuteOnCommitPostDelegateeDeferral(t *testing.T) { require := require.New(t) - env := newEnvironment(t, true /*postBanff*/, true /*postCortina*/, true /*postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/, false /*=postDurango*/) defer func() { require.NoError(shutdownEnvironment(env)) }() diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 8a0c6046d67f..5a260fd72cfc 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -44,7 +44,11 @@ var ( // verifySubnetValidatorPrimaryNetworkRequirements verifies the primary // network requirements for [subnetValidator]. An error is returned if they // are not fulfilled. -func verifySubnetValidatorPrimaryNetworkRequirements(chainState state.Chain, subnetValidator txs.Validator) error { +func verifySubnetValidatorPrimaryNetworkRequirements( + isDurangoActive bool, + chainState state.Chain, + subnetValidator txs.Validator, +) error { primaryNetworkValidator, err := GetValidator(chainState, constants.PrimaryNetworkID, subnetValidator.NodeID) if err == database.ErrNotFound { return fmt.Errorf( @@ -63,8 +67,12 @@ func verifySubnetValidatorPrimaryNetworkRequirements(chainState state.Chain, sub // Ensure that the period this validator validates the specified subnet // is a subset of the time they validate the primary network. + startTime := chainState.GetTimestamp() + if !isDurangoActive { + startTime = subnetValidator.StartTime() + } if !txs.BoundedBy( - subnetValidator.StartTime(), + startTime, subnetValidator.EndTime(), primaryNetworkValidator.StartTime, primaryNetworkValidator.EndTime, @@ -92,7 +100,15 @@ func verifyAddValidatorTx( return nil, err } - duration := tx.Validator.Duration() + var ( + currentTimestamp = chainState.GetTimestamp() + isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + startTime = currentTimestamp + ) + if !isDurangoActive { + startTime = tx.StartTime() + } + duration := tx.EndTime().Sub(startTime) switch { case tx.Validator.Wght < backend.Config.MinValidatorStake: // Ensure validator is staking at least the minimum amount @@ -123,11 +139,7 @@ func verifyAddValidatorTx( return outs, nil } - var ( - currentTimestamp = chainState.GetTimestamp() - startTime = tx.StartTime() - ) - if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return nil, err } @@ -163,7 +175,7 @@ func verifyAddValidatorTx( // verifyStakerStartsSoon is checked last to allow // the verifier visitor to explicitly check for this error. - return outs, verifyStakerStartsSoon(currentTimestamp, startTime) + return outs, verifyStakerStartsSoon(isDurangoActive, currentTimestamp, startTime) } // verifyAddSubnetValidatorTx carries out the validation for an @@ -179,7 +191,16 @@ func verifyAddSubnetValidatorTx( return err } - duration := tx.Validator.Duration() + var ( + currentTimestamp = chainState.GetTimestamp() + isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + startTime = currentTimestamp + ) + if !isDurangoActive { + startTime = tx.StartTime() + } + duration := tx.EndTime().Sub(startTime) + switch { case duration < backend.Config.MinStakeDuration: // Ensure staking length is not too short @@ -194,11 +215,7 @@ func verifyAddSubnetValidatorTx( return nil } - var ( - currentTimestamp = chainState.GetTimestamp() - startTime = tx.StartTime() - ) - if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return err } @@ -219,7 +236,7 @@ func verifyAddSubnetValidatorTx( ) } - if err := verifySubnetValidatorPrimaryNetworkRequirements(chainState, tx.Validator); err != nil { + if err := verifySubnetValidatorPrimaryNetworkRequirements(isDurangoActive, chainState, tx.Validator); err != nil { return err } @@ -244,7 +261,7 @@ func verifyAddSubnetValidatorTx( // verifyStakerStartsSoon is checked last to allow // the verifier visitor to explicitly check for this error. - return verifyStakerStartsSoon(currentTimestamp, startTime) + return verifyStakerStartsSoon(isDurangoActive, currentTimestamp, startTime) } // Returns the representation of [tx.NodeID] validating [tx.Subnet]. @@ -331,7 +348,17 @@ func verifyAddDelegatorTx( return nil, err } - duration := tx.Validator.Duration() + var ( + currentTimestamp = chainState.GetTimestamp() + isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + endTime = tx.EndTime() + startTime = currentTimestamp + ) + if !isDurangoActive { + startTime = tx.StartTime() + } + duration := endTime.Sub(startTime) + switch { case duration < backend.Config.MinStakeDuration: // Ensure staking length is not too short @@ -354,11 +381,7 @@ func verifyAddDelegatorTx( return outs, nil } - var ( - currentTimestamp = chainState.GetTimestamp() - startTime = tx.StartTime() - ) - if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return nil, err } @@ -380,21 +403,22 @@ func verifyAddDelegatorTx( maximumWeight = safemath.Min(maximumWeight, backend.Config.MaxValidatorStake) } - txID := sTx.ID() - newStaker, err := state.NewPendingStaker(txID, tx) - if err != nil { - return nil, err - } - if !txs.BoundedBy( - newStaker.StartTime, - newStaker.EndTime, + startTime, + endTime, primaryNetworkValidator.StartTime, primaryNetworkValidator.EndTime, ) { return nil, ErrPeriodMismatch } - overDelegated, err := overDelegated(chainState, primaryNetworkValidator, maximumWeight, newStaker) + overDelegated, err := overDelegated( + chainState, + primaryNetworkValidator, + maximumWeight, + tx.Validator.Wght, + startTime, + endTime, + ) if err != nil { return nil, err } @@ -418,7 +442,7 @@ func verifyAddDelegatorTx( // verifyStakerStartsSoon is checked last to allow // the verifier visitor to explicitly check for this error. - return outs, verifyStakerStartsSoon(currentTimestamp, startTime) + return outs, verifyStakerStartsSoon(isDurangoActive, currentTimestamp, startTime) } // verifyAddPermissionlessValidatorTx carries out the validation for an @@ -440,9 +464,15 @@ func verifyAddPermissionlessValidatorTx( var ( currentTimestamp = chainState.GetTimestamp() - startTime = tx.StartTime() + isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + startTime = currentTimestamp ) - if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + if !isDurangoActive { + startTime = tx.StartTime() + } + duration := tx.EndTime().Sub(startTime) + + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return err } @@ -451,10 +481,7 @@ func verifyAddPermissionlessValidatorTx( return err } - var ( - duration = tx.Validator.Duration() - stakedAssetID = tx.StakeOuts[0].AssetID() - ) + stakedAssetID := tx.StakeOuts[0].AssetID() switch { case tx.Validator.Wght < validatorRules.minValidatorStake: // Ensure validator is staking at least the minimum amount @@ -506,7 +533,7 @@ func verifyAddPermissionlessValidatorTx( var txFee uint64 if tx.Subnet != constants.PrimaryNetworkID { - if err := verifySubnetValidatorPrimaryNetworkRequirements(chainState, tx.Validator); err != nil { + if err := verifySubnetValidatorPrimaryNetworkRequirements(isDurangoActive, chainState, tx.Validator); err != nil { return err } @@ -535,7 +562,7 @@ func verifyAddPermissionlessValidatorTx( // verifyStakerStartsSoon is checked last to allow // the verifier visitor to explicitly check for this error. - return verifyStakerStartsSoon(currentTimestamp, startTime) + return verifyStakerStartsSoon(isDurangoActive, currentTimestamp, startTime) } // verifyAddPermissionlessDelegatorTx carries out the validation for an @@ -557,9 +584,16 @@ func verifyAddPermissionlessDelegatorTx( var ( currentTimestamp = chainState.GetTimestamp() - startTime = tx.StartTime() + isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp) + endTime = tx.EndTime() + startTime = currentTimestamp ) - if err := verifyStakerStartTime(currentTimestamp, startTime); err != nil { + if !isDurangoActive { + startTime = tx.StartTime() + } + duration := endTime.Sub(startTime) + + if err := verifyStakerStartTime(isDurangoActive, currentTimestamp, startTime); err != nil { return err } @@ -568,10 +602,7 @@ func verifyAddPermissionlessDelegatorTx( return err } - var ( - duration = tx.Validator.Duration() - stakedAssetID = tx.StakeOuts[0].AssetID() - ) + stakedAssetID := tx.StakeOuts[0].AssetID() switch { case tx.Validator.Wght < delegatorRules.minDelegatorStake: // Ensure delegator is staking at least the minimum amount @@ -614,21 +645,22 @@ func verifyAddPermissionlessDelegatorTx( } maximumWeight = safemath.Min(maximumWeight, delegatorRules.maxValidatorStake) - txID := sTx.ID() - newStaker, err := state.NewPendingStaker(txID, tx) - if err != nil { - return err - } - if !txs.BoundedBy( - newStaker.StartTime, - newStaker.EndTime, + startTime, + endTime, validator.StartTime, validator.EndTime, ) { return ErrPeriodMismatch } - overDelegated, err := overDelegated(chainState, validator, maximumWeight, newStaker) + overDelegated, err := overDelegated( + chainState, + validator, + maximumWeight, + tx.Validator.Wght, + startTime, + endTime, + ) if err != nil { return err } @@ -673,7 +705,7 @@ func verifyAddPermissionlessDelegatorTx( // verifyStakerStartsSoon is checked last to allow // the verifier visitor to explicitly check for this error. - return verifyStakerStartsSoon(currentTimestamp, startTime) + return verifyStakerStartsSoon(isDurangoActive, currentTimestamp, startTime) } // Returns an error if the given tx is invalid. @@ -724,7 +756,13 @@ func verifyTransferSubnetOwnershipTx( } // Ensure the proposed validator starts after the current time -func verifyStakerStartTime(chainTime, stakerTime time.Time) error { +func verifyStakerStartTime(isDurangoActive bool, chainTime, stakerTime time.Time) error { + // Pre Durango activation, start time must be after current chain time. + // Post Durango activation, start time is not validated + if isDurangoActive { + return nil + } + if !chainTime.Before(stakerTime) { return fmt.Errorf( "%w: %s >= %s", @@ -736,8 +774,13 @@ func verifyStakerStartTime(chainTime, stakerTime time.Time) error { return nil } -func verifyStakerStartsSoon(chainTime, stakerStartTime time.Time) error { - // Make sure the tx doesn't start too far in the future. +func verifyStakerStartsSoon(isDurangoActive bool, chainTime, stakerStartTime time.Time) error { + if isDurangoActive { + return nil + } + + // Make sure the tx doesn't start too far in the future. This is done last + // to allow the verifier visitor to explicitly check for this error. maxStartTime := chainTime.Add(MaxFutureStartTime) if stakerStartTime.After(maxStartTime) { return ErrFutureStakeTime diff --git a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go index ea84cb16906f..24f5e1cba8d2 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go @@ -151,13 +151,15 @@ func overDelegated( state state.Chain, validator *state.Staker, weightLimit uint64, - delegator *state.Staker, + delegatorWeight uint64, + delegatorStartTime time.Time, + delegatorEndTime time.Time, ) (bool, error) { - maxWeight, err := GetMaxWeight(state, validator, delegator.StartTime, delegator.EndTime) + maxWeight, err := GetMaxWeight(state, validator, delegatorStartTime, delegatorEndTime) if err != nil { return true, err } - newMaxWeight, err := math.Add64(maxWeight, delegator.Weight) + newMaxWeight, err := math.Add64(maxWeight, delegatorWeight) if err != nil { return true, err } diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index f0da597939b9..231b34a9e30d 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -72,9 +72,10 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, Validator: txs.Validator{ NodeID: ids.GenerateTestNodeID(), - Start: uint64(startTime.Unix()), - End: uint64(endTime.Unix()), - Wght: unsignedTransformTx.MinValidatorStake, + // Note: [Start] is not set here as it will be ignored + // Post-Durango in favor of the current chain time + End: uint64(endTime.Unix()), + Wght: unsignedTransformTx.MinValidatorStake, }, Subnet: subnetID, StakeOuts: []*avax.TransferableOutput{ @@ -321,7 +322,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { tx.DelegationShares = unsignedTransformTx.MinDelegationFee // Note the duration is more than the maximum - tx.Validator.End = tx.Validator.Start + uint64(unsignedTransformTx.MaxStakeDuration) + 1 + tx.Validator.End = uint64(unsignedTransformTx.MaxStakeDuration) + 2 return &tx }, expectedErr: ErrStakeTooLong, @@ -405,7 +406,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) @@ -452,7 +453,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now) // chain time is after latest fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after latest fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) @@ -499,7 +500,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now) // chain time is Cortina fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is Cortina fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) @@ -550,7 +551,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { }, stateF: func(ctrl *gomock.Controller) state.Chain { mockState := state.NewMockChain(ctrl) - mockState.EXPECT().GetTimestamp().Return(now) // chain time is after Durango fork activation since now.After(activeForkTime) + mockState.EXPECT().GetTimestamp().Return(now).Times(2) // chain time is after Durango fork activation since now.After(activeForkTime) mockState.EXPECT().GetSubnetTransformation(subnetID).Return(&transformTx, nil) mockState.EXPECT().GetCurrentValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) mockState.EXPECT().GetPendingValidator(subnetID, verifiedTx.NodeID()).Return(nil, database.ErrNotFound) diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index b9930075875a..53269520d88e 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -24,8 +24,9 @@ import ( var ( _ txs.Visitor = (*StandardTxExecutor)(nil) - errEmptyNodeID = errors.New("validator nodeID cannot be empty") - errMaxStakeDurationTooLarge = errors.New("max stake duration must be less than or equal to the global max stake duration") + errEmptyNodeID = errors.New("validator nodeID cannot be empty") + errMaxStakeDurationTooLarge = errors.New("max stake duration must be less than or equal to the global max stake duration") + errMissingStartTimePreDurango = errors.New("staker transactions must have a StartTime pre-Durango") ) type StandardTxExecutor struct { @@ -534,14 +535,63 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error { } // Creates the staker as defined in [stakerTx] and adds it to [e.State]. -func (e *StandardTxExecutor) putStaker(stakerTx txs.ScheduledStaker) error { - txID := e.Tx.ID() - staker, err := state.NewPendingStaker(txID, stakerTx) +func (e *StandardTxExecutor) putStaker(stakerTx txs.Staker) error { + var ( + chainTime = e.State.GetTimestamp() + txID = e.Tx.ID() + staker *state.Staker + err error + ) + + if !e.Config.IsDurangoActivated(chainTime) { + // Pre-Durango, stakers set a future [StartTime] and are added to the + // pending staker set. They are promoted to the current staker set once + // the chain time reaches [StartTime]. + scheduledStakerTx, ok := stakerTx.(txs.ScheduledStaker) + if !ok { + return fmt.Errorf("%w: %T", errMissingStartTimePreDurango, stakerTx) + } + staker, err = state.NewPendingStaker(txID, scheduledStakerTx) + } else { + // Only calculate the potentialReward for permissionless stakers. + // Recall that we only need to check if this is a permissioned + // validator as there are no permissioned delegators + var potentialReward uint64 + if !stakerTx.CurrentPriority().IsPermissionedValidator() { + subnetID := stakerTx.SubnetID() + currentSupply, err := e.State.GetCurrentSupply(subnetID) + if err != nil { + return err + } + + rewards, err := GetRewardsCalculator(e.Backend, e.State, subnetID) + if err != nil { + return err + } + + // Post-Durango, stakers are immediately added to the current staker + // set. Their [StartTime] is the current chain time. + stakeDuration := stakerTx.EndTime().Sub(chainTime) + potentialReward = rewards.Calculate( + stakeDuration, + stakerTx.Weight(), + currentSupply, + ) + + e.State.SetCurrentSupply(subnetID, currentSupply+potentialReward) + } + + staker, err = state.NewCurrentStaker(txID, stakerTx, chainTime, potentialReward) + } if err != nil { return err } switch priority := staker.Priority; { + case priority.IsCurrentValidator(): + e.State.PutCurrentValidator(staker) + case priority.IsCurrentDelegator(): + e.State.PutCurrentDelegator(staker) case priority.IsPendingValidator(): e.State.PutPendingValidator(staker) case priority.IsPendingDelegator(): diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index 19ca07604ccf..a5617d13b69c 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -807,7 +807,7 @@ func TestStandardTxExecutorAddSubnetValidator(t *testing.T) { func TestStandardTxExecutorBanffAddValidator(t *testing.T) { require := require.New(t) - env := newEnvironment(t, false /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) + env := newEnvironment(t, true /*=postBanff*/, false /*=postCortina*/, false /*=postDurango*/) env.ctx.Lock.Lock() defer func() { require.NoError(shutdownEnvironment(env)) @@ -978,6 +978,51 @@ func TestStandardTxExecutorBanffAddValidator(t *testing.T) { } } +func TestStandardTxExecutorDurangoAddValidator(t *testing.T) { + require := require.New(t) + env := newEnvironment(t, true /*=postBanff*/, true /*=postCortina*/, true /*=postDurango*/) + env.ctx.Lock.Lock() + defer func() { + require.NoError(shutdownEnvironment(env)) + env.ctx.Lock.Unlock() + }() + + var ( + nodeID = ids.GenerateTestNodeID() + chainTime = env.state.GetTimestamp() + endTime = chainTime.Add(defaultMaxStakingDuration) + ) + + addValTx, err := env.txBuilder.NewAddValidatorTx( + env.config.MinValidatorStake, + 0, + uint64(endTime.Unix()), + nodeID, + ids.ShortEmpty, + reward.PercentDenominator, + []*secp256k1.PrivateKey{preFundedKeys[0]}, + ids.ShortEmpty, // change addr + ) + require.NoError(err) + + onAcceptState, err := state.NewDiff(env.state.GetLastAccepted(), env) + require.NoError(err) + + require.NoError(addValTx.Unsigned.Visit(&StandardTxExecutor{ + Backend: &env.backend, + State: onAcceptState, + Tx: addValTx, + })) + + // Check that a current validator is added + val, err := onAcceptState.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) + require.NoError(err) + + require.Equal(addValTx.ID(), val.TxID) + require.Equal(chainTime, val.StartTime) + require.Equal(endTime, val.EndTime) +} + // Returns a RemoveSubnetValidatorTx that passes syntactic verification. func newRemoveSubnetValidatorTx(t *testing.T) (*txs.RemoveSubnetValidatorTx, *txs.Tx) { t.Helper() diff --git a/vms/platformvm/txs/validator.go b/vms/platformvm/txs/validator.go index ea7d048f5074..e8f4a6150806 100644 --- a/vms/platformvm/txs/validator.go +++ b/vms/platformvm/txs/validator.go @@ -40,11 +40,6 @@ func (v *Validator) EndTime() time.Time { return time.Unix(int64(v.End), 0) } -// Duration is the amount of time that this validator will be in the validator set -func (v *Validator) Duration() time.Duration { - return v.EndTime().Sub(v.StartTime()) -} - // Weight is this validator's weight when sampling func (v *Validator) Weight() uint64 { return v.Wght diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 189e220679ff..5eff65b68729 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -391,26 +391,7 @@ func internalAddValidator(vm *VM, signedTx *txs.Tx) (*state.Staker, error) { return nil, fmt.Errorf("failed setting preference: %w", err) } - // move time ahead, promoting the validator to current - stakerTx := signedTx.Unsigned.(txs.ScheduledStaker) - currentTime := stakerTx.StartTime() - vm.clock.Set(currentTime) - vm.state.SetTimestamp(currentTime) - - blk, err = vm.Builder.BuildBlock(context.Background()) - if err != nil { - return nil, fmt.Errorf("failed building block: %w", err) - } - if err := blk.Verify(context.Background()); err != nil { - return nil, fmt.Errorf("failed verifying block: %w", err) - } - if err := blk.Accept(context.Background()); err != nil { - return nil, fmt.Errorf("failed accepting block: %w", err) - } - if err := vm.SetPreference(context.Background(), vm.manager.LastAccepted()); err != nil { - return nil, fmt.Errorf("failed setting preference: %w", err) - } - + stakerTx := signedTx.Unsigned.(txs.Staker) return vm.state.GetCurrentValidator(stakerTx.SubnetID(), stakerTx.NodeID()) } diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 00290385a972..cfc0b20329ca 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -212,7 +212,6 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() @@ -470,7 +469,6 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() @@ -679,7 +677,6 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() @@ -995,7 +992,6 @@ func TestValidatorSetAtCacheOverwriteRegression(t *testing.T) { vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() @@ -1221,7 +1217,6 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() @@ -1439,9 +1434,9 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() + subnetID := testSubnet1.TxID // setup time @@ -1721,7 +1716,6 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() @@ -1881,9 +1875,9 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() + subnetID := testSubnet1.TxID // setup time @@ -2092,9 +2086,9 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { vm.ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) - vm.ctx.Lock.Unlock() }() + subnetID := testSubnet1.TxID // setup time diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 59df851a5bc3..8eeb3d8bf8ff 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -530,8 +530,8 @@ func TestAddValidatorCommit(t *testing.T) { require.NoError(err) require.Equal(status.Committed, txStatus) - // Verify that new validator now in pending validator set - _, err = vm.state.GetPendingValidator(constants.PrimaryNetworkID, nodeID) + // Verify that new validator now in current validator set + _, err = vm.state.GetCurrentValidator(constants.PrimaryNetworkID, nodeID) require.NoError(err) } @@ -711,8 +711,8 @@ func TestAddSubnetValidatorAccept(t *testing.T) { require.NoError(err) require.Equal(status.Committed, txStatus) - // Verify that new validator is in pending validator set - _, err = vm.state.GetPendingValidator(testSubnet1.ID(), nodeID) + // Verify that new validator is in current validator set + _, err = vm.state.GetCurrentValidator(testSubnet1.ID(), nodeID) require.NoError(err) } @@ -758,8 +758,8 @@ func TestAddSubnetValidatorReject(t *testing.T) { _, _, err = vm.state.GetTx(tx.ID()) require.ErrorIs(err, database.ErrNotFound) - // Verify that new validator NOT in pending validator set - _, err = vm.state.GetPendingValidator(testSubnet1.ID(), nodeID) + // Verify that new validator NOT in validator set + _, err = vm.state.GetCurrentValidator(testSubnet1.ID(), nodeID) require.ErrorIs(err, database.ErrNotFound) } @@ -969,9 +969,8 @@ func TestCreateChain(t *testing.T) { // test where we: // 1) Create a subnet -// 2) Add a validator to the subnet's pending validator set -// 3) Advance timestamp to validator's start time (moving the validator from pending to current) -// 4) Advance timestamp to validator's end time (removing validator from current) +// 2) Add a validator to the subnet's current validator set +// 3) Advance timestamp to validator's end time (removing validator from current) func TestCreateSubnet(t *testing.T) { require := require.New(t) vm, _, _ := defaultVM(t, latestFork) @@ -1040,7 +1039,7 @@ func TestCreateSubnet(t *testing.T) { require.NoError(err) require.NoError(blk.Verify(context.Background())) - require.NoError(blk.Accept(context.Background())) // add the validator to pending validator set + require.NoError(blk.Accept(context.Background())) // add the validator to current validator set require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) txID := blk.(block.Block).Txs()[0].ID() @@ -1048,19 +1047,6 @@ func TestCreateSubnet(t *testing.T) { require.NoError(err) require.Equal(status.Committed, txStatus) - _, err = vm.state.GetPendingValidator(createSubnetTx.ID(), nodeID) - require.NoError(err) - - // Advance time to when new validator should start validating - // Create a block with an advance time tx that moves validator - // from pending to current validator set - vm.clock.Set(startTime) - blk, err = vm.Builder.BuildBlock(context.Background()) // should be advance time tx - require.NoError(err) - require.NoError(blk.Verify(context.Background())) - require.NoError(blk.Accept(context.Background())) // move validator addValidatorTx from pending to current - require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) - _, err = vm.state.GetPendingValidator(createSubnetTx.ID(), nodeID) require.ErrorIs(err, database.ErrNotFound) From 44d71dba572636753708a79e502d36318e71bc38 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 19:05:26 -0500 Subject: [PATCH 163/267] Bump golang.org/x/crypto from 0.14.0 to 0.17.0 (#2502) Signed-off-by: dependabot[bot] Signed-off-by: Stephen Buttolph Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bcc9c4a86703..b224c8fea9d6 100644 --- a/go.mod +++ b/go.mod @@ -58,7 +58,7 @@ require ( go.uber.org/goleak v1.2.1 go.uber.org/mock v0.2.0 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.16.0 + golang.org/x/crypto v0.17.0 golang.org/x/exp v0.0.0-20231127185646-65229373498e golang.org/x/net v0.19.0 golang.org/x/sync v0.5.0 diff --git a/go.sum b/go.sum index d49e45a92af9..989cf75cc92d 100644 --- a/go.sum +++ b/go.sum @@ -696,8 +696,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= From 7a9bdada4d4cb6c46cdf144971e5d3c77ce1d3b5 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 19 Dec 2023 10:44:20 -0500 Subject: [PATCH 164/267] Remove unused `BuildGenesisTest` function (#2503) --- vms/platformvm/vm_test.go | 72 --------------------------------------- 1 file changed, 72 deletions(-) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 8eeb3d8bf8ff..bb210f0ffe16 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -243,78 +243,6 @@ func defaultGenesis(t *testing.T) (*api.BuildGenesisArgs, []byte) { return &buildGenesisArgs, genesisBytes } -// Returns: -// 1) The genesis state -// 2) The byte representation of the default genesis for tests -func BuildGenesisTest(t *testing.T) (*api.BuildGenesisArgs, []byte) { - return BuildGenesisTestWithArgs(t, nil) -} - -// Returns: -// 1) The genesis state -// 2) The byte representation of the default genesis for tests -func BuildGenesisTestWithArgs(t *testing.T, args *api.BuildGenesisArgs) (*api.BuildGenesisArgs, []byte) { - require := require.New(t) - genesisUTXOs := make([]api.UTXO, len(keys)) - for i, key := range keys { - id := key.PublicKey().Address() - addr, err := address.FormatBech32(constants.UnitTestHRP, id.Bytes()) - require.NoError(err) - - genesisUTXOs[i] = api.UTXO{ - Amount: json.Uint64(defaultBalance), - Address: addr, - } - } - - genesisValidators := make([]api.GenesisPermissionlessValidator, len(genesisNodeIDs)) - for i, nodeID := range genesisNodeIDs { - addr, err := address.FormatBech32(constants.UnitTestHRP, nodeID.Bytes()) - require.NoError(err) - - genesisValidators[i] = api.GenesisPermissionlessValidator{ - GenesisValidator: api.GenesisValidator{ - StartTime: json.Uint64(defaultValidateStartTime.Unix()), - EndTime: json.Uint64(defaultValidateEndTime.Unix()), - NodeID: nodeID, - }, - RewardOwner: &api.Owner{ - Threshold: 1, - Addresses: []string{addr}, - }, - Staked: []api.UTXO{{ - Amount: json.Uint64(defaultWeight), - Address: addr, - }}, - DelegationFee: reward.PercentDenominator, - } - } - - buildGenesisArgs := api.BuildGenesisArgs{ - NetworkID: json.Uint32(constants.UnitTestID), - AvaxAssetID: avaxAssetID, - UTXOs: genesisUTXOs, - Validators: genesisValidators, - Chains: nil, - Time: json.Uint64(defaultGenesisTime.Unix()), - InitialSupply: json.Uint64(360 * units.MegaAvax), - Encoding: formatting.Hex, - } - - if args != nil { - buildGenesisArgs = *args - } - - buildGenesisResponse := api.BuildGenesisReply{} - platformvmSS := api.StaticService{} - require.NoError(platformvmSS.BuildGenesis(nil, &buildGenesisArgs, &buildGenesisResponse)) - - genesisBytes, err := formatting.Decode(buildGenesisResponse.Encoding, buildGenesisResponse.Bytes) - require.NoError(err) - - return &buildGenesisArgs, genesisBytes -} - func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableSharedMemory) { require := require.New(t) var ( From 6c64372e69f5b04e472525a6fd462e350a34f3ec Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 19 Dec 2023 11:45:58 -0500 Subject: [PATCH 165/267] Remove unused `AcceptorTracker` struct (#2508) --- snow/acceptor.go | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/snow/acceptor.go b/snow/acceptor.go index f1a92e2f0303..c4ed74519e14 100644 --- a/snow/acceptor.go +++ b/snow/acceptor.go @@ -15,7 +15,6 @@ import ( var ( _ Acceptor = noOpAcceptor{} - _ Acceptor = (*AcceptorTracker)(nil) _ Acceptor = acceptorWrapper{} _ AcceptorGroup = (*acceptorGroup)(nil) @@ -38,33 +37,6 @@ func (noOpAcceptor) Accept(*ConsensusContext, ids.ID, []byte) error { return nil } -// AcceptorTracker tracks the dispatched accept events by its ID and counts. -// Useful for testing. -type AcceptorTracker struct { - lock sync.RWMutex - accepted map[ids.ID]int -} - -func NewAcceptorTracker() *AcceptorTracker { - return &AcceptorTracker{ - accepted: make(map[ids.ID]int), - } -} - -func (a *AcceptorTracker) Accept(_ *ConsensusContext, containerID ids.ID, _ []byte) error { - a.lock.Lock() - a.accepted[containerID]++ - a.lock.Unlock() - return nil -} - -func (a *AcceptorTracker) IsAccepted(containerID ids.ID) (int, bool) { - a.lock.RLock() - count, ok := a.accepted[containerID] - a.lock.RUnlock() - return count, ok -} - type acceptorWrapper struct { Acceptor From 58d2779537b336f003f4c80b746083b8fae39fa3 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 19 Dec 2023 14:01:16 -0500 Subject: [PATCH 166/267] Dedupe secp256k1 key usage in tests (#2511) --- tests/e2e/static-handlers/suites.go | 16 +--------------- vms/avm/environment_test.go | 17 +++++------------ 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/tests/e2e/static-handlers/suites.go b/tests/e2e/static-handlers/suites.go index 67b12a0cbb04..09367186da32 100644 --- a/tests/e2e/static-handlers/suites.go +++ b/tests/e2e/static-handlers/suites.go @@ -13,7 +13,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/cb58" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/formatting" @@ -114,20 +113,7 @@ var _ = ginkgo.Describe("[StaticHandlers]", func() { }) ginkgo.It("can make calls to platformvm static api", func() { - keys := []*secp256k1.PrivateKey{} - for _, key := range []string{ - "24jUJ9vZexUM6expyMcT48LBx27k1m7xpraoV62oSQAHdziao5", - "2MMvUMsxx6zsHSNXJdFD8yc5XkancvwyKPwpw4xUK3TCGDuNBY", - "cxb7KpGWhDMALTjNNSJ7UQkkomPesyWAPUaWRGdyeBNzR6f35", - "ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN", - "2RWLv6YVEXDiWLpaCbXhhqxtLbnFaKQsWPSSMSPhpWo47uJAeV", - } { - privKeyBytes, err := cb58.Decode(key) - require.NoError(err) - pk, err := secp256k1.ToPrivateKey(privKeyBytes) - require.NoError(err) - keys = append(keys, pk) - } + keys := secp256k1.TestKeys() genesisUTXOs := make([]api.UTXO, len(keys)) hrp := constants.NetworkIDToHRP[constants.UnitTestID] diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index e1e9e29f630e..96a84b2659a7 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -21,7 +21,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/cb58" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/formatting" @@ -70,22 +69,16 @@ var ( chainID = ids.ID{5, 4, 3, 2, 1} assetID = ids.ID{1, 2, 3} - keys []*secp256k1.PrivateKey - addrs []ids.ShortID // addrs[i] corresponds to keys[i] + keys = secp256k1.TestKeys()[:3] // TODO: Remove [:3] + addrs []ids.ShortID // addrs[i] corresponds to keys[i] errMissing = errors.New("missing") ) func init() { - for _, key := range []string{ - "24jUJ9vZexUM6expyMcT48LBx27k1m7xpraoV62oSQAHdziao5", - "2MMvUMsxx6zsHSNXJdFD8yc5XkancvwyKPwpw4xUK3TCGDuNBY", - "cxb7KpGWhDMALTjNNSJ7UQkkomPesyWAPUaWRGdyeBNzR6f35", - } { - keyBytes, _ := cb58.Decode(key) - pk, _ := secp256k1.ToPrivateKey(keyBytes) - keys = append(keys, pk) - addrs = append(addrs, pk.PublicKey().Address()) + addrs = make([]ids.ShortID, len(keys)) + for i, key := range keys { + addrs[i] = key.Address() } } From fc3ffb39c58f5f22ecb406df96a06628eb007cfd Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Tue, 19 Dec 2023 16:02:21 -0500 Subject: [PATCH 167/267] Merkledb readme updates (#2510) --- x/merkledb/README.md | 110 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 6 deletions(-) diff --git a/x/merkledb/README.md b/x/merkledb/README.md index acbddc16c2ca..a84a1f8ab8d9 100644 --- a/x/merkledb/README.md +++ b/x/merkledb/README.md @@ -2,7 +2,6 @@ ## Structure - A _Merkle radix trie_ is a data structure that is both a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree) and a [radix trie](https://en.wikipedia.org/wiki/Radix_tree). MerkleDB is an implementation of a persisted key-value store (sometimes just called "a store") using a Merkle radix trie. We sometimes use "Merkle radix trie" and "MerkleDB instance" interchangeably below, but the two are not the same. MerkleDB maintains data in a Merkle radix trie, but not all Merkle radix tries implement a key-value store. Like all tries, a MerkleDB instance is composed of nodes. Conceputally, a node has: @@ -26,7 +25,7 @@ Node +--------------------------------------------+ ``` -This conceptual picture differs slightly from the implementation of the `node` in MerkleDB but is still useful in understanding how MerkleDB works. +This conceptual picture differs slightly from the implementation of the `node` in MerkleDB but is still useful in understanding how MerkleDB works. ## Root IDs and Revisions @@ -36,7 +35,7 @@ The root ID also serves as a unique identifier of a given state; instances with ## Views -A _view_ is a proposal to modify a MerkleDB. If a view is _committed_, its changes are written to the MerkleDB. It can be queried, and when it is, it will return the state that the MerkleDB will contain if the view is committed. +A _view_ is a proposal to modify a MerkleDB. If a view is _committed_, its changes are written to the MerkleDB. It can be queried, and when it is, it returns the state that the MerkleDB will contain if the view is committed. A view is immutable after creation. Namely, none of its key-value pairs can be modified. A view can be built atop the MerkleDB itself, or it can be built atop another view. Views can be chained together. For example, we might have: @@ -56,6 +55,8 @@ where `view1` and `view2` are built atop MerkleDB instance `db` and `view3` is b A view can be committed only if its parent is the MerkleDB (and not another view). A view can only be committed once. In the above diagram, `view3` can't be committed until `view1` is committed. +When a view is created, we don't apply changes to the trie's structure or calculate the new IDs of nodes because this requires expensive hashing. Instead, we lazily apply changes and calculate node IDs (including the root ID) when necessary. + ### Validity When a view is committed, its siblings and all of their descendants are _invalidated_. An invalid view can't be read or committed. Method calls on it will return `ErrInvalid`. @@ -68,7 +69,7 @@ In the diagram above, if `view1` were committed, `view2` would be invalidated. I MerkleDB instances can produce _merkle proofs_, sometimes just called "proofs." A merkle proof uses cryptography to prove that a given key-value pair is or isn't in the key-value store with a given root. That is, a MerkleDB instance with root ID `r` can create a proof that shows that it has a key-value pair `(k,v)`, or that `k` is not present. -Proofs can be useful as a client fetching data in a Byzantine environment. Suppose there are one or more servers, which may be Byzantine, serving a distirbuted key-value store using MerkleDB, and a client that wants to retrieve key-value pairs. Suppose also that the client can learn a "trusted" root ID, perhaps because it's posted on a blockchain. The client can request a key-value pair from a server, and use the returned proof to verify that the returned key-value pair is actually in the key-value store with (or isn't, as it were.) To put a finer point on it, the flow is: +Proofs can be useful as a client fetching data in a Byzantine environment. Suppose there are one or more servers, which may be Byzantine, serving a distirbuted key-value store using MerkleDB, and a client that wants to retrieve key-value pairs. Suppose also that the client can learn a "trusted" root ID, perhaps because it's posted on a blockchain. The client can request a key-value pair from a server, and use the returned proof to verify that the returned key-value pair is actually in the key-value store with (or isn't, as it were.) ```mermaid flowchart TD @@ -82,9 +83,47 @@ flowchart TD `Proof(k,r)` is a proof that purports to show either that key-value pair `(k,v)` exists in the revision at `r`, or that `k` isn't in the revision. +#### Verification + +A proof is represented as: + +```go +type Proof struct { + // Nodes in the proof path from root --> target key + // (or node that would be where key is if it doesn't exist). + // Always contains at least the root. + Path []ProofNode + + // This is a proof that [key] exists/doesn't exist. + Key Key + + // Nothing if [Key] isn't in the trie. + // Otherwise, the value corresponding to [Key]. + Value maybe.Maybe[[]byte] +} + +type ProofNode struct { + Key Key + // Nothing if this is an intermediate node. + // The value in this node if its length < [HashLen]. + // The hash of the value in this node otherwise. + ValueOrHash maybe.Maybe[[]byte] + Children map[byte]ids.ID +} +``` + +For an inclusion proof, the last node in `Path` should be the one containing `Key`. +For an exclusion proof, the last node is either: +* The node that would be the parent of `Key`, if such node has no child at the index `Key` would be at. +* The node at the same child index `Key` would be at, otherwise. + +In other words, the last node of a proof says either, "the key is in the trie, and this node contains it," or, "the key isn't in the trie, and this node's existence precludes the existence of the key." + +The prover can't simply trust that such a node exists, though. It has to verify this. The prover creates an empty trie and inserts the nodes in `Path`. If the root ID of this trie matches the `r`, the verifier can trust that the last node really does exist in the trie. If the last node _didn't_ really exist, the proof creator couldn't create `Path` such that its nodes both imply the existence of the ("fake") last node and also result in the correct root ID. This follows from the one-way property of hashing. + ### Range Proofs -MerkleDB instances can also produce _range proofs_. A range proof proves that a contiguous set of key-value pairs is or isn't in the key-value store with a given root. This is similar to the merkle proofs described above, except for multiple key-value pairs. Similar to above, the flow is: +MerkleDB instances can also produce _range proofs_. A range proof proves that a contiguous set of key-value pairs is or isn't in the key-value store with a given root. This is similar to the merkle proofs described above, except for multiple key-value pairs. ```mermaid flowchart TD @@ -103,8 +142,55 @@ flowchart TD Clients can use range proofs to efficiently download many key-value pairs at a time from a MerkleDB instance, as opposed to getting a proof for each key-value pair individually. +#### Verification + Like simple proofs, range proofs can be verified without any additional context or knowledge of the contents of the key-value store. +A range proof is represented as: + +```go +type RangeProof struct { + // Invariant: At least one of [StartProof], [EndProof], [KeyValues] is non-empty. + + // A proof that the smallest key in the requested range does/doesn't exist. + // Note that this may not be an entire proof -- nodes are omitted if + // they are also in [EndProof]. + StartProof []ProofNode + + // If no upper range bound was given and [KeyValues] is empty, this is empty. + // + // If no upper range bound was given and [KeyValues] is non-empty, this is + // a proof for the largest key in [KeyValues]. + // + // Otherwise this is a proof for the upper range bound. + EndProof []ProofNode + + // This proof proves that the key-value pairs in [KeyValues] are in the trie. + // Sorted by increasing key. + KeyValues []KeyValue +} +``` + +The prover creates an empty trie and adds to it all of the key-value pairs in `KeyValues`. + +Then, it inserts: +* The nodes in `StartProof` +* The nodes in `EndProof` + +For each node in `StartProof`, the prover only populates `Children` entries whose key is before `start`. +For each node in `EndProof`, it populates only `Children` entries whose key is after `end`, where `end` is the largest key proven by the range proof. + +Then, it calculates the root ID of this trie and compares it to the expected one. + +If the proof: +* Omits any key-values in the range +* Includes additional key-values that aren't really in the range +* Provides an incorrect value for a key in the range + +then the actual root ID won't match the expected root ID. + +Like simple proofs, range proof verification relies on the fact that the proof generator can't forge data such that it results in a trie with both incorrect data and the correct root ID. + ### Change Proofs Finally, MerkleDB instances can produce and verify _change proofs_. A change proof proves that a set of key-value changes were applied to a MerkleDB instance in the process of changing its root from `r` to `r'`. For example, suppose there's an instance with root `r` @@ -126,6 +212,12 @@ flowchart TD Change proofs are useful for applying changes between revisions. For example, suppose a client has a MerkleDB instance at revision `r`. The client learns that the state has been updated and that the new root is `r'`. The client can request a change proof from a server at revision `r'`, and apply the changes in the change proof to change its state from `r` to `r'`. Note that `r` and `r'` need not be "consecutive" revisions. For example, it's possible that the state goes from revision `r` to `r1` to `r2` to `r'`. The client apply changes to get directly from `r` to `r'`, without ever needing to be at revision `r1` or `r2`. +#### Verification + +Unlike simple proofs and range proofs, change proofs require additional context to verify. Namely, the prover must have the trie at the start root `r`. + +The verification algorithm is similar to range proofs, except that instead of inserting the key-value changes, start proof and end proof into an empty trie, they are added to the trie at revision `r`. + ## Serialization ### Node @@ -258,6 +350,13 @@ Each node must have a unique ID that identifies it. This ID is calculated by has * The node's value digest * The node's key +The node's value digest is: +* Nothing, if the node has no value +* The node's value, if it has a value < 32 bytes +* The hash of the node's value otherwise + +We use the node's value digest rather than its value when hashing so that when we send proofs, each `ProofNode` doesn't need to contain the node's value, which could be very large. By using the value digest, we allow a proof verifier to calculate a node's ID while limiting the size of the data sent to the verifier. + Specifically, we encode these values in the following way: ``` @@ -345,6 +444,5 @@ The `validityTrackingLock` goes the opposite way. A view can lock the `validityT ## TODOs -- [ ] Remove special casing around the root node from the physical structure of the hashed tree. - [ ] Analyze performance of using database snapshots rather than in-memory history - [ ] Improve intermediate node regeneration after ungraceful shutdown by reusing successfully written subtrees From 618f02c27e2e95b9aec88a54095d6fddda7c07bb Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:59:33 -0500 Subject: [PATCH 168/267] Gossip Test structs (#2514) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- network/p2p/gossip/gossip.go | 31 +++++++++++++++++++++++ network/p2p/gossip/gossip_test.go | 21 +++------------- network/p2p/handler.go | 31 +++++++++++++++++++++++ network/p2p/handler_test.go | 4 +-- network/p2p/network_test.go | 24 +++++++++--------- network/p2p/throttler_handler_test.go | 36 +++------------------------ 6 files changed, 83 insertions(+), 64 deletions(-) diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index f8c39e258fcc..4f5f5e5ebfc3 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -33,9 +33,11 @@ var ( _ Gossiper = (*ValidatorGossiper)(nil) _ Gossiper = (*PullGossiper[testTx, *testTx])(nil) _ Gossiper = (*NoOpGossiper)(nil) + _ Gossiper = (*TestGossiper)(nil) _ Accumulator[*testTx] = (*PushGossiper[*testTx])(nil) _ Accumulator[*testTx] = (*NoOpAccumulator[*testTx])(nil) + _ Accumulator[*testTx] = (*TestAccumulator[*testTx])(nil) metricLabels = []string{typeLabel} ) @@ -359,3 +361,32 @@ func (NoOpAccumulator[_]) Gossip(context.Context) error { } func (NoOpAccumulator[T]) Add(...T) {} + +type TestGossiper struct { + GossipF func(ctx context.Context) error +} + +func (t *TestGossiper) Gossip(ctx context.Context) error { + return t.GossipF(ctx) +} + +type TestAccumulator[T Gossipable] struct { + GossipF func(ctx context.Context) error + AddF func(...T) +} + +func (t TestAccumulator[T]) Gossip(ctx context.Context) error { + if t.GossipF == nil { + return nil + } + + return t.GossipF(ctx) +} + +func (t TestAccumulator[T]) Add(gossipables ...T) { + if t.AddF == nil { + return + } + + t.AddF(gossipables...) +} diff --git a/network/p2p/gossip/gossip_test.go b/network/p2p/gossip/gossip_test.go index 5ccebba9756c..a25a6dce07aa 100644 --- a/network/p2p/gossip/gossip_test.go +++ b/network/p2p/gossip/gossip_test.go @@ -26,11 +26,6 @@ import ( "github.com/ava-labs/avalanchego/utils/units" ) -var ( - _ p2p.ValidatorSet = (*testValidatorSet)(nil) - _ Gossiper = (*testGossiper)(nil) -) - func TestGossiperShutdown(*testing.T) { gossiper := NewPullGossiper[testTx]( logging.NoLog{}, @@ -190,8 +185,8 @@ func TestGossiperGossip(t *testing.T) { func TestEvery(*testing.T) { ctx, cancel := context.WithCancel(context.Background()) calls := 0 - gossiper := &testGossiper{ - gossipF: func(context.Context) error { + gossiper := &TestGossiper{ + GossipF: func(context.Context) error { if calls >= 10 { cancel() return nil @@ -217,8 +212,8 @@ func TestValidatorGossiper(t *testing.T) { calls := 0 gossiper := ValidatorGossiper{ - Gossiper: &testGossiper{ - gossipF: func(context.Context) error { + Gossiper: &TestGossiper{ + GossipF: func(context.Context) error { calls++ return nil }, @@ -439,14 +434,6 @@ func TestPushGossipE2E(t *testing.T) { require.Equal(want, gotForwarded) } -type testGossiper struct { - gossipF func(ctx context.Context) error -} - -func (t *testGossiper) Gossip(ctx context.Context) error { - return t.gossipF(ctx) -} - type testValidatorSet struct { validators set.Set[ids.NodeID] } diff --git a/network/p2p/handler.go b/network/p2p/handler.go index 27c220565a04..6829f0b94213 100644 --- a/network/p2p/handler.go +++ b/network/p2p/handler.go @@ -20,6 +20,7 @@ var ( ErrNotValidator = errors.New("not a validator") _ Handler = (*NoOpHandler)(nil) + _ Handler = (*TestHandler)(nil) _ Handler = (*ValidatorHandler)(nil) ) @@ -151,3 +152,33 @@ func (r *responder) CrossChainAppRequest(ctx context.Context, chainID ids.ID, re return r.sender.SendCrossChainAppResponse(ctx, chainID, requestID, appResponse) } + +type TestHandler struct { + AppGossipF func(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) + AppRequestF func(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) + CrossChainAppRequestF func(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) +} + +func (t TestHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { + if t.AppGossipF == nil { + return + } + + t.AppGossipF(ctx, nodeID, gossipBytes) +} + +func (t TestHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { + if t.AppRequestF == nil { + return nil, nil + } + + return t.AppRequestF(ctx, nodeID, deadline, requestBytes) +} + +func (t TestHandler) CrossChainAppRequest(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) { + if t.CrossChainAppRequestF == nil { + return nil, nil + } + + return t.CrossChainAppRequestF(ctx, chainID, deadline, requestBytes) +} diff --git a/network/p2p/handler_test.go b/network/p2p/handler_test.go index 3bbb6bc46711..3ed82cb06cbd 100644 --- a/network/p2p/handler_test.go +++ b/network/p2p/handler_test.go @@ -56,8 +56,8 @@ func TestValidatorHandlerAppGossip(t *testing.T) { called := false handler := NewValidatorHandler( - &testHandler{ - appGossipF: func(context.Context, ids.NodeID, []byte) { + &TestHandler{ + AppGossipF: func(context.Context, ids.NodeID, []byte) { called = true }, }, diff --git a/network/p2p/network_test.go b/network/p2p/network_test.go index ef42830db6ac..f86399809885 100644 --- a/network/p2p/network_test.go +++ b/network/p2p/network_test.go @@ -38,19 +38,19 @@ func TestMessageRouting(t *testing.T) { wantMsg := []byte("message") var appGossipCalled, appRequestCalled, crossChainAppRequestCalled bool - testHandler := &testHandler{ - appGossipF: func(_ context.Context, nodeID ids.NodeID, msg []byte) { + testHandler := &TestHandler{ + AppGossipF: func(_ context.Context, nodeID ids.NodeID, msg []byte) { appGossipCalled = true require.Equal(wantNodeID, nodeID) require.Equal(wantMsg, msg) }, - appRequestF: func(_ context.Context, nodeID ids.NodeID, _ time.Time, msg []byte) ([]byte, error) { + AppRequestF: func(_ context.Context, nodeID ids.NodeID, _ time.Time, msg []byte) ([]byte, error) { appRequestCalled = true require.Equal(wantNodeID, nodeID) require.Equal(wantMsg, msg) return nil, nil }, - crossChainAppRequestF: func(_ context.Context, chainID ids.ID, _ time.Time, msg []byte) ([]byte, error) { + CrossChainAppRequestF: func(_ context.Context, chainID ids.ID, _ time.Time, msg []byte) ([]byte, error) { crossChainAppRequestCalled = true require.Equal(wantChainID, chainID) require.Equal(wantMsg, msg) @@ -290,15 +290,15 @@ func TestMessageForUnregisteredHandler(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) ctx := context.Background() - handler := &testHandler{ - appGossipF: func(context.Context, ids.NodeID, []byte) { + handler := &TestHandler{ + AppGossipF: func(context.Context, ids.NodeID, []byte) { require.Fail("should not be called") }, - appRequestF: func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { + AppRequestF: func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { require.Fail("should not be called") return nil, nil }, - crossChainAppRequestF: func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { + CrossChainAppRequestF: func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { require.Fail("should not be called") return nil, nil }, @@ -338,15 +338,15 @@ func TestResponseForUnrequestedRequest(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) ctx := context.Background() - handler := &testHandler{ - appGossipF: func(context.Context, ids.NodeID, []byte) { + handler := &TestHandler{ + AppGossipF: func(context.Context, ids.NodeID, []byte) { require.Fail("should not be called") }, - appRequestF: func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { + AppRequestF: func(context.Context, ids.NodeID, time.Time, []byte) ([]byte, error) { require.Fail("should not be called") return nil, nil }, - crossChainAppRequestF: func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { + CrossChainAppRequestF: func(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { require.Fail("should not be called") return nil, nil }, diff --git a/network/p2p/throttler_handler_test.go b/network/p2p/throttler_handler_test.go index 79b1dc88665d..8c18a10dc308 100644 --- a/network/p2p/throttler_handler_test.go +++ b/network/p2p/throttler_handler_test.go @@ -14,7 +14,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) -var _ Handler = (*testHandler)(nil) +var _ Handler = (*TestHandler)(nil) func TestThrottlerHandlerAppGossip(t *testing.T) { tests := []struct { @@ -38,8 +38,8 @@ func TestThrottlerHandlerAppGossip(t *testing.T) { called := false handler := NewThrottlerHandler( - testHandler{ - appGossipF: func(context.Context, ids.NodeID, []byte) { + TestHandler{ + AppGossipF: func(context.Context, ids.NodeID, []byte) { called = true }, }, @@ -83,33 +83,3 @@ func TestThrottlerHandlerAppRequest(t *testing.T) { }) } } - -type testHandler struct { - appGossipF func(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) - appRequestF func(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) - crossChainAppRequestF func(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) -} - -func (t testHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { - if t.appGossipF == nil { - return - } - - t.appGossipF(ctx, nodeID, gossipBytes) -} - -func (t testHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { - if t.appRequestF == nil { - return nil, nil - } - - return t.appRequestF(ctx, nodeID, deadline, requestBytes) -} - -func (t testHandler) CrossChainAppRequest(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) { - if t.crossChainAppRequestF == nil { - return nil, nil - } - - return t.crossChainAppRequestF(ctx, chainID, deadline, requestBytes) -} From fa21d781838744c8574b8e06b9c3bf151b501581 Mon Sep 17 00:00:00 2001 From: marun Date: Tue, 19 Dec 2023 14:01:09 -0800 Subject: [PATCH 169/267] `tmpnet`: Separate node into orchestration, config and process (#2460) --- tests/e2e/faultinjection/duplicate_node_id.go | 2 +- tests/e2e/p/interchain_workflow.go | 2 +- tests/e2e/p/staking_rewards.go | 4 +- tests/fixture/e2e/env.go | 2 +- tests/fixture/e2e/helpers.go | 38 +- tests/fixture/tmpnet/README.md | 35 +- tests/fixture/tmpnet/cmd/main.go | 8 +- tests/fixture/tmpnet/defaults.go | 11 +- tests/fixture/tmpnet/network.go | 51 ++- tests/fixture/tmpnet/network_test.go | 3 + tests/fixture/tmpnet/node.go | 384 +++++------------- tests/fixture/tmpnet/node_config.go | 100 +++++ tests/fixture/tmpnet/node_process.go | 258 ++++++++++++ tests/fixture/tmpnet/utils.go | 4 + tests/upgrade/upgrade_test.go | 9 +- 15 files changed, 554 insertions(+), 357 deletions(-) create mode 100644 tests/fixture/tmpnet/node_config.go create mode 100644 tests/fixture/tmpnet/node_process.go diff --git a/tests/e2e/faultinjection/duplicate_node_id.go b/tests/e2e/faultinjection/duplicate_node_id.go index 65a81a0a05eb..938d60f9303f 100644 --- a/tests/e2e/faultinjection/duplicate_node_id.go +++ b/tests/e2e/faultinjection/duplicate_node_id.go @@ -49,7 +49,7 @@ var _ = ginkgo.Describe("Duplicate node handling", func() { require.ErrorIs(err, context.DeadlineExceeded) ginkgo.By("stopping the first new node") - require.NoError(node1.Stop()) + require.NoError(node1.Stop(e2e.DefaultContext())) ginkgo.By("checking that the second new node becomes healthy within timeout") e2e.WaitForHealthy(node2) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 64caab902531..59e90198bed0 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -209,7 +209,7 @@ var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainL require.Positive(balance.Cmp(big.NewInt(0))) ginkgo.By("stopping validator node to free up resources for a bootstrap check") - require.NoError(node.Stop()) + require.NoError(node.Stop(e2e.DefaultContext())) e2e.CheckBootstrapIsPossible(network) }) diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index 2ede58b53832..134c055dcde4 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -227,7 +227,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { }) ginkgo.By("stopping beta node to prevent it and its delegator from receiving a validation reward") - require.NoError(betaNode.Stop()) + require.NoError(betaNode.Stop(e2e.DefaultContext())) ginkgo.By("retrieving staking periods from the chain") data, err := pvmClient.GetCurrentValidators(e2e.DefaultContext(), constants.PlatformChainID, []ids.NodeID{alphaNodeID}) @@ -302,7 +302,7 @@ var _ = ginkgo.Describe("[Staking Rewards]", func() { } ginkgo.By("stopping alpha to free up resources for a bootstrap check") - require.NoError(alphaNode.Stop()) + require.NoError(alphaNode.Stop(e2e.DefaultContext())) e2e.CheckBootstrapIsPossible(network) }) diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index 8c7733fa41a7..1ea9dc69f2b9 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -132,5 +132,5 @@ func (te *TestEnvironment) NewPrivateNetwork() *tmpnet.Network { privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName) te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute)) - return StartNetwork(sharedNetwork.ExecPath, privateNetworksDir) + return StartNetwork(sharedNetwork.AvalancheGoPath, privateNetworksDir) } diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 7df75ad85cf7..ddebfbc8b81c 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -118,22 +118,21 @@ func Eventually(condition func() bool, waitFor time.Duration, tick time.Duration } } -// Add an ephemeral node that is only intended to be used by a single test. Its ID and -// URI are not intended to be returned from the Network instance to minimize -// accessibility from other tests. +// Adds an ephemeral node intended to be used by a single test. func AddEphemeralNode(network *tmpnet.Network, flags tmpnet.FlagsMap) *tmpnet.Node { require := require.New(ginkgo.GinkgoT()) - node, err := network.AddEphemeralNode(ginkgo.GinkgoWriter, flags) + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() + node, err := network.AddEphemeralNode(ctx, ginkgo.GinkgoWriter, flags) require.NoError(err) - // Ensure node is stopped on teardown. It's configuration is not removed to enable - // collection in CI to aid in troubleshooting failures. ginkgo.DeferCleanup(func() { - tests.Outf("Shutting down ephemeral node %s\n", node.NodeID) - require.NoError(node.Stop()) + tests.Outf("shutting down ephemeral node %q\n", node.NodeID) + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() + require.NoError(node.Stop(ctx)) }) - return node } @@ -191,26 +190,13 @@ func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network *tmpnet.Network) { - require := require.New(ginkgo.GinkgoT()) - if len(os.Getenv(SkipBootstrapChecksEnvName)) > 0 { tests.Outf("{{yellow}}Skipping bootstrap check due to the %s env var being set", SkipBootstrapChecksEnvName) return } ginkgo.By("checking if bootstrap is possible with the current network state") - // Call network.AddEphemeralNode instead of AddEphemeralNode to support - // checking for bootstrap implicitly on teardown via a function registered - // with ginkgo.DeferCleanup. It's not possible to call DeferCleanup from - // within a function called by DeferCleanup. - node, err := network.AddEphemeralNode(ginkgo.GinkgoWriter, tmpnet.FlagsMap{}) - require.NoError(err) - - defer func() { - tests.Outf("Shutting down ephemeral node %s\n", node.NodeID) - require.NoError(node.Stop()) - }() - + node := AddEphemeralNode(network, tmpnet.FlagsMap{}) WaitForHealthy(node) } @@ -224,7 +210,7 @@ func StartNetwork(avalancheGoExecPath string, networkDir string) *tmpnet.Network networkDir, &tmpnet.Network{ NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ - ExecPath: avalancheGoExecPath, + AvalancheGoPath: avalancheGoExecPath, }, }, tmpnet.DefaultNodeCount, @@ -233,7 +219,9 @@ func StartNetwork(avalancheGoExecPath string, networkDir string) *tmpnet.Network require.NoError(err) ginkgo.DeferCleanup(func() { tests.Outf("Shutting down network\n") - require.NoError(network.Stop()) + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() + require.NoError(network.Stop(ctx)) }) tests.Outf("{{green}}Successfully started network{{/}}\n") diff --git a/tests/fixture/tmpnet/README.md b/tests/fixture/tmpnet/README.md index dfe430ea10a0..90ec7f678b2f 100644 --- a/tests/fixture/tmpnet/README.md +++ b/tests/fixture/tmpnet/README.md @@ -1,4 +1,4 @@ -# tmpnet (temporary network fixture) +# tmpnet - temporary network orchestration This package implements a simple orchestrator for the avalanchego nodes of a temporary network. Configuration is stored on disk, and @@ -31,6 +31,8 @@ the following non-test files: | genesis.go | | Creates test genesis | | network.go | Network | Orchestrates and configures temporary networks | | node.go | Node | Orchestrates and configures nodes | +| node_config.go | Node | Reads and writes node configuration | +| node_process.go | NodeProcess | Orchestrates node processes | | utils.go | | Defines shared utility functions | ## Usage @@ -76,7 +78,7 @@ network, _ := tmpnet.StartNetwork( ginkgo.GinkgoWriter, // Writer to report progress of network start "", // Use default root dir (~/.tmpnet) &tmpnet.Network{ - DefaultRuntime: tmpnet.NodeRuntimeConfig{ + NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ ExecPath: "/path/to/avalanchego", // Defining the avalanchego exec path is required }, }, @@ -102,7 +104,7 @@ network, _ := tmpnet.StartNetwork( ginkgo.GinkgoWriter, "", &tmpnet.Network{ - DefaultRuntime: tmpnet.NodeRuntimeConfig{ + NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ ExecPath: "/path/to/avalanchego", }, Nodes: []*Node{ @@ -147,9 +149,10 @@ HOME ├── NodeID-37E8UK3x2YFsHE3RdALmfWcppcZ1eTuj9 // The ID of a node is the name of its data dir │ ├── chainData │ │ └── ... - │ ├── config.json // Node flags + │ ├── config.json // Node runtime configuration │ ├── db │ │ └── ... + │ ├── flags.json // Node flags │ ├── logs │ │ └── ... │ ├── plugins @@ -160,11 +163,7 @@ HOME │ └── config.json // C-Chain config for all nodes ├── defaults.json // Default flags and configuration for network ├── genesis.json // Genesis for all nodes - ├── network.env // Sets network dir env to simplify use of network - └── ephemeral // Parent directory for ephemeral nodes (e.g. created by tests) - └─ NodeID-FdxnAvr4jK9XXAwsYZPgWAHW2QnwSZ // Data dir for an ephemeral node - └── ... - + └── network.env // Sets network dir env var to simplify network usage ``` ### Default flags and configuration @@ -203,6 +202,13 @@ this file (i.e. `source network.env`) in a shell will configure ginkgo e2e and the `tmpnetctl` cli to target the network path specified in the env var. +Set `TMPNET_ROOT_DIR` to specify the root directory in which to create +the configuration directory of new networks +(e.g. `$TMPNET_ROOT_DIR/[network-dir]`). The default root directory is +`~/.tmpdir/networks`. Configuring the root directory is only relevant +when creating new networks as the path of existing networks will +already have been set. + ### Node configuration The data dir for a node is set by default to @@ -210,12 +216,19 @@ The data dir for a node is set by default to non-default path by explicitly setting the `--data-dir` flag. +#### Runtime config + +The details required to configure a node's execution are written to +`[network-path]/[node-id]/config.json`. This file contains the +runtime-specific details like the path of the avalanchego binary to +start the node with. + #### Flags All flags used to configure a node are written to -`[network-path]/[node-id]/config.json` so that a node can be +`[network-path]/[node-id]/flags.json` so that a node can be configured with only a single argument: -`--config-file=/path/to/config.json`. This simplifies node launch and +`--config-file=/path/to/flags.json`. This simplifies node launch and ensures all parameters used to launch a node can be modified by editing the config file. diff --git a/tests/fixture/tmpnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go index 6e0a87e272a2..9baf4557bca4 100644 --- a/tests/fixture/tmpnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -62,10 +62,10 @@ func main() { network := &tmpnet.Network{ NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ - ExecPath: execPath, + AvalancheGoPath: execPath, }, } - ctx, cancel := context.WithTimeout(context.Background(), tmpnet.DefaultNetworkStartTimeout) + ctx, cancel := context.WithTimeout(context.Background(), tmpnet.DefaultNetworkTimeout) defer cancel() network, err := tmpnet.StartNetwork(ctx, os.Stdout, rootDir, network, int(nodeCount), int(preFundedKeyCount)) if err != nil { @@ -105,7 +105,9 @@ func main() { if len(networkDir) == 0 { return errNetworkDirRequired } - if err := tmpnet.StopNetwork(networkDir); err != nil { + ctx, cancel := context.WithTimeout(context.Background(), tmpnet.DefaultNetworkTimeout) + defer cancel() + if err := tmpnet.StopNetwork(ctx, networkDir); err != nil { return err } fmt.Fprintf(os.Stdout, "Stopped network configured at: %s\n", networkDir) diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index 1ca62e26bd4f..11e9ab72787d 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -12,13 +12,10 @@ import ( const ( // Constants defining the names of shell variables whose value can // configure temporary network orchestration. - AvalancheGoPathEnvName = "AVALANCHEGO_PATH" - NetworkDirEnvName = "TMPNET_NETWORK_DIR" - RootDirEnvName = "TMPNET_ROOT_DIR" + NetworkDirEnvName = "TMPNET_NETWORK_DIR" + RootDirEnvName = "TMPNET_ROOT_DIR" - DefaultNetworkStartTimeout = 2 * time.Minute - DefaultNodeInitTimeout = 10 * time.Second - DefaultNodeStopTimeout = 5 * time.Second + DefaultNetworkTimeout = 2 * time.Minute // Minimum required to ensure connectivity-based health checks will pass DefaultNodeCount = 2 @@ -28,6 +25,8 @@ const ( // A short minimum stake duration enables testing of staking logic. DefaultMinStakeDuration = time.Second + + defaultConfigFilename = "config.json" ) // A set of flags appropriate for testing. diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 11b0128df3bb..5f1eaf5a4513 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -97,11 +97,11 @@ type Network struct { } // Adds a backend-agnostic ephemeral node to the network -func (n *Network) AddEphemeralNode(w io.Writer, flags FlagsMap) (*Node, error) { +func (n *Network) AddEphemeralNode(ctx context.Context, w io.Writer, flags FlagsMap) (*Node, error) { if flags == nil { flags = FlagsMap{} } - return n.AddNode(w, &Node{ + return n.AddNode(ctx, w, &Node{ Flags: flags, }, true /* isEphemeral */) } @@ -116,7 +116,7 @@ func StartNetwork( nodeCount int, keyCount int, ) (*Network, error) { - if _, err := fmt.Fprintf(w, "Preparing configuration for new temporary network with %s\n", network.ExecPath); err != nil { + if _, err := fmt.Fprintf(w, "Preparing configuration for new temporary network with %s\n", network.AvalancheGoPath); err != nil { return nil, err } @@ -198,12 +198,12 @@ func ReadNetwork(dir string) (*Network, error) { } // Stop the nodes of the network configured in the provided directory. -func StopNetwork(dir string) error { +func StopNetwork(ctx context.Context, dir string) error { network, err := ReadNetwork(dir) if err != nil { return err } - return network.Stop() + return network.Stop(ctx) } // Ensure the network has the configuration it needs to start. @@ -291,8 +291,15 @@ func (n *Network) PopulateNodeConfig(node *Node, nodeParentDir string) error { return err } + // Ensure the node is configured with a runtime config + if node.RuntimeConfig == nil { + node.RuntimeConfig = &NodeRuntimeConfig{ + AvalancheGoPath: n.AvalancheGoPath, + } + } + // Ensure the node's data dir is configured - dataDir := node.GetDataDir() + dataDir := node.getDataDir() if len(dataDir) == 0 { // NodeID will have been set by EnsureKeys dataDir = filepath.Join(nodeParentDir, node.NodeID.String()) @@ -331,7 +338,7 @@ func (n *Network) Start(w io.Writer) error { node.SetNetworkingConfig(bootstrapIDs, bootstrapIPs) // Write configuration to disk in preparation for node start - if err := node.WriteConfig(); err != nil { + if err := node.Write(); err != nil { return err } @@ -340,7 +347,7 @@ func (n *Network) Start(w io.Writer) error { // its staking port. The network will start faster with this // synchronization due to the avoidance of exponential backoff // if a node tries to connect to a beacon that is not ready. - if err := node.Start(w, n.ExecPath); err != nil { + if err := node.Start(w); err != nil { return err } @@ -406,11 +413,11 @@ func (n *Network) GetURIs() []NodeURI { } // Stop all nodes in the network. -func (n *Network) Stop() error { +func (n *Network) Stop(ctx context.Context) error { var errs []error // Assume the nodes are loaded and the pids are current for _, node := range n.Nodes { - if err := node.Stop(); err != nil { + if err := node.Stop(ctx); err != nil { errs = append(errs, fmt.Errorf("failed to stop node %s: %w", node.NodeID, err)) } } @@ -476,9 +483,9 @@ func (n *Network) WriteCChainConfig() error { // Used to marshal/unmarshal persistent network defaults. type networkDefaults struct { - Flags FlagsMap - ExecPath string - PreFundedKeys []*secp256k1.PrivateKey + Flags FlagsMap + AvalancheGoPath string + PreFundedKeys []*secp256k1.PrivateKey } func (n *Network) GetDefaultsPath() string { @@ -495,16 +502,16 @@ func (n *Network) ReadDefaults() error { return fmt.Errorf("failed to unmarshal defaults: %w", err) } n.DefaultFlags = defaults.Flags - n.ExecPath = defaults.ExecPath + n.AvalancheGoPath = defaults.AvalancheGoPath n.PreFundedKeys = defaults.PreFundedKeys return nil } func (n *Network) WriteDefaults() error { defaults := networkDefaults{ - Flags: n.DefaultFlags, - ExecPath: n.ExecPath, - PreFundedKeys: n.PreFundedKeys, + Flags: n.DefaultFlags, + AvalancheGoPath: n.AvalancheGoPath, + PreFundedKeys: n.PreFundedKeys, } bytes, err := DefaultJSONMarshal(defaults) if err != nil { @@ -534,7 +541,7 @@ func (n *Network) WriteEnvFile() error { func (n *Network) WriteNodes() error { for _, node := range n.Nodes { - if err := node.WriteConfig(); err != nil { + if err := node.Write(); err != nil { return err } } @@ -611,7 +618,7 @@ func (n *Network) ReadAll() error { return n.ReadNodes() } -func (n *Network) AddNode(w io.Writer, node *Node, isEphemeral bool) (*Node, error) { +func (n *Network) AddNode(ctx context.Context, w io.Writer, node *Node, isEphemeral bool) (*Node, error) { // Assume network configuration has been written to disk and is current in memory if node == nil { @@ -644,15 +651,15 @@ func (n *Network) AddNode(w io.Writer, node *Node, isEphemeral bool) (*Node, err } node.SetNetworkingConfig(bootstrapIDs, bootstrapIPs) - if err := node.WriteConfig(); err != nil { + if err := node.Write(); err != nil { return nil, err } - err = node.Start(w, n.ExecPath) + err = node.Start(w) if err != nil { // Attempt to stop an unhealthy node to provide some assurance to the caller // that an error condition will not result in a lingering process. - stopErr := node.Stop() + stopErr := node.Stop(ctx) if stopErr != nil { err = errors.Join(err, stopErr) } diff --git a/tests/fixture/tmpnet/network_test.go b/tests/fixture/tmpnet/network_test.go index 7955fa4fd622..1a06a07f4a38 100644 --- a/tests/fixture/tmpnet/network_test.go +++ b/tests/fixture/tmpnet/network_test.go @@ -18,6 +18,9 @@ func TestNetworkSerialization(t *testing.T) { require.NoError(network.PopulateNetworkConfig(1337, 1, 1)) require.NoError(network.WriteAll()) + // Ensure node runtime is initialized + require.NoError(network.ReadNodes()) + loadedNetwork, err := ReadNetwork(tmpDir) require.NoError(err) for _, key := range loadedNetwork.PreFundedKeys { diff --git a/tests/fixture/tmpnet/node.go b/tests/fixture/tmpnet/node.go index 0bd18cc65ae9..955e38dc6995 100644 --- a/tests/fixture/tmpnet/node.go +++ b/tests/fixture/tmpnet/node.go @@ -6,59 +6,74 @@ package tmpnet import ( "context" "encoding/base64" - "encoding/json" "errors" "fmt" "io" - "io/fs" - "net" "os" - "os/exec" "path/filepath" "strings" - "syscall" "time" "github.com/spf13/cast" - "github.com/ava-labs/avalanchego/api/health" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/node" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) +// The Node type is defined in this file (node.go - orchestration) and +// node_config.go (reading/writing configuration). + +const ( + defaultNodeTickerInterval = 50 * time.Millisecond +) + var ( - errNodeAlreadyRunning = errors.New("failed to start node: node is already running") errMissingTLSKeyForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingTLSKeyContentKey) errMissingCertForNodeID = fmt.Errorf("failed to ensure node ID: missing value for %q", config.StakingCertContentKey) errInvalidKeypair = fmt.Errorf("%q and %q must be provided together or not at all", config.StakingTLSKeyContentKey, config.StakingCertContentKey) ) -// Defines configuration to execute a node. -// -// TODO(marun) Support persisting this configuration per-node when -// node restart is implemented. Currently it can be supplied for node -// start but won't survive restart. +// NodeRuntime defines the methods required to support running a node. +type NodeRuntime interface { + readState() error + Start(w io.Writer) error + InitiateStop() error + WaitForStopped(ctx context.Context) error + IsHealthy(ctx context.Context) (bool, error) +} + +// Configuration required to configure a node runtime. type NodeRuntimeConfig struct { - // Path to avalanchego binary - ExecPath string + AvalancheGoPath string } -// Stores the configuration and process details of a node in a temporary network. +// Node supports configuring and running a node participating in a temporary network. type Node struct { - NodeRuntimeConfig - node.NodeProcessContext - + // Set by EnsureNodeID which is also called when the node is read. NodeID ids.NodeID - Flags FlagsMap - // Configuration is intended to be stored at the path identified in NodeConfig.Flags[config.DataDirKey] + // Flags that will be supplied to the node at startup + Flags FlagsMap + + // An ephemeral node is not expected to be a persistent member of the network and + // should therefore not be used as for bootstrapping purposes. + IsEphemeral bool + + // The configuration used to initialize the node runtime. + RuntimeConfig *NodeRuntimeConfig + + // Runtime state, intended to be set by NodeRuntime + URI string + StakingAddress string + + // Initialized on demand + runtime NodeRuntime } +// Initializes a new node with only the data dir set func NewNode(dataDir string) *Node { return &Node{ Flags: FlagsMap{ @@ -67,271 +82,86 @@ func NewNode(dataDir string) *Node { } } -// Attempt to read configuration and process details for a node -// from the specified directory. +// Reads a node's configuration from the specified directory. func ReadNode(dataDir string) (*Node, error) { node := NewNode(dataDir) - if _, err := os.Stat(node.GetConfigPath()); err != nil { - return nil, fmt.Errorf("failed to read node config file: %w", err) - } - return node, node.ReadAll() -} - -func (n *Node) GetDataDir() string { - return cast.ToString(n.Flags[config.DataDirKey]) + return node, node.Read() } -func (n *Node) GetConfigPath() string { - return filepath.Join(n.GetDataDir(), "config.json") -} +// Reads nodes from the specified network directory. +func ReadNodes(networkDir string) ([]*Node, error) { + nodes := []*Node{} -func (n *Node) ReadConfig() error { - bytes, err := os.ReadFile(n.GetConfigPath()) + // Node configuration is stored in child directories + entries, err := os.ReadDir(networkDir) if err != nil { - return fmt.Errorf("failed to read node config: %w", err) + return nil, fmt.Errorf("failed to read dir: %w", err) } - flags := FlagsMap{} - if err := json.Unmarshal(bytes, &flags); err != nil { - return fmt.Errorf("failed to unmarshal node config: %w", err) - } - n.Flags = flags - if err := n.EnsureNodeID(); err != nil { - return err - } - return nil -} + for _, entry := range entries { + if !entry.IsDir() { + continue + } -func (n *Node) WriteConfig() error { - if err := os.MkdirAll(n.GetDataDir(), perms.ReadWriteExecute); err != nil { - return fmt.Errorf("failed to create node dir: %w", err) - } + nodeDir := filepath.Join(networkDir, entry.Name()) + node, err := ReadNode(nodeDir) + if errors.Is(err, os.ErrNotExist) { + // If no config file exists, assume this is not the path of a node + continue + } else if err != nil { + return nil, err + } - bytes, err := DefaultJSONMarshal(n.Flags) - if err != nil { - return fmt.Errorf("failed to marshal node config: %w", err) + nodes = append(nodes, node) } - if err := os.WriteFile(n.GetConfigPath(), bytes, perms.ReadWrite); err != nil { - return fmt.Errorf("failed to write node config: %w", err) - } - return nil + return nodes, nil } -func (n *Node) GetProcessContextPath() string { - return filepath.Join(n.GetDataDir(), config.DefaultProcessContextFilename) +// Retrieves the runtime for the node. +func (n *Node) getRuntime() NodeRuntime { + if n.runtime == nil { + n.runtime = &NodeProcess{ + node: n, + } + } + return n.runtime } -func (n *Node) ReadProcessContext() error { - path := n.GetProcessContextPath() - if _, err := os.Stat(path); errors.Is(err, fs.ErrNotExist) { - // The absence of the process context file indicates the node is not running - n.NodeProcessContext = node.NodeProcessContext{} - return nil - } +// Runtime methods - bytes, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("failed to read node process context: %w", err) - } - processContext := node.NodeProcessContext{} - if err := json.Unmarshal(bytes, &processContext); err != nil { - return fmt.Errorf("failed to unmarshal node process context: %w", err) - } - n.NodeProcessContext = processContext - return nil +func (n *Node) IsHealthy(ctx context.Context) (bool, error) { + return n.getRuntime().IsHealthy(ctx) } -func (n *Node) ReadAll() error { - if err := n.ReadConfig(); err != nil { - return err - } - return n.ReadProcessContext() +func (n *Node) Start(w io.Writer) error { + return n.getRuntime().Start(w) } -func (n *Node) Start(w io.Writer, defaultExecPath string) error { - // Avoid attempting to start an already running node. - proc, err := n.GetProcess() - if err != nil { - return fmt.Errorf("failed to start node: %w", err) - } - if proc != nil { - return errNodeAlreadyRunning - } - - // Ensure a stale process context file is removed so that the - // creation of a new file can indicate node start. - if err := os.Remove(n.GetProcessContextPath()); err != nil && !errors.Is(err, fs.ErrNotExist) { - return fmt.Errorf("failed to remove stale process context file: %w", err) - } - - execPath := n.ExecPath - if len(execPath) == 0 { - execPath = defaultExecPath - } - - cmd := exec.Command(execPath, "--config-file", n.GetConfigPath()) - if err := cmd.Start(); err != nil { - return err - } - - // Determine appropriate level of node description detail - nodeDescription := fmt.Sprintf("node %q", n.NodeID) - isEphemeralNode := filepath.Base(filepath.Dir(n.GetDataDir())) == defaultEphemeralDirName - if isEphemeralNode { - nodeDescription = "ephemeral " + nodeDescription - } - nonDefaultNodeDir := filepath.Base(n.GetDataDir()) != n.NodeID.String() - if nonDefaultNodeDir { - // Only include the data dir if its base is not the default (the node ID) - nodeDescription = fmt.Sprintf("%s with path: %s", nodeDescription, n.GetDataDir()) - } - - go func() { - if err := cmd.Wait(); err != nil { - if err.Error() != "signal: killed" { - _, _ = fmt.Fprintf(w, "%s finished with error: %v\n", nodeDescription, err) - } - } - _, _ = fmt.Fprintf(w, "%s exited\n", nodeDescription) - }() - - // A node writes a process context file on start. If the file is not - // found in a reasonable amount of time, the node is unlikely to have - // started successfully. - if err := n.WaitForProcessContext(context.Background()); err != nil { - return fmt.Errorf("failed to start node: %w", err) - } - - _, err = fmt.Fprintf(w, "Started %s\n", nodeDescription) - return err +func (n *Node) InitiateStop() error { + return n.getRuntime().InitiateStop() } -// Retrieve the node process if it is running. As part of determining -// process liveness, the node's process context will be refreshed if -// live or cleared if not running. -func (n *Node) GetProcess() (*os.Process, error) { - // Read the process context to ensure freshness. The node may have - // stopped or been restarted since last read. - if err := n.ReadProcessContext(); err != nil { - return nil, fmt.Errorf("failed to read process context: %w", err) - } - - if n.PID == 0 { - // Process is not running - return nil, nil - } - - proc, err := os.FindProcess(n.PID) - if err != nil { - return nil, fmt.Errorf("failed to find process: %w", err) - } - - // Sending 0 will not actually send a signal but will perform - // error checking. - err = proc.Signal(syscall.Signal(0)) - if err == nil { - // Process is running - return proc, nil - } - if errors.Is(err, os.ErrProcessDone) { - // Process is not running - return nil, nil - } - return nil, fmt.Errorf("failed to determine process status: %w", err) +func (n *Node) WaitForStopped(ctx context.Context) error { + return n.getRuntime().WaitForStopped(ctx) } -// Signals the node process to stop and waits for the node process to -// stop running. -func (n *Node) Stop() error { - proc, err := n.GetProcess() - if err != nil { - return fmt.Errorf("failed to retrieve process to stop: %w", err) - } - if proc == nil { - // Already stopped - return nil - } - if err := proc.Signal(syscall.SIGTERM); err != nil { - return fmt.Errorf("failed to send SIGTERM to pid %d: %w", n.PID, err) - } - - // Wait for the node process to stop - ticker := time.NewTicker(DefaultNodeTickerInterval) - defer ticker.Stop() - ctx, cancel := context.WithTimeout(context.Background(), DefaultNodeStopTimeout) - defer cancel() - for { - proc, err := n.GetProcess() - if err != nil { - return fmt.Errorf("failed to retrieve process: %w", err) - } - if proc == nil { - return nil - } - - select { - case <-ctx.Done(): - return fmt.Errorf("failed to see node process stop %q before timeout: %w", n.NodeID, ctx.Err()) - case <-ticker.C: - } - } +func (n *Node) readState() error { + return n.getRuntime().readState() } -func (n *Node) IsHealthy(ctx context.Context) (bool, error) { - // Check that the node process is running as a precondition for - // checking health. GetProcess will also ensure that the node's - // API URI is current. - proc, err := n.GetProcess() - if err != nil { - return false, fmt.Errorf("failed to determine process status: %w", err) - } - if proc == nil { - return false, ErrNotRunning - } - - // Check that the node is reporting healthy - health, err := health.NewClient(n.URI).Health(ctx, nil) - if err == nil { - return health.Healthy, nil - } - - switch t := err.(type) { - case *net.OpError: - if t.Op == "read" { - // Connection refused - potentially recoverable - return false, nil - } - case syscall.Errno: - if t == syscall.ECONNREFUSED { - // Connection refused - potentially recoverable - return false, nil - } - } - // Assume all other errors are not recoverable - return false, fmt.Errorf("failed to query node health: %w", err) +func (n *Node) getDataDir() string { + return cast.ToString(n.Flags[config.DataDirKey]) } -func (n *Node) WaitForProcessContext(ctx context.Context) error { - ticker := time.NewTicker(DefaultNodeTickerInterval) - defer ticker.Stop() - - ctx, cancel := context.WithTimeout(ctx, DefaultNodeInitTimeout) - defer cancel() - for len(n.URI) == 0 { - err := n.ReadProcessContext() - if err != nil { - return fmt.Errorf("failed to read process context for node %q: %w", n.NodeID, err) - } - - select { - case <-ctx.Done(): - return fmt.Errorf("failed to load process context for node %q before timeout: %w", n.NodeID, ctx.Err()) - case <-ticker.C: - } +// Initiates node shutdown and waits for the node to stop. +func (n *Node) Stop(ctx context.Context) error { + if err := n.InitiateStop(); err != nil { + return err } - return nil + return n.WaitForStopped(ctx) } +// Sets networking configuration for the node. // Convenience method for setting networking flags. func (n *Node) SetNetworkingConfig(bootstrapIDs []string, bootstrapIPs []string) { var ( @@ -354,28 +184,9 @@ func (n *Node) EnsureKeys() error { if err := n.EnsureStakingKeypair(); err != nil { return err } - // Once a staking keypair is guaranteed it is safe to derive the node ID return n.EnsureNodeID() } -// Derives the nodes proof-of-possession. Requires the node to have a -// BLS signing key. -func (n *Node) GetProofOfPossession() (*signer.ProofOfPossession, error) { - signingKey, err := n.Flags.GetStringVal(config.StakingSignerKeyContentKey) - if err != nil { - return nil, err - } - signingKeyBytes, err := base64.StdEncoding.DecodeString(signingKey) - if err != nil { - return nil, err - } - secretKey, err := bls.SecretKeyFromBytes(signingKeyBytes) - if err != nil { - return nil, err - } - return signer.NewProofOfPossession(secretKey), nil -} - // Ensures a BLS signing key is generated if not already present. func (n *Node) EnsureBLSSigningKey() error { // Attempt to retrieve an existing key @@ -425,15 +236,28 @@ func (n *Node) EnsureStakingKeypair() error { return errInvalidKeypair } - err = n.EnsureNodeID() + return nil +} + +// Derives the nodes proof-of-possession. Requires the node to have a +// BLS signing key. +func (n *Node) GetProofOfPossession() (*signer.ProofOfPossession, error) { + signingKey, err := n.Flags.GetStringVal(config.StakingSignerKeyContentKey) if err != nil { - return fmt.Errorf("failed to derive a node ID: %w", err) + return nil, err } - - return nil + signingKeyBytes, err := base64.StdEncoding.DecodeString(signingKey) + if err != nil { + return nil, err + } + secretKey, err := bls.SecretKeyFromBytes(signingKeyBytes) + if err != nil { + return nil, err + } + return signer.NewProofOfPossession(secretKey), nil } -// Attempt to derive the node ID from the node configuration. +// Derives the node ID. Requires that a tls keypair is present. func (n *Node) EnsureNodeID() error { keyKey := config.StakingTLSKeyContentKey certKey := config.StakingCertContentKey diff --git a/tests/fixture/tmpnet/node_config.go b/tests/fixture/tmpnet/node_config.go new file mode 100644 index 000000000000..8771ce48f2bd --- /dev/null +++ b/tests/fixture/tmpnet/node_config.go @@ -0,0 +1,100 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package tmpnet + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + + "github.com/ava-labs/avalanchego/utils/perms" +) + +// The Node type is defined in this file node_config.go +// (reading/writing configuration) and node.go (orchestration). + +func (n *Node) getFlagsPath() string { + return filepath.Join(n.getDataDir(), "flags.json") +} + +func (n *Node) readFlags() error { + bytes, err := os.ReadFile(n.getFlagsPath()) + if err != nil { + return fmt.Errorf("failed to read node flags: %w", err) + } + flags := FlagsMap{} + if err := json.Unmarshal(bytes, &flags); err != nil { + return fmt.Errorf("failed to unmarshal node flags: %w", err) + } + n.Flags = flags + return n.EnsureNodeID() +} + +func (n *Node) writeFlags() error { + bytes, err := DefaultJSONMarshal(n.Flags) + if err != nil { + return fmt.Errorf("failed to marshal node flags: %w", err) + } + if err := os.WriteFile(n.getFlagsPath(), bytes, perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write node flags: %w", err) + } + return nil +} + +func (n *Node) getConfigPath() string { + return filepath.Join(n.getDataDir(), defaultConfigFilename) +} + +func (n *Node) readConfig() error { + bytes, err := os.ReadFile(n.getConfigPath()) + if err != nil { + return fmt.Errorf("failed to read node config: %w", err) + } + if err := json.Unmarshal(bytes, n); err != nil { + return fmt.Errorf("failed to unmarshal node config: %w", err) + } + return nil +} + +type serializedNodeConfig struct { + IsEphemeral bool + RuntimeConfig *NodeRuntimeConfig +} + +func (n *Node) writeConfig() error { + config := serializedNodeConfig{ + IsEphemeral: n.IsEphemeral, + RuntimeConfig: n.RuntimeConfig, + } + bytes, err := DefaultJSONMarshal(config) + if err != nil { + return fmt.Errorf("failed to marshal node config: %w", err) + } + if err := os.WriteFile(n.getConfigPath(), bytes, perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write node config: %w", err) + } + return nil +} + +func (n *Node) Read() error { + if err := n.readFlags(); err != nil { + return err + } + if err := n.readConfig(); err != nil { + return err + } + return n.readState() +} + +func (n *Node) Write() error { + if err := os.MkdirAll(n.getDataDir(), perms.ReadWriteExecute); err != nil { + return fmt.Errorf("failed to create node dir: %w", err) + } + + if err := n.writeFlags(); err != nil { + return nil + } + return n.writeConfig() +} diff --git a/tests/fixture/tmpnet/node_process.go b/tests/fixture/tmpnet/node_process.go new file mode 100644 index 000000000000..bec294b20713 --- /dev/null +++ b/tests/fixture/tmpnet/node_process.go @@ -0,0 +1,258 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package tmpnet + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "io/fs" + "net" + "os" + "os/exec" + "path/filepath" + "syscall" + "time" + + "github.com/ava-labs/avalanchego/api/health" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/node" +) + +const ( + AvalancheGoPathEnvName = "AVALANCHEGO_PATH" + + defaultNodeInitTimeout = 10 * time.Second +) + +var errNodeAlreadyRunning = errors.New("failed to start node: node is already running") + +func checkNodeHealth(ctx context.Context, uri string) (bool, error) { + // Check that the node is reporting healthy + health, err := health.NewClient(uri).Health(ctx, nil) + if err == nil { + return health.Healthy, nil + } + + switch t := err.(type) { + case *net.OpError: + if t.Op == "read" { + // Connection refused - potentially recoverable + return false, nil + } + case syscall.Errno: + if t == syscall.ECONNREFUSED { + // Connection refused - potentially recoverable + return false, nil + } + } + // Assume all other errors are not recoverable + return false, fmt.Errorf("failed to query node health: %w", err) +} + +// Defines local-specific node configuration. Supports setting default +// and node-specific values. +type NodeProcess struct { + node *Node + + // PID of the node process + pid int +} + +func (p *NodeProcess) setProcessContext(processContext node.NodeProcessContext) { + p.pid = processContext.PID + p.node.URI = processContext.URI + p.node.StakingAddress = processContext.StakingAddress +} + +func (p *NodeProcess) readState() error { + path := p.getProcessContextPath() + if _, err := os.Stat(path); errors.Is(err, fs.ErrNotExist) { + // The absence of the process context file indicates the node is not running + p.setProcessContext(node.NodeProcessContext{}) + return nil + } + + bytes, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read node process context: %w", err) + } + processContext := node.NodeProcessContext{} + if err := json.Unmarshal(bytes, &processContext); err != nil { + return fmt.Errorf("failed to unmarshal node process context: %w", err) + } + p.setProcessContext(processContext) + return nil +} + +// Start waits for the process context to be written which +// indicates that the node will be accepting connections on +// its staking port. The network will start faster with this +// synchronization due to the avoidance of exponential backoff +// if a node tries to connect to a beacon that is not ready. +func (p *NodeProcess) Start(w io.Writer) error { + // Avoid attempting to start an already running node. + proc, err := p.getProcess() + if err != nil { + return fmt.Errorf("failed to retrieve existing process: %w", err) + } + if proc != nil { + return errNodeAlreadyRunning + } + + // Ensure a stale process context file is removed so that the + // creation of a new file can indicate node start. + if err := os.Remove(p.getProcessContextPath()); err != nil && !errors.Is(err, fs.ErrNotExist) { + return fmt.Errorf("failed to remove stale process context file: %w", err) + } + + cmd := exec.Command(p.node.RuntimeConfig.AvalancheGoPath, "--config-file", p.node.getFlagsPath()) // #nosec G204 + if err := cmd.Start(); err != nil { + return err + } + + // Determine appropriate level of node description detail + dataDir := p.node.getDataDir() + nodeDescription := fmt.Sprintf("node %q", p.node.NodeID) + if p.node.IsEphemeral { + nodeDescription = "ephemeral " + nodeDescription + } + nonDefaultNodeDir := filepath.Base(dataDir) != p.node.NodeID.String() + if nonDefaultNodeDir { + // Only include the data dir if its base is not the default (the node ID) + nodeDescription = fmt.Sprintf("%s with path: %s", nodeDescription, dataDir) + } + + go func() { + if err := cmd.Wait(); err != nil { + if err.Error() != "signal: killed" { + _, _ = fmt.Fprintf(w, "%s finished with error: %v\n", nodeDescription, err) + } + } + _, _ = fmt.Fprintf(w, "%s exited\n", nodeDescription) + }() + + // A node writes a process context file on start. If the file is not + // found in a reasonable amount of time, the node is unlikely to have + // started successfully. + if err := p.waitForProcessContext(context.Background()); err != nil { + return fmt.Errorf("failed to start local node: %w", err) + } + + _, err = fmt.Fprintf(w, "Started %s\n", nodeDescription) + return err +} + +// Signals the node process to stop. +func (p *NodeProcess) InitiateStop() error { + proc, err := p.getProcess() + if err != nil { + return fmt.Errorf("failed to retrieve process to stop: %w", err) + } + if proc == nil { + // Already stopped + return nil + } + if err := proc.Signal(syscall.SIGTERM); err != nil { + return fmt.Errorf("failed to send SIGTERM to pid %d: %w", p.pid, err) + } + return nil +} + +// Waits for the node process to stop. +func (p *NodeProcess) WaitForStopped(ctx context.Context) error { + ticker := time.NewTicker(defaultNodeTickerInterval) + defer ticker.Stop() + for { + proc, err := p.getProcess() + if err != nil { + return fmt.Errorf("failed to retrieve process: %w", err) + } + if proc == nil { + return nil + } + + select { + case <-ctx.Done(): + return fmt.Errorf("failed to see node process stop %q before timeout: %w", p.node.NodeID, ctx.Err()) + case <-ticker.C: + } + } +} + +func (p *NodeProcess) IsHealthy(ctx context.Context) (bool, error) { + // Check that the node process is running as a precondition for + // checking health. getProcess will also ensure that the node's + // API URI is current. + proc, err := p.getProcess() + if err != nil { + return false, fmt.Errorf("failed to determine process status: %w", err) + } + if proc == nil { + return false, ErrNotRunning + } + + return checkNodeHealth(ctx, p.node.URI) +} + +func (p *NodeProcess) getProcessContextPath() string { + return filepath.Join(p.node.getDataDir(), config.DefaultProcessContextFilename) +} + +func (p *NodeProcess) waitForProcessContext(ctx context.Context) error { + ticker := time.NewTicker(defaultNodeTickerInterval) + defer ticker.Stop() + + ctx, cancel := context.WithTimeout(ctx, defaultNodeInitTimeout) + defer cancel() + for len(p.node.URI) == 0 { + err := p.readState() + if err != nil { + return fmt.Errorf("failed to read process context for node %q: %w", p.node.NodeID, err) + } + + select { + case <-ctx.Done(): + return fmt.Errorf("failed to load process context for node %q before timeout: %w", p.node.NodeID, ctx.Err()) + case <-ticker.C: + } + } + return nil +} + +// Retrieve the node process if it is running. As part of determining +// process liveness, the node's process context will be refreshed if +// live or cleared if not running. +func (p *NodeProcess) getProcess() (*os.Process, error) { + // Read the process context to ensure freshness. The node may have + // stopped or been restarted since last read. + if err := p.readState(); err != nil { + return nil, fmt.Errorf("failed to read process context: %w", err) + } + + if p.pid == 0 { + // Process is not running + return nil, nil + } + + proc, err := os.FindProcess(p.pid) + if err != nil { + return nil, fmt.Errorf("failed to find process: %w", err) + } + + // Sending 0 will not actually send a signal but will perform + // error checking. + err = proc.Signal(syscall.Signal(0)) + if err == nil { + // Process is running + return proc, nil + } + if errors.Is(err, os.ErrProcessDone) { + // Process is not running + return nil, nil + } + return nil, fmt.Errorf("failed to determine process status: %w", err) +} diff --git a/tests/fixture/tmpnet/utils.go b/tests/fixture/tmpnet/utils.go index fd0bc64427f3..74e6e3737069 100644 --- a/tests/fixture/tmpnet/utils.go +++ b/tests/fixture/tmpnet/utils.go @@ -54,6 +54,10 @@ type NodeURI struct { func GetNodeURIs(nodes []*Node) []NodeURI { uris := make([]NodeURI, 0, len(nodes)) for _, node := range nodes { + if node.IsEphemeral { + // Avoid returning URIs for nodes whose lifespan is indeterminate + continue + } // Only append URIs that are not empty. A node may have an // empty URI if it is not currently running. if len(node.URI) > 0 { diff --git a/tests/upgrade/upgrade_test.go b/tests/upgrade/upgrade_test.go index 0f65c0202385..862b08555b4f 100644 --- a/tests/upgrade/upgrade_test.go +++ b/tests/upgrade/upgrade_test.go @@ -53,7 +53,7 @@ var _ = ginkgo.Describe("[Upgrade]", func() { ginkgo.By(fmt.Sprintf("restarting all nodes with %q binary", avalancheGoExecPathToUpgradeTo)) for _, node := range network.Nodes { ginkgo.By(fmt.Sprintf("restarting node %q with %q binary", node.NodeID, avalancheGoExecPathToUpgradeTo)) - require.NoError(node.Stop()) + require.NoError(node.Stop(e2e.DefaultContext())) // A node must start with sufficient bootstrap nodes to represent a quorum. Since the node's current // bootstrap configuration may not satisfy this requirement (i.e. if on network start the node was one of @@ -66,11 +66,10 @@ var _ = ginkgo.Describe("[Upgrade]", func() { require.NotEmpty(bootstrapIDs) node.Flags[config.BootstrapIDsKey] = strings.Join(bootstrapIDs, ",") node.Flags[config.BootstrapIPsKey] = strings.Join(bootstrapIPs, ",") - require.NoError(node.WriteConfig()) + node.RuntimeConfig.AvalancheGoPath = avalancheGoExecPath + require.NoError(node.Write()) - // Ensure the new node starts with the upgrade binary - node.ExecPath = avalancheGoExecPathToUpgradeTo - require.NoError(node.Start(ginkgo.GinkgoWriter, "" /* defaultExecPath */)) + require.NoError(node.Start(ginkgo.GinkgoWriter)) ginkgo.By(fmt.Sprintf("waiting for node %q to report healthy after restart", node.NodeID)) e2e.WaitForHealthy(node) From 7140a84704c51ec9c8d46be98efc0a0d33e82886 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 19 Dec 2023 17:05:06 -0500 Subject: [PATCH 170/267] Move `snow.DefaultConsensusContextTest` to `snowtest.ConsensusContext` (#2507) --- indexer/index_test.go | 8 +-- indexer/indexer_test.go | 9 +-- network/test_network.go | 4 +- snow/acceptor.go | 7 -- snow/consensus/snowman/consensus_test.go | 64 +++++++++---------- snow/consensus/snowman/network_test.go | 4 +- snow/context.go | 11 ---- .../avalanche/bootstrap/bootstrapper_test.go | 3 +- snow/engine/common/queue/jobs_test.go | 10 +-- .../snowman/bootstrap/bootstrapper_test.go | 7 +- snow/engine/snowman/config_test.go | 4 +- .../snowman/syncer/state_syncer_test.go | 34 +++++----- snow/networking/benchlist/benchlist_test.go | 8 +-- snow/networking/handler/handler_test.go | 15 +++-- snow/networking/handler/health_test.go | 3 +- snow/networking/handler/message_queue_test.go | 4 +- snow/networking/router/chain_router_test.go | 17 ++--- snow/networking/sender/sender_test.go | 13 ++-- snow/snowtest/snowtest.go | 30 +++++++++ vms/platformvm/vm_test.go | 3 +- 20 files changed, 139 insertions(+), 119 deletions(-) create mode 100644 snow/snowtest/snowtest.go diff --git a/indexer/index_test.go b/indexer/index_test.go index f31117c77b71..7edab5823feb 100644 --- a/indexer/index_test.go +++ b/indexer/index_test.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" @@ -28,7 +28,7 @@ func TestIndex(t *testing.T) { require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) baseDB := memdb.New() db := versiondb.New(baseDB) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() indexIntf, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) @@ -116,7 +116,7 @@ func TestIndexGetContainerByRangeMaxPageSize(t *testing.T) { codec := codec.NewDefaultManager() require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) db := memdb.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() indexIntf, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) idx := indexIntf.(*index) @@ -156,7 +156,7 @@ func TestDontIndexSameContainerTwice(t *testing.T) { codec := codec.NewDefaultManager() require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) db := memdb.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() idx, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) diff --git a/indexer/indexer_test.go b/indexer/indexer_test.go index a8c2f474f743..bf651101ed61 100644 --- a/indexer/indexer_test.go +++ b/indexer/indexer_test.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" ) @@ -153,7 +154,7 @@ func TestIndexer(t *testing.T) { idxr.clock.Set(now) // Assert state is right - chain1Ctx := snow.DefaultConsensusContextTest() + chain1Ctx := snowtest.ConsensusContext() chain1Ctx.ChainID = ids.GenerateTestID() isIncomplete, err := idxr.isIncomplete(chain1Ctx.ChainID) require.NoError(err) @@ -258,7 +259,7 @@ func TestIndexer(t *testing.T) { require.Contains(server.endpoints, "/block") // Register a DAG chain - chain2Ctx := snow.DefaultConsensusContextTest() + chain2Ctx := snowtest.ConsensusContext() chain2Ctx.ChainID = ids.GenerateTestID() isIncomplete, err = idxr.isIncomplete(chain2Ctx.ChainID) require.NoError(err) @@ -418,7 +419,7 @@ func TestIncompleteIndex(t *testing.T) { require.False(idxr.indexingEnabled) // Register a chain - chain1Ctx := snow.DefaultConsensusContextTest() + chain1Ctx := snowtest.ConsensusContext() chain1Ctx.ChainID = ids.GenerateTestID() isIncomplete, err := idxr.isIncomplete(chain1Ctx.ChainID) require.NoError(err) @@ -501,7 +502,7 @@ func TestIgnoreNonDefaultChains(t *testing.T) { idxr := idxrIntf.(*indexer) // Assert state is right - chain1Ctx := snow.DefaultConsensusContextTest() + chain1Ctx := snowtest.ConsensusContext() chain1Ctx.ChainID = ids.GenerateTestID() chain1Ctx.SubnetID = ids.GenerateTestID() diff --git a/network/test_network.go b/network/test_network.go index d8795e14e044..4f9b12fa48d8 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -18,9 +18,9 @@ import ( "github.com/ava-labs/avalanchego/network/dialer" "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/network/throttling" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/ava-labs/avalanchego/snow/networking/tracker" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" @@ -187,7 +187,7 @@ func NewTestNetwork( networkConfig.TLSConfig = tlsConfig networkConfig.TLSKey = tlsCert.PrivateKey.(crypto.Signer) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := validators.NewManager() networkConfig.Validators = currentValidators networkConfig.Beacons = beacons diff --git a/snow/acceptor.go b/snow/acceptor.go index c4ed74519e14..9c07a2aa0235 100644 --- a/snow/acceptor.go +++ b/snow/acceptor.go @@ -14,7 +14,6 @@ import ( ) var ( - _ Acceptor = noOpAcceptor{} _ Acceptor = acceptorWrapper{} _ AcceptorGroup = (*acceptorGroup)(nil) @@ -31,12 +30,6 @@ type Acceptor interface { Accept(ctx *ConsensusContext, containerID ids.ID, container []byte) error } -type noOpAcceptor struct{} - -func (noOpAcceptor) Accept(*ConsensusContext, ids.ID, []byte) error { - return nil -} - type acceptorWrapper struct { Acceptor diff --git a/snow/consensus/snowman/consensus_test.go b/snow/consensus/snowman/consensus_test.go index a7558e67034d..0894f2290b77 100644 --- a/snow/consensus/snowman/consensus_test.go +++ b/snow/consensus/snowman/consensus_test.go @@ -20,9 +20,9 @@ import ( "gonum.org/v1/gonum/mathext/prng" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowball" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/bag" ) @@ -94,7 +94,7 @@ func InitializeTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -119,7 +119,7 @@ func NumProcessingTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -161,7 +161,7 @@ func AddToTailTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -200,7 +200,7 @@ func AddToNonTailTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -248,7 +248,7 @@ func AddToUnknownTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -288,7 +288,7 @@ func StatusOrProcessingPreviouslyAcceptedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -317,7 +317,7 @@ func StatusOrProcessingPreviouslyRejectedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -354,7 +354,7 @@ func StatusOrProcessingUnissuedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -391,7 +391,7 @@ func StatusOrProcessingIssuedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -430,7 +430,7 @@ func RecordPollAcceptSingleBlockTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -472,7 +472,7 @@ func RecordPollAcceptAndRejectTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -525,7 +525,7 @@ func RecordPollSplitVoteNoChangeTest(t *testing.T, factory Factory) { require := require.New(t) sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() registerer := prometheus.NewRegistry() ctx.Registerer = registerer @@ -588,7 +588,7 @@ func RecordPollWhenFinalizedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -613,7 +613,7 @@ func RecordPollRejectTransitivelyTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -683,7 +683,7 @@ func RecordPollTransitivelyResetConfidenceTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -775,7 +775,7 @@ func RecordPollInvalidVoteTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -816,7 +816,7 @@ func RecordPollTransitiveVotingTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 3, AlphaPreference: 3, @@ -926,7 +926,7 @@ func RecordPollDivergedVotingTest(t *testing.T, factory Factory) { sm := factory.New() require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1029,7 +1029,7 @@ func RecordPollDivergedVotingWithNoConflictingBitTest(t *testing.T, factory Fact sm := factory.New() require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1133,7 +1133,7 @@ func RecordPollChangePreferredChainTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1240,7 +1240,7 @@ func LastAcceptedTest(t *testing.T, factory Factory) { sm := factory.New() require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1324,7 +1324,7 @@ func MetricsProcessingErrorTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1353,7 +1353,7 @@ func MetricsAcceptedErrorTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1382,7 +1382,7 @@ func MetricsRejectedErrorTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1411,7 +1411,7 @@ func ErrorOnInitialRejectionTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1450,7 +1450,7 @@ func ErrorOnAcceptTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1487,7 +1487,7 @@ func ErrorOnRejectSiblingTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1533,7 +1533,7 @@ func ErrorOnTransitiveRejectionTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1623,7 +1623,7 @@ func ErrorOnAddDecidedBlockTest(t *testing.T, factory Factory) { sm := factory.New() require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1653,7 +1653,7 @@ func ErrorOnAddDuplicateBlockIDTest(t *testing.T, factory Factory) { sm := factory.New() require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1717,7 +1717,7 @@ func RecordPollWithDefaultParameters(t *testing.T, factory Factory) { sm := factory.New() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() params := snowball.DefaultParameters require.NoError(sm.Initialize(ctx, params, GenesisID, GenesisHeight, GenesisTimestamp)) diff --git a/snow/consensus/snowman/network_test.go b/snow/consensus/snowman/network_test.go index f6e734f3cbce..3102c0cae573 100644 --- a/snow/consensus/snowman/network_test.go +++ b/snow/consensus/snowman/network_test.go @@ -7,9 +7,9 @@ import ( "context" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowball" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/bag" "github.com/ava-labs/avalanchego/utils/sampler" @@ -66,7 +66,7 @@ func (n *Network) shuffleColors() { } func (n *Network) AddNode(sm Consensus) error { - if err := sm.Initialize(snow.DefaultConsensusContextTest(), n.params, Genesis.ID(), Genesis.Height(), Genesis.Timestamp()); err != nil { + if err := sm.Initialize(snowtest.ConsensusContext(), n.params, Genesis.ID(), Genesis.Height(), Genesis.Timestamp()); err != nil { return err } diff --git a/snow/context.go b/snow/context.go index c89c2dd07a11..086243868bc2 100644 --- a/snow/context.go +++ b/snow/context.go @@ -115,14 +115,3 @@ func DefaultContextTest() *Context { ChainDataDir: "", } } - -func DefaultConsensusContextTest() *ConsensusContext { - return &ConsensusContext{ - Context: DefaultContextTest(), - Registerer: prometheus.NewRegistry(), - AvalancheRegisterer: prometheus.NewRegistry(), - BlockAcceptor: noOpAcceptor{}, - TxAcceptor: noOpAcceptor{}, - VertexAcceptor: noOpAcceptor{}, - } -} diff --git a/snow/engine/avalanche/bootstrap/bootstrapper_test.go b/snow/engine/avalanche/bootstrap/bootstrapper_test.go index 4e61e9b137ee..8efaef5ee647 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper_test.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper_test.go @@ -27,6 +27,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/common/queue" "github.com/ava-labs/avalanchego/snow/engine/common/tracker" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/set" @@ -55,7 +56,7 @@ func (t *testTx) Accept(ctx context.Context) error { func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *vertex.TestManager, *vertex.TestVM) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() db := memdb.New() diff --git a/snow/engine/common/queue/jobs_test.go b/snow/engine/common/queue/jobs_test.go index 57b63e19750d..f5db64d66dfc 100644 --- a/snow/engine/common/queue/jobs_test.go +++ b/snow/engine/common/queue/jobs_test.go @@ -16,8 +16,8 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/set" ) @@ -116,7 +116,7 @@ func TestPushAndExecute(t *testing.T) { return job, nil } - count, err := jobs.ExecuteAll(context.Background(), snow.DefaultConsensusContextTest(), &common.Halter{}, false) + count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(), &common.Halter{}, false) require.NoError(err) require.Equal(1, count) @@ -182,7 +182,7 @@ func TestRemoveDependency(t *testing.T) { } } - count, err := jobs.ExecuteAll(context.Background(), snow.DefaultConsensusContextTest(), &common.Halter{}, false) + count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(), &common.Halter{}, false) require.NoError(err) require.Equal(2, count) require.True(executed0) @@ -355,7 +355,7 @@ func TestHandleJobWithMissingDependencyOnRunnableStack(t *testing.T) { } } - _, err = jobs.ExecuteAll(context.Background(), snow.DefaultConsensusContextTest(), &common.Halter{}, false) + _, err = jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(), &common.Halter{}, false) // Assert that the database closed error on job1 causes ExecuteAll // to fail in the middle of execution. require.ErrorIs(err, database.ErrClosed) @@ -387,7 +387,7 @@ func TestHandleJobWithMissingDependencyOnRunnableStack(t *testing.T) { require.NoError(err) require.True(hasNext) - count, err := jobs.ExecuteAll(context.Background(), snow.DefaultConsensusContextTest(), &common.Halter{}, false) + count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(), &common.Halter{}, false) require.NoError(err) require.Equal(2, count) require.True(executed1) diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index 4f7e54882920..d78ee2fe3e61 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/getter" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" @@ -38,7 +39,7 @@ var errUnknownBlock = errors.New("unknown block") func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *block.TestVM) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() @@ -104,7 +105,7 @@ func TestBootstrapperStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { sender.Default(true) vm.Default(true) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() // create boostrapper configuration peers := validators.NewManager() sampleK := 2 @@ -1314,7 +1315,7 @@ func TestBootstrapContinueAfterHalt(t *testing.T) { func TestBootstrapNoParseOnNew(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() peers := validators.NewManager() sender := &common.SenderTest{} diff --git a/snow/engine/snowman/config_test.go b/snow/engine/snowman/config_test.go index 9611990d9d95..36e01d0d8f14 100644 --- a/snow/engine/snowman/config_test.go +++ b/snow/engine/snowman/config_test.go @@ -4,18 +4,18 @@ package snowman import ( - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" ) func DefaultConfig() Config { return Config{ - Ctx: snow.DefaultConsensusContextTest(), + Ctx: snowtest.ConsensusContext(), VM: &block.TestVM{}, Sender: &common.SenderTest{}, Validators: validators.NewManager(), diff --git a/snow/engine/snowman/syncer/state_syncer_test.go b/snow/engine/snowman/syncer/state_syncer_test.go index c3dd9b2f16a6..7e6b58694375 100644 --- a/snow/engine/snowman/syncer/state_syncer_test.go +++ b/snow/engine/snowman/syncer/state_syncer_test.go @@ -17,11 +17,11 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/common/tracker" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/getter" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" @@ -39,7 +39,7 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { require := require.New(t) // Build state syncer - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() sender := &common.SenderTest{T: t} // Non state syncableVM case @@ -109,7 +109,7 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { func TestStateSyncingStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) alpha, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -151,7 +151,7 @@ func TestStateSyncingStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { func TestStateSyncLocalSummaryIsIncludedAmongFrontiersIfAvailable(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -188,7 +188,7 @@ func TestStateSyncLocalSummaryIsIncludedAmongFrontiersIfAvailable(t *testing.T) func TestStateSyncNotFoundOngoingSummaryIsNotIncludedAmongFrontiers(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -218,7 +218,7 @@ func TestStateSyncNotFoundOngoingSummaryIsNotIncludedAmongFrontiers(t *testing.T func TestBeaconsAreReachedForFrontiersUponStartup(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -256,7 +256,7 @@ func TestBeaconsAreReachedForFrontiersUponStartup(t *testing.T) { func TestUnRequestedStateSummaryFrontiersAreDropped(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -345,7 +345,7 @@ func TestUnRequestedStateSummaryFrontiersAreDropped(t *testing.T) { func TestMalformedStateSummaryFrontiersAreDropped(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -413,7 +413,7 @@ func TestMalformedStateSummaryFrontiersAreDropped(t *testing.T) { func TestLateResponsesFromUnresponsiveFrontiersAreNotRecorded(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -495,7 +495,7 @@ func TestLateResponsesFromUnresponsiveFrontiersAreNotRecorded(t *testing.T) { func TestStateSyncIsRestartedIfTooManyFrontierSeedersTimeout(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -583,7 +583,7 @@ func TestStateSyncIsRestartedIfTooManyFrontierSeedersTimeout(t *testing.T) { func TestVoteRequestsAreSentAsAllFrontierBeaconsResponded(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -653,7 +653,7 @@ func TestVoteRequestsAreSentAsAllFrontierBeaconsResponded(t *testing.T) { func TestUnRequestedVotesAreDropped(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -769,7 +769,7 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { func TestVotesForUnknownSummariesAreDropped(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -871,7 +871,7 @@ func TestVotesForUnknownSummariesAreDropped(t *testing.T) { func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -1015,7 +1015,7 @@ func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -1120,7 +1120,7 @@ func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -1265,7 +1265,7 @@ func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing. func TestStateSyncIsDoneOnceVMNotifies(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) diff --git a/snow/networking/benchlist/benchlist_test.go b/snow/networking/benchlist/benchlist_test.go index 394d38c8e8c1..aef4513edf6d 100644 --- a/snow/networking/benchlist/benchlist_test.go +++ b/snow/networking/benchlist/benchlist_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" ) @@ -20,7 +20,7 @@ var minimumFailingDuration = 5 * time.Minute func TestBenchlistAdd(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() vdrID0 := ids.GenerateTestNodeID() vdrID1 := ids.GenerateTestNodeID() @@ -144,7 +144,7 @@ func TestBenchlistAdd(t *testing.T) { func TestBenchlistMaxStake(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() vdrID0 := ids.GenerateTestNodeID() vdrID1 := ids.GenerateTestNodeID() @@ -257,7 +257,7 @@ func TestBenchlistMaxStake(t *testing.T) { func TestBenchlistRemove(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() vdrID0 := ids.GenerateTestNodeID() vdrID1 := ids.GenerateTestNodeID() diff --git a/snow/networking/handler/handler_test.go b/snow/networking/handler/handler_test.go index bb434e2017d4..80330f872f45 100644 --- a/snow/networking/handler/handler_test.go +++ b/snow/networking/handler/handler_test.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/networking/tracker" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/utils/math/meter" @@ -40,7 +41,7 @@ func TestHandlerDropsTimedOutMessages(t *testing.T) { called := make(chan struct{}) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() vdr0 := ids.GenerateTestNodeID() @@ -135,7 +136,7 @@ func TestHandlerClosesOnError(t *testing.T) { require := require.New(t) closed := make(chan struct{}, 1) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -226,7 +227,7 @@ func TestHandlerDropsGossipDuringBootstrapping(t *testing.T) { require := require.New(t) closed := make(chan struct{}, 1) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -303,7 +304,7 @@ func TestHandlerDropsGossipDuringBootstrapping(t *testing.T) { func TestHandlerDispatchInternal(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() msgFromVMChan := make(chan common.Message) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -372,7 +373,7 @@ func TestHandlerDispatchInternal(t *testing.T) { func TestHandlerSubnetConnector(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -547,7 +548,7 @@ func TestDynamicEngineTypeDispatch(t *testing.T) { require := require.New(t) messageReceived := make(chan struct{}) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -620,7 +621,7 @@ func TestDynamicEngineTypeDispatch(t *testing.T) { func TestHandlerStartError(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() resourceTracker, err := tracker.NewResourceTracker( prometheus.NewRegistry(), resource.NoUsage, diff --git a/snow/networking/handler/health_test.go b/snow/networking/handler/health_test.go index 63b7dbea140c..3b1335417fa1 100644 --- a/snow/networking/handler/health_test.go +++ b/snow/networking/handler/health_test.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/networking/tracker" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/utils/math/meter" @@ -47,7 +48,7 @@ func TestHealthCheckSubnet(t *testing.T) { t.Run(name, func(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() diff --git a/snow/networking/handler/message_queue_test.go b/snow/networking/handler/message_queue_test.go index 1eabfd96c410..3930bcf4522b 100644 --- a/snow/networking/handler/message_queue_test.go +++ b/snow/networking/handler/message_queue_test.go @@ -15,8 +15,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/proto/pb/p2p" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/networking/tracker" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" ) @@ -26,7 +26,7 @@ func TestQueue(t *testing.T) { ctrl := gomock.NewController(t) require := require.New(t) cpuTracker := tracker.NewMockTracker(ctrl) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() vdr1ID, vdr2ID := ids.GenerateTestNodeID(), ids.GenerateTestNodeID() require.NoError(vdrs.AddStaker(ctx.SubnetID, vdr1ID, nil, ids.Empty, 1)) diff --git a/snow/networking/router/chain_router_test.go b/snow/networking/router/chain_router_test.go index 05e749ed7bcf..6e08f8e7b7c2 100644 --- a/snow/networking/router/chain_router_test.go +++ b/snow/networking/router/chain_router_test.go @@ -25,6 +25,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/handler" "github.com/ava-labs/avalanchego/snow/networking/timeout" "github.com/ava-labs/avalanchego/snow/networking/tracker" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/utils/constants" @@ -48,7 +49,7 @@ const ( func TestShutdown(t *testing.T) { require := require.New(t) - chainCtx := snow.DefaultConsensusContextTest() + chainCtx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(chainCtx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) benchlist := benchlist.NewNoBenchlist() @@ -183,7 +184,7 @@ func TestShutdown(t *testing.T) { func TestShutdownTimesOut(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() nodeID := ids.EmptyNodeID vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -377,7 +378,7 @@ func TestRouterTimeout(t *testing.T) { wg = sync.WaitGroup{} ) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -726,7 +727,7 @@ func TestRouterHonorsRequestedEngine(t *testing.T) { h := handler.NewMockHandler(ctrl) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() h.EXPECT().Context().Return(ctx).AnyTimes() h.EXPECT().SetOnStopped(gomock.Any()).AnyTimes() h.EXPECT().Stop(gomock.Any()).AnyTimes() @@ -950,7 +951,7 @@ func TestValidatorOnlyMessageDrops(t *testing.T) { calledF := false wg := sync.WaitGroup{} - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() sb := subnets.New(ctx.NodeID, subnets.Config{ValidatorOnly: true}) vdrs := validators.NewManager() vID := ids.GenerateTestNodeID() @@ -1102,7 +1103,7 @@ func TestConnectedSubnet(t *testing.T) { )) // Create bootstrapper, engine and handler - platform := snow.DefaultConsensusContextTest() + platform := snowtest.ConsensusContext() platform.ChainID = constants.PlatformChainID platform.SubnetID = constants.PrimaryNetworkID platform.Registerer = prometheus.NewRegistry() @@ -1221,7 +1222,7 @@ func TestValidatorOnlyAllowedNodeMessageDrops(t *testing.T) { calledF := false wg := sync.WaitGroup{} - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() allowedID := ids.GenerateTestNodeID() allowedSet := set.Of(allowedID) sb := subnets.New(ctx.NodeID, subnets.Config{ValidatorOnly: true, AllowedNodes: allowedSet}) @@ -1546,7 +1547,7 @@ func newChainRouterTest(t *testing.T) (*ChainRouter, *common.EngineTest) { )) // Create bootstrapper, engine and handler - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index b0e9280d2e16..b4ba9db4f89a 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/ava-labs/avalanchego/snow/networking/timeout" "github.com/ava-labs/avalanchego/snow/networking/tracker" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/utils/constants" @@ -53,7 +54,7 @@ var defaultSubnetConfig = subnets.Config{ func TestTimeout(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) benchlist := benchlist.NewNoBenchlist() @@ -112,7 +113,7 @@ func TestTimeout(t *testing.T) { ) require.NoError(err) - ctx2 := snow.DefaultConsensusContextTest() + ctx2 := snowtest.ConsensusContext() resourceTracker, err := tracker.NewResourceTracker( prometheus.NewRegistry(), resource.NoUsage, @@ -317,7 +318,7 @@ func TestTimeout(t *testing.T) { func TestReliableMessages(t *testing.T) { require := require.New(t) - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.BuildTestNodeID([]byte{1}), nil, ids.Empty, 1)) benchlist := benchlist.NewNoBenchlist() @@ -377,7 +378,7 @@ func TestReliableMessages(t *testing.T) { ) require.NoError(err) - ctx2 := snow.DefaultConsensusContextTest() + ctx2 := snowtest.ConsensusContext() resourceTracker, err := tracker.NewResourceTracker( prometheus.NewRegistry(), resource.NoUsage, @@ -463,7 +464,7 @@ func TestReliableMessagesToMyself(t *testing.T) { require := require.New(t) benchlist := benchlist.NewNoBenchlist() - ctx := snow.DefaultConsensusContextTest() + ctx := snowtest.ConsensusContext() vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) tm, err := timeout.NewManager( @@ -522,7 +523,7 @@ func TestReliableMessagesToMyself(t *testing.T) { ) require.NoError(err) - ctx2 := snow.DefaultConsensusContextTest() + ctx2 := snowtest.ConsensusContext() resourceTracker, err := tracker.NewResourceTracker( prometheus.NewRegistry(), resource.NoUsage, diff --git a/snow/snowtest/snowtest.go b/snow/snowtest/snowtest.go new file mode 100644 index 000000000000..2dfd1a443b84 --- /dev/null +++ b/snow/snowtest/snowtest.go @@ -0,0 +1,30 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package snowtest + +import ( + "github.com/prometheus/client_golang/prometheus" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" +) + +var _ snow.Acceptor = noOpAcceptor{} + +type noOpAcceptor struct{} + +func (noOpAcceptor) Accept(*snow.ConsensusContext, ids.ID, []byte) error { + return nil +} + +func ConsensusContext() *snow.ConsensusContext { + return &snow.ConsensusContext{ + Context: snow.DefaultContextTest(), + Registerer: prometheus.NewRegistry(), + AvalancheRegisterer: prometheus.NewRegistry(), + BlockAcceptor: noOpAcceptor{}, + TxAcceptor: noOpAcceptor{}, + VertexAcceptor: noOpAcceptor{}, + } +} diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index bb210f0ffe16..3c3a017ec396 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -35,6 +35,7 @@ import ( "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/ava-labs/avalanchego/snow/networking/sender" "github.com/ava-labs/avalanchego/snow/networking/timeout" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/subnets" @@ -1306,7 +1307,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { m := atomic.NewMemory(atomicDB) ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) - consensusCtx := snow.DefaultConsensusContextTest() + consensusCtx := snowtest.ConsensusContext() consensusCtx.Context = ctx ctx.Lock.Lock() From 39a532097f001b331925dc58685873e8ed3e0448 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Tue, 19 Dec 2023 19:58:22 -0500 Subject: [PATCH 171/267] Add gossip Marshaller interface (#2509) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- go.mod | 2 +- go.sum | 4 +-- network/p2p/gossip/bloom.go | 4 +-- network/p2p/gossip/gossip.go | 60 +++++++++++++++---------------- network/p2p/gossip/gossip_test.go | 43 ++++++++++++++++------ network/p2p/gossip/gossipable.go | 10 ++++-- network/p2p/gossip/handler.go | 35 +++++++++--------- network/p2p/gossip/test_gossip.go | 22 +++++++----- 8 files changed, 106 insertions(+), 74 deletions(-) diff --git a/go.mod b/go.mod index b224c8fea9d6..f165bfa3ed70 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213223840-6e78d609ed32 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231219231451-224728dbacb4 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 989cf75cc92d..9c5c86ffbb1d 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213223840-6e78d609ed32 h1:CZ1N++oMSL6yKV/FcCx/7/2cmpAk3rQse797Xz/6Ro0= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231213223840-6e78d609ed32/go.mod h1:bHPGzEjcBOLIKGbik9ZzETOhHxnzdLyVX+Q/XvGmGeE= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231219231451-224728dbacb4 h1:LXL5nSxcblyBFR5/zdO4TAqSWqoB15bT3sGb1Nkh7o4= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231219231451-224728dbacb4/go.mod h1:84JZyt3colgzGI/jOYGB5Wzxr/wNP0zjebHiWZjFthk= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/network/p2p/gossip/bloom.go b/network/p2p/gossip/bloom.go index 5b1c6bc8c390..c113396bf0b3 100644 --- a/network/p2p/gossip/bloom.go +++ b/network/p2p/gossip/bloom.go @@ -46,7 +46,7 @@ type BloomFilter struct { } func (b *BloomFilter) Add(gossipable Gossipable) { - h := gossipable.GetID() + h := gossipable.GossipID() salted := &hasher{ hash: h[:], salt: b.Salt, @@ -55,7 +55,7 @@ func (b *BloomFilter) Add(gossipable Gossipable) { } func (b *BloomFilter) Has(gossipable Gossipable) bool { - h := gossipable.GetID() + h := gossipable.GossipID() salted := &hasher{ hash: h[:], salt: b.Salt, diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index 4f5f5e5ebfc3..c35d169c4259 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -31,7 +31,7 @@ const ( var ( _ Gossiper = (*ValidatorGossiper)(nil) - _ Gossiper = (*PullGossiper[testTx, *testTx])(nil) + _ Gossiper = (*PullGossiper[*testTx])(nil) _ Gossiper = (*NoOpGossiper)(nil) _ Gossiper = (*TestGossiper)(nil) @@ -55,13 +55,6 @@ type Accumulator[T Gossipable] interface { Add(gossipables ...T) } -// GossipableAny exists to help create non-nil pointers to a concrete Gossipable -// ref: https://stackoverflow.com/questions/69573113/how-can-i-instantiate-a-non-nil-pointer-of-type-argument-with-generic-go -type GossipableAny[T any] interface { - *T - Gossipable -} - // ValidatorGossiper only calls [Gossip] if the given node is a validator type ValidatorGossiper struct { Gossiper @@ -123,35 +116,38 @@ func (v ValidatorGossiper) Gossip(ctx context.Context) error { return v.Gossiper.Gossip(ctx) } -func NewPullGossiper[T any, U GossipableAny[T]]( +func NewPullGossiper[T Gossipable]( log logging.Logger, - set Set[U], + marshaller Marshaller[T], + set Set[T], client *p2p.Client, metrics Metrics, pollSize int, -) *PullGossiper[T, U] { - return &PullGossiper[T, U]{ - log: log, - set: set, - client: client, - metrics: metrics, - pollSize: pollSize, +) *PullGossiper[T] { + return &PullGossiper[T]{ + log: log, + marshaller: marshaller, + set: set, + client: client, + metrics: metrics, + pollSize: pollSize, labels: prometheus.Labels{ typeLabel: pullType, }, } } -type PullGossiper[T any, U GossipableAny[T]] struct { - log logging.Logger - set Set[U] - client *p2p.Client - metrics Metrics - pollSize int - labels prometheus.Labels +type PullGossiper[T Gossipable] struct { + log logging.Logger + marshaller Marshaller[T] + set Set[T] + client *p2p.Client + metrics Metrics + pollSize int + labels prometheus.Labels } -func (p *PullGossiper[_, _]) Gossip(ctx context.Context) error { +func (p *PullGossiper[_]) Gossip(ctx context.Context) error { bloom, salt, err := p.set.GetFilter() if err != nil { return err @@ -175,7 +171,7 @@ func (p *PullGossiper[_, _]) Gossip(ctx context.Context) error { return nil } -func (p *PullGossiper[T, U]) handleResponse( +func (p *PullGossiper[_]) handleResponse( _ context.Context, nodeID ids.NodeID, responseBytes []byte, @@ -200,8 +196,8 @@ func (p *PullGossiper[T, U]) handleResponse( for _, bytes := range response.Gossip { receivedBytes += len(bytes) - gossipable := U(new(T)) - if err := gossipable.Unmarshal(bytes); err != nil { + gossipable, err := p.marshaller.UnmarshalGossip(bytes) + if err != nil { p.log.Debug( "failed to unmarshal gossip", zap.Stringer("nodeID", nodeID), @@ -210,7 +206,7 @@ func (p *PullGossiper[T, U]) handleResponse( continue } - hash := gossipable.GetID() + hash := gossipable.GossipID() p.log.Debug( "received gossip", zap.Stringer("nodeID", nodeID), @@ -244,8 +240,9 @@ func (p *PullGossiper[T, U]) handleResponse( } // NewPushGossiper returns an instance of PushGossiper -func NewPushGossiper[T Gossipable](client *p2p.Client, metrics Metrics, targetGossipSize int) *PushGossiper[T] { +func NewPushGossiper[T Gossipable](marshaller Marshaller[T], client *p2p.Client, metrics Metrics, targetGossipSize int) *PushGossiper[T] { return &PushGossiper[T]{ + marshaller: marshaller, client: client, metrics: metrics, targetGossipSize: targetGossipSize, @@ -258,6 +255,7 @@ func NewPushGossiper[T Gossipable](client *p2p.Client, metrics Metrics, targetGo // PushGossiper broadcasts gossip to peers randomly in the network type PushGossiper[T Gossipable] struct { + marshaller Marshaller[T] client *p2p.Client metrics Metrics targetGossipSize int @@ -288,7 +286,7 @@ func (p *PushGossiper[T]) Gossip(ctx context.Context) error { break } - bytes, err := gossipable.Marshal() + bytes, err := p.marshaller.MarshalGossip(gossipable) if err != nil { // remove this item so we don't get stuck in a loop _, _ = p.pending.PopLeft() diff --git a/network/p2p/gossip/gossip_test.go b/network/p2p/gossip/gossip_test.go index a25a6dce07aa..25bfac3a4303 100644 --- a/network/p2p/gossip/gossip_test.go +++ b/network/p2p/gossip/gossip_test.go @@ -27,10 +27,11 @@ import ( ) func TestGossiperShutdown(*testing.T) { - gossiper := NewPullGossiper[testTx]( + gossiper := NewPullGossiper[*testTx]( logging.NoLog{}, nil, nil, + nil, Metrics{}, 0, ) @@ -122,8 +123,10 @@ func TestGossiperGossip(t *testing.T) { metrics, err := NewMetrics(prometheus.NewRegistry(), "") require.NoError(err) - handler := NewHandler[testTx, *testTx]( + marshaller := testMarshaller{} + handler := NewHandler[*testTx]( logging.NoLog{}, + marshaller, NoOpAccumulator[*testTx]{}, responseSet, metrics, @@ -153,8 +156,9 @@ func TestGossiperGossip(t *testing.T) { requestClient := requestNetwork.NewClient(0x0) require.NoError(err) - gossiper := NewPullGossiper[testTx, *testTx]( + gossiper := NewPullGossiper[*testTx]( logging.NoLog{}, + marshaller, requestSet, requestClient, metrics, @@ -317,7 +321,13 @@ func TestPushGossiper(t *testing.T) { client := network.NewClient(0) metrics, err := NewMetrics(prometheus.NewRegistry(), "") require.NoError(err) - gossiper := NewPushGossiper[*testTx](client, metrics, units.MiB) + marshaller := testMarshaller{} + gossiper := NewPushGossiper[*testTx]( + marshaller, + client, + metrics, + units.MiB, + ) for _, gossipables := range tt.cycles { gossiper.Add(gossipables...) @@ -328,7 +338,7 @@ func TestPushGossiper(t *testing.T) { } for _, gossipable := range gossipables { - bytes, err := gossipable.Marshal() + bytes, err := marshaller.MarshalGossip(gossipable) require.NoError(err) want.Gossip = append(want.Gossip, bytes) @@ -373,10 +383,17 @@ func TestPushGossipE2E(t *testing.T) { metrics, err := NewMetrics(prometheus.NewRegistry(), "") require.NoError(err) - forwarderGossiper := NewPushGossiper[*testTx](client, metrics, units.MiB) + marshaller := testMarshaller{} + forwarderGossiper := NewPushGossiper[*testTx]( + marshaller, + client, + metrics, + units.MiB, + ) - handler := NewHandler[testTx, *testTx]( + handler := NewHandler[*testTx]( log, + marshaller, forwarderGossiper, set, metrics, @@ -392,7 +409,12 @@ func TestPushGossipE2E(t *testing.T) { require.NoError(err) issuerClient := issuerNetwork.NewClient(handlerID) require.NoError(err) - issuerGossiper := NewPushGossiper[*testTx](issuerClient, metrics, units.MiB) + issuerGossiper := NewPushGossiper[*testTx]( + marshaller, + issuerClient, + metrics, + units.MiB, + ) want := []*testTx{ {id: ids.GenerateTestID()}, @@ -425,9 +447,10 @@ func TestPushGossipE2E(t *testing.T) { require.Len(forwardedMsg.Gossip, len(want)) gotForwarded := make([]*testTx, 0, len(addedToSet)) + for _, bytes := range forwardedMsg.Gossip { - tx := &testTx{} - require.NoError(tx.Unmarshal(bytes)) + tx, err := marshaller.UnmarshalGossip(bytes) + require.NoError(err) gotForwarded = append(gotForwarded, tx) } diff --git a/network/p2p/gossip/gossipable.go b/network/p2p/gossip/gossipable.go index d488e90e949c..bf6ff1644634 100644 --- a/network/p2p/gossip/gossipable.go +++ b/network/p2p/gossip/gossipable.go @@ -7,9 +7,13 @@ import "github.com/ava-labs/avalanchego/ids" // Gossipable is an item that can be gossiped across the network type Gossipable interface { - GetID() ids.ID - Marshal() ([]byte, error) - Unmarshal(bytes []byte) error + GossipID() ids.ID +} + +// Marshaller handles parsing logic for a concrete Gossipable type +type Marshaller[T Gossipable] interface { + MarshalGossip(T) ([]byte, error) + UnmarshalGossip([]byte) (T, error) } // Set holds a set of known Gossipable items diff --git a/network/p2p/gossip/handler.go b/network/p2p/gossip/handler.go index f1da62a03962..de74d78169cf 100644 --- a/network/p2p/gossip/handler.go +++ b/network/p2p/gossip/handler.go @@ -22,18 +22,20 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) -var _ p2p.Handler = (*Handler[testTx, *testTx])(nil) +var _ p2p.Handler = (*Handler[*testTx])(nil) -func NewHandler[T any, U GossipableAny[T]]( +func NewHandler[T Gossipable]( log logging.Logger, - accumulator Accumulator[U], - set Set[U], + marshaller Marshaller[T], + accumulator Accumulator[T], + set Set[T], metrics Metrics, targetResponseSize int, -) *Handler[T, U] { - return &Handler[T, U]{ +) *Handler[T] { + return &Handler[T]{ Handler: p2p.NoOpHandler{}, log: log, + marshaller: marshaller, accumulator: accumulator, set: set, metrics: metrics, @@ -44,11 +46,12 @@ func NewHandler[T any, U GossipableAny[T]]( } } -type Handler[T any, U GossipableAny[T]] struct { +type Handler[T Gossipable] struct { p2p.Handler - accumulator Accumulator[U] + marshaller Marshaller[T] + accumulator Accumulator[T] log logging.Logger - set Set[U] + set Set[T] metrics Metrics targetResponseSize int @@ -56,7 +59,7 @@ type Handler[T any, U GossipableAny[T]] struct { pushLabels prometheus.Labels } -func (h Handler[_, U]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, requestBytes []byte) ([]byte, error) { +func (h Handler[T]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, requestBytes []byte) ([]byte, error) { request := &sdk.PullGossipRequest{} if err := proto.Unmarshal(requestBytes, request); err != nil { return nil, err @@ -77,14 +80,14 @@ func (h Handler[_, U]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, responseSize := 0 gossipBytes := make([][]byte, 0) - h.set.Iterate(func(gossipable U) bool { + h.set.Iterate(func(gossipable T) bool { // filter out what the requesting peer already knows about if filter.Has(gossipable) { return true } var bytes []byte - bytes, err = gossipable.Marshal() + bytes, err = h.marshaller.MarshalGossip(gossipable) if err != nil { return false } @@ -121,7 +124,7 @@ func (h Handler[_, U]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, return proto.Marshal(response) } -func (h Handler[T, U]) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { +func (h Handler[_]) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { msg := &sdk.PushGossip{} if err := proto.Unmarshal(gossipBytes, msg); err != nil { h.log.Debug("failed to unmarshal gossip", zap.Error(err)) @@ -131,8 +134,8 @@ func (h Handler[T, U]) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipB receivedBytes := 0 for _, bytes := range msg.Gossip { receivedBytes += len(bytes) - gossipable := U(new(T)) - if err := gossipable.Unmarshal(bytes); err != nil { + gossipable, err := h.marshaller.UnmarshalGossip(bytes) + if err != nil { h.log.Debug("failed to unmarshal gossip", zap.Stringer("nodeID", nodeID), zap.Error(err), @@ -144,7 +147,7 @@ func (h Handler[T, U]) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipB h.log.Debug( "failed to add gossip to the known set", zap.Stringer("nodeID", nodeID), - zap.Stringer("id", gossipable.GetID()), + zap.Stringer("id", gossipable.GossipID()), zap.Error(err), ) continue diff --git a/network/p2p/gossip/test_gossip.go b/network/p2p/gossip/test_gossip.go index 8e87ba70da94..83021730d444 100644 --- a/network/p2p/gossip/test_gossip.go +++ b/network/p2p/gossip/test_gossip.go @@ -10,26 +10,30 @@ import ( ) var ( - _ Gossipable = (*testTx)(nil) - _ Set[*testTx] = (*testSet)(nil) + _ Gossipable = (*testTx)(nil) + _ Set[*testTx] = (*testSet)(nil) + _ Marshaller[*testTx] = (*testMarshaller)(nil) ) type testTx struct { id ids.ID } -func (t *testTx) GetID() ids.ID { +func (t *testTx) GossipID() ids.ID { return t.id } -func (t *testTx) Marshal() ([]byte, error) { - return t.id[:], nil +type testMarshaller struct{} + +func (testMarshaller) MarshalGossip(tx *testTx) ([]byte, error) { + return tx.id[:], nil } -func (t *testTx) Unmarshal(bytes []byte) error { - t.id = ids.ID{} - copy(t.id[:], bytes) - return nil +func (testMarshaller) UnmarshalGossip(bytes []byte) (*testTx, error) { + id, err := ids.ToID(bytes) + return &testTx{ + id: id, + }, err } type testSet struct { From 9d19143888a540b2bb9c7ded3df0846afce4dfc8 Mon Sep 17 00:00:00 2001 From: marun Date: Tue, 19 Dec 2023 18:41:56 -0800 Subject: [PATCH 172/267] Include chain creation error in health check (#2519) Signed-off-by: marun Co-authored-by: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> --- chains/manager.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chains/manager.go b/chains/manager.go index 43160e136f7c..74263c85317e 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -368,7 +368,7 @@ func (m *manager) createChain(chainParams ChainParameters) { // created or not. This attempts to notify the node operator that their // node may not be properly validating the subnet they expect to be // validating. - healthCheckErr := fmt.Errorf("failed to create chain on subnet: %s", chainParams.SubnetID) + healthCheckErr := fmt.Errorf("failed to create chain on subnet %s: %w", chainParams.SubnetID, err) err := m.Health.RegisterHealthCheck( chainAlias, health.CheckerFunc(func(context.Context) (interface{}, error) { From 0d0ac62e65f09292793026e11e947306ff515238 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 20 Dec 2023 10:21:28 -0500 Subject: [PATCH 173/267] Make X-chain mempool safe for concurrent use (#2520) --- vms/avm/block/builder/builder_test.go | 4 +- vms/avm/network/network.go | 2 +- vms/avm/network/network_test.go | 22 +- vms/avm/txs/mempool/mempool.go | 116 +++++---- vms/avm/txs/mempool/mempool_test.go | 343 ++++++++++++++++---------- vms/avm/txs/mempool/mock_mempool.go | 19 +- 6 files changed, 298 insertions(+), 208 deletions(-) diff --git a/vms/avm/block/builder/builder_test.go b/vms/avm/block/builder/builder_test.go index d15a5f8d08f7..e034db41cf91 100644 --- a/vms/avm/block/builder/builder_test.go +++ b/vms/avm/block/builder/builder_test.go @@ -510,7 +510,9 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { tx := transactions[0] txID := tx.ID() require.NoError(mempool.Add(tx)) - require.True(mempool.Has(txID)) + + _, ok := mempool.Get(txID) + require.True(ok) parser, err := block.NewParser([]fxs.Fx{ &secp256k1fx.Fx{}, diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index a1d3337ddb23..0f4fc6b52de2 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -141,7 +141,7 @@ func (n *network) IssueTx(ctx context.Context, tx *txs.Tx) error { // returns nil if the tx is in the mempool func (n *network) issueTx(tx *txs.Tx) error { txID := tx.ID() - if n.mempool.Has(txID) { + if _, ok := n.mempool.Get(txID); ok { // The tx is already in the mempool return nil } diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index 6d779eadcc28..0217430a2d22 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -91,7 +91,8 @@ func TestNetworkAppGossip(t *testing.T) { }, }, { - // Issue returns nil because mempool has tx. We should gossip the tx. + // Issue returns nil because mempool has tx. We haven't gossipped + // the tx recently, so we should gossip it. name: "issuance succeeds", msgBytesFunc: func() []byte { msg := message.Tx{ @@ -103,17 +104,18 @@ func TestNetworkAppGossip(t *testing.T) { }, mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(true) + mempool.EXPECT().Get(gomock.Any()).Return(testTx, true) return mempool }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Times(1) return appSender }, }, { - // Issue returns error because tx was dropped. We shouldn't gossip the tx. + // Issue returns error because tx was dropped. We shouldn't gossip + // the tx. name: "issuance fails", msgBytesFunc: func() []byte { msg := message.Tx{ @@ -125,7 +127,7 @@ func TestNetworkAppGossip(t *testing.T) { }, mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(errTest) return mempool }, @@ -176,7 +178,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "mempool has transaction", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(true) + mempool.EXPECT().Get(gomock.Any()).Return(nil, true) return mempool }, managerFunc: func(ctrl *gomock.Controller) executor.Manager { @@ -195,7 +197,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "transaction marked as dropped in mempool", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(errTest) return mempool }, @@ -213,7 +215,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "transaction invalid", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool @@ -233,7 +235,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "can't add transaction to mempool", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().Add(gomock.Any()).Return(errTest) mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) @@ -254,7 +256,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "happy path", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().Add(gomock.Any()).Return(nil) mempool.EXPECT().RequestBuildBlock() diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index 6e22ee61407a..db42c9cca418 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -6,12 +6,14 @@ package mempool import ( "errors" "fmt" + "sync" "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/avalanchego/cache" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/linkedhashmap" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" @@ -26,8 +28,6 @@ const ( // droppedTxIDsCacheSize is the maximum number of dropped txIDs to cache droppedTxIDsCacheSize = 64 - initialConsumedUTXOsSize = 512 - // maxMempoolSize is the maximum number of bytes allowed in the mempool maxMempoolSize = 64 * units.MiB ) @@ -44,13 +44,16 @@ var ( // Mempool contains transactions that have not yet been put into a block. type Mempool interface { Add(tx *txs.Tx) error - Has(txID ids.ID) bool - Get(txID ids.ID) *txs.Tx + Get(txID ids.ID) (*txs.Tx, bool) Remove(txs []*txs.Tx) // Peek returns the oldest tx in the mempool. Peek() (tx *txs.Tx, exists bool) + // Iterate over transactions from oldest to newest until the function + // returns false or there are no more transactions. + Iterate(f func(tx *txs.Tx) bool) + // RequestBuildBlock notifies the consensus engine that a block should be // built if there is at least one transaction in the mempool. RequestBuildBlock() @@ -62,19 +65,16 @@ type Mempool interface { } type mempool struct { - bytesAvailableMetric prometheus.Gauge - bytesAvailable int - - unissuedTxs linkedhashmap.LinkedHashmap[ids.ID, *txs.Tx] - numTxs prometheus.Gauge + lock sync.RWMutex + unissuedTxs linkedhashmap.LinkedHashmap[ids.ID, *txs.Tx] + consumedUTXOs set.Set[ids.ID] + bytesAvailable int + droppedTxIDs *cache.LRU[ids.ID, error] // TxID -> Verification error toEngine chan<- common.Message - // Key: Tx ID - // Value: Verification error - droppedTxIDs *cache.LRU[ids.ID, error] - - consumedUTXOs set.Set[ids.ID] + numTxs prometheus.Gauge + bytesAvailableMetric prometheus.Gauge } func New( @@ -82,40 +82,38 @@ func New( registerer prometheus.Registerer, toEngine chan<- common.Message, ) (Mempool, error) { - bytesAvailableMetric := prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "bytes_available", - Help: "Number of bytes of space currently available in the mempool", - }) - if err := registerer.Register(bytesAvailableMetric); err != nil { - return nil, err + m := &mempool{ + unissuedTxs: linkedhashmap.New[ids.ID, *txs.Tx](), + bytesAvailable: maxMempoolSize, + droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, + toEngine: toEngine, + numTxs: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "count", + Help: "Number of transactions in the mempool", + }), + bytesAvailableMetric: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "bytes_available", + Help: "Number of bytes of space currently available in the mempool", + }), } + m.bytesAvailableMetric.Set(maxMempoolSize) - numTxsMetric := prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "count", - Help: "Number of transactions in the mempool", - }) - if err := registerer.Register(numTxsMetric); err != nil { - return nil, err - } - - bytesAvailableMetric.Set(maxMempoolSize) - return &mempool{ - bytesAvailableMetric: bytesAvailableMetric, - bytesAvailable: maxMempoolSize, - unissuedTxs: linkedhashmap.New[ids.ID, *txs.Tx](), - numTxs: numTxsMetric, - toEngine: toEngine, - droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, - consumedUTXOs: set.NewSet[ids.ID](initialConsumedUTXOsSize), - }, nil + err := utils.Err( + registerer.Register(m.numTxs), + registerer.Register(m.bytesAvailableMetric), + ) + return m, err } func (m *mempool) Add(tx *txs.Tx) error { - // Note: a previously dropped tx can be re-added txID := tx.ID() - if m.Has(txID) { + + m.lock.Lock() + defer m.lock.Unlock() + + if _, ok := m.unissuedTxs.Get(txID); ok { return fmt.Errorf("%w: %s", errDuplicateTx, txID) } @@ -151,21 +149,20 @@ func (m *mempool) Add(tx *txs.Tx) error { // Mark these UTXOs as consumed in the mempool m.consumedUTXOs.Union(inputs) - // An explicitly added tx must not be marked as dropped. + // An added tx must not be marked as dropped. m.droppedTxIDs.Evict(txID) return nil } -func (m *mempool) Has(txID ids.ID) bool { - return m.Get(txID) != nil -} - -func (m *mempool) Get(txID ids.ID) *txs.Tx { - tx, _ := m.unissuedTxs.Get(txID) - return tx +func (m *mempool) Get(txID ids.ID) (*txs.Tx, bool) { + tx, ok := m.unissuedTxs.Get(txID) + return tx, ok } func (m *mempool) Remove(txsToRemove []*txs.Tx) { + m.lock.Lock() + defer m.lock.Unlock() + for _, tx := range txsToRemove { txID := tx.ID() if !m.unissuedTxs.Delete(txID) { @@ -187,6 +184,18 @@ func (m *mempool) Peek() (*txs.Tx, bool) { return tx, exists } +func (m *mempool) Iterate(f func(*txs.Tx) bool) { + m.lock.RLock() + defer m.lock.RUnlock() + + it := m.unissuedTxs.NewIterator() + for it.Next() { + if !f(it.Value()) { + return + } + } +} + func (m *mempool) RequestBuildBlock() { if m.unissuedTxs.Len() == 0 { return @@ -199,6 +208,13 @@ func (m *mempool) RequestBuildBlock() { } func (m *mempool) MarkDropped(txID ids.ID, reason error) { + m.lock.RLock() + defer m.lock.RUnlock() + + if _, ok := m.unissuedTxs.Get(txID); ok { + return + } + m.droppedTxIDs.Put(txID, reason) } diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index 2e009fc44520..a4760ceba792 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -4,6 +4,7 @@ package mempool import ( + "errors" "testing" "github.com/prometheus/client_golang/prometheus" @@ -13,196 +14,266 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -var ( - keys = secp256k1.TestKeys() - chainID = ids.ID{5, 4, 3, 2, 1} - assetID = ids.ID{1, 2, 3} -) +func TestAdd(t *testing.T) { + tx0 := newTx(0, 32) + + tests := []struct { + name string + initialTxs []*txs.Tx + tx *txs.Tx + err error + }{ + { + name: "successfully add tx", + initialTxs: nil, + tx: tx0, + err: nil, + }, + { + name: "attempt adding duplicate tx", + initialTxs: []*txs.Tx{tx0}, + tx: tx0, + err: errDuplicateTx, + }, + { + name: "attempt adding too large tx", + initialTxs: nil, + tx: newTx(0, MaxTxSize+1), + err: errTxTooLarge, + }, + { + name: "attempt adding tx when full", + initialTxs: newTxs(maxMempoolSize/MaxTxSize, MaxTxSize), + tx: newTx(maxMempoolSize/MaxTxSize, MaxTxSize), + err: errMempoolFull, + }, + { + name: "attempt adding conflicting tx", + initialTxs: []*txs.Tx{tx0}, + tx: newTx(0, 32), + err: errConflictsWithOtherTx, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + mempool, err := New( + "mempool", + prometheus.NewRegistry(), + nil, + ) + require.NoError(err) + + for _, tx := range test.initialTxs { + require.NoError(mempool.Add(tx)) + } + + err = mempool.Add(test.tx) + require.ErrorIs(err, test.err) + }) + } +} -// shows that valid tx is not added to mempool if this would exceed its maximum -// size -func TestBlockBuilderMaxMempoolSizeHandling(t *testing.T) { +func TestGet(t *testing.T) { require := require.New(t) - registerer := prometheus.NewRegistry() - mempoolIntf, err := New("mempool", registerer, nil) + mempool, err := New( + "mempool", + prometheus.NewRegistry(), + nil, + ) require.NoError(err) - mempool := mempoolIntf.(*mempool) + tx := newTx(0, 32) + txID := tx.ID() - testTxs := createTestTxs(2) - tx := testTxs[0] + _, exists := mempool.Get(txID) + require.False(exists) - // shortcut to simulated almost filled mempool - mempool.bytesAvailable = len(tx.Bytes()) - 1 + require.NoError(mempool.Add(tx)) - err = mempool.Add(tx) - require.ErrorIs(err, errMempoolFull) + returned, exists := mempool.Get(txID) + require.True(exists) + require.Equal(tx, returned) - // shortcut to simulated almost filled mempool - mempool.bytesAvailable = len(tx.Bytes()) + mempool.Remove([]*txs.Tx{tx}) - require.NoError(mempool.Add(tx)) + _, exists = mempool.Get(txID) + require.False(exists) } -func TestTxsInMempool(t *testing.T) { +func TestPeek(t *testing.T) { require := require.New(t) - registerer := prometheus.NewRegistry() - toEngine := make(chan common.Message, 100) - mempool, err := New("mempool", registerer, toEngine) + mempool, err := New( + "mempool", + prometheus.NewRegistry(), + nil, + ) require.NoError(err) - testTxs := createTestTxs(2) + _, exists := mempool.Peek() + require.False(exists) - mempool.RequestBuildBlock() - select { - case <-toEngine: - require.FailNow("should not have sent message to engine") - default: - } + tx0 := newTx(0, 32) + tx1 := newTx(1, 32) + + require.NoError(mempool.Add(tx0)) + require.NoError(mempool.Add(tx1)) - for _, tx := range testTxs { - txID := tx.ID() - // tx not already there - require.False(mempool.Has(txID)) + tx, exists := mempool.Peek() + require.True(exists) + require.Equal(tx, tx0) - // we can insert - require.NoError(mempool.Add(tx)) + mempool.Remove([]*txs.Tx{tx0}) - // we can get it - require.True(mempool.Has(txID)) + tx, exists = mempool.Peek() + require.True(exists) + require.Equal(tx, tx1) - retrieved := mempool.Get(txID) - require.NotNil(retrieved) - require.Equal(tx, retrieved) + mempool.Remove([]*txs.Tx{tx0}) - // tx exists in mempool - require.True(mempool.Has(txID)) + tx, exists = mempool.Peek() + require.True(exists) + require.Equal(tx, tx1) - // once removed it cannot be there - mempool.Remove([]*txs.Tx{tx}) + mempool.Remove([]*txs.Tx{tx1}) - require.False(mempool.Has(txID)) - require.Nil(mempool.Get(txID)) + _, exists = mempool.Peek() + require.False(exists) +} - // we can reinsert it again to grow the mempool - require.NoError(mempool.Add(tx)) +func TestIterate(t *testing.T) { + require := require.New(t) + + mempool, err := New( + "mempool", + prometheus.NewRegistry(), + nil, + ) + require.NoError(err) + + var ( + iteratedTxs []*txs.Tx + maxLen = 2 + ) + addTxs := func(tx *txs.Tx) bool { + iteratedTxs = append(iteratedTxs, tx) + return len(iteratedTxs) < maxLen } + mempool.Iterate(addTxs) + require.Empty(iteratedTxs) + + tx0 := newTx(0, 32) + require.NoError(mempool.Add(tx0)) + + mempool.Iterate(addTxs) + require.Equal([]*txs.Tx{tx0}, iteratedTxs) + + tx1 := newTx(1, 32) + require.NoError(mempool.Add(tx1)) + + iteratedTxs = nil + mempool.Iterate(addTxs) + require.Equal([]*txs.Tx{tx0, tx1}, iteratedTxs) + + tx2 := newTx(2, 32) + require.NoError(mempool.Add(tx2)) + + iteratedTxs = nil + mempool.Iterate(addTxs) + require.Equal([]*txs.Tx{tx0, tx1}, iteratedTxs) + + mempool.Remove([]*txs.Tx{tx0, tx2}) + + iteratedTxs = nil + mempool.Iterate(addTxs) + require.Equal([]*txs.Tx{tx1}, iteratedTxs) +} + +func TestRequestBuildBlock(t *testing.T) { + require := require.New(t) + + toEngine := make(chan common.Message, 1) + mempool, err := New( + "mempool", + prometheus.NewRegistry(), + toEngine, + ) + require.NoError(err) mempool.RequestBuildBlock() select { case <-toEngine: + require.FailNow("should not have sent message to engine") default: - require.FailNow("should have sent message to engine") } - mempool.Remove(testTxs) + tx := newTx(0, 32) + require.NoError(mempool.Add(tx)) mempool.RequestBuildBlock() + mempool.RequestBuildBlock() // Must not deadlock select { case <-toEngine: - require.FailNow("should not have sent message to engine") default: + require.FailNow("should have sent message to engine") } -} - -func createTestTxs(count int) []*txs.Tx { - testTxs := make([]*txs.Tx, 0, count) - addr := keys[0].PublicKey().Address() - for i := uint32(0); i < uint32(count); i++ { - tx := &txs.Tx{Unsigned: &txs.CreateAssetTx{ - BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ - NetworkID: constants.UnitTestID, - BlockchainID: chainID, - Ins: []*avax.TransferableInput{{ - UTXOID: avax.UTXOID{ - TxID: ids.ID{'t', 'x', 'I', 'D'}, - OutputIndex: i, - }, - Asset: avax.Asset{ID: assetID}, - In: &secp256k1fx.TransferInput{ - Amt: 54321, - Input: secp256k1fx.Input{ - SigIndices: []uint32{i}, - }, - }, - }}, - Outs: []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: assetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: 12345, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{addr}, - }, - }, - }}, - }}, - Name: "NormalName", - Symbol: "TICK", - Denomination: byte(2), - States: []*txs.InitialState{ - { - FxIndex: 0, - Outs: []verify.State{ - &secp256k1fx.TransferOutput{ - Amt: 12345, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{addr}, - }, - }, - }, - }, - }, - }} - tx.SetBytes(utils.RandomBytes(16), utils.RandomBytes(16)) - testTxs = append(testTxs, tx) + select { + case <-toEngine: + require.FailNow("should have only sent one message to engine") + default: } - return testTxs } -func TestPeekTxs(t *testing.T) { +func TestDropped(t *testing.T) { require := require.New(t) - registerer := prometheus.NewRegistry() - toEngine := make(chan common.Message, 100) - mempool, err := New("mempool", registerer, toEngine) + mempool, err := New( + "mempool", + prometheus.NewRegistry(), + nil, + ) require.NoError(err) - testTxs := createTestTxs(2) - - tx, exists := mempool.Peek() - require.False(exists) - require.Nil(tx) + tx := newTx(0, 32) + txID := tx.ID() + testErr := errors.New("test") - require.NoError(mempool.Add(testTxs[0])) - require.NoError(mempool.Add(testTxs[1])) + mempool.MarkDropped(txID, testErr) - tx, exists = mempool.Peek() - require.True(exists) - require.Equal(tx, testTxs[0]) - require.NotEqual(tx, testTxs[1]) + err = mempool.GetDropReason(txID) + require.ErrorIs(err, testErr) - mempool.Remove([]*txs.Tx{testTxs[0]}) + require.NoError(mempool.Add(tx)) + require.NoError(mempool.GetDropReason(txID)) - tx, exists = mempool.Peek() - require.True(exists) - require.NotEqual(tx, testTxs[0]) - require.Equal(tx, testTxs[1]) + mempool.MarkDropped(txID, testErr) + require.NoError(mempool.GetDropReason(txID)) +} - mempool.Remove([]*txs.Tx{testTxs[1]}) +func newTxs(num int, size int) []*txs.Tx { + txs := make([]*txs.Tx, num) + for i := range txs { + txs[i] = newTx(uint32(i), size) + } + return txs +} - tx, exists = mempool.Peek() - require.False(exists) - require.Nil(tx) +func newTx(index uint32, size int) *txs.Tx { + tx := &txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ + Ins: []*avax.TransferableInput{{ + UTXOID: avax.UTXOID{ + TxID: ids.ID{'t', 'x', 'I', 'D'}, + OutputIndex: index, + }, + }}, + }}} + tx.SetBytes(utils.RandomBytes(size), utils.RandomBytes(size)) + return tx } diff --git a/vms/avm/txs/mempool/mock_mempool.go b/vms/avm/txs/mempool/mock_mempool.go index 8660976dde0d..9c85b8f4590a 100644 --- a/vms/avm/txs/mempool/mock_mempool.go +++ b/vms/avm/txs/mempool/mock_mempool.go @@ -53,11 +53,12 @@ func (mr *MockMempoolMockRecorder) Add(arg0 interface{}) *gomock.Call { } // Get mocks base method. -func (m *MockMempool) Get(arg0 ids.ID) *txs.Tx { +func (m *MockMempool) Get(arg0 ids.ID) (*txs.Tx, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", arg0) ret0, _ := ret[0].(*txs.Tx) - return ret0 + ret1, _ := ret[1].(bool) + return ret0, ret1 } // Get indicates an expected call of Get. @@ -80,18 +81,16 @@ func (mr *MockMempoolMockRecorder) GetDropReason(arg0 interface{}) *gomock.Call return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDropReason", reflect.TypeOf((*MockMempool)(nil).GetDropReason), arg0) } -// Has mocks base method. -func (m *MockMempool) Has(arg0 ids.ID) bool { +// Iterate mocks base method. +func (m *MockMempool) Iterate(arg0 func(*txs.Tx) bool) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Has", arg0) - ret0, _ := ret[0].(bool) - return ret0 + m.ctrl.Call(m, "Iterate", arg0) } -// Has indicates an expected call of Has. -func (mr *MockMempoolMockRecorder) Has(arg0 interface{}) *gomock.Call { +// Iterate indicates an expected call of Iterate. +func (mr *MockMempoolMockRecorder) Iterate(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMempool)(nil).Has), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockMempool)(nil).Iterate), arg0) } // MarkDropped mocks base method. From 5c02d0c77bb9e81596a7787b9c4f23f8fe4091e5 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 20 Dec 2023 11:32:13 -0500 Subject: [PATCH 174/267] Initialize transactions once (#2521) --- genesis/genesis.go | 2 +- vms/avm/block/parser.go | 22 ---------------------- vms/avm/block/standard_block.go | 13 ++++++++++++- vms/avm/environment_test.go | 2 +- vms/avm/network/network_test.go | 2 +- vms/avm/service_test.go | 2 +- vms/avm/state/state_test.go | 4 ++-- vms/avm/txs/base_tx_test.go | 2 +- vms/avm/txs/create_asset_tx_test.go | 4 ++-- vms/avm/txs/export_tx_test.go | 2 +- vms/avm/txs/import_tx_test.go | 2 +- vms/avm/txs/parser.go | 27 --------------------------- vms/avm/vm.go | 2 +- vms/avm/vm_regression_test.go | 2 +- vms/avm/vm_test.go | 6 +++--- 15 files changed, 28 insertions(+), 66 deletions(-) diff --git a/genesis/genesis.go b/genesis/genesis.go index 533795b56973..567f21f061be 100644 --- a/genesis/genesis.go +++ b/genesis/genesis.go @@ -571,7 +571,7 @@ func AVAXAssetID(avmGenesisBytes []byte) (ids.ID, error) { genesisTx := genesis.Txs[0] tx := xchaintxs.Tx{Unsigned: &genesisTx.CreateAssetTx} - if err := parser.InitializeGenesisTx(&tx); err != nil { + if err := tx.Initialize(genesisCodec); err != nil { return ids.Empty, err } return tx.ID(), nil diff --git a/vms/avm/block/parser.go b/vms/avm/block/parser.go index 230568149b6d..2394ea8dec0a 100644 --- a/vms/avm/block/parser.go +++ b/vms/avm/block/parser.go @@ -4,7 +4,6 @@ package block import ( - "fmt" "reflect" "github.com/ava-labs/avalanchego/codec" @@ -25,9 +24,6 @@ type Parser interface { ParseBlock(bytes []byte) (Block, error) ParseGenesisBlock(bytes []byte) (Block, error) - - InitializeBlock(block Block) error - InitializeGenesisBlock(block Block) error } type parser struct { @@ -88,21 +84,3 @@ func parse(cm codec.Manager, bytes []byte) (Block, error) { } return blk, blk.initialize(bytes, cm) } - -func (p *parser) InitializeBlock(block Block) error { - return initialize(block, p.Codec()) -} - -func (p *parser) InitializeGenesisBlock(block Block) error { - return initialize(block, p.GenesisCodec()) -} - -func initialize(blk Block, cm codec.Manager) error { - // We serialize this block as a pointer so that it can be deserialized into - // a Block - bytes, err := cm.Marshal(CodecVersion, &blk) - if err != nil { - return fmt.Errorf("couldn't marshal block: %w", err) - } - return blk.initialize(bytes, cm) -} diff --git a/vms/avm/block/standard_block.go b/vms/avm/block/standard_block.go index be6f1c7456cd..98c676c7ea52 100644 --- a/vms/avm/block/standard_block.go +++ b/vms/avm/block/standard_block.go @@ -88,5 +88,16 @@ func NewStandardBlock( Time: uint64(timestamp.Unix()), Transactions: txs, } - return blk, initialize(blk, cm) + + // We serialize this block as a pointer so that it can be deserialized into + // a Block + var blkIntf Block = blk + bytes, err := cm.Marshal(CodecVersion, &blkIntf) + if err != nil { + return nil, fmt.Errorf("couldn't marshal block: %w", err) + } + + blk.BlockID = hashing.ComputeHash256Array(bytes) + blk.bytes = bytes + return blk, nil } diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index 96a84b2659a7..a5b45b943ad9 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -289,7 +289,7 @@ func getCreateTxFromGenesisTest(tb testing.TB, genesisBytes []byte, assetName st tx := &txs.Tx{ Unsigned: &assetTx.CreateAssetTx, } - require.NoError(parser.InitializeGenesisTx(tx)) + require.NoError(tx.Initialize(parser.GenesisCodec())) return tx } diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index 0217430a2d22..b900232173f2 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -45,7 +45,7 @@ func TestNetworkAppGossip(t *testing.T) { &secp256k1fx.Fx{}, }) require.NoError(t, err) - require.NoError(t, parser.InitializeTx(testTx)) + require.NoError(t, testTx.Initialize(parser.Codec())) type test struct { name string diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 19cacb158d13..f2928ea2c0d9 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -918,7 +918,7 @@ func newAvaxExportTxWithOutputs(t *testing.T, genesisBytes []byte, vm *VM) *txs. func newAvaxCreateAssetTxWithOutputs(t *testing.T, vm *VM) *txs.Tx { key := keys[0] tx := buildCreateAssetTx(key) - require.NoError(t, vm.parser.InitializeTx(tx)) + require.NoError(t, tx.Initialize(vm.parser.Codec())) return tx } diff --git a/vms/avm/state/state_test.go b/vms/avm/state/state_test.go index c97836aee794..a9d468d436bb 100644 --- a/vms/avm/state/state_test.go +++ b/vms/avm/state/state_test.go @@ -61,7 +61,7 @@ func init() { populatedTx = &txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ BlockchainID: ids.GenerateTestID(), }}} - err = parser.InitializeTx(populatedTx) + err = populatedTx.Initialize(parser.Codec()) if err != nil { panic(err) } @@ -197,7 +197,7 @@ func ChainTxTest(t *testing.T, c Chain) { tx := &txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ BlockchainID: ids.GenerateTestID(), }}} - require.NoError(parser.InitializeTx(tx)) + require.NoError(tx.Initialize(parser.Codec())) txID := tx.ID() _, err = c.GetTx(txID) diff --git a/vms/avm/txs/base_tx_test.go b/vms/avm/txs/base_tx_test.go index 6ec386a7ab8a..ed1665c707fb 100644 --- a/vms/avm/txs/base_tx_test.go +++ b/vms/avm/txs/base_tx_test.go @@ -130,7 +130,7 @@ func TestBaseTxSerialization(t *testing.T) { }) require.NoError(err) - require.NoError(parser.InitializeTx(tx)) + require.NoError(tx.Initialize(parser.Codec())) require.Equal(tx.ID().String(), "zeqT8FTnRAxes7QQQYkaWhNkHavd9d6aCdH8TQu2Mx5KEydEz") result := tx.Bytes() diff --git a/vms/avm/txs/create_asset_tx_test.go b/vms/avm/txs/create_asset_tx_test.go index 08d0c46f4d54..dfcfb27c1bdd 100644 --- a/vms/avm/txs/create_asset_tx_test.go +++ b/vms/avm/txs/create_asset_tx_test.go @@ -198,7 +198,7 @@ func TestCreateAssetTxSerialization(t *testing.T) { }) require.NoError(err) - require.NoError(parser.InitializeTx(tx)) + require.NoError(tx.Initialize(parser.Codec())) result := tx.Bytes() require.Equal(expected, result) @@ -366,7 +366,7 @@ func TestCreateAssetTxSerializationAgain(t *testing.T) { &secp256k1fx.Fx{}, }) require.NoError(err) - require.NoError(parser.InitializeTx(tx)) + require.NoError(tx.Initialize(parser.Codec())) result := tx.Bytes() require.Equal(expected, result) diff --git a/vms/avm/txs/export_tx_test.go b/vms/avm/txs/export_tx_test.go index a7c1ed16196f..e384b8bfc327 100644 --- a/vms/avm/txs/export_tx_test.go +++ b/vms/avm/txs/export_tx_test.go @@ -113,7 +113,7 @@ func TestExportTxSerialization(t *testing.T) { }) require.NoError(err) - require.NoError(parser.InitializeTx(tx)) + require.NoError(tx.Initialize(parser.Codec())) require.Equal(tx.ID().String(), "2PKJE4TrKYpgynBFCpNPpV3GHK7d9QTgrL5mpYG6abHKDvNBG3") result := tx.Bytes() diff --git a/vms/avm/txs/import_tx_test.go b/vms/avm/txs/import_tx_test.go index 4172a4047792..6b94ea1c7e11 100644 --- a/vms/avm/txs/import_tx_test.go +++ b/vms/avm/txs/import_tx_test.go @@ -113,7 +113,7 @@ func TestImportTxSerialization(t *testing.T) { }) require.NoError(err) - require.NoError(parser.InitializeTx(tx)) + require.NoError(tx.Initialize(parser.Codec())) require.Equal(tx.ID().String(), "9wdPb5rsThXYLX4WxkNeyYrNMfDE5cuWLgifSjxKiA2dCmgCZ") result := tx.Bytes() diff --git a/vms/avm/txs/parser.go b/vms/avm/txs/parser.go index def42dfed501..55722c75b9cf 100644 --- a/vms/avm/txs/parser.go +++ b/vms/avm/txs/parser.go @@ -31,9 +31,6 @@ type Parser interface { ParseTx(bytes []byte) (*Tx, error) ParseGenesisTx(bytes []byte) (*Tx, error) - - InitializeTx(tx *Tx) error - InitializeGenesisTx(tx *Tx) error } type parser struct { @@ -130,14 +127,6 @@ func (p *parser) ParseGenesisTx(bytes []byte) (*Tx, error) { return parse(p.gcm, bytes) } -func (p *parser) InitializeTx(tx *Tx) error { - return initializeTx(p.cm, tx) -} - -func (p *parser) InitializeGenesisTx(tx *Tx) error { - return initializeTx(p.gcm, tx) -} - func parse(cm codec.Manager, signedBytes []byte) (*Tx, error) { tx := &Tx{} parsedVersion, err := cm.Unmarshal(signedBytes, tx) @@ -157,19 +146,3 @@ func parse(cm codec.Manager, signedBytes []byte) (*Tx, error) { tx.SetBytes(unsignedBytes, signedBytes) return tx, nil } - -func initializeTx(cm codec.Manager, tx *Tx) error { - signedBytes, err := cm.Marshal(CodecVersion, tx) - if err != nil { - return fmt.Errorf("problem creating transaction: %w", err) - } - - unsignedBytesLen, err := cm.Size(CodecVersion, &tx.Unsigned) - if err != nil { - return fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) - } - - unsignedBytes := signedBytes[:unsignedBytesLen] - tx.SetBytes(unsignedBytes, signedBytes) - return nil -} diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 36049befd07c..72951a5890bf 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -534,7 +534,7 @@ func (vm *VM) initGenesis(genesisBytes []byte) error { tx := &txs.Tx{ Unsigned: &genesisTx.CreateAssetTx, } - if err := vm.parser.InitializeGenesisTx(tx); err != nil { + if err := tx.Initialize(genesisCodec); err != nil { return err } diff --git a/vms/avm/vm_regression_test.go b/vms/avm/vm_regression_test.go index 6c1dd1be1798..69030b737830 100644 --- a/vms/avm/vm_regression_test.go +++ b/vms/avm/vm_regression_test.go @@ -66,7 +66,7 @@ func TestVerifyFxUsage(t *testing.T) { }, }, }} - require.NoError(env.vm.parser.InitializeTx(createAssetTx)) + require.NoError(createAssetTx.Initialize(env.vm.parser.Codec())) issueAndAccept(require, env.vm, env.issuer, createAssetTx) mintNFTTx := &txs.Tx{Unsigned: &txs.OperationTx{ diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index 3b4dc9558807..e59333f03072 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -167,7 +167,7 @@ func TestIssueNFT(t *testing.T) { }, }}, }} - require.NoError(env.vm.parser.InitializeTx(createAssetTx)) + require.NoError(createAssetTx.Initialize(env.vm.parser.Codec())) issueAndAccept(require, env.vm, env.issuer, createAssetTx) mintNFTTx := &txs.Tx{Unsigned: &txs.OperationTx{ @@ -222,7 +222,7 @@ func TestIssueNFT(t *testing.T) { }, }, } - require.NoError(env.vm.parser.InitializeTx(transferNFTTx)) + require.NoError(transferNFTTx.Initialize(env.vm.parser.Codec())) issueAndAccept(require, env.vm, env.issuer, transferNFTTx) } @@ -262,7 +262,7 @@ func TestIssueProperty(t *testing.T) { }, }}, }} - require.NoError(env.vm.parser.InitializeTx(createAssetTx)) + require.NoError(createAssetTx.Initialize(env.vm.parser.Codec())) issueAndAccept(require, env.vm, env.issuer, createAssetTx) mintPropertyTx := &txs.Tx{Unsigned: &txs.OperationTx{ From 5f7d460bb908cac6aad8c40e4a12ca1086698b8d Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 20 Dec 2023 16:52:42 -0500 Subject: [PATCH 175/267] `vms/avm`: Remove usage of `require.Contains` from service tests (#2517) --- vms/avm/service_test.go | 767 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 711 insertions(+), 56 deletions(-) diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index f2928ea2c0d9..0d71a6012ae4 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -6,6 +6,7 @@ package avm import ( "context" "fmt" + "strings" "testing" "time" @@ -557,10 +558,66 @@ func TestServiceGetTxJSON_BaseTx(t *testing.T) { }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - require.Contains(jsonString, `"memo":"0x0102030405060708"`) - require.Contains(jsonString, `"inputs":[{"txID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","outputIndex":2,"assetID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","input":{"amount":50000,"signatureIndices":[0]}}]`) - require.Contains(jsonString, `"outputs":[{"assetID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","output":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"amount":49000,"locktime":0,"threshold":1}}]`) + + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) + + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [ + { + "assetID": "2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ", + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "output": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "amount": 49000, + "locktime": 0, + "threshold": 1 + } + } + ], + "inputs": [ + { + "txID": "2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ", + "outputIndex": 2, + "assetID": "2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ", + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "input": { + "amount": 50000, + "signatureIndices": [ + 0 + ] + } + } + ], + "memo": "0x0102030405060708" + }, + "credentials": [ + { + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + } + ], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", newTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", newTx.Unsigned.(*txs.BaseTx).BlockchainID.String(), 1) + + sigStr, err := formatting.Encode(formatting.HexNC, newTx.Creds[0].Credential.(*secp256k1fx.Credential).Sigs[0][:]) + require.NoError(err) + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_SIGNATURE", sigStr, 1) + + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func TestServiceGetTxJSON_ExportTx(t *testing.T) { @@ -585,9 +642,67 @@ func TestServiceGetTxJSON_ExportTx(t *testing.T) { }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - require.Contains(jsonString, `"inputs":[{"txID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","outputIndex":2,"assetID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","input":{"amount":50000,"signatureIndices":[0]}}]`) - require.Contains(jsonString, `"exportedOutputs":[{"assetID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","output":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"amount":49000,"locktime":0,"threshold":1}}]}`) + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) + + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [], + "inputs": [ + { + "txID": "2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ", + "outputIndex": 2, + "assetID": "2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ", + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "input": { + "amount": 50000, + "signatureIndices": [ + 0 + ] + } + } + ], + "memo": "0x", + "destinationChain": "11111111111111111111111111111111LpoYY", + "exportedOutputs": [ + { + "assetID": "2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ", + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "output": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "amount": 49000, + "locktime": 0, + "threshold": 1 + } + } + ] + }, + "credentials": [ + { + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + } + ], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", newTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", newTx.Unsigned.(*txs.ExportTx).BlockchainID.String(), 1) + + sigStr, err := formatting.Encode(formatting.HexNC, newTx.Creds[0].Credential.(*secp256k1fx.Credential).Sigs[0][:]) + require.NoError(err) + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_SIGNATURE", sigStr, 1) + + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { @@ -618,11 +733,93 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - // contains the address in the right format - require.Contains(jsonString, `"outputs":[{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"groupID":1,"locktime":0,"threshold":1},{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"groupID":2,"locktime":0,"threshold":1}]}`) - require.Contains(jsonString, `"initialStates":[{"fxIndex":0,"fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","outputs":[{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"locktime":0,"threshold":1},{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"locktime":0,"threshold":1}]},{"fxIndex":1,"fxID":"qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT","outputs":[{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"groupID":1,"locktime":0,"threshold":1},{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"groupID":2,"locktime":0,"threshold":1}]},{"fxIndex":2,"fxID":"rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy","outputs":[{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"locktime":0,"threshold":1},{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"locktime":0,"threshold":1}]}]},"credentials":[],"id":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS"}`) + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) + + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [], + "inputs": [], + "memo": "0x", + "name": "Team Rocket", + "symbol": "TR", + "denomination": 0, + "initialStates": [ + { + "fxIndex": 0, + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "outputs": [ + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + }, + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + } + ] + }, + { + "fxIndex": 1, + "fxID": "qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT", + "outputs": [ + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "groupID": 1, + "locktime": 0, + "threshold": 1 + }, + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "groupID": 2, + "locktime": 0, + "threshold": 1 + } + ] + }, + { + "fxIndex": 2, + "fxID": "rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy", + "outputs": [ + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + }, + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + } + ] + } + ] + }, + "credentials": [], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", createAssetTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", createAssetTx.Unsigned.(*txs.CreateAssetTx).BlockchainID.String(), 1) + + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { @@ -658,15 +855,71 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - // assert memo and payload are in hex - require.Contains(jsonString, `"memo":"0x"`) - require.Contains(jsonString, `"payload":"0x68656c6c6f"`) - // contains the address in the right format - require.Contains(jsonString, `"outputs":[{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`) - // contains the fxID - require.Contains(jsonString, `"operations":[{"assetID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","inputIDs":[{"txID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","outputIndex":2}],"fxID":"qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT"`) - require.Contains(jsonString, `"credentials":[{"fxID":"qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT","credential":{"signatures":["0x571f18cfdb254263ab6b987f742409bd5403eafe08b4dbc297c5cd8d1c85eb8812e4541e11d3dc692cd14b5f4bccc1835ec001df6d8935ce881caf97017c2a4801"]}}]`) + + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) + + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [], + "inputs": [], + "memo": "0x", + "operations": [ + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 2 + } + ], + "fxID": "qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "groupID": 1, + "payload": "0x68656c6c6f", + "outputs": [ + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + } + ] + } + } + ] + }, + "credentials": [ + { + "fxID": "qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + } + ], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_CREATE_ASSET_TX_ID", createAssetTx.ID().String(), 2) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", mintNFTTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", mintNFTTx.Unsigned.(*txs.OperationTx).BlockchainID.String(), 1) + + sigStr, err := formatting.Encode(formatting.HexNC, mintNFTTx.Creds[0].Credential.(*nftfx.Credential).Sigs[0][:]) + require.NoError(err) + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_SIGNATURE", sigStr, 1) + + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { @@ -705,14 +958,107 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - // contains the address in the right format - require.Contains(jsonString, `"outputs":[{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`) + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) + + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [], + "inputs": [], + "memo": "0x", + "operations": [ + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 2 + } + ], + "fxID": "qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "groupID": 1, + "payload": "0x68656c6c6f", + "outputs": [ + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + } + ] + } + }, + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 3 + } + ], + "fxID": "qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "groupID": 2, + "payload": "0x68656c6c6f", + "outputs": [ + { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + } + ] + } + } + ] + }, + "credentials": [ + { + "fxID": "qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + }, + { + "fxID": "qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + } + ], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_CREATE_ASSET_TX_ID", createAssetTx.ID().String(), 4) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", mintNFTTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", mintNFTTx.Unsigned.(*txs.OperationTx).BlockchainID.String(), 1) + + sigStr, err := formatting.Encode(formatting.HexNC, mintNFTTx.Creds[0].Credential.(*nftfx.Credential).Sigs[0][:]) + require.NoError(err) + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_SIGNATURE", sigStr, 2) - // contains the fxID - require.Contains(jsonString, `"operations":[{"assetID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","inputIDs":[{"txID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","outputIndex":2}],"fxID":"qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT"`) - require.Contains(jsonString, `"credentials":[{"fxID":"qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT","credential":{"signatures":["0x2400cf2cf978697b3484d5340609b524eb9dfa401e5b2bd5d1bc6cee2a6b1ae41926550f00ae0651c312c35e225cb3f39b506d96c5170fb38a820dcfed11ccd801"]}},{"fxID":"qd2U4HDWUvMrVUeTcCHp6xH3Qpnn1XbU5MDdnBoiifFqvgXwT","credential":{"signatures":["0x2400cf2cf978697b3484d5340609b524eb9dfa401e5b2bd5d1bc6cee2a6b1ae41926550f00ae0651c312c35e225cb3f39b506d96c5170fb38a820dcfed11ccd801"]}}]`) + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { @@ -748,17 +1094,75 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - // ensure memo is in hex - require.Contains(jsonString, `"memo":"0x"`) - // contains the address in the right format - require.Contains(jsonString, `"mintOutput":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`) - require.Contains(jsonString, `"transferOutput":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"amount":1,"locktime":0,"threshold":1}}}]}`) + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) + + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [], + "inputs": [], + "memo": "0x", + "operations": [ + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 0 + } + ], + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "mintOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + }, + "transferOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "amount": 1, + "locktime": 0, + "threshold": 1 + } + } + } + ] + }, + "credentials": [ + { + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + } + ], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_CREATE_ASSET_TX_ID", createAssetTx.ID().String(), 2) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", mintSecpOpTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", mintSecpOpTx.Unsigned.(*txs.OperationTx).BlockchainID.String(), 1) + + sigStr, err := formatting.Encode(formatting.HexNC, mintSecpOpTx.Creds[0].Credential.(*secp256k1fx.Credential).Sigs[0][:]) + require.NoError(err) + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_SIGNATURE", sigStr, 1) - // contains the fxID - require.Contains(jsonString, `"operations":[{"assetID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","inputIDs":[{"txID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","outputIndex":0}],"fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ"`) - require.Contains(jsonString, `"credentials":[{"fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","credential":{"signatures":["0x6d7406d5e1bdb1d80de542e276e2d162b0497d0df1170bec72b14d40e84ecf7929cb571211d60149404413a9342fdfa0a2b5d07b48e6f3eaea1e2f9f183b480500"]}}]`) + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { @@ -797,15 +1201,115 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - // contains the address in the right format - require.Contains(jsonString, `"mintOutput":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`) - require.Contains(jsonString, `"transferOutput":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"amount":1,"locktime":0,"threshold":1}}}`) + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) + + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [], + "inputs": [], + "memo": "0x", + "operations": [ + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 0 + } + ], + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "mintOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + }, + "transferOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "amount": 1, + "locktime": 0, + "threshold": 1 + } + } + }, + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 1 + } + ], + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "mintOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + }, + "transferOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "amount": 1, + "locktime": 0, + "threshold": 1 + } + } + } + ] + }, + "credentials": [ + { + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + }, + { + "fxID": "spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + } + ], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_CREATE_ASSET_TX_ID", createAssetTx.ID().String(), 4) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", mintSecpOpTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", mintSecpOpTx.Unsigned.(*txs.OperationTx).BlockchainID.String(), 1) - // contains the fxID - require.Contains(jsonString, `"assetID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","inputIDs":[{"txID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","outputIndex":1}],"fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ"`) - require.Contains(jsonString, `"credentials":[{"fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","credential":{"signatures":["0xcc650f48341601c348d8634e8d207e07ea7b4ee4fbdeed3055fa1f1e4f4e27556d25056447a3bd5d949e5f1cbb0155bb20216ac3a4055356e3c82dca74323e7401"]}},{"fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","credential":{"signatures":["0xcc650f48341601c348d8634e8d207e07ea7b4ee4fbdeed3055fa1f1e4f4e27556d25056447a3bd5d949e5f1cbb0155bb20216ac3a4055356e3c82dca74323e7401"]}}]`) + sigStr, err := formatting.Encode(formatting.HexNC, mintSecpOpTx.Creds[0].Credential.(*secp256k1fx.Credential).Sigs[0][:]) + require.NoError(err) + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_SIGNATURE", sigStr, 2) + + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { @@ -841,16 +1345,72 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - // ensure memo is in hex - require.Contains(jsonString, `"memo":"0x"`) - // contains the address in the right format - require.Contains(jsonString, `"mintOutput":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`) + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) - // contains the fxID - require.Contains(jsonString, `"assetID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","inputIDs":[{"txID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","outputIndex":4}],"fxID":"rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy"`) - require.Contains(jsonString, `"credentials":[{"fxID":"rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy","credential":{"signatures":["0xa3a00a03d3f1551ff696d6c0abdde73ae7002cd6dcce1c37d720de3b7ed80757411c9698cd9681a0fa55ca685904ca87056a3b8abc858a8ac08f45483b32a80201"]}}]`) + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [], + "inputs": [], + "memo": "0x", + "operations": [ + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 4 + } + ], + "fxID": "rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "mintOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + }, + "ownedOutput": { + "addresses": [], + "locktime": 0, + "threshold": 0 + } + } + } + ] + }, + "credentials": [ + { + "fxID": "rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + } + ], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_CREATE_ASSET_TX_ID", createAssetTx.ID().String(), 2) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", mintPropertyFxOpTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", mintPropertyFxOpTx.Unsigned.(*txs.OperationTx).BlockchainID.String(), 1) + + sigStr, err := formatting.Encode(formatting.HexNC, mintPropertyFxOpTx.Creds[0].Credential.(*propertyfx.Credential).Sigs[0][:]) + require.NoError(err) + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_SIGNATURE", sigStr, 1) + + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) { @@ -889,14 +1449,109 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) }, &reply)) require.Equal(reply.Encoding, formatting.JSON) - jsonString := string(reply.Tx) - // contains the address in the right format - require.Contains(jsonString, `"mintOutput":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`) + replyTxBytes, err := stdjson.MarshalIndent(reply.Tx, "", "\t") + require.NoError(err) + + expectedReplyTxString := `{ + "unsignedTx": { + "networkID": 10, + "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", + "outputs": [], + "inputs": [], + "memo": "0x", + "operations": [ + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 4 + } + ], + "fxID": "rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "mintOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + }, + "ownedOutput": { + "addresses": [], + "locktime": 0, + "threshold": 0 + } + } + }, + { + "assetID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "inputIDs": [ + { + "txID": "PLACEHOLDER_CREATE_ASSET_TX_ID", + "outputIndex": 5 + } + ], + "fxID": "rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy", + "operation": { + "mintInput": { + "signatureIndices": [ + 0 + ] + }, + "mintOutput": { + "addresses": [ + "X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e" + ], + "locktime": 0, + "threshold": 1 + }, + "ownedOutput": { + "addresses": [], + "locktime": 0, + "threshold": 0 + } + } + } + ] + }, + "credentials": [ + { + "fxID": "rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + }, + { + "fxID": "rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy", + "credential": { + "signatures": [ + "PLACEHOLDER_SIGNATURE" + ] + } + } + ], + "id": "PLACEHOLDER_TX_ID" +}` + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_CREATE_ASSET_TX_ID", createAssetTx.ID().String(), 4) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_TX_ID", mintPropertyFxOpTx.ID().String(), 1) + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_BLOCKCHAIN_ID", mintPropertyFxOpTx.Unsigned.(*txs.OperationTx).BlockchainID.String(), 1) + + sigStr, err := formatting.Encode(formatting.HexNC, mintPropertyFxOpTx.Creds[0].Credential.(*propertyfx.Credential).Sigs[0][:]) + require.NoError(err) + + expectedReplyTxString = strings.Replace(expectedReplyTxString, "PLACEHOLDER_SIGNATURE", sigStr, 2) - // contains the fxID - require.Contains(jsonString, `"operations":[{"assetID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","inputIDs":[{"txID":"2MDgrsBHMRsEPa4D4NA1Bo1pjkVLUK173S3dd9BgT2nCJNiDuS","outputIndex":4}],"fxID":"rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy"`) - require.Contains(jsonString, `"credentials":[{"fxID":"rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy","credential":{"signatures":["0x25b7ca14df108d4a32877bda4f10d84eda6d653c620f4c8d124265bdcf0ac91f45712b58b33f4b62a19698325a3c89adff214b77f772d9f311742860039abb5601"]}},{"fxID":"rXJsCSEYXg2TehWxCEEGj6JU2PWKTkd6cBdNLjoe2SpsKD9cy","credential":{"signatures":["0x25b7ca14df108d4a32877bda4f10d84eda6d653c620f4c8d124265bdcf0ac91f45712b58b33f4b62a19698325a3c89adff214b77f772d9f311742860039abb5601"]}}]`) + require.Equal(expectedReplyTxString, string(replyTxBytes)) } func newAvaxBaseTxWithOutputs(t *testing.T, genesisBytes []byte, vm *VM) *txs.Tx { From fca1a16899aab100fc4f25167e1fabc74a6cb75a Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 20 Dec 2023 17:24:18 -0500 Subject: [PATCH 176/267] Move context lock into issueTx (#2524) --- vms/avm/environment_test.go | 4 +- vms/avm/service.go | 432 ++++++++++++++++++++---------------- vms/avm/service_test.go | 32 +-- vms/avm/vm.go | 39 ++-- vms/avm/wallet_service.go | 36 +-- 5 files changed, 298 insertions(+), 245 deletions(-) diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index a5b45b943ad9..5c0cf55b5ff2 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -524,7 +524,9 @@ func issueAndAccept( issuer <-chan common.Message, tx *txs.Tx, ) { - txID, err := vm.IssueTx(tx.Bytes()) + vm.ctx.Lock.Unlock() + txID, err := vm.issueTx(tx) + vm.ctx.Lock.Lock() require.NoError(err) require.Equal(tx.ID(), txID) diff --git a/vms/avm/service.go b/vms/avm/service.go index f0ce5aef5daa..7ccc26c278ed 100644 --- a/vms/avm/service.go +++ b/vms/avm/service.go @@ -206,16 +206,16 @@ func (s *Service) IssueTx(_ *http.Request, args *api.FormattedTx, reply *api.JSO return fmt.Errorf("problem decoding transaction: %w", err) } - s.vm.ctx.Lock.Lock() - defer s.vm.ctx.Lock.Unlock() - - txID, err := s.vm.IssueTx(txBytes) + tx, err := s.vm.parser.ParseTx(txBytes) if err != nil { + s.vm.ctx.Log.Debug("failed to parse tx", + zap.Error(err), + ) return err } - reply.TxID = txID - return nil + reply.TxID, err = s.vm.issueTx(tx) + return err } // GetTxStatusReply defines the GetTxStatus replies returned from the API @@ -710,14 +710,30 @@ func (s *Service) CreateAsset(_ *http.Request, args *CreateAssetArgs, reply *Ass zap.Int("numMinters", len(args.MinterSets)), ) + tx, changeAddr, err := s.buildCreateAssetTx(args) + if err != nil { + return err + } + + assetID, err := s.vm.issueTx(tx) + if err != nil { + return fmt.Errorf("problem issuing transaction: %w", err) + } + + reply.AssetID = assetID + reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) + return err +} + +func (s *Service) buildCreateAssetTx(args *CreateAssetArgs) (*txs.Tx, ids.ShortID, error) { if len(args.InitialHolders) == 0 && len(args.MinterSets) == 0 { - return errNoHoldersOrMinters + return nil, ids.ShortEmpty, errNoHoldersOrMinters } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.vm, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -726,16 +742,16 @@ func (s *Service) CreateAsset(_ *http.Request, args *CreateAssetArgs, reply *Ass // Get the UTXOs/keys for the from addresses utxos, kc, err := s.vm.LoadUser(args.Username, args.Password, fromAddrs) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the change address. if len(kc.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr, err := s.vm.selectChangeAddr(kc.Keys[0].PublicKey().Address(), args.ChangeAddr) if err != nil { - return err + return nil, ids.ShortEmpty, err } amountsSpent, ins, keys, err := s.vm.Spend( @@ -746,7 +762,7 @@ func (s *Service) CreateAsset(_ *http.Request, args *CreateAssetArgs, reply *Ass }, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } outs := []*avax.TransferableOutput{} @@ -771,7 +787,7 @@ func (s *Service) CreateAsset(_ *http.Request, args *CreateAssetArgs, reply *Ass for _, holder := range args.InitialHolders { addr, err := avax.ParseServiceAddress(s.vm, holder.Address) if err != nil { - return err + return nil, ids.ShortEmpty, err } initialState.Outs = append(initialState.Outs, &secp256k1fx.TransferOutput{ Amt: uint64(holder.Amount), @@ -790,15 +806,17 @@ func (s *Service) CreateAsset(_ *http.Request, args *CreateAssetArgs, reply *Ass } minterAddrsSet, err := avax.ParseServiceAddresses(s.vm, owner.Minters) if err != nil { - return err + return nil, ids.ShortEmpty, err } minter.Addrs = minterAddrsSet.List() utils.Sort(minter.Addrs) initialState.Outs = append(initialState.Outs, minter) } - initialState.Sort(s.vm.parser.Codec()) - tx := txs.Tx{Unsigned: &txs.CreateAssetTx{ + codec := s.vm.parser.Codec() + initialState.Sort(codec) + + tx := &txs.Tx{Unsigned: &txs.CreateAssetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: s.vm.ctx.NetworkID, BlockchainID: s.vm.ctx.ChainID, @@ -810,18 +828,7 @@ func (s *Service) CreateAsset(_ *http.Request, args *CreateAssetArgs, reply *Ass Denomination: args.Denomination, States: []*txs.InitialState{initialState}, }} - if err := tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys); err != nil { - return err - } - - assetID, err := s.vm.IssueTx(tx.Bytes()) - if err != nil { - return fmt.Errorf("problem issuing transaction: %w", err) - } - - reply.AssetID = assetID - reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) - return err + return tx, changeAddr, tx.SignSECP256K1Fx(codec, keys) } // CreateFixedCapAsset returns ID of the newly created asset @@ -868,14 +875,30 @@ func (s *Service) CreateNFTAsset(_ *http.Request, args *CreateNFTAssetArgs, repl zap.Int("numMinters", len(args.MinterSets)), ) + tx, changeAddr, err := s.buildCreateNFTAsset(args) + if err != nil { + return err + } + + assetID, err := s.vm.issueTx(tx) + if err != nil { + return fmt.Errorf("problem issuing transaction: %w", err) + } + + reply.AssetID = assetID + reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) + return err +} + +func (s *Service) buildCreateNFTAsset(args *CreateNFTAssetArgs) (*txs.Tx, ids.ShortID, error) { if len(args.MinterSets) == 0 { - return errNoMinters + return nil, ids.ShortEmpty, errNoMinters } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.vm, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -884,16 +907,16 @@ func (s *Service) CreateNFTAsset(_ *http.Request, args *CreateNFTAssetArgs, repl // Get the UTXOs/keys for the from addresses utxos, kc, err := s.vm.LoadUser(args.Username, args.Password, fromAddrs) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the change address. if len(kc.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr, err := s.vm.selectChangeAddr(kc.Keys[0].PublicKey().Address(), args.ChangeAddr) if err != nil { - return err + return nil, ids.ShortEmpty, err } amountsSpent, ins, keys, err := s.vm.Spend( @@ -904,7 +927,7 @@ func (s *Service) CreateNFTAsset(_ *http.Request, args *CreateNFTAssetArgs, repl }, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } outs := []*avax.TransferableOutput{} @@ -935,15 +958,17 @@ func (s *Service) CreateNFTAsset(_ *http.Request, args *CreateNFTAssetArgs, repl } minterAddrsSet, err := avax.ParseServiceAddresses(s.vm, owner.Minters) if err != nil { - return err + return nil, ids.ShortEmpty, err } minter.Addrs = minterAddrsSet.List() utils.Sort(minter.Addrs) initialState.Outs = append(initialState.Outs, minter) } - initialState.Sort(s.vm.parser.Codec()) - tx := txs.Tx{Unsigned: &txs.CreateAssetTx{ + codec := s.vm.parser.Codec() + initialState.Sort(codec) + + tx := &txs.Tx{Unsigned: &txs.CreateAssetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: s.vm.ctx.NetworkID, BlockchainID: s.vm.ctx.ChainID, @@ -955,18 +980,7 @@ func (s *Service) CreateNFTAsset(_ *http.Request, args *CreateNFTAssetArgs, repl Denomination: 0, // NFTs are non-fungible States: []*txs.InitialState{initialState}, }} - if err := tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys); err != nil { - return err - } - - assetID, err := s.vm.IssueTx(tx.Bytes()) - if err != nil { - return fmt.Errorf("problem issuing transaction: %w", err) - } - - reply.AssetID = assetID - reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) - return err + return tx, changeAddr, tx.SignSECP256K1Fx(codec, keys) } // CreateAddress creates an address for the user [args.Username] @@ -1181,18 +1195,34 @@ func (s *Service) SendMultiple(_ *http.Request, args *SendMultipleArgs, reply *a logging.UserString("username", args.Username), ) + tx, changeAddr, err := s.buildSendMultiple(args) + if err != nil { + return err + } + + txID, err := s.vm.issueTx(tx) + if err != nil { + return fmt.Errorf("problem issuing transaction: %w", err) + } + + reply.TxID = txID + reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) + return err +} + +func (s *Service) buildSendMultiple(args *SendMultipleArgs) (*txs.Tx, ids.ShortID, error) { // Validate the memo field memoBytes := []byte(args.Memo) if l := len(memoBytes); l > avax.MaxMemoSize { - return fmt.Errorf("max memo length is %d but provided memo field is length %d", avax.MaxMemoSize, l) + return nil, ids.ShortEmpty, fmt.Errorf("max memo length is %d but provided memo field is length %d", avax.MaxMemoSize, l) } else if len(args.Outputs) == 0 { - return errNoOutputs + return nil, ids.ShortEmpty, errNoOutputs } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.vm, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1201,16 +1231,16 @@ func (s *Service) SendMultiple(_ *http.Request, args *SendMultipleArgs, reply *a // Load user's UTXOs/keys utxos, kc, err := s.vm.LoadUser(args.Username, args.Password, fromAddrs) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the change address. if len(kc.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr, err := s.vm.selectChangeAddr(kc.Keys[0].PublicKey().Address(), args.ChangeAddr) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Calculate required input amounts and create the desired outputs @@ -1222,27 +1252,27 @@ func (s *Service) SendMultiple(_ *http.Request, args *SendMultipleArgs, reply *a outs := []*avax.TransferableOutput{} for _, output := range args.Outputs { if output.Amount == 0 { - return errZeroAmount + return nil, ids.ShortEmpty, errZeroAmount } assetID, ok := assetIDs[output.AssetID] // Asset ID of next output if !ok { assetID, err = s.vm.lookupAssetID(output.AssetID) if err != nil { - return fmt.Errorf("couldn't find asset %s", output.AssetID) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't find asset %s", output.AssetID) } assetIDs[output.AssetID] = assetID } currentAmount := amounts[assetID] newAmount, err := safemath.Add64(currentAmount, uint64(output.Amount)) if err != nil { - return fmt.Errorf("problem calculating required spend amount: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("problem calculating required spend amount: %w", err) } amounts[assetID] = newAmount // Parse the to address to, err := avax.ParseServiceAddress(s.vm, output.To) if err != nil { - return fmt.Errorf("problem parsing to address %q: %w", output.To, err) + return nil, ids.ShortEmpty, fmt.Errorf("problem parsing to address %q: %w", output.To, err) } // Create the Output @@ -1266,7 +1296,7 @@ func (s *Service) SendMultiple(_ *http.Request, args *SendMultipleArgs, reply *a amountWithFee, err := safemath.Add64(amounts[s.vm.feeAssetID], s.vm.TxFee) if err != nil { - return fmt.Errorf("problem calculating required spend amount: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("problem calculating required spend amount: %w", err) } amountsWithFee[s.vm.feeAssetID] = amountWithFee @@ -1276,7 +1306,7 @@ func (s *Service) SendMultiple(_ *http.Request, args *SendMultipleArgs, reply *a amountsWithFee, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Add the required change outputs @@ -1297,27 +1327,18 @@ func (s *Service) SendMultiple(_ *http.Request, args *SendMultipleArgs, reply *a }) } } - avax.SortTransferableOutputs(outs, s.vm.parser.Codec()) - tx := txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ + codec := s.vm.parser.Codec() + avax.SortTransferableOutputs(outs, codec) + + tx := &txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: s.vm.ctx.NetworkID, BlockchainID: s.vm.ctx.ChainID, Outs: outs, Ins: ins, Memo: memoBytes, }}} - if err := tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys); err != nil { - return err - } - - txID, err := s.vm.IssueTx(tx.Bytes()) - if err != nil { - return fmt.Errorf("problem issuing transaction: %w", err) - } - - reply.TxID = txID - reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) - return err + return tx, changeAddr, tx.SignSECP256K1Fx(codec, keys) } // MintArgs are arguments for passing into Mint requests @@ -1336,24 +1357,46 @@ func (s *Service) Mint(_ *http.Request, args *MintArgs, reply *api.JSONTxIDChang logging.UserString("username", args.Username), ) + tx, changeAddr, err := s.buildMint(args) + if err != nil { + return err + } + + txID, err := s.vm.issueTx(tx) + if err != nil { + return fmt.Errorf("problem issuing transaction: %w", err) + } + + reply.TxID = txID + reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) + return err +} + +func (s *Service) buildMint(args *MintArgs) (*txs.Tx, ids.ShortID, error) { + s.vm.ctx.Log.Warn("deprecated API called", + zap.String("service", "avm"), + zap.String("method", "mint"), + logging.UserString("username", args.Username), + ) + if args.Amount == 0 { - return errInvalidMintAmount + return nil, ids.ShortEmpty, errInvalidMintAmount } assetID, err := s.vm.lookupAssetID(args.AssetID) if err != nil { - return err + return nil, ids.ShortEmpty, err } to, err := avax.ParseServiceAddress(s.vm, args.To) if err != nil { - return fmt.Errorf("problem parsing to address %q: %w", args.To, err) + return nil, ids.ShortEmpty, fmt.Errorf("problem parsing to address %q: %w", args.To, err) } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.vm, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1362,16 +1405,16 @@ func (s *Service) Mint(_ *http.Request, args *MintArgs, reply *api.JSONTxIDChang // Get the UTXOs/keys for the from addresses feeUTXOs, feeKc, err := s.vm.LoadUser(args.Username, args.Password, fromAddrs) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the change address. if len(feeKc.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr, err := s.vm.selectChangeAddr(feeKc.Keys[0].PublicKey().Address(), args.ChangeAddr) if err != nil { - return err + return nil, ids.ShortEmpty, err } amountsSpent, ins, keys, err := s.vm.Spend( @@ -1382,7 +1425,7 @@ func (s *Service) Mint(_ *http.Request, args *MintArgs, reply *api.JSONTxIDChang }, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } outs := []*avax.TransferableOutput{} @@ -1403,7 +1446,7 @@ func (s *Service) Mint(_ *http.Request, args *MintArgs, reply *api.JSONTxIDChang // Get all UTXOs/keys for the user utxos, kc, err := s.vm.LoadUser(args.Username, args.Password, nil) if err != nil { - return err + return nil, ids.ShortEmpty, err } ops, opKeys, err := s.vm.Mint( @@ -1415,11 +1458,11 @@ func (s *Service) Mint(_ *http.Request, args *MintArgs, reply *api.JSONTxIDChang to, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } keys = append(keys, opKeys...) - tx := txs.Tx{Unsigned: &txs.OperationTx{ + tx := &txs.Tx{Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: s.vm.ctx.NetworkID, BlockchainID: s.vm.ctx.ChainID, @@ -1428,18 +1471,7 @@ func (s *Service) Mint(_ *http.Request, args *MintArgs, reply *api.JSONTxIDChang }}, Ops: ops, }} - if err := tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys); err != nil { - return err - } - - txID, err := s.vm.IssueTx(tx.Bytes()) - if err != nil { - return fmt.Errorf("problem issuing transaction: %w", err) - } - - reply.TxID = txID - reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) - return err + return tx, changeAddr, tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys) } // SendNFTArgs are arguments for passing into SendNFT requests @@ -1458,22 +1490,38 @@ func (s *Service) SendNFT(_ *http.Request, args *SendNFTArgs, reply *api.JSONTxI logging.UserString("username", args.Username), ) + tx, changeAddr, err := s.buildSendNFT(args) + if err != nil { + return err + } + + txID, err := s.vm.issueTx(tx) + if err != nil { + return fmt.Errorf("problem issuing transaction: %w", err) + } + + reply.TxID = txID + reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) + return err +} + +func (s *Service) buildSendNFT(args *SendNFTArgs) (*txs.Tx, ids.ShortID, error) { // Parse the asset ID assetID, err := s.vm.lookupAssetID(args.AssetID) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the to address to, err := avax.ParseServiceAddress(s.vm, args.To) if err != nil { - return fmt.Errorf("problem parsing to address %q: %w", args.To, err) + return nil, ids.ShortEmpty, fmt.Errorf("problem parsing to address %q: %w", args.To, err) } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.vm, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1482,16 +1530,16 @@ func (s *Service) SendNFT(_ *http.Request, args *SendNFTArgs, reply *api.JSONTxI // Get the UTXOs/keys for the from addresses utxos, kc, err := s.vm.LoadUser(args.Username, args.Password, fromAddrs) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the change address. if len(kc.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr, err := s.vm.selectChangeAddr(kc.Keys[0].PublicKey().Address(), args.ChangeAddr) if err != nil { - return err + return nil, ids.ShortEmpty, err } amountsSpent, ins, secpKeys, err := s.vm.Spend( @@ -1502,7 +1550,7 @@ func (s *Service) SendNFT(_ *http.Request, args *SendNFTArgs, reply *api.JSONTxI }, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } outs := []*avax.TransferableOutput{} @@ -1528,10 +1576,10 @@ func (s *Service) SendNFT(_ *http.Request, args *SendNFTArgs, reply *api.JSONTxI to, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } - tx := txs.Tx{Unsigned: &txs.OperationTx{ + tx := &txs.Tx{Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: s.vm.ctx.NetworkID, BlockchainID: s.vm.ctx.ChainID, @@ -1540,21 +1588,12 @@ func (s *Service) SendNFT(_ *http.Request, args *SendNFTArgs, reply *api.JSONTxI }}, Ops: ops, }} - if err := tx.SignSECP256K1Fx(s.vm.parser.Codec(), secpKeys); err != nil { - return err - } - if err := tx.SignNFTFx(s.vm.parser.Codec(), nftKeys); err != nil { - return err - } - txID, err := s.vm.IssueTx(tx.Bytes()) - if err != nil { - return fmt.Errorf("problem issuing transaction: %w", err) + codec := s.vm.parser.Codec() + if err := tx.SignSECP256K1Fx(codec, secpKeys); err != nil { + return nil, ids.ShortEmpty, err } - - reply.TxID = txID - reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) - return err + return tx, changeAddr, tx.SignNFTFx(codec, nftKeys) } // MintNFTArgs are arguments for passing into MintNFT requests @@ -1574,25 +1613,41 @@ func (s *Service) MintNFT(_ *http.Request, args *MintNFTArgs, reply *api.JSONTxI logging.UserString("username", args.Username), ) - assetID, err := s.vm.lookupAssetID(args.AssetID) + tx, changeAddr, err := s.buildMintNFT(args) if err != nil { return err } + txID, err := s.vm.issueTx(tx) + if err != nil { + return fmt.Errorf("problem issuing transaction: %w", err) + } + + reply.TxID = txID + reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) + return err +} + +func (s *Service) buildMintNFT(args *MintNFTArgs) (*txs.Tx, ids.ShortID, error) { + assetID, err := s.vm.lookupAssetID(args.AssetID) + if err != nil { + return nil, ids.ShortEmpty, err + } + to, err := avax.ParseServiceAddress(s.vm, args.To) if err != nil { - return fmt.Errorf("problem parsing to address %q: %w", args.To, err) + return nil, ids.ShortEmpty, fmt.Errorf("problem parsing to address %q: %w", args.To, err) } payloadBytes, err := formatting.Decode(args.Encoding, args.Payload) if err != nil { - return fmt.Errorf("problem decoding payload bytes: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("problem decoding payload bytes: %w", err) } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.vm, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1601,16 +1656,16 @@ func (s *Service) MintNFT(_ *http.Request, args *MintNFTArgs, reply *api.JSONTxI // Get the UTXOs/keys for the from addresses feeUTXOs, feeKc, err := s.vm.LoadUser(args.Username, args.Password, fromAddrs) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the change address. if len(feeKc.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr, err := s.vm.selectChangeAddr(feeKc.Keys[0].PublicKey().Address(), args.ChangeAddr) if err != nil { - return err + return nil, ids.ShortEmpty, err } amountsSpent, ins, secpKeys, err := s.vm.Spend( @@ -1621,7 +1676,7 @@ func (s *Service) MintNFT(_ *http.Request, args *MintNFTArgs, reply *api.JSONTxI }, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } outs := []*avax.TransferableOutput{} @@ -1642,7 +1697,7 @@ func (s *Service) MintNFT(_ *http.Request, args *MintNFTArgs, reply *api.JSONTxI // Get all UTXOs/keys utxos, kc, err := s.vm.LoadUser(args.Username, args.Password, nil) if err != nil { - return err + return nil, ids.ShortEmpty, err } ops, nftKeys, err := s.vm.MintNFT( @@ -1653,10 +1708,10 @@ func (s *Service) MintNFT(_ *http.Request, args *MintNFTArgs, reply *api.JSONTxI to, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } - tx := txs.Tx{Unsigned: &txs.OperationTx{ + tx := &txs.Tx{Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: s.vm.ctx.NetworkID, BlockchainID: s.vm.ctx.ChainID, @@ -1665,21 +1720,12 @@ func (s *Service) MintNFT(_ *http.Request, args *MintNFTArgs, reply *api.JSONTxI }}, Ops: ops, }} - if err := tx.SignSECP256K1Fx(s.vm.parser.Codec(), secpKeys); err != nil { - return err - } - if err := tx.SignNFTFx(s.vm.parser.Codec(), nftKeys); err != nil { - return err - } - txID, err := s.vm.IssueTx(tx.Bytes()) - if err != nil { - return fmt.Errorf("problem issuing transaction: %w", err) + codec := s.vm.parser.Codec() + if err := tx.SignSECP256K1Fx(codec, secpKeys); err != nil { + return nil, ids.ShortEmpty, err } - - reply.TxID = txID - reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) - return err + return tx, changeAddr, tx.SignNFTFx(codec, nftKeys) } // ImportArgs are arguments for passing into Import requests @@ -1704,14 +1750,29 @@ func (s *Service) Import(_ *http.Request, args *ImportArgs, reply *api.JSONTxID) logging.UserString("username", args.Username), ) + tx, err := s.buildImport(args) + if err != nil { + return err + } + + txID, err := s.vm.issueTx(tx) + if err != nil { + return fmt.Errorf("problem issuing transaction: %w", err) + } + + reply.TxID = txID + return nil +} + +func (s *Service) buildImport(args *ImportArgs) (*txs.Tx, error) { chainID, err := s.vm.ctx.BCLookup.Lookup(args.SourceChain) if err != nil { - return fmt.Errorf("problem parsing chainID %q: %w", args.SourceChain, err) + return nil, fmt.Errorf("problem parsing chainID %q: %w", args.SourceChain, err) } to, err := avax.ParseServiceAddress(s.vm, args.To) if err != nil { - return fmt.Errorf("problem parsing to address %q: %w", args.To, err) + return nil, fmt.Errorf("problem parsing to address %q: %w", args.To, err) } s.vm.ctx.Lock.Lock() @@ -1719,17 +1780,17 @@ func (s *Service) Import(_ *http.Request, args *ImportArgs, reply *api.JSONTxID) utxos, kc, err := s.vm.LoadUser(args.Username, args.Password, nil) if err != nil { - return err + return nil, err } atomicUTXOs, _, _, err := s.vm.GetAtomicUTXOs(chainID, kc.Addrs, ids.ShortEmpty, ids.Empty, int(maxPageSize)) if err != nil { - return fmt.Errorf("problem retrieving user's atomic UTXOs: %w", err) + return nil, fmt.Errorf("problem retrieving user's atomic UTXOs: %w", err) } amountsSpent, importInputs, importKeys, err := s.vm.SpendAll(atomicUTXOs, kc) if err != nil { - return err + return nil, err } ins := []*avax.TransferableInput{} @@ -1745,12 +1806,12 @@ func (s *Service) Import(_ *http.Request, args *ImportArgs, reply *api.JSONTxID) }, ) if err != nil { - return err + return nil, err } for asset, amount := range localAmountsSpent { newAmount, err := safemath.Add64(amountsSpent[asset], amount) if err != nil { - return fmt.Errorf("problem calculating required spend amount: %w", err) + return nil, fmt.Errorf("problem calculating required spend amount: %w", err) } amountsSpent[asset] = newAmount } @@ -1780,7 +1841,7 @@ func (s *Service) Import(_ *http.Request, args *ImportArgs, reply *api.JSONTxID) } avax.SortTransferableOutputs(outs, s.vm.parser.Codec()) - tx := txs.Tx{Unsigned: &txs.ImportTx{ + tx := &txs.Tx{Unsigned: &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: s.vm.ctx.NetworkID, BlockchainID: s.vm.ctx.ChainID, @@ -1790,17 +1851,7 @@ func (s *Service) Import(_ *http.Request, args *ImportArgs, reply *api.JSONTxID) SourceChain: chainID, ImportedIns: importInputs, }} - if err := tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys); err != nil { - return err - } - - txID, err := s.vm.IssueTx(tx.Bytes()) - if err != nil { - return fmt.Errorf("problem issuing transaction: %w", err) - } - - reply.TxID = txID - return nil + return tx, tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys) } // ExportArgs are arguments for passing into ExportAVA requests @@ -1830,10 +1881,26 @@ func (s *Service) Export(_ *http.Request, args *ExportArgs, reply *api.JSONTxIDC logging.UserString("username", args.Username), ) + tx, changeAddr, err := s.buildExport(args) + if err != nil { + return err + } + + txID, err := s.vm.issueTx(tx) + if err != nil { + return fmt.Errorf("problem issuing transaction: %w", err) + } + + reply.TxID = txID + reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) + return err +} + +func (s *Service) buildExport(args *ExportArgs) (*txs.Tx, ids.ShortID, error) { // Parse the asset ID assetID, err := s.vm.lookupAssetID(args.AssetID) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Get the chainID and parse the to address @@ -1841,22 +1908,22 @@ func (s *Service) Export(_ *http.Request, args *ExportArgs, reply *api.JSONTxIDC if err != nil { chainID, err = s.vm.ctx.BCLookup.Lookup(args.TargetChain) if err != nil { - return err + return nil, ids.ShortEmpty, err } to, err = ids.ShortFromString(args.To) if err != nil { - return err + return nil, ids.ShortEmpty, err } } if args.Amount == 0 { - return errZeroAmount + return nil, ids.ShortEmpty, errZeroAmount } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.vm, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1865,23 +1932,23 @@ func (s *Service) Export(_ *http.Request, args *ExportArgs, reply *api.JSONTxIDC // Get the UTXOs/keys for the from addresses utxos, kc, err := s.vm.LoadUser(args.Username, args.Password, fromAddrs) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the change address. if len(kc.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr, err := s.vm.selectChangeAddr(kc.Keys[0].PublicKey().Address(), args.ChangeAddr) if err != nil { - return err + return nil, ids.ShortEmpty, err } amounts := map[ids.ID]uint64{} if assetID == s.vm.feeAssetID { amountWithFee, err := safemath.Add64(uint64(args.Amount), s.vm.TxFee) if err != nil { - return fmt.Errorf("problem calculating required spend amount: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("problem calculating required spend amount: %w", err) } amounts[s.vm.feeAssetID] = amountWithFee } else { @@ -1891,7 +1958,7 @@ func (s *Service) Export(_ *http.Request, args *ExportArgs, reply *api.JSONTxIDC amountsSpent, ins, keys, err := s.vm.Spend(utxos, kc, amounts) if err != nil { - return err + return nil, ids.ShortEmpty, err } exportOuts := []*avax.TransferableOutput{{ @@ -1923,9 +1990,11 @@ func (s *Service) Export(_ *http.Request, args *ExportArgs, reply *api.JSONTxIDC }) } } - avax.SortTransferableOutputs(outs, s.vm.parser.Codec()) - tx := txs.Tx{Unsigned: &txs.ExportTx{ + codec := s.vm.parser.Codec() + avax.SortTransferableOutputs(outs, codec) + + tx := &txs.Tx{Unsigned: &txs.ExportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: s.vm.ctx.NetworkID, BlockchainID: s.vm.ctx.ChainID, @@ -1935,16 +2004,5 @@ func (s *Service) Export(_ *http.Request, args *ExportArgs, reply *api.JSONTxIDC DestinationChain: chainID, ExportedOuts: exportOuts, }} - if err := tx.SignSECP256K1Fx(s.vm.parser.Codec(), keys); err != nil { - return err - } - - txID, err := s.vm.IssueTx(tx.Bytes()) - if err != nil { - return fmt.Errorf("problem issuing transaction: %w", err) - } - - reply.TxID = txID - reply.ChangeAddr, err = s.vm.FormatLocalAddress(changeAddr) - return err + return tx, changeAddr, tx.SignSECP256K1Fx(codec, keys) } diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 0d71a6012ae4..7703b81e807a 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -649,7 +649,7 @@ func TestServiceGetTxJSON_ExportTx(t *testing.T) { "unsignedTx": { "networkID": 10, "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", - "outputs": [], + "outputs": null, "inputs": [ { "txID": "2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ", @@ -741,8 +741,8 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { "unsignedTx": { "networkID": 10, "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", - "outputs": [], - "inputs": [], + "outputs": null, + "inputs": null, "memo": "0x", "name": "Team Rocket", "symbol": "TR", @@ -812,7 +812,7 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { } ] }, - "credentials": [], + "credentials": null, "id": "PLACEHOLDER_TX_ID" }` @@ -863,8 +863,8 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { "unsignedTx": { "networkID": 10, "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", - "outputs": [], - "inputs": [], + "outputs": null, + "inputs": null, "memo": "0x", "operations": [ { @@ -966,8 +966,8 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { "unsignedTx": { "networkID": 10, "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", - "outputs": [], - "inputs": [], + "outputs": null, + "inputs": null, "memo": "0x", "operations": [ { @@ -1102,8 +1102,8 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { "unsignedTx": { "networkID": 10, "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", - "outputs": [], - "inputs": [], + "outputs": null, + "inputs": null, "memo": "0x", "operations": [ { @@ -1209,8 +1209,8 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { "unsignedTx": { "networkID": 10, "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", - "outputs": [], - "inputs": [], + "outputs": null, + "inputs": null, "memo": "0x", "operations": [ { @@ -1353,8 +1353,8 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { "unsignedTx": { "networkID": 10, "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", - "outputs": [], - "inputs": [], + "outputs": null, + "inputs": null, "memo": "0x", "operations": [ { @@ -1457,8 +1457,8 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) "unsignedTx": { "networkID": 10, "blockchainID": "PLACEHOLDER_BLOCKCHAIN_ID", - "outputs": [], - "inputs": [], + "outputs": null, + "inputs": null, "memo": "0x", "operations": [ { diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 72951a5890bf..951d6caac19e 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -59,7 +59,6 @@ var ( errIncompatibleFx = errors.New("incompatible feature extension") errUnknownFx = errors.New("unknown feature extension") errGenesisAssetMustHaveState = errors.New("genesis asset must have non-empty state") - errBootstrapping = errors.New("chain is currently bootstrapping") _ vertex.LinearizableVMWithEngine = (*VM)(nil) ) @@ -115,6 +114,7 @@ type VM struct { txBackend *txexecutor.Backend // These values are only initialized after the chain has been linearized. + mempool mempool.Mempool blockbuilder.Builder chainManager blockexecutor.Manager network network.Network @@ -403,13 +403,13 @@ func (vm *VM) Linearize(_ context.Context, stopVertexID ids.ID, toEngine chan<- return err } - mempool, err := mempool.New("mempool", vm.registerer, toEngine) + vm.mempool, err = mempool.New("mempool", vm.registerer, toEngine) if err != nil { return fmt.Errorf("failed to create mempool: %w", err) } vm.chainManager = blockexecutor.NewManager( - mempool, + vm.mempool, vm.metrics, vm.state, vm.txBackend, @@ -421,14 +421,14 @@ func (vm *VM) Linearize(_ context.Context, stopVertexID ids.ID, toEngine chan<- vm.txBackend, vm.chainManager, &vm.clock, - mempool, + vm.mempool, ) vm.network = network.New( vm.ctx, vm.parser, vm.chainManager, - mempool, + vm.mempool, vm.appSender, ) @@ -477,32 +477,21 @@ func (vm *VM) ParseTx(_ context.Context, bytes []byte) (snowstorm.Tx, error) { ****************************************************************************** */ -// IssueTx attempts to send a transaction to consensus. -// If onDecide is specified, the function will be called when the transaction is -// either accepted or rejected with the appropriate status. This function will -// go out of scope when the transaction is removed from memory. -func (vm *VM) IssueTx(b []byte) (ids.ID, error) { - if !vm.bootstrapped || vm.Builder == nil { - return ids.ID{}, errBootstrapping - } +// issueTx attempts to send a transaction to consensus. +// +// Invariant: The context lock is not held +// Invariant: This function is only called after Linearize has been called. +func (vm *VM) issueTx(tx *txs.Tx) (ids.ID, error) { + vm.ctx.Lock.Lock() + defer vm.ctx.Lock.Unlock() - tx, err := vm.parser.ParseTx(b) - if err != nil { - vm.ctx.Log.Debug("failed to parse tx", - zap.Error(err), - ) - return ids.ID{}, err - } - - err = vm.network.IssueTx(context.TODO(), tx) + err := vm.network.IssueTx(context.TODO(), tx) if err != nil { vm.ctx.Log.Debug("failed to add tx to mempool", zap.Error(err), ) - return ids.ID{}, err } - - return tx.ID(), nil + return tx.ID(), err } /* diff --git a/vms/avm/wallet_service.go b/vms/avm/wallet_service.go index 47aa3bbf88ef..04e5f423cc6f 100644 --- a/vms/avm/wallet_service.go +++ b/vms/avm/wallet_service.go @@ -31,27 +31,26 @@ type WalletService struct { } func (w *WalletService) decided(txID ids.ID) { - if _, ok := w.pendingTxs.Get(txID); !ok { + if !w.pendingTxs.Delete(txID) { return } w.vm.ctx.Log.Info("tx decided over wallet API", zap.Stringer("txID", txID), ) - w.pendingTxs.Delete(txID) - for { txID, tx, ok := w.pendingTxs.Oldest() if !ok { return } - txBytes := tx.Bytes() - _, err := w.vm.IssueTx(txBytes) + err := w.vm.mempool.Add(tx) if err == nil { w.vm.ctx.Log.Info("issued tx to mempool over wallet API", zap.Stringer("txID", txID), ) + + w.vm.mempool.RequestBuildBlock() return } @@ -63,12 +62,7 @@ func (w *WalletService) decided(txID ids.ID) { } } -func (w *WalletService) issue(txBytes []byte) (ids.ID, error) { - tx, err := w.vm.parser.ParseTx(txBytes) - if err != nil { - return ids.ID{}, err - } - +func (w *WalletService) issue(tx *txs.Tx) (ids.ID, error) { txID := tx.ID() w.vm.ctx.Log.Info("issuing tx over wallet API", zap.Stringer("txID", txID), @@ -82,11 +76,16 @@ func (w *WalletService) issue(txBytes []byte) (ids.ID, error) { } if w.pendingTxs.Len() == 0 { - _, err := w.vm.IssueTx(txBytes) - if err != nil { + if err := w.vm.mempool.Add(tx); err != nil { + w.vm.ctx.Log.Warn("failed to issue tx over wallet API", + zap.Stringer("txID", txID), + zap.Error(err), + ) return ids.ID{}, err } + w.vm.mempool.RequestBuildBlock() + w.vm.ctx.Log.Info("issued tx to mempool over wallet API", zap.Stringer("txID", txID), ) @@ -142,10 +141,15 @@ func (w *WalletService) IssueTx(_ *http.Request, args *api.FormattedTx, reply *a return fmt.Errorf("problem decoding transaction: %w", err) } + tx, err := w.vm.parser.ParseTx(txBytes) + if err != nil { + return err + } + w.vm.ctx.Lock.Lock() defer w.vm.ctx.Lock.Unlock() - txID, err := w.issue(txBytes) + txID, err := w.issue(tx) reply.TxID = txID return err } @@ -291,7 +295,7 @@ func (w *WalletService) SendMultiple(_ *http.Request, args *SendMultipleArgs, re codec := w.vm.parser.Codec() avax.SortTransferableOutputs(outs, codec) - tx := txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ + tx := &txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: w.vm.ctx.NetworkID, BlockchainID: w.vm.ctx.ChainID, Outs: outs, @@ -302,7 +306,7 @@ func (w *WalletService) SendMultiple(_ *http.Request, args *SendMultipleArgs, re return err } - txID, err := w.issue(tx.Bytes()) + txID, err := w.issue(tx) if err != nil { return fmt.Errorf("problem issuing transaction: %w", err) } From e41fa535ba06e8153e14ca543dd32ce647ec183c Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 20 Dec 2023 17:59:28 -0500 Subject: [PATCH 177/267] Rework X-chain locking in tests (#2526) --- vms/avm/environment_test.go | 17 +++-- vms/avm/index_test.go | 14 ++++- vms/avm/service_test.go | 109 ++++++++++++--------------------- vms/avm/vm_regression_test.go | 2 + vms/avm/vm_test.go | 26 +++++++- vms/avm/wallet_service_test.go | 6 +- 6 files changed, 88 insertions(+), 86 deletions(-) diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index 5c0cf55b5ff2..6f15d210901a 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -313,7 +313,7 @@ func buildGenesisTestWithArgs(tb testing.TB, args *BuildGenesisArgs) []byte { return b } -func newTx(tb testing.TB, genesisBytes []byte, vm *VM, assetName string) *txs.Tx { +func newTx(tb testing.TB, genesisBytes []byte, parser txs.Parser, assetName string) *txs.Tx { require := require.New(tb) createTx := getCreateTxFromGenesisTest(tb, genesisBytes, assetName) @@ -338,14 +338,14 @@ func newTx(tb testing.TB, genesisBytes []byte, vm *VM, assetName string) *txs.Tx }}, }, }} - require.NoError(tx.SignSECP256K1Fx(vm.parser.Codec(), [][]*secp256k1.PrivateKey{{keys[0]}})) + require.NoError(tx.SignSECP256K1Fx(parser.Codec(), [][]*secp256k1.PrivateKey{{keys[0]}})) return tx } // Sample from a set of addresses and return them raw and formatted as strings. // The size of the sample is between 1 and len(addrs) // If len(addrs) == 0, returns nil -func sampleAddrs(tb testing.TB, vm *VM, addrs []ids.ShortID) ([]ids.ShortID, []string) { +func sampleAddrs(tb testing.TB, addressFormatter avax.AddressManager, addrs []ids.ShortID) ([]ids.ShortID, []string) { require := require.New(tb) sampledAddrs := []ids.ShortID{} @@ -359,7 +359,7 @@ func sampleAddrs(tb testing.TB, vm *VM, addrs []ids.ShortID) ([]ids.ShortID, []s require.NoError(err) for _, index := range indices { addr := addrs[index] - addrStr, err := vm.FormatLocalAddress(addr) + addrStr, err := addressFormatter.FormatLocalAddress(addr) require.NoError(err) sampledAddrs = append(sampledAddrs, addr) @@ -517,32 +517,31 @@ func makeCustomAssetGenesis(tb testing.TB) *BuildGenesisArgs { } } -// issueAndAccept expects the context lock to be held +// issueAndAccept expects the context lock not to be held func issueAndAccept( require *require.Assertions, vm *VM, issuer <-chan common.Message, tx *txs.Tx, ) { - vm.ctx.Lock.Unlock() txID, err := vm.issueTx(tx) - vm.ctx.Lock.Lock() require.NoError(err) require.Equal(tx.ID(), txID) buildAndAccept(require, vm, issuer, txID) } -// buildAndAccept expects the context lock to be held +// buildAndAccept expects the context lock not to be held func buildAndAccept( require *require.Assertions, vm *VM, issuer <-chan common.Message, txID ids.ID, ) { - vm.ctx.Lock.Unlock() require.Equal(common.PendingTxs, <-issuer) + vm.ctx.Lock.Lock() + defer vm.ctx.Lock.Unlock() blkIntf, err := vm.BuildBlock(context.Background()) require.NoError(err) diff --git a/vms/avm/index_test.go b/vms/avm/index_test.go index 74b306c16c0f..be21fa60023a 100644 --- a/vms/avm/index_test.go +++ b/vms/avm/index_test.go @@ -55,9 +55,12 @@ func TestIndexTransaction_Ordered(t *testing.T) { tx := buildTX(utxoID, txAssetID, addr) require.NoError(tx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) - // issue transaction + env.vm.ctx.Lock.Unlock() + issueAndAccept(require, env.vm, env.issuer, tx) + env.vm.ctx.Lock.Lock() + txs = append(txs, tx) } @@ -96,9 +99,13 @@ func TestIndexTransaction_MultipleTransactions(t *testing.T) { tx := buildTX(utxoID, txAssetID, addr) require.NoError(tx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) + env.vm.ctx.Lock.Unlock() + // issue transaction issueAndAccept(require, env.vm, env.issuer, tx) + env.vm.ctx.Lock.Lock() + addressTxMap[addr] = tx } @@ -145,9 +152,12 @@ func TestIndexTransaction_MultipleAddresses(t *testing.T) { tx := buildTX(utxoID, txAssetID, addrs...) require.NoError(tx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) - // issue transaction + env.vm.ctx.Lock.Unlock() + issueAndAccept(require, env.vm, env.issuer, tx) + env.vm.ctx.Lock.Lock() + assertIndexedTX(t, env.vm.db, 0, addr, txAssetID.ID, tx.ID()) assertLatestIdx(t, env.vm.db, addr, txAssetID.ID, 1) } diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 7703b81e807a..2241621a389d 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -64,7 +64,7 @@ func TestServiceIssueTx(t *testing.T) { err := env.service.IssueTx(nil, txArgs, txReply) require.ErrorIs(err, codec.ErrCantUnpackVersion) - tx := newTx(t, env.genesisBytes, env.vm, "AVAX") + tx := newTx(t, env.genesisBytes, env.vm.parser, "AVAX") txArgs.Tx, err = formatting.Encode(formatting.Hex, tx.Bytes()) require.NoError(err) txArgs.Encoding = formatting.Hex @@ -90,7 +90,7 @@ func TestServiceGetTxStatus(t *testing.T) { err := env.service.GetTxStatus(nil, statusArgs, statusReply) require.ErrorIs(err, errNilTxID) - newTx := newAvaxBaseTxWithOutputs(t, env.genesisBytes, env.vm) + newTx := newAvaxBaseTxWithOutputs(t, env.genesisBytes, env.vm.TxFee, env.vm.parser) txID := newTx.ID() statusArgs = &api.JSONTxID{ @@ -100,12 +100,8 @@ func TestServiceGetTxStatus(t *testing.T) { require.NoError(env.service.GetTxStatus(nil, statusArgs, statusReply)) require.Equal(choices.Unknown, statusReply.Status) - env.vm.ctx.Lock.Lock() - issueAndAccept(require, env.vm, env.issuer, newTx) - env.vm.ctx.Lock.Unlock() - statusReply = &GetTxStatusReply{} require.NoError(env.service.GetTxStatus(nil, statusArgs, statusReply)) require.Equal(choices.Accepted, statusReply.Status) @@ -540,17 +536,16 @@ func TestServiceGetTxJSON_BaseTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{}) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() - newTx := newAvaxBaseTxWithOutputs(t, env.genesisBytes, env.vm) + newTx := newAvaxBaseTxWithOutputs(t, env.genesisBytes, env.vm.TxFee, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, newTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: newTx.ID(), @@ -624,17 +619,16 @@ func TestServiceGetTxJSON_ExportTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{}) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() - newTx := newAvaxExportTxWithOutputs(t, env.genesisBytes, env.vm) + newTx := newAvaxExportTxWithOutputs(t, env.genesisBytes, env.vm.TxFee, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, newTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: newTx.ID(), @@ -715,17 +709,16 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { Fx: &propertyfx.Fx{}, }}, }) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: createAssetTx.ID(), @@ -832,6 +825,7 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { Fx: &propertyfx.Fx{}, }}, }) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -839,15 +833,13 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) mintNFTTx := buildOperationTxWithOp(buildNFTxMintOp(createAssetTx, key, 2, 1)) require.NoError(mintNFTTx.SignNFTFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) issueAndAccept(require, env.vm, env.issuer, mintNFTTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: mintNFTTx.ID(), @@ -932,6 +924,7 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { Fx: &propertyfx.Fx{}, }}, }) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -939,7 +932,7 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) mintOp1 := buildNFTxMintOp(createAssetTx, key, 2, 1) @@ -949,8 +942,6 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { require.NoError(mintNFTTx.SignNFTFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}, {key}})) issueAndAccept(require, env.vm, env.issuer, mintNFTTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: mintNFTTx.ID(), @@ -1071,6 +1062,7 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { Fx: &propertyfx.Fx{}, }}, }) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -1078,15 +1070,13 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) mintSecpOpTx := buildOperationTxWithOp(buildSecpMintOp(createAssetTx, key, 0)) require.NoError(mintSecpOpTx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) issueAndAccept(require, env.vm, env.issuer, mintSecpOpTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: mintSecpOpTx.ID(), @@ -1175,6 +1165,7 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { Fx: &propertyfx.Fx{}, }}, }) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -1182,7 +1173,7 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) op1 := buildSecpMintOp(createAssetTx, key, 0) @@ -1192,8 +1183,6 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { require.NoError(mintSecpOpTx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}, {key}})) issueAndAccept(require, env.vm, env.issuer, mintSecpOpTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: mintSecpOpTx.ID(), @@ -1322,6 +1311,7 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { Fx: &propertyfx.Fx{}, }}, }) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -1329,15 +1319,13 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) mintPropertyFxOpTx := buildOperationTxWithOp(buildPropertyFxMintOp(createAssetTx, key, 4)) require.NoError(mintPropertyFxOpTx.SignPropertyFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) issueAndAccept(require, env.vm, env.issuer, mintPropertyFxOpTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: mintPropertyFxOpTx.ID(), @@ -1423,6 +1411,7 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) Fx: &propertyfx.Fx{}, }}, }) + env.vm.ctx.Lock.Unlock() defer func() { env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) @@ -1430,7 +1419,7 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) op1 := buildPropertyFxMintOp(createAssetTx, key, 4) @@ -1440,8 +1429,6 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) require.NoError(mintPropertyFxOpTx.SignPropertyFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}, {key}})) issueAndAccept(require, env.vm, env.issuer, mintPropertyFxOpTx) - env.vm.ctx.Lock.Unlock() - reply := api.GetTxReply{} require.NoError(env.service.GetTx(nil, &api.GetTxArgs{ TxID: mintPropertyFxOpTx.ID(), @@ -1554,30 +1541,30 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) require.Equal(expectedReplyTxString, string(replyTxBytes)) } -func newAvaxBaseTxWithOutputs(t *testing.T, genesisBytes []byte, vm *VM) *txs.Tx { +func newAvaxBaseTxWithOutputs(t *testing.T, genesisBytes []byte, fee uint64, parser txs.Parser) *txs.Tx { avaxTx := getCreateTxFromGenesisTest(t, genesisBytes, "AVAX") key := keys[0] - tx := buildBaseTx(avaxTx, vm, key) - require.NoError(t, tx.SignSECP256K1Fx(vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) + tx := buildBaseTx(avaxTx, fee, key) + require.NoError(t, tx.SignSECP256K1Fx(parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) return tx } -func newAvaxExportTxWithOutputs(t *testing.T, genesisBytes []byte, vm *VM) *txs.Tx { +func newAvaxExportTxWithOutputs(t *testing.T, genesisBytes []byte, fee uint64, parser txs.Parser) *txs.Tx { avaxTx := getCreateTxFromGenesisTest(t, genesisBytes, "AVAX") key := keys[0] - tx := buildExportTx(avaxTx, vm, key) - require.NoError(t, tx.SignSECP256K1Fx(vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) + tx := buildExportTx(avaxTx, fee, key) + require.NoError(t, tx.SignSECP256K1Fx(parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) return tx } -func newAvaxCreateAssetTxWithOutputs(t *testing.T, vm *VM) *txs.Tx { +func newAvaxCreateAssetTxWithOutputs(t *testing.T, parser txs.Parser) *txs.Tx { key := keys[0] tx := buildCreateAssetTx(key) - require.NoError(t, tx.Initialize(vm.parser.Codec())) + require.NoError(t, tx.Initialize(parser.Codec())) return tx } -func buildBaseTx(avaxTx *txs.Tx, vm *VM, key *secp256k1.PrivateKey) *txs.Tx { +func buildBaseTx(avaxTx *txs.Tx, fee uint64, key *secp256k1.PrivateKey) *txs.Tx { return &txs.Tx{Unsigned: &txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, @@ -1601,7 +1588,7 @@ func buildBaseTx(avaxTx *txs.Tx, vm *VM, key *secp256k1.PrivateKey) *txs.Tx { Outs: []*avax.TransferableOutput{{ Asset: avax.Asset{ID: avaxTx.ID()}, Out: &secp256k1fx.TransferOutput{ - Amt: startBalance - vm.TxFee, + Amt: startBalance - fee, OutputOwners: secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{key.PublicKey().Address()}, @@ -1612,7 +1599,7 @@ func buildBaseTx(avaxTx *txs.Tx, vm *VM, key *secp256k1.PrivateKey) *txs.Tx { }} } -func buildExportTx(avaxTx *txs.Tx, vm *VM, key *secp256k1.PrivateKey) *txs.Tx { +func buildExportTx(avaxTx *txs.Tx, fee uint64, key *secp256k1.PrivateKey) *txs.Tx { return &txs.Tx{Unsigned: &txs.ExportTx{ BaseTx: txs.BaseTx{ BaseTx: avax.BaseTx{ @@ -1635,7 +1622,7 @@ func buildExportTx(avaxTx *txs.Tx, vm *VM, key *secp256k1.PrivateKey) *txs.Tx { ExportedOuts: []*avax.TransferableOutput{{ Asset: avax.Asset{ID: avaxTx.ID()}, Out: &secp256k1fx.TransferOutput{ - Amt: startBalance - vm.TxFee, + Amt: startBalance - fee, OutputOwners: secp256k1fx.OutputOwners{ Threshold: 1, Addrs: []ids.ShortID{key.PublicKey().Address()}, @@ -2156,7 +2143,7 @@ func TestCreateFixedCapAsset(t *testing.T) { changeAddrStr, err := env.vm.FormatLocalAddress(testChangeAddr) require.NoError(err) - _, fromAddrsStr := sampleAddrs(t, env.vm, addrs) + _, fromAddrsStr := sampleAddrs(t, env.vm.AddressManager, addrs) require.NoError(env.service.CreateFixedCapAsset(nil, &CreateAssetArgs{ JSONSpendHeader: api.JSONSpendHeader{ @@ -2204,7 +2191,7 @@ func TestCreateVariableCapAsset(t *testing.T) { reply := AssetIDChangeAddr{} minterAddrStr, err := env.vm.FormatLocalAddress(keys[0].PublicKey().Address()) require.NoError(err) - _, fromAddrsStr := sampleAddrs(t, env.vm, addrs) + _, fromAddrsStr := sampleAddrs(t, env.vm.AddressManager, addrs) changeAddrStr := fromAddrsStr[0] require.NoError(env.service.CreateVariableCapAsset(nil, &CreateAssetArgs{ @@ -2229,12 +2216,8 @@ func TestCreateVariableCapAsset(t *testing.T) { }, &reply)) require.Equal(changeAddrStr, reply.ChangeAddr) - env.vm.ctx.Lock.Lock() - buildAndAccept(require, env.vm, env.issuer, reply.AssetID) - env.vm.ctx.Lock.Unlock() - createdAssetID := reply.AssetID.String() // Test minting of the created variable cap asset mintArgs := &MintArgs{ @@ -2253,12 +2236,8 @@ func TestCreateVariableCapAsset(t *testing.T) { require.NoError(env.service.Mint(nil, mintArgs, mintReply)) require.Equal(changeAddrStr, mintReply.ChangeAddr) - env.vm.ctx.Lock.Lock() - buildAndAccept(require, env.vm, env.issuer, mintReply.TxID) - env.vm.ctx.Lock.Unlock() - sendArgs := &SendArgs{ JSONSpendHeader: api.JSONSpendHeader{ UserPass: api.UserPass{ @@ -2302,7 +2281,7 @@ func TestNFTWorkflow(t *testing.T) { env.vm.ctx.Lock.Unlock() }() - fromAddrs, fromAddrsStr := sampleAddrs(t, env.vm, addrs) + fromAddrs, fromAddrsStr := sampleAddrs(t, env.vm.AddressManager, addrs) // Test minting of the created variable cap asset addrStr, err := env.vm.FormatLocalAddress(keys[0].PublicKey().Address()) @@ -2332,12 +2311,8 @@ func TestNFTWorkflow(t *testing.T) { require.NoError(env.service.CreateNFTAsset(nil, createArgs, createReply)) require.Equal(fromAddrsStr[0], createReply.ChangeAddr) - env.vm.ctx.Lock.Lock() - buildAndAccept(require, env.vm, env.issuer, createReply.AssetID) - env.vm.ctx.Lock.Unlock() - // Key: Address // Value: AVAX balance balances := map[ids.ShortID]uint64{} @@ -2387,13 +2362,9 @@ func TestNFTWorkflow(t *testing.T) { require.NoError(env.service.MintNFT(nil, mintArgs, mintReply)) require.Equal(fromAddrsStr[0], createReply.ChangeAddr) - env.vm.ctx.Lock.Lock() - // Accept the transaction so that we can send the newly minted NFT buildAndAccept(require, env.vm, env.issuer, mintReply.TxID) - env.vm.ctx.Lock.Unlock() - sendArgs := &SendNFTArgs{ JSONSpendHeader: api.JSONSpendHeader{ UserPass: api.UserPass{ @@ -2521,6 +2492,7 @@ func TestSend(t *testing.T) { env.vm.ctx.Lock.Unlock() defer func() { + env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() @@ -2532,7 +2504,7 @@ func TestSend(t *testing.T) { require.NoError(err) changeAddrStr, err := env.vm.FormatLocalAddress(testChangeAddr) require.NoError(err) - _, fromAddrsStr := sampleAddrs(t, env.vm, addrs) + _, fromAddrsStr := sampleAddrs(t, env.vm.AddressManager, addrs) args := &SendArgs{ JSONSpendHeader: api.JSONSpendHeader{ @@ -2553,8 +2525,6 @@ func TestSend(t *testing.T) { require.NoError(env.service.Send(nil, args, reply)) require.Equal(changeAddrStr, reply.ChangeAddr) - env.vm.ctx.Lock.Lock() - buildAndAccept(require, env.vm, env.issuer, reply.TxID) } @@ -2574,6 +2544,7 @@ func TestSendMultiple(t *testing.T) { env.vm.ctx.Lock.Unlock() defer func() { + env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() @@ -2585,7 +2556,7 @@ func TestSendMultiple(t *testing.T) { require.NoError(err) changeAddrStr, err := env.vm.FormatLocalAddress(testChangeAddr) require.NoError(err) - _, fromAddrsStr := sampleAddrs(t, env.vm, addrs) + _, fromAddrsStr := sampleAddrs(t, env.vm.AddressManager, addrs) args := &SendMultipleArgs{ JSONSpendHeader: api.JSONSpendHeader{ @@ -2613,8 +2584,6 @@ func TestSendMultiple(t *testing.T) { require.NoError(env.service.SendMultiple(nil, args, reply)) require.Equal(changeAddrStr, reply.ChangeAddr) - env.vm.ctx.Lock.Lock() - buildAndAccept(require, env.vm, env.issuer, reply.TxID) }) } diff --git a/vms/avm/vm_regression_test.go b/vms/avm/vm_regression_test.go index 69030b737830..829aa1966d71 100644 --- a/vms/avm/vm_regression_test.go +++ b/vms/avm/vm_regression_test.go @@ -26,7 +26,9 @@ func TestVerifyFxUsage(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{}, }) + env.vm.ctx.Lock.Unlock() defer func() { + env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index e59333f03072..1ee15fc5698a 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -118,12 +118,14 @@ func TestIssueTx(t *testing.T) { require := require.New(t) env := setup(t, &envConfig{}) + env.vm.ctx.Lock.Unlock() defer func() { + env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() - tx := newTx(t, env.genesisBytes, env.vm, "AVAX") + tx := newTx(t, env.genesisBytes, env.vm.parser, "AVAX") issueAndAccept(require, env.vm, env.issuer, tx) } @@ -134,7 +136,9 @@ func TestIssueNFT(t *testing.T) { env := setup(t, &envConfig{ vmStaticConfig: &config.Config{}, }) + env.vm.ctx.Lock.Unlock() defer func() { + env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() @@ -237,7 +241,9 @@ func TestIssueProperty(t *testing.T) { Fx: &propertyfx.Fx{}, }}, }) + env.vm.ctx.Lock.Unlock() defer func() { + env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() @@ -324,13 +330,15 @@ func TestIssueTxWithFeeAsset(t *testing.T) { env := setup(t, &envConfig{ isCustomFeeAsset: true, }) + env.vm.ctx.Lock.Unlock() defer func() { + env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() // send first asset - tx := newTx(t, env.genesisBytes, env.vm, feeAssetName) + tx := newTx(t, env.genesisBytes, env.vm.parser, feeAssetName) issueAndAccept(require, env.vm, env.issuer, tx) } @@ -340,7 +348,9 @@ func TestIssueTxWithAnotherAsset(t *testing.T) { env := setup(t, &envConfig{ isCustomFeeAsset: true, }) + env.vm.ctx.Lock.Unlock() defer func() { + env.vm.ctx.Lock.Lock() require.NoError(env.vm.Shutdown(context.Background())) env.vm.ctx.Lock.Unlock() }() @@ -593,8 +603,12 @@ func TestIssueImportTx(t *testing.T) { }, })) + env.vm.ctx.Lock.Unlock() + issueAndAccept(require, env.vm, env.issuer, tx) + env.vm.ctx.Lock.Lock() + assertIndexedTX(t, env.vm.db, 0, key.PublicKey().Address(), txAssetID.AssetID(), tx.ID()) assertLatestIdx(t, env.vm.db, key.PublicKey().Address(), avaxID, 1) @@ -738,8 +752,12 @@ func TestIssueExportTx(t *testing.T) { require.NoError(err) require.Empty(utxoBytes) + env.vm.ctx.Lock.Unlock() + issueAndAccept(require, env.vm, env.issuer, tx) + env.vm.ctx.Lock.Lock() + utxoBytes, _, _, err = peerSharedMemory.Indexed( env.vm.ctx.ChainID, [][]byte{ @@ -813,8 +831,12 @@ func TestClearForceAcceptedExportTx(t *testing.T) { _, err := peerSharedMemory.Get(env.vm.ctx.ChainID, [][]byte{utxoID[:]}) require.ErrorIs(err, database.ErrNotFound) + env.vm.ctx.Lock.Unlock() + issueAndAccept(require, env.vm, env.issuer, tx) + env.vm.ctx.Lock.Lock() + _, err = peerSharedMemory.Get(env.vm.ctx.ChainID, [][]byte{utxoID[:]}) require.ErrorIs(err, database.ErrNotFound) diff --git a/vms/avm/wallet_service_test.go b/vms/avm/wallet_service_test.go index 7a9232e00a6a..62860995d8f6 100644 --- a/vms/avm/wallet_service_test.go +++ b/vms/avm/wallet_service_test.go @@ -39,7 +39,7 @@ func TestWalletService_SendMultiple(t *testing.T) { require.NoError(err) changeAddrStr, err := env.vm.FormatLocalAddress(testChangeAddr) require.NoError(err) - _, fromAddrsStr := sampleAddrs(t, env.vm, addrs) + _, fromAddrsStr := sampleAddrs(t, env.vm.AddressManager, addrs) args := &SendMultipleArgs{ JSONSpendHeader: api.JSONSpendHeader{ @@ -67,10 +67,10 @@ func TestWalletService_SendMultiple(t *testing.T) { require.NoError(env.walletService.SendMultiple(nil, args, reply)) require.Equal(changeAddrStr, reply.ChangeAddr) - env.vm.ctx.Lock.Lock() - buildAndAccept(require, env.vm, env.issuer, reply.TxID) + env.vm.ctx.Lock.Lock() + _, err = env.vm.state.GetTx(reply.TxID) require.NoError(err) }) From fb5f0cd98806193b52ba1fa4ef7f54be09195715 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 21 Dec 2023 13:11:42 -0500 Subject: [PATCH 178/267] `vms/avm`: Simplify `mempool.Remove` signature (#2527) --- vms/avm/block/builder/builder.go | 2 +- vms/avm/block/executor/block.go | 4 ++-- vms/avm/txs/mempool/mempool.go | 6 +++--- vms/avm/txs/mempool/mempool_test.go | 10 +++++----- vms/avm/txs/mempool/mock_mempool.go | 12 ++++++++---- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/vms/avm/block/builder/builder.go b/vms/avm/block/builder/builder.go index 6b7a643d19c9..29131f3251e7 100644 --- a/vms/avm/block/builder/builder.go +++ b/vms/avm/block/builder/builder.go @@ -101,7 +101,7 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { if !exists || len(tx.Bytes()) > remainingSize { break } - b.mempool.Remove([]*txs.Tx{tx}) + b.mempool.Remove(tx) // Invariant: [tx] has already been syntactically verified. diff --git a/vms/avm/block/executor/block.go b/vms/avm/block/executor/block.go index 5e643ad4ecc0..439e7f009d53 100644 --- a/vms/avm/block/executor/block.go +++ b/vms/avm/block/executor/block.go @@ -200,7 +200,7 @@ func (b *Block) Verify(context.Context) error { stateDiff.AddBlock(b.Block) b.manager.blkIDToState[blkID] = blockState - b.manager.mempool.Remove(txs) + b.manager.mempool.Remove(txs...) return nil } @@ -220,7 +220,7 @@ func (b *Block) Accept(context.Context) error { } b.manager.lastAccepted = blkID - b.manager.mempool.Remove(txs) + b.manager.mempool.Remove(txs...) blkState, ok := b.manager.blkIDToState[blkID] if !ok { diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index db42c9cca418..254313322f9b 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -45,7 +45,7 @@ var ( type Mempool interface { Add(tx *txs.Tx) error Get(txID ids.ID) (*txs.Tx, bool) - Remove(txs []*txs.Tx) + Remove(txs ...*txs.Tx) // Peek returns the oldest tx in the mempool. Peek() (tx *txs.Tx, exists bool) @@ -159,11 +159,11 @@ func (m *mempool) Get(txID ids.ID) (*txs.Tx, bool) { return tx, ok } -func (m *mempool) Remove(txsToRemove []*txs.Tx) { +func (m *mempool) Remove(txs ...*txs.Tx) { m.lock.Lock() defer m.lock.Unlock() - for _, tx := range txsToRemove { + for _, tx := range txs { txID := tx.ID() if !m.unissuedTxs.Delete(txID) { continue diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index a4760ceba792..fff0f9f21248 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -101,7 +101,7 @@ func TestGet(t *testing.T) { require.True(exists) require.Equal(tx, returned) - mempool.Remove([]*txs.Tx{tx}) + mempool.Remove(tx) _, exists = mempool.Get(txID) require.False(exists) @@ -130,19 +130,19 @@ func TestPeek(t *testing.T) { require.True(exists) require.Equal(tx, tx0) - mempool.Remove([]*txs.Tx{tx0}) + mempool.Remove(tx0) tx, exists = mempool.Peek() require.True(exists) require.Equal(tx, tx1) - mempool.Remove([]*txs.Tx{tx0}) + mempool.Remove(tx0) tx, exists = mempool.Peek() require.True(exists) require.Equal(tx, tx1) - mempool.Remove([]*txs.Tx{tx1}) + mempool.Remove(tx1) _, exists = mempool.Peek() require.False(exists) @@ -189,7 +189,7 @@ func TestIterate(t *testing.T) { mempool.Iterate(addTxs) require.Equal([]*txs.Tx{tx0, tx1}, iteratedTxs) - mempool.Remove([]*txs.Tx{tx0, tx2}) + mempool.Remove(tx0, tx2) iteratedTxs = nil mempool.Iterate(addTxs) diff --git a/vms/avm/txs/mempool/mock_mempool.go b/vms/avm/txs/mempool/mock_mempool.go index 9c85b8f4590a..15125b1ce675 100644 --- a/vms/avm/txs/mempool/mock_mempool.go +++ b/vms/avm/txs/mempool/mock_mempool.go @@ -121,15 +121,19 @@ func (mr *MockMempoolMockRecorder) Peek() *gomock.Call { } // Remove mocks base method. -func (m *MockMempool) Remove(arg0 []*txs.Tx) { +func (m *MockMempool) Remove(arg0 ...*txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Remove", arg0) + varargs := []interface{}{} + for _, a := range arg0 { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "Remove", varargs...) } // Remove indicates an expected call of Remove. -func (mr *MockMempoolMockRecorder) Remove(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Remove(arg0 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockMempool)(nil).Remove), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockMempool)(nil).Remove), arg0...) } // RequestBuildBlock mocks base method. From 620a5230abe10c959cbbcbb02de6ac2ada8efa89 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 21 Dec 2023 13:30:51 -0500 Subject: [PATCH 179/267] Remove unused mocks (#2528) --- network/peer/mock_gossip_tracker.go | 167 ---------------- scripts/mocks.mockgen.txt | 2 - vms/platformvm/txs/builder/mock_builder.go | 222 --------------------- 3 files changed, 391 deletions(-) delete mode 100644 network/peer/mock_gossip_tracker.go delete mode 100644 vms/platformvm/txs/builder/mock_builder.go diff --git a/network/peer/mock_gossip_tracker.go b/network/peer/mock_gossip_tracker.go deleted file mode 100644 index ee7b8c21ca91..000000000000 --- a/network/peer/mock_gossip_tracker.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/network/peer (interfaces: GossipTracker) - -// Package peer is a generated GoMock package. -package peer - -import ( - reflect "reflect" - - ids "github.com/ava-labs/avalanchego/ids" - gomock "go.uber.org/mock/gomock" -) - -// MockGossipTracker is a mock of GossipTracker interface. -type MockGossipTracker struct { - ctrl *gomock.Controller - recorder *MockGossipTrackerMockRecorder -} - -// MockGossipTrackerMockRecorder is the mock recorder for MockGossipTracker. -type MockGossipTrackerMockRecorder struct { - mock *MockGossipTracker -} - -// NewMockGossipTracker creates a new mock instance. -func NewMockGossipTracker(ctrl *gomock.Controller) *MockGossipTracker { - mock := &MockGossipTracker{ctrl: ctrl} - mock.recorder = &MockGossipTrackerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockGossipTracker) EXPECT() *MockGossipTrackerMockRecorder { - return m.recorder -} - -// AddKnown mocks base method. -func (m *MockGossipTracker) AddKnown(arg0 ids.NodeID, arg1, arg2 []ids.ID) ([]ids.ID, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddKnown", arg0, arg1, arg2) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// AddKnown indicates an expected call of AddKnown. -func (mr *MockGossipTrackerMockRecorder) AddKnown(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddKnown", reflect.TypeOf((*MockGossipTracker)(nil).AddKnown), arg0, arg1, arg2) -} - -// AddValidator mocks base method. -func (m *MockGossipTracker) AddValidator(arg0 ValidatorID) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddValidator", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// AddValidator indicates an expected call of AddValidator. -func (mr *MockGossipTrackerMockRecorder) AddValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddValidator", reflect.TypeOf((*MockGossipTracker)(nil).AddValidator), arg0) -} - -// GetNodeID mocks base method. -func (m *MockGossipTracker) GetNodeID(arg0 ids.ID) (ids.NodeID, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNodeID", arg0) - ret0, _ := ret[0].(ids.NodeID) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// GetNodeID indicates an expected call of GetNodeID. -func (mr *MockGossipTrackerMockRecorder) GetNodeID(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodeID", reflect.TypeOf((*MockGossipTracker)(nil).GetNodeID), arg0) -} - -// GetUnknown mocks base method. -func (m *MockGossipTracker) GetUnknown(arg0 ids.NodeID) ([]ValidatorID, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUnknown", arg0) - ret0, _ := ret[0].([]ValidatorID) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// GetUnknown indicates an expected call of GetUnknown. -func (mr *MockGossipTrackerMockRecorder) GetUnknown(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUnknown", reflect.TypeOf((*MockGossipTracker)(nil).GetUnknown), arg0) -} - -// RemoveValidator mocks base method. -func (m *MockGossipTracker) RemoveValidator(arg0 ids.NodeID) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RemoveValidator", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// RemoveValidator indicates an expected call of RemoveValidator. -func (mr *MockGossipTrackerMockRecorder) RemoveValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveValidator", reflect.TypeOf((*MockGossipTracker)(nil).RemoveValidator), arg0) -} - -// ResetValidator mocks base method. -func (m *MockGossipTracker) ResetValidator(arg0 ids.NodeID) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ResetValidator", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// ResetValidator indicates an expected call of ResetValidator. -func (mr *MockGossipTrackerMockRecorder) ResetValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetValidator", reflect.TypeOf((*MockGossipTracker)(nil).ResetValidator), arg0) -} - -// StartTrackingPeer mocks base method. -func (m *MockGossipTracker) StartTrackingPeer(arg0 ids.NodeID) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StartTrackingPeer", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// StartTrackingPeer indicates an expected call of StartTrackingPeer. -func (mr *MockGossipTrackerMockRecorder) StartTrackingPeer(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartTrackingPeer", reflect.TypeOf((*MockGossipTracker)(nil).StartTrackingPeer), arg0) -} - -// StopTrackingPeer mocks base method. -func (m *MockGossipTracker) StopTrackingPeer(arg0 ids.NodeID) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StopTrackingPeer", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// StopTrackingPeer indicates an expected call of StopTrackingPeer. -func (mr *MockGossipTrackerMockRecorder) StopTrackingPeer(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopTrackingPeer", reflect.TypeOf((*MockGossipTracker)(nil).StopTrackingPeer), arg0) -} - -// Tracked mocks base method. -func (m *MockGossipTracker) Tracked(arg0 ids.NodeID) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Tracked", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// Tracked indicates an expected call of Tracked. -func (mr *MockGossipTrackerMockRecorder) Tracked(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tracked", reflect.TypeOf((*MockGossipTracker)(nil).Tracked), arg0) -} diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 97b0eb8f799e..c01efb8e5869 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -5,7 +5,6 @@ github.com/ava-labs/avalanchego/database=Batch=database/mock_batch.go github.com/ava-labs/avalanchego/database=Iterator=database/mock_iterator.go github.com/ava-labs/avalanchego/message=OutboundMessage=message/mock_message.go github.com/ava-labs/avalanchego/message=OutboundMsgBuilder=message/mock_outbound_message_builder.go -github.com/ava-labs/avalanchego/network/peer=GossipTracker=network/peer/mock_gossip_tracker.go github.com/ava-labs/avalanchego/snow/consensus/snowman=Block=snow/consensus/snowman/mock_block.go github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex=LinearizableVM=snow/engine/avalanche/vertex/mock_vm.go github.com/ava-labs/avalanchego/snow/engine/snowman/block=BuildBlockWithContextChainVM=snow/engine/snowman/block/mocks/build_block_with_context_vm.go @@ -33,7 +32,6 @@ github.com/ava-labs/avalanchego/vms/components/verify=Verifiable=vms/components/ github.com/ava-labs/avalanchego/vms/platformvm/block=Block=vms/platformvm/block/mock_block.go github.com/ava-labs/avalanchego/vms/platformvm/state=Chain,Diff,State,Versions=vms/platformvm/state/mock_state.go github.com/ava-labs/avalanchego/vms/platformvm/state=StakerIterator=vms/platformvm/state/mock_staker_iterator.go -github.com/ava-labs/avalanchego/vms/platformvm/txs/builder=Builder=vms/platformvm/txs/builder/mock_builder.go github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool=Mempool=vms/platformvm/txs/mempool/mock_mempool.go github.com/ava-labs/avalanchego/vms/platformvm/utxo=Verifier=vms/platformvm/utxo/mock_verifier.go github.com/ava-labs/avalanchego/vms/proposervm/proposer=Windower=vms/proposervm/proposer/mock_windower.go diff --git a/vms/platformvm/txs/builder/mock_builder.go b/vms/platformvm/txs/builder/mock_builder.go deleted file mode 100644 index 19f74a7bed2f..000000000000 --- a/vms/platformvm/txs/builder/mock_builder.go +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/txs/builder (interfaces: Builder) - -// Package builder is a generated GoMock package. -package builder - -import ( - reflect "reflect" - time "time" - - ids "github.com/ava-labs/avalanchego/ids" - secp256k1 "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" - secp256k1fx "github.com/ava-labs/avalanchego/vms/secp256k1fx" - gomock "go.uber.org/mock/gomock" -) - -// MockBuilder is a mock of Builder interface. -type MockBuilder struct { - ctrl *gomock.Controller - recorder *MockBuilderMockRecorder -} - -// MockBuilderMockRecorder is the mock recorder for MockBuilder. -type MockBuilderMockRecorder struct { - mock *MockBuilder -} - -// NewMockBuilder creates a new mock instance. -func NewMockBuilder(ctrl *gomock.Controller) *MockBuilder { - mock := &MockBuilder{ctrl: ctrl} - mock.recorder = &MockBuilderMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBuilder) EXPECT() *MockBuilderMockRecorder { - return m.recorder -} - -// NewAddDelegatorTx mocks base method. -func (m *MockBuilder) NewAddDelegatorTx(arg0, arg1, arg2 uint64, arg3 ids.NodeID, arg4 ids.ShortID, arg5 []*secp256k1.PrivateKey, arg6 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewAddDelegatorTx", arg0, arg1, arg2, arg3, arg4, arg5, arg6) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewAddDelegatorTx indicates an expected call of NewAddDelegatorTx. -func (mr *MockBuilderMockRecorder) NewAddDelegatorTx(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddDelegatorTx", reflect.TypeOf((*MockBuilder)(nil).NewAddDelegatorTx), arg0, arg1, arg2, arg3, arg4, arg5, arg6) -} - -// NewAddSubnetValidatorTx mocks base method. -func (m *MockBuilder) NewAddSubnetValidatorTx(arg0, arg1, arg2 uint64, arg3 ids.NodeID, arg4 ids.ID, arg5 []*secp256k1.PrivateKey, arg6 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewAddSubnetValidatorTx", arg0, arg1, arg2, arg3, arg4, arg5, arg6) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewAddSubnetValidatorTx indicates an expected call of NewAddSubnetValidatorTx. -func (mr *MockBuilderMockRecorder) NewAddSubnetValidatorTx(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddSubnetValidatorTx", reflect.TypeOf((*MockBuilder)(nil).NewAddSubnetValidatorTx), arg0, arg1, arg2, arg3, arg4, arg5, arg6) -} - -// NewAddValidatorTx mocks base method. -func (m *MockBuilder) NewAddValidatorTx(arg0, arg1, arg2 uint64, arg3 ids.NodeID, arg4 ids.ShortID, arg5 uint32, arg6 []*secp256k1.PrivateKey, arg7 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewAddValidatorTx", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewAddValidatorTx indicates an expected call of NewAddValidatorTx. -func (mr *MockBuilderMockRecorder) NewAddValidatorTx(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddValidatorTx", reflect.TypeOf((*MockBuilder)(nil).NewAddValidatorTx), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) -} - -// NewAdvanceTimeTx mocks base method. -func (m *MockBuilder) NewAdvanceTimeTx(arg0 time.Time) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewAdvanceTimeTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewAdvanceTimeTx indicates an expected call of NewAdvanceTimeTx. -func (mr *MockBuilderMockRecorder) NewAdvanceTimeTx(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAdvanceTimeTx", reflect.TypeOf((*MockBuilder)(nil).NewAdvanceTimeTx), arg0) -} - -// NewBaseTx mocks base method. -func (m *MockBuilder) NewBaseTx(arg0 uint64, arg1 secp256k1fx.OutputOwners, arg2 []*secp256k1.PrivateKey, arg3 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewBaseTx", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewBaseTx indicates an expected call of NewBaseTx. -func (mr *MockBuilderMockRecorder) NewBaseTx(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBaseTx", reflect.TypeOf((*MockBuilder)(nil).NewBaseTx), arg0, arg1, arg2, arg3) -} - -// NewCreateChainTx mocks base method. -func (m *MockBuilder) NewCreateChainTx(arg0 ids.ID, arg1 []byte, arg2 ids.ID, arg3 []ids.ID, arg4 string, arg5 []*secp256k1.PrivateKey, arg6 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewCreateChainTx", arg0, arg1, arg2, arg3, arg4, arg5, arg6) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewCreateChainTx indicates an expected call of NewCreateChainTx. -func (mr *MockBuilderMockRecorder) NewCreateChainTx(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateChainTx", reflect.TypeOf((*MockBuilder)(nil).NewCreateChainTx), arg0, arg1, arg2, arg3, arg4, arg5, arg6) -} - -// NewCreateSubnetTx mocks base method. -func (m *MockBuilder) NewCreateSubnetTx(arg0 uint32, arg1 []ids.ShortID, arg2 []*secp256k1.PrivateKey, arg3 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewCreateSubnetTx", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewCreateSubnetTx indicates an expected call of NewCreateSubnetTx. -func (mr *MockBuilderMockRecorder) NewCreateSubnetTx(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewCreateSubnetTx", reflect.TypeOf((*MockBuilder)(nil).NewCreateSubnetTx), arg0, arg1, arg2, arg3) -} - -// NewExportTx mocks base method. -func (m *MockBuilder) NewExportTx(arg0 uint64, arg1 ids.ID, arg2 ids.ShortID, arg3 []*secp256k1.PrivateKey, arg4 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewExportTx", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewExportTx indicates an expected call of NewExportTx. -func (mr *MockBuilderMockRecorder) NewExportTx(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewExportTx", reflect.TypeOf((*MockBuilder)(nil).NewExportTx), arg0, arg1, arg2, arg3, arg4) -} - -// NewImportTx mocks base method. -func (m *MockBuilder) NewImportTx(arg0 ids.ID, arg1 ids.ShortID, arg2 []*secp256k1.PrivateKey, arg3 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewImportTx", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewImportTx indicates an expected call of NewImportTx. -func (mr *MockBuilderMockRecorder) NewImportTx(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewImportTx", reflect.TypeOf((*MockBuilder)(nil).NewImportTx), arg0, arg1, arg2, arg3) -} - -// NewRemoveSubnetValidatorTx mocks base method. -func (m *MockBuilder) NewRemoveSubnetValidatorTx(arg0 ids.NodeID, arg1 ids.ID, arg2 []*secp256k1.PrivateKey, arg3 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewRemoveSubnetValidatorTx", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewRemoveSubnetValidatorTx indicates an expected call of NewRemoveSubnetValidatorTx. -func (mr *MockBuilderMockRecorder) NewRemoveSubnetValidatorTx(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRemoveSubnetValidatorTx", reflect.TypeOf((*MockBuilder)(nil).NewRemoveSubnetValidatorTx), arg0, arg1, arg2, arg3) -} - -// NewRewardValidatorTx mocks base method. -func (m *MockBuilder) NewRewardValidatorTx(arg0 ids.ID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewRewardValidatorTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewRewardValidatorTx indicates an expected call of NewRewardValidatorTx. -func (mr *MockBuilderMockRecorder) NewRewardValidatorTx(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRewardValidatorTx", reflect.TypeOf((*MockBuilder)(nil).NewRewardValidatorTx), arg0) -} - -// NewTransferSubnetOwnershipTx mocks base method. -func (m *MockBuilder) NewTransferSubnetOwnershipTx(arg0 ids.ID, arg1 uint32, arg2 []ids.ShortID, arg3 []*secp256k1.PrivateKey, arg4 ids.ShortID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewTransferSubnetOwnershipTx", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewTransferSubnetOwnershipTx indicates an expected call of NewTransferSubnetOwnershipTx. -func (mr *MockBuilderMockRecorder) NewTransferSubnetOwnershipTx(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewTransferSubnetOwnershipTx", reflect.TypeOf((*MockBuilder)(nil).NewTransferSubnetOwnershipTx), arg0, arg1, arg2, arg3, arg4) -} From d5bbe8d306adfb9174304a5f8cdc7d2c300eee1e Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:18:04 -0500 Subject: [PATCH 180/267] Move `avm.newContext` to `snowtest.Context` (#2513) --- snow/snowtest/snowtest.go | 56 ++++++++++++++++++- vms/avm/environment_test.go | 45 ++------------- vms/avm/index_test.go | 8 +-- vms/avm/service_test.go | 54 +++++++++--------- vms/avm/state_test.go | 2 +- .../txs/executor/semantic_verifier_test.go | 20 ++----- .../txs/executor/syntactic_verifier_test.go | 29 ++-------- vms/avm/vm_benchmark_test.go | 2 +- vms/avm/vm_regression_test.go | 6 +- vms/avm/vm_test.go | 37 ++++++------ 10 files changed, 125 insertions(+), 134 deletions(-) diff --git a/snow/snowtest/snowtest.go b/snow/snowtest/snowtest.go index 2dfd1a443b84..2c103214688b 100644 --- a/snow/snowtest/snowtest.go +++ b/snow/snowtest/snowtest.go @@ -4,13 +4,30 @@ package snowtest import ( + "context" + "errors" + "testing" + "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/constants" ) -var _ snow.Acceptor = noOpAcceptor{} +var ( + XChainID = ids.GenerateTestID() + CChainID = ids.GenerateTestID() + PChainID = constants.PlatformChainID + AVAXAssetID = ids.GenerateTestID() + + errMissing = errors.New("missing") + + _ snow.Acceptor = noOpAcceptor{} +) type noOpAcceptor struct{} @@ -28,3 +45,40 @@ func ConsensusContext() *snow.ConsensusContext { VertexAcceptor: noOpAcceptor{}, } } + +func Context(tb testing.TB, chainID ids.ID) *snow.Context { + require := require.New(tb) + + ctx := snow.DefaultContextTest() + + ctx.NetworkID = constants.UnitTestID + ctx.SubnetID = constants.PrimaryNetworkID + ctx.ChainID = chainID + ctx.XChainID = XChainID + ctx.CChainID = CChainID + ctx.AVAXAssetID = AVAXAssetID + + aliaser := ctx.BCLookup.(ids.Aliaser) + require.NoError(aliaser.Alias(constants.PlatformChainID, "P")) + require.NoError(aliaser.Alias(constants.PlatformChainID, constants.PlatformChainID.String())) + require.NoError(aliaser.Alias(ctx.XChainID, "X")) + require.NoError(aliaser.Alias(ctx.XChainID, ctx.XChainID.String())) + require.NoError(aliaser.Alias(ctx.CChainID, "C")) + require.NoError(aliaser.Alias(ctx.CChainID, ctx.CChainID.String())) + + ctx.ValidatorState = &validators.TestState{ + GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) { + subnetID, ok := map[ids.ID]ids.ID{ + constants.PlatformChainID: constants.PrimaryNetworkID, + ctx.XChainID: constants.PrimaryNetworkID, + ctx.CChainID: constants.PrimaryNetworkID, + }[chainID] + if !ok { + return ids.Empty, errMissing + } + return subnetID, nil + }, + } + + return ctx +} diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index 6f15d210901a..5616371041ea 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -5,7 +5,6 @@ package avm import ( "context" - "errors" "math/rand" "testing" @@ -20,7 +19,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/formatting" @@ -66,13 +65,10 @@ var ( }, } - chainID = ids.ID{5, 4, 3, 2, 1} assetID = ids.ID{1, 2, 3} keys = secp256k1.TestKeys()[:3] // TODO: Remove [:3] addrs []ids.ShortID // addrs[i] corresponds to keys[i] - - errMissing = errors.New("missing") ) func init() { @@ -124,7 +120,8 @@ func setup(tb testing.TB, c *envConfig) *environment { } genesisBytes := buildGenesisTestWithArgs(tb, genesisArgs) - ctx := newContext(tb) + + ctx := snowtest.Context(tb, snowtest.XChainID) baseDB := memdb.New() m := atomic.NewMemory(prefixdb.New([]byte{0}, baseDB)) @@ -225,40 +222,6 @@ func setup(tb testing.TB, c *envConfig) *environment { return env } -func newContext(tb testing.TB) *snow.Context { - require := require.New(tb) - - genesisBytes := buildGenesisTest(tb) - tx := getCreateTxFromGenesisTest(tb, genesisBytes, "AVAX") - - ctx := snow.DefaultContextTest() - ctx.NetworkID = constants.UnitTestID - ctx.ChainID = chainID - ctx.AVAXAssetID = tx.ID() - ctx.XChainID = ids.Empty.Prefix(0) - ctx.CChainID = ids.Empty.Prefix(1) - aliaser := ctx.BCLookup.(ids.Aliaser) - - require.NoError(aliaser.Alias(chainID, "X")) - require.NoError(aliaser.Alias(chainID, chainID.String())) - require.NoError(aliaser.Alias(constants.PlatformChainID, "P")) - require.NoError(aliaser.Alias(constants.PlatformChainID, constants.PlatformChainID.String())) - - ctx.ValidatorState = &validators.TestState{ - GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) { - subnetID, ok := map[ids.ID]ids.ID{ - constants.PlatformChainID: ctx.SubnetID, - chainID: ctx.SubnetID, - }[chainID] - if !ok { - return ids.Empty, errMissing - } - return subnetID, nil - }, - } - return ctx -} - // Returns: // // 1. tx in genesis that creates asset @@ -313,7 +276,7 @@ func buildGenesisTestWithArgs(tb testing.TB, args *BuildGenesisArgs) []byte { return b } -func newTx(tb testing.TB, genesisBytes []byte, parser txs.Parser, assetName string) *txs.Tx { +func newTx(tb testing.TB, genesisBytes []byte, chainID ids.ID, parser txs.Parser, assetName string) *txs.Tx { require := require.New(tb) createTx := getCreateTxFromGenesisTest(tb, genesisBytes, assetName) diff --git a/vms/avm/index_test.go b/vms/avm/index_test.go index be21fa60023a..3a70b4a62948 100644 --- a/vms/avm/index_test.go +++ b/vms/avm/index_test.go @@ -52,7 +52,7 @@ func TestIndexTransaction_Ordered(t *testing.T) { env.vm.state.AddUTXO(utxo) // make transaction - tx := buildTX(utxoID, txAssetID, addr) + tx := buildTX(env.vm.ctx.XChainID, utxoID, txAssetID, addr) require.NoError(tx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) env.vm.ctx.Lock.Unlock() @@ -96,7 +96,7 @@ func TestIndexTransaction_MultipleTransactions(t *testing.T) { env.vm.state.AddUTXO(utxo) // make transaction - tx := buildTX(utxoID, txAssetID, addr) + tx := buildTX(env.vm.ctx.XChainID, utxoID, txAssetID, addr) require.NoError(tx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) env.vm.ctx.Lock.Unlock() @@ -149,7 +149,7 @@ func TestIndexTransaction_MultipleAddresses(t *testing.T) { env.vm.state.AddUTXO(utxo) // make transaction - tx := buildTX(utxoID, txAssetID, addrs...) + tx := buildTX(env.vm.ctx.XChainID, utxoID, txAssetID, addrs...) require.NoError(tx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) env.vm.ctx.Lock.Unlock() @@ -268,7 +268,7 @@ func buildUTXO(utxoID avax.UTXOID, txAssetID avax.Asset, addr ids.ShortID) *avax } } -func buildTX(utxoID avax.UTXOID, txAssetID avax.Asset, address ...ids.ShortID) *txs.Tx { +func buildTX(chainID ids.ID, utxoID avax.UTXOID, txAssetID avax.Asset, address ...ids.ShortID) *txs.Tx { return &txs.Tx{Unsigned: &txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 2241621a389d..6984d1640a53 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -64,7 +64,7 @@ func TestServiceIssueTx(t *testing.T) { err := env.service.IssueTx(nil, txArgs, txReply) require.ErrorIs(err, codec.ErrCantUnpackVersion) - tx := newTx(t, env.genesisBytes, env.vm.parser, "AVAX") + tx := newTx(t, env.genesisBytes, env.vm.ctx.ChainID, env.vm.parser, "AVAX") txArgs.Tx, err = formatting.Encode(formatting.Hex, tx.Bytes()) require.NoError(err) txArgs.Encoding = formatting.Hex @@ -90,7 +90,7 @@ func TestServiceGetTxStatus(t *testing.T) { err := env.service.GetTxStatus(nil, statusArgs, statusReply) require.ErrorIs(err, errNilTxID) - newTx := newAvaxBaseTxWithOutputs(t, env.genesisBytes, env.vm.TxFee, env.vm.parser) + newTx := newAvaxBaseTxWithOutputs(t, env.genesisBytes, env.vm.ctx.ChainID, env.vm.TxFee, env.vm.parser) txID := newTx.ID() statusArgs = &api.JSONTxID{ @@ -543,7 +543,7 @@ func TestServiceGetTxJSON_BaseTx(t *testing.T) { env.vm.ctx.Lock.Unlock() }() - newTx := newAvaxBaseTxWithOutputs(t, env.genesisBytes, env.vm.TxFee, env.vm.parser) + newTx := newAvaxBaseTxWithOutputs(t, env.genesisBytes, env.vm.ctx.ChainID, env.vm.TxFee, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, newTx) reply := api.GetTxReply{} @@ -626,7 +626,7 @@ func TestServiceGetTxJSON_ExportTx(t *testing.T) { env.vm.ctx.Lock.Unlock() }() - newTx := newAvaxExportTxWithOutputs(t, env.genesisBytes, env.vm.TxFee, env.vm.parser) + newTx := newAvaxExportTxWithOutputs(t, env.genesisBytes, env.vm.ctx.ChainID, env.vm.TxFee, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, newTx) reply := api.GetTxReply{} @@ -716,7 +716,7 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) { env.vm.ctx.Lock.Unlock() }() - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.ctx.ChainID, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) reply := api.GetTxReply{} @@ -833,10 +833,10 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.ctx.ChainID, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) - mintNFTTx := buildOperationTxWithOp(buildNFTxMintOp(createAssetTx, key, 2, 1)) + mintNFTTx := buildOperationTxWithOp(env.vm.ctx.ChainID, buildNFTxMintOp(createAssetTx, key, 2, 1)) require.NoError(mintNFTTx.SignNFTFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) issueAndAccept(require, env.vm, env.issuer, mintNFTTx) @@ -932,12 +932,12 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.ctx.ChainID, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) mintOp1 := buildNFTxMintOp(createAssetTx, key, 2, 1) mintOp2 := buildNFTxMintOp(createAssetTx, key, 3, 2) - mintNFTTx := buildOperationTxWithOp(mintOp1, mintOp2) + mintNFTTx := buildOperationTxWithOp(env.vm.ctx.ChainID, mintOp1, mintOp2) require.NoError(mintNFTTx.SignNFTFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}, {key}})) issueAndAccept(require, env.vm, env.issuer, mintNFTTx) @@ -1070,10 +1070,10 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.ctx.ChainID, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) - mintSecpOpTx := buildOperationTxWithOp(buildSecpMintOp(createAssetTx, key, 0)) + mintSecpOpTx := buildOperationTxWithOp(env.vm.ctx.ChainID, buildSecpMintOp(createAssetTx, key, 0)) require.NoError(mintSecpOpTx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) issueAndAccept(require, env.vm, env.issuer, mintSecpOpTx) @@ -1173,12 +1173,12 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.ctx.ChainID, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) op1 := buildSecpMintOp(createAssetTx, key, 0) op2 := buildSecpMintOp(createAssetTx, key, 1) - mintSecpOpTx := buildOperationTxWithOp(op1, op2) + mintSecpOpTx := buildOperationTxWithOp(env.vm.ctx.ChainID, op1, op2) require.NoError(mintSecpOpTx.SignSECP256K1Fx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}, {key}})) issueAndAccept(require, env.vm, env.issuer, mintSecpOpTx) @@ -1319,10 +1319,10 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) { }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.ctx.ChainID, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) - mintPropertyFxOpTx := buildOperationTxWithOp(buildPropertyFxMintOp(createAssetTx, key, 4)) + mintPropertyFxOpTx := buildOperationTxWithOp(env.vm.ctx.ChainID, buildPropertyFxMintOp(createAssetTx, key, 4)) require.NoError(mintPropertyFxOpTx.SignPropertyFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) issueAndAccept(require, env.vm, env.issuer, mintPropertyFxOpTx) @@ -1419,12 +1419,12 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) }() key := keys[0] - createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.parser) + createAssetTx := newAvaxCreateAssetTxWithOutputs(t, env.vm.ctx.ChainID, env.vm.parser) issueAndAccept(require, env.vm, env.issuer, createAssetTx) op1 := buildPropertyFxMintOp(createAssetTx, key, 4) op2 := buildPropertyFxMintOp(createAssetTx, key, 5) - mintPropertyFxOpTx := buildOperationTxWithOp(op1, op2) + mintPropertyFxOpTx := buildOperationTxWithOp(env.vm.ctx.ChainID, op1, op2) require.NoError(mintPropertyFxOpTx.SignPropertyFx(env.vm.parser.Codec(), [][]*secp256k1.PrivateKey{{key}, {key}})) issueAndAccept(require, env.vm, env.issuer, mintPropertyFxOpTx) @@ -1541,30 +1541,30 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T) require.Equal(expectedReplyTxString, string(replyTxBytes)) } -func newAvaxBaseTxWithOutputs(t *testing.T, genesisBytes []byte, fee uint64, parser txs.Parser) *txs.Tx { +func newAvaxBaseTxWithOutputs(t *testing.T, genesisBytes []byte, chainID ids.ID, fee uint64, parser txs.Parser) *txs.Tx { avaxTx := getCreateTxFromGenesisTest(t, genesisBytes, "AVAX") key := keys[0] - tx := buildBaseTx(avaxTx, fee, key) + tx := buildBaseTx(avaxTx, chainID, fee, key) require.NoError(t, tx.SignSECP256K1Fx(parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) return tx } -func newAvaxExportTxWithOutputs(t *testing.T, genesisBytes []byte, fee uint64, parser txs.Parser) *txs.Tx { +func newAvaxExportTxWithOutputs(t *testing.T, genesisBytes []byte, chainID ids.ID, fee uint64, parser txs.Parser) *txs.Tx { avaxTx := getCreateTxFromGenesisTest(t, genesisBytes, "AVAX") key := keys[0] - tx := buildExportTx(avaxTx, fee, key) + tx := buildExportTx(avaxTx, chainID, fee, key) require.NoError(t, tx.SignSECP256K1Fx(parser.Codec(), [][]*secp256k1.PrivateKey{{key}})) return tx } -func newAvaxCreateAssetTxWithOutputs(t *testing.T, parser txs.Parser) *txs.Tx { +func newAvaxCreateAssetTxWithOutputs(t *testing.T, chainID ids.ID, parser txs.Parser) *txs.Tx { key := keys[0] - tx := buildCreateAssetTx(key) + tx := buildCreateAssetTx(chainID, key) require.NoError(t, tx.Initialize(parser.Codec())) return tx } -func buildBaseTx(avaxTx *txs.Tx, fee uint64, key *secp256k1.PrivateKey) *txs.Tx { +func buildBaseTx(avaxTx *txs.Tx, chainID ids.ID, fee uint64, key *secp256k1.PrivateKey) *txs.Tx { return &txs.Tx{Unsigned: &txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, @@ -1599,7 +1599,7 @@ func buildBaseTx(avaxTx *txs.Tx, fee uint64, key *secp256k1.PrivateKey) *txs.Tx }} } -func buildExportTx(avaxTx *txs.Tx, fee uint64, key *secp256k1.PrivateKey) *txs.Tx { +func buildExportTx(avaxTx *txs.Tx, chainID ids.ID, fee uint64, key *secp256k1.PrivateKey) *txs.Tx { return &txs.Tx{Unsigned: &txs.ExportTx{ BaseTx: txs.BaseTx{ BaseTx: avax.BaseTx{ @@ -1632,7 +1632,7 @@ func buildExportTx(avaxTx *txs.Tx, fee uint64, key *secp256k1.PrivateKey) *txs.T }} } -func buildCreateAssetTx(key *secp256k1.PrivateKey) *txs.Tx { +func buildCreateAssetTx(chainID ids.ID, key *secp256k1.PrivateKey) *txs.Tx { return &txs.Tx{Unsigned: &txs.CreateAssetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, @@ -1771,7 +1771,7 @@ func buildSecpMintOp(createAssetTx *txs.Tx, key *secp256k1.PrivateKey, outputInd } } -func buildOperationTxWithOp(op ...*txs.Operation) *txs.Tx { +func buildOperationTxWithOp(chainID ids.ID, op ...*txs.Operation) *txs.Tx { return &txs.Tx{Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, diff --git a/vms/avm/state_test.go b/vms/avm/state_test.go index 976ce1c60840..2c0d61559925 100644 --- a/vms/avm/state_test.go +++ b/vms/avm/state_test.go @@ -51,7 +51,7 @@ func TestSetsAndGets(t *testing.T) { tx := &txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Ins: []*avax.TransferableInput{{ UTXOID: avax.UTXOID{ TxID: ids.Empty, diff --git a/vms/avm/txs/executor/semantic_verifier_test.go b/vms/avm/txs/executor/semantic_verifier_test.go index 7c659f7ec227..bda0f9245631 100644 --- a/vms/avm/txs/executor/semantic_verifier_test.go +++ b/vms/avm/txs/executor/semantic_verifier_test.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -30,7 +31,7 @@ import ( ) func TestSemanticVerifierBaseTx(t *testing.T) { - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) typeToFxIndex := make(map[reflect.Type]int) secpFx := &secp256k1fx.Fx{} @@ -387,12 +388,7 @@ func TestSemanticVerifierBaseTx(t *testing.T) { } func TestSemanticVerifierExportTx(t *testing.T) { - ctx := newContext(t) - ctrl := gomock.NewController(t) - - validatorState := validators.NewMockState(ctrl) - validatorState.EXPECT().GetSubnetID(gomock.Any(), ctx.CChainID).AnyTimes().Return(ctx.SubnetID, nil) - ctx.ValidatorState = validatorState + ctx := snowtest.Context(t, snowtest.XChainID) typeToFxIndex := make(map[reflect.Type]int) secpFx := &secp256k1fx.Fx{} @@ -756,7 +752,7 @@ func TestSemanticVerifierExportTxDifferentSubnet(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) validatorState := validators.NewMockState(ctrl) validatorState.EXPECT().GetSubnetID(gomock.Any(), ctx.CChainID).AnyTimes().Return(ids.GenerateTestID(), nil) @@ -873,13 +869,7 @@ func TestSemanticVerifierExportTxDifferentSubnet(t *testing.T) { } func TestSemanticVerifierImportTx(t *testing.T) { - ctrl := gomock.NewController(t) - - ctx := newContext(t) - - validatorState := validators.NewMockState(ctrl) - validatorState.EXPECT().GetSubnetID(gomock.Any(), ctx.CChainID).AnyTimes().Return(ctx.SubnetID, nil) - ctx.ValidatorState = validatorState + ctx := snowtest.Context(t, snowtest.XChainID) m := atomic.NewMemory(prefixdb.New([]byte{0}, memdb.New())) ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) diff --git a/vms/avm/txs/executor/syntactic_verifier_test.go b/vms/avm/txs/executor/syntactic_verifier_test.go index 34f1b27ebbcc..ad5e906a029e 100644 --- a/vms/avm/txs/executor/syntactic_verifier_test.go +++ b/vms/avm/txs/executor/syntactic_verifier_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/avm/config" @@ -32,25 +32,8 @@ var ( } ) -func newContext(t testing.TB) *snow.Context { - require := require.New(t) - - ctx := snow.DefaultContextTest() - ctx.NetworkID = constants.UnitTestID - ctx.ChainID = ids.GenerateTestID() - ctx.XChainID = ctx.ChainID - ctx.CChainID = ids.GenerateTestID() - - aliaser := ctx.BCLookup.(ids.Aliaser) - require.NoError(aliaser.Alias(ctx.XChainID, "X")) - require.NoError(aliaser.Alias(ctx.XChainID, ctx.XChainID.String())) - require.NoError(aliaser.Alias(constants.PlatformChainID, "P")) - require.NoError(aliaser.Alias(constants.PlatformChainID, constants.PlatformChainID.String())) - return ctx -} - func TestSyntacticVerifierBaseTx(t *testing.T) { - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} parser, err := txs.NewParser([]fxs.Fx{ @@ -420,7 +403,7 @@ func TestSyntacticVerifierBaseTx(t *testing.T) { } func TestSyntacticVerifierCreateAssetTx(t *testing.T) { - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} parser, err := txs.NewParser([]fxs.Fx{ @@ -1027,7 +1010,7 @@ func TestSyntacticVerifierCreateAssetTx(t *testing.T) { } func TestSyntacticVerifierOperationTx(t *testing.T) { - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} parser, err := txs.NewParser([]fxs.Fx{ @@ -1514,7 +1497,7 @@ func TestSyntacticVerifierOperationTx(t *testing.T) { } func TestSyntacticVerifierImportTx(t *testing.T) { - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} parser, err := txs.NewParser([]fxs.Fx{ @@ -1912,7 +1895,7 @@ func TestSyntacticVerifierImportTx(t *testing.T) { } func TestSyntacticVerifierExportTx(t *testing.T) { - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} parser, err := txs.NewParser([]fxs.Fx{ diff --git a/vms/avm/vm_benchmark_test.go b/vms/avm/vm_benchmark_test.go index ba6ca3cef957..cec505f3c2ff 100644 --- a/vms/avm/vm_benchmark_test.go +++ b/vms/avm/vm_benchmark_test.go @@ -82,7 +82,7 @@ func GetAllUTXOsBenchmark(b *testing.B, utxoCount int) { TxID: ids.GenerateTestID(), OutputIndex: rand.Uint32(), }, - Asset: avax.Asset{ID: ids.ID{'y', 'e', 'e', 't'}}, + Asset: avax.Asset{ID: env.vm.ctx.AVAXAssetID}, Out: &secp256k1fx.TransferOutput{ Amt: 100000, OutputOwners: secp256k1fx.OutputOwners{ diff --git a/vms/avm/vm_regression_test.go b/vms/avm/vm_regression_test.go index 829aa1966d71..0e41c55ef92a 100644 --- a/vms/avm/vm_regression_test.go +++ b/vms/avm/vm_regression_test.go @@ -36,7 +36,7 @@ func TestVerifyFxUsage(t *testing.T) { createAssetTx := &txs.Tx{Unsigned: &txs.CreateAssetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, }}, Name: "Team Rocket", Symbol: "TR", @@ -74,7 +74,7 @@ func TestVerifyFxUsage(t *testing.T) { mintNFTTx := &txs.Tx{Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, }}, Ops: []*txs.Operation{{ Asset: avax.Asset{ID: createAssetTx.ID()}, @@ -97,7 +97,7 @@ func TestVerifyFxUsage(t *testing.T) { spendTx := &txs.Tx{Unsigned: &txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Ins: []*avax.TransferableInput{{ UTXOID: avax.UTXOID{ TxID: createAssetTx.ID(), diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index 1ee15fc5698a..ae4a2f0c0af0 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/avm/config" @@ -32,7 +33,7 @@ func TestInvalidGenesis(t *testing.T) { require := require.New(t) vm := &VM{} - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -57,7 +58,7 @@ func TestInvalidFx(t *testing.T) { require := require.New(t) vm := &VM{} - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -85,7 +86,7 @@ func TestFxInitializationFailure(t *testing.T) { require := require.New(t) vm := &VM{} - ctx := newContext(t) + ctx := snowtest.Context(t, snowtest.XChainID) ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -125,7 +126,7 @@ func TestIssueTx(t *testing.T) { env.vm.ctx.Lock.Unlock() }() - tx := newTx(t, env.genesisBytes, env.vm.parser, "AVAX") + tx := newTx(t, env.genesisBytes, env.vm.ctx.ChainID, env.vm.parser, "AVAX") issueAndAccept(require, env.vm, env.issuer, tx) } @@ -146,7 +147,7 @@ func TestIssueNFT(t *testing.T) { createAssetTx := &txs.Tx{Unsigned: &txs.CreateAssetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, }}, Name: "Team Rocket", Symbol: "TR", @@ -177,7 +178,7 @@ func TestIssueNFT(t *testing.T) { mintNFTTx := &txs.Tx{Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, }}, Ops: []*txs.Operation{{ Asset: avax.Asset{ID: createAssetTx.ID()}, @@ -202,7 +203,7 @@ func TestIssueNFT(t *testing.T) { Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, }}, Ops: []*txs.Operation{{ Asset: avax.Asset{ID: createAssetTx.ID()}, @@ -251,7 +252,7 @@ func TestIssueProperty(t *testing.T) { createAssetTx := &txs.Tx{Unsigned: &txs.CreateAssetTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, }}, Name: "Team Rocket", Symbol: "TR", @@ -274,7 +275,7 @@ func TestIssueProperty(t *testing.T) { mintPropertyTx := &txs.Tx{Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, }}, Ops: []*txs.Operation{{ Asset: avax.Asset{ID: createAssetTx.ID()}, @@ -306,7 +307,7 @@ func TestIssueProperty(t *testing.T) { burnPropertyTx := &txs.Tx{Unsigned: &txs.OperationTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, }}, Ops: []*txs.Operation{{ Asset: avax.Asset{ID: createAssetTx.ID()}, @@ -338,7 +339,7 @@ func TestIssueTxWithFeeAsset(t *testing.T) { }() // send first asset - tx := newTx(t, env.genesisBytes, env.vm.parser, feeAssetName) + tx := newTx(t, env.genesisBytes, env.vm.ctx.ChainID, env.vm.parser, feeAssetName) issueAndAccept(require, env.vm, env.issuer, tx) } @@ -362,7 +363,7 @@ func TestIssueTxWithAnotherAsset(t *testing.T) { tx := &txs.Tx{Unsigned: &txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Ins: []*avax.TransferableInput{ // fee asset { @@ -445,7 +446,7 @@ func TestTxAcceptAfterParseTx(t *testing.T) { firstTx := &txs.Tx{Unsigned: &txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Ins: []*avax.TransferableInput{{ UTXOID: avax.UTXOID{ TxID: env.genesisTx.ID(), @@ -478,7 +479,7 @@ func TestTxAcceptAfterParseTx(t *testing.T) { secondTx := &txs.Tx{Unsigned: &txs.BaseTx{ BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Ins: []*avax.TransferableInput{{ UTXOID: avax.UTXOID{ TxID: firstTx.ID(), @@ -548,7 +549,7 @@ func TestIssueImportTx(t *testing.T) { tx := &txs.Tx{Unsigned: &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Outs: []*avax.TransferableOutput{{ Asset: txAssetID, Out: &secp256k1fx.TransferOutput{ @@ -647,7 +648,7 @@ func TestForceAcceptImportTx(t *testing.T) { tx := &txs.Tx{Unsigned: &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Outs: []*avax.TransferableOutput{{ Asset: txAssetID, Out: &secp256k1fx.TransferOutput{ @@ -712,7 +713,7 @@ func TestIssueExportTx(t *testing.T) { tx := &txs.Tx{Unsigned: &txs.ExportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Ins: []*avax.TransferableInput{{ UTXOID: avax.UTXOID{ TxID: avaxID, @@ -788,7 +789,7 @@ func TestClearForceAcceptedExportTx(t *testing.T) { tx := &txs.Tx{Unsigned: &txs.ExportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: constants.UnitTestID, - BlockchainID: chainID, + BlockchainID: env.vm.ctx.XChainID, Ins: []*avax.TransferableInput{{ UTXOID: avax.UTXOID{ TxID: avaxID, From c15d1a9c91b204eb875b1fd3614c3cc73a01965c Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 21 Dec 2023 16:18:51 -0500 Subject: [PATCH 181/267] Do not fail-fast in Tests / Unit (#2530) --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f81c05786ef9..a9e0501d677f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,7 @@ jobs: Unit: runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [macos-12, ubuntu-20.04, ubuntu-22.04, windows-2022, [self-hosted, linux, ARM64, focal], [self-hosted, linux, ARM64, jammy]] steps: From 35907e012fdc038e46d71f79b0631a831625bb2d Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:34:39 -0500 Subject: [PATCH 182/267] Make P-Chain Mempool thread-safe (#2523) --- vms/platformvm/block/builder/builder.go | 2 +- vms/platformvm/block/builder/builder_test.go | 60 +++++----- vms/platformvm/block/executor/verifier.go | 6 +- vms/platformvm/network/network.go | 2 +- vms/platformvm/network/network_test.go | 18 +-- vms/platformvm/service.go | 2 +- vms/platformvm/txs/mempool/mempool.go | 117 +++++++++++-------- vms/platformvm/txs/mempool/mempool_test.go | 38 +++--- vms/platformvm/txs/mempool/mock_mempool.go | 31 ++--- 9 files changed, 150 insertions(+), 126 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index fc272453aba5..93716733ac09 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -341,7 +341,7 @@ func packBlockTxs( if txSize > remainingSize { break } - mempool.Remove([]*txs.Tx{tx}) + mempool.Remove(tx) // Invariant: [tx] has already been syntactically verified. diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 1de7f77af15e..51062fa3cdb7 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -53,7 +53,8 @@ func TestBuildBlockBasic(t *testing.T) { // Issue the transaction require.NoError(env.network.IssueTx(context.Background(), tx)) - require.True(env.mempool.Has(txID)) + _, ok := env.mempool.Get(txID) + require.True(ok) // [BuildBlock] should build a block with the transaction blkIntf, err := env.Builder.BuildBlock(context.Background()) @@ -65,7 +66,8 @@ func TestBuildBlockBasic(t *testing.T) { require.Equal(txID, blk.Txs()[0].ID()) // Mempool should not contain the transaction or have marked it as dropped - require.False(env.mempool.Has(txID)) + _, ok = env.mempool.Get(txID) + require.False(ok) require.NoError(env.mempool.GetDropReason(txID)) } @@ -124,7 +126,8 @@ func TestBuildBlockShouldReward(t *testing.T) { // Issue the transaction require.NoError(env.network.IssueTx(context.Background(), tx)) - require.True(env.mempool.Has(txID)) + _, ok := env.mempool.Get(txID) + require.True(ok) // Build and accept a block with the tx blk, err := env.Builder.BuildBlock(context.Background()) @@ -247,7 +250,8 @@ func TestBuildBlockForceAdvanceTime(t *testing.T) { // Issue the transaction require.NoError(env.network.IssueTx(context.Background(), tx)) - require.True(env.mempool.Has(txID)) + _, ok := env.mempool.Get(txID) + require.True(ok) var ( now = env.backend.Clk.Time() @@ -312,7 +316,8 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { require.NoError(err) require.NoError(env.mempool.Add(tx1)) tx1ID := tx1.ID() - require.True(env.mempool.Has(tx1ID)) + _, ok := env.mempool.Get(tx1ID) + require.True(ok) // Add a validator with StartTime before current chain time validator2StartTime := now.Add(-5 * time.Second) @@ -331,7 +336,8 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { require.NoError(err) require.NoError(env.mempool.Add(tx2)) tx2ID := tx2.ID() - require.True(env.mempool.Has(tx2ID)) + _, ok = env.mempool.Get(tx2ID) + require.True(ok) // Add a validator with StartTime in the future past [MaxFutureStartTime] validator3StartTime := now.Add(txexecutor.MaxFutureStartTime + 5*time.Second) @@ -350,7 +356,8 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { require.NoError(err) require.NoError(env.mempool.Add(tx3)) tx3ID := tx3.ID() - require.True(env.mempool.Has(tx3ID)) + _, ok = env.mempool.Get(tx3ID) + require.True(ok) // Only tx1 should be in a built block blkIntf, err := env.Builder.BuildBlock(context.Background()) @@ -362,9 +369,12 @@ func TestBuildBlockDropExpiredStakerTxs(t *testing.T) { require.Equal(tx1ID, blk.Txs()[0].ID()) // Mempool should have none of the txs - require.False(env.mempool.Has(tx1ID)) - require.False(env.mempool.Has(tx2ID)) - require.False(env.mempool.Has(tx3ID)) + _, ok = env.mempool.Get(tx1ID) + require.False(ok) + _, ok = env.mempool.Get(tx2ID) + require.False(ok) + _, ok = env.mempool.Get(tx3ID) + require.False(ok) // Only tx2 and tx3 should be dropped require.NoError(env.mempool.GetDropReason(tx1ID)) @@ -411,7 +421,8 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { require.NoError(err) require.NoError(env.mempool.Add(tx1)) tx1ID := tx1.ID() - require.True(env.mempool.Has(tx1ID)) + _, ok := env.mempool.Get(tx1ID) + require.True(ok) // Add a validator ending past [MaxStakeDuration] validator2EndTime := now.Add(env.config.MaxStakeDuration + time.Second) @@ -429,7 +440,8 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { require.NoError(err) require.NoError(env.mempool.Add(tx2)) tx2ID := tx2.ID() - require.True(env.mempool.Has(tx2ID)) + _, ok = env.mempool.Get(tx2ID) + require.True(ok) // Only tx1 should be in a built block since [MaxStakeDuration] is satisfied. blkIntf, err := env.Builder.BuildBlock(context.Background()) @@ -441,8 +453,10 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { require.Equal(tx1ID, blk.Txs()[0].ID()) // Mempool should have none of the txs - require.False(env.mempool.Has(tx1ID)) - require.False(env.mempool.Has(tx2ID)) + _, ok = env.mempool.Get(tx1ID) + require.False(ok) + _, ok = env.mempool.Get(tx2ID) + require.False(ok) // Only tx2 should be dropped require.NoError(env.mempool.GetDropReason(tx1ID)) @@ -474,11 +488,8 @@ func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { require.NoError(err) txID := tx.ID() - // Issue the transaction - require.NoError(env.network.IssueTx(context.Background(), tx)) - require.True(env.mempool.Has(txID)) - - // Transaction should not be marked as dropped when added to the mempool + // Transaction should not be marked as dropped before being added to the + // mempool reason := env.mempool.GetDropReason(txID) require.NoError(reason) @@ -488,15 +499,10 @@ func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { reason = env.mempool.GetDropReason(txID) require.ErrorIs(reason, errTestingDropped) - // Dropped transactions should still be in the mempool - require.True(env.mempool.Has(txID)) - - // Remove the transaction from the mempool - env.mempool.Remove([]*txs.Tx{tx}) - - // Issue the transaction again + // Issue the transaction require.NoError(env.network.IssueTx(context.Background(), tx)) - require.True(env.mempool.Has(txID)) + _, ok := env.mempool.Get(txID) + require.True(ok) // When issued again, the mempool should not be marked as dropped reason = env.mempool.GetDropReason(txID) diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 37129f8cc03a..f16816d81db7 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -223,7 +223,7 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { return err } - v.Mempool.Remove([]*txs.Tx{b.Tx}) + v.Mempool.Remove(b.Tx) blkID := b.ID() v.blkIDToState[blkID] = &blockState{ @@ -393,7 +393,7 @@ func (v *verifier) proposalBlock( onCommitState.AddTx(b.Tx, status.Committed) onAbortState.AddTx(b.Tx, status.Aborted) - v.Mempool.Remove([]*txs.Tx{b.Tx}) + v.Mempool.Remove(b.Tx) blkID := b.ID() v.blkIDToState[blkID] = &blockState{ @@ -428,7 +428,7 @@ func (v *verifier) standardBlock( return err } - v.Mempool.Remove(b.Transactions) + v.Mempool.Remove(b.Transactions...) blkID := b.ID() v.blkIDToState[blkID] = &blockState{ diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index 4600cce7f581..971ba8aa28f0 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -149,7 +149,7 @@ func (n *network) IssueTx(ctx context.Context, tx *txs.Tx) error { // returns nil if the tx is in the mempool func (n *network) issueTx(tx *txs.Tx) error { txID := tx.ID() - if n.mempool.Has(txID) { + if _, ok := n.mempool.Get(txID); ok { // The tx is already in the mempool return nil } diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go index 000cbda7e195..1dcdbfdb572d 100644 --- a/vms/platformvm/network/network_test.go +++ b/vms/platformvm/network/network_test.go @@ -95,7 +95,7 @@ func TestNetworkAppGossip(t *testing.T) { }, mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(true) + mempool.EXPECT().Get(gomock.Any()).Return(testTx, true) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) return mempool }, @@ -170,6 +170,8 @@ func TestNetworkAppGossip(t *testing.T) { } func TestNetworkIssueTx(t *testing.T) { + tx := &txs.Tx{} + type test struct { name string mempoolFunc func(*gomock.Controller) mempool.Mempool @@ -184,7 +186,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "mempool has transaction", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(true) + mempool.EXPECT().Get(gomock.Any()).Return(tx, true) return mempool }, managerFunc: func(ctrl *gomock.Controller) executor.Manager { @@ -203,7 +205,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "transaction marked as dropped in mempool", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, @@ -222,7 +224,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "transaction invalid", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, @@ -241,7 +243,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "can't add transaction to mempool", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().Add(gomock.Any()).Return(errTest) mempool.EXPECT().MarkDropped(gomock.Any(), errTest) return mempool @@ -261,7 +263,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "AppGossip tx but do not add to mempool if primary network is not being fully synced", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) return mempool }, managerFunc: func(ctrl *gomock.Controller) executor.Manager { @@ -282,7 +284,7 @@ func TestNetworkIssueTx(t *testing.T) { name: "happy path", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Has(gomock.Any()).Return(false) + mempool.EXPECT().Get(gomock.Any()).Return(tx, false) mempool.EXPECT().Add(gomock.Any()).Return(nil) mempool.EXPECT().RequestBuildBlock(false) return mempool @@ -316,7 +318,7 @@ func TestNetworkIssueTx(t *testing.T) { tt.partialSyncPrimaryNetwork, tt.appSenderFunc(ctrl), ) - err := n.IssueTx(context.Background(), &txs.Tx{}) + err := n.IssueTx(context.Background(), tx) require.ErrorIs(err, tt.expectedErr) }) } diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index fe9fa66f7b4c..09489dd08209 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -2259,7 +2259,7 @@ func (s *Service) GetTxStatus(_ *http.Request, args *GetTxStatusArgs, response * return err } - if s.vm.Builder.Has(args.TxID) { + if _, ok := s.vm.Builder.Get(args.TxID); ok { // Found the tx in the mempool. Report tx is processing. response.Status = status.Processing return nil diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 7e7aee09520a..45412f4ca9d8 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -6,12 +6,14 @@ package mempool import ( "errors" "fmt" + "sync" "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/avalanchego/cache" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/linkedhashmap" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" @@ -45,13 +47,15 @@ var ( type Mempool interface { Add(tx *txs.Tx) error - Has(txID ids.ID) bool - Get(txID ids.ID) *txs.Tx - Remove(txs []*txs.Tx) + Get(txID ids.ID) (*txs.Tx, bool) + Remove(txs ...*txs.Tx) // Peek returns the oldest tx in the mempool. Peek() (tx *txs.Tx, exists bool) + // Iterate iterates over the txs until f returns false + Iterate(f func(tx *txs.Tx) bool) + // RequestBuildBlock notifies the consensus engine that a block should be // built. If [emptyBlockPermitted] is true, the notification will be sent // regardless of whether there are no transactions in the mempool. If not, @@ -69,19 +73,16 @@ type Mempool interface { // Transactions from clients that have not yet been put into blocks and added to // consensus type mempool struct { - bytesAvailableMetric prometheus.Gauge - bytesAvailable int - - unissuedTxs linkedhashmap.LinkedHashmap[ids.ID, *txs.Tx] - numTxs prometheus.Gauge - - // Key: Tx ID - // Value: Verification error - droppedTxIDs *cache.LRU[ids.ID, error] - - consumedUTXOs set.Set[ids.ID] + lock sync.RWMutex + unissuedTxs linkedhashmap.LinkedHashmap[ids.ID, *txs.Tx] + consumedUTXOs set.Set[ids.ID] + bytesAvailable int + droppedTxIDs *cache.LRU[ids.ID, error] // TxID -> verification error toEngine chan<- common.Message + + numTxs prometheus.Gauge + bytesAvailableMetric prometheus.Gauge } func New( @@ -89,39 +90,36 @@ func New( registerer prometheus.Registerer, toEngine chan<- common.Message, ) (Mempool, error) { - bytesAvailableMetric := prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "bytes_available", - Help: "Number of bytes of space currently available in the mempool", - }) - if err := registerer.Register(bytesAvailableMetric); err != nil { - return nil, err - } - - numTxs := prometheus.NewGauge(prometheus.GaugeOpts{ - Namespace: namespace, - Name: "txs", - Help: "Number of decision/staker transactions in the mempool", - }) - if err := registerer.Register(numTxs); err != nil { - return nil, err + m := &mempool{ + unissuedTxs: linkedhashmap.New[ids.ID, *txs.Tx](), + consumedUTXOs: set.NewSet[ids.ID](initialConsumedUTXOsSize), + bytesAvailable: maxMempoolSize, + droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, + toEngine: toEngine, + numTxs: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "txs", + Help: "Number of decision/staker transactions in the mempool", + }), + bytesAvailableMetric: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "bytes_available", + Help: "Number of bytes of space currently available in the mempool", + }), } + m.bytesAvailableMetric.Set(maxMempoolSize) - bytesAvailableMetric.Set(maxMempoolSize) - return &mempool{ - bytesAvailableMetric: bytesAvailableMetric, - bytesAvailable: maxMempoolSize, - - unissuedTxs: linkedhashmap.New[ids.ID, *txs.Tx](), - numTxs: numTxs, - - droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, - consumedUTXOs: set.NewSet[ids.ID](initialConsumedUTXOsSize), - toEngine: toEngine, - }, nil + err := utils.Err( + registerer.Register(m.numTxs), + registerer.Register(m.bytesAvailableMetric), + ) + return m, err } func (m *mempool) Add(tx *txs.Tx) error { + m.lock.Lock() + defer m.lock.Unlock() + switch tx.Unsigned.(type) { case *txs.AdvanceTimeTx: return errCantIssueAdvanceTimeTx @@ -132,7 +130,7 @@ func (m *mempool) Add(tx *txs.Tx) error { // Note: a previously dropped tx can be re-added txID := tx.ID() - if m.Has(txID) { + if _, ok := m.unissuedTxs.Get(txID); ok { return fmt.Errorf("%w: %s", errDuplicateTx, txID) } @@ -173,17 +171,15 @@ func (m *mempool) Add(tx *txs.Tx) error { return nil } -func (m *mempool) Has(txID ids.ID) bool { - return m.Get(txID) != nil +func (m *mempool) Get(txID ids.ID) (*txs.Tx, bool) { + return m.unissuedTxs.Get(txID) } -func (m *mempool) Get(txID ids.ID) *txs.Tx { - tx, _ := m.unissuedTxs.Get(txID) - return tx -} +func (m *mempool) Remove(txs ...*txs.Tx) { + m.lock.Lock() + defer m.lock.Unlock() -func (m *mempool) Remove(txsToRemove []*txs.Tx) { - for _, tx := range txsToRemove { + for _, tx := range txs { txID := tx.ID() if !m.unissuedTxs.Delete(txID) { continue @@ -203,7 +199,26 @@ func (m *mempool) Peek() (*txs.Tx, bool) { return tx, exists } +func (m *mempool) Iterate(f func(tx *txs.Tx) bool) { + m.lock.RLock() + defer m.lock.RUnlock() + + itr := m.unissuedTxs.NewIterator() + for itr.Next() { + if !f(itr.Value()) { + return + } + } +} + func (m *mempool) MarkDropped(txID ids.ID, reason error) { + m.lock.RLock() + defer m.lock.RUnlock() + + if _, ok := m.unissuedTxs.Get(txID); ok { + return + } + m.droppedTxIDs.Put(txID, reason) } diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index 2f6b9782d2fe..5eb3baa9590b 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -60,23 +60,22 @@ func TestDecisionTxsInMempool(t *testing.T) { for _, tx := range decisionTxs { // tx not already there - require.False(mpool.Has(tx.ID())) + _, ok := mpool.Get(tx.ID()) + require.False(ok) // we can insert require.NoError(mpool.Add(tx)) // we can get it - require.True(mpool.Has(tx.ID())) - - retrieved := mpool.Get(tx.ID()) - require.NotNil(retrieved) - require.Equal(tx, retrieved) + got, ok := mpool.Get(tx.ID()) + require.True(ok) + require.Equal(tx, got) // once removed it cannot be there - mpool.Remove([]*txs.Tx{tx}) + mpool.Remove(tx) - require.False(mpool.Has(tx.ID())) - require.Equal((*txs.Tx)(nil), mpool.Get(tx.ID())) + _, ok = mpool.Get(tx.ID()) + require.False(ok) // we can reinsert it again to grow the mempool require.NoError(mpool.Add(tx)) @@ -97,23 +96,22 @@ func TestProposalTxsInMempool(t *testing.T) { require.NoError(err) for _, tx := range proposalTxs { - require.False(mpool.Has(tx.ID())) + _, ok := mpool.Get(tx.ID()) + require.False(ok) // we can insert require.NoError(mpool.Add(tx)) // we can get it - require.True(mpool.Has(tx.ID())) - - retrieved := mpool.Get(tx.ID()) - require.NotNil(retrieved) - require.Equal(tx, retrieved) + got, ok := mpool.Get(tx.ID()) + require.Equal(tx, got) + require.True(ok) // once removed it cannot be there - mpool.Remove([]*txs.Tx{tx}) + mpool.Remove(tx) - require.False(mpool.Has(tx.ID())) - require.Equal((*txs.Tx)(nil), mpool.Get(tx.ID())) + _, ok = mpool.Get(tx.ID()) + require.False(ok) // we can reinsert it again to grow the mempool require.NoError(mpool.Add(tx)) @@ -224,14 +222,14 @@ func TestPeekTxs(t *testing.T) { require.Equal(tx, testDecisionTxs[0]) require.NotEqual(tx, testProposalTxs[0]) - mempool.Remove([]*txs.Tx{testDecisionTxs[0]}) + mempool.Remove(testDecisionTxs[0]) tx, exists = mempool.Peek() require.True(exists) require.NotEqual(tx, testDecisionTxs[0]) require.Equal(tx, testProposalTxs[0]) - mempool.Remove([]*txs.Tx{testProposalTxs[0]}) + mempool.Remove(testProposalTxs[0]) tx, exists = mempool.Peek() require.False(exists) diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index 384959d46694..949d99f1b41d 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -53,11 +53,12 @@ func (mr *MockMempoolMockRecorder) Add(arg0 interface{}) *gomock.Call { } // Get mocks base method. -func (m *MockMempool) Get(arg0 ids.ID) *txs.Tx { +func (m *MockMempool) Get(arg0 ids.ID) (*txs.Tx, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", arg0) ret0, _ := ret[0].(*txs.Tx) - return ret0 + ret1, _ := ret[1].(bool) + return ret0, ret1 } // Get indicates an expected call of Get. @@ -80,18 +81,16 @@ func (mr *MockMempoolMockRecorder) GetDropReason(arg0 interface{}) *gomock.Call return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDropReason", reflect.TypeOf((*MockMempool)(nil).GetDropReason), arg0) } -// Has mocks base method. -func (m *MockMempool) Has(arg0 ids.ID) bool { +// Iterate mocks base method. +func (m *MockMempool) Iterate(arg0 func(*txs.Tx) bool) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Has", arg0) - ret0, _ := ret[0].(bool) - return ret0 + m.ctrl.Call(m, "Iterate", arg0) } -// Has indicates an expected call of Has. -func (mr *MockMempoolMockRecorder) Has(arg0 interface{}) *gomock.Call { +// Iterate indicates an expected call of Iterate. +func (mr *MockMempoolMockRecorder) Iterate(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMempool)(nil).Has), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockMempool)(nil).Iterate), arg0) } // MarkDropped mocks base method. @@ -122,15 +121,19 @@ func (mr *MockMempoolMockRecorder) Peek() *gomock.Call { } // Remove mocks base method. -func (m *MockMempool) Remove(arg0 []*txs.Tx) { +func (m *MockMempool) Remove(arg0 ...*txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Remove", arg0) + varargs := []interface{}{} + for _, a := range arg0 { + varargs = append(varargs, a) + } + m.ctrl.Call(m, "Remove", varargs...) } // Remove indicates an expected call of Remove. -func (mr *MockMempoolMockRecorder) Remove(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Remove(arg0 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockMempool)(nil).Remove), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockMempool)(nil).Remove), arg0...) } // RequestBuildBlock mocks base method. From 3e45123fa22b6080863349e01e7f06462f0a4b6e Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:48:35 -0500 Subject: [PATCH 183/267] `vms/platformvm`: Use `snowtest.Context` helper (#2515) --- vms/platformvm/block/builder/helpers_test.go | 49 ++--------- .../block/builder/standard_block_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 44 ++-------- vms/platformvm/service_test.go | 17 ++-- vms/platformvm/txs/add_delegator_test.go | 8 +- vms/platformvm/txs/add_validator_test.go | 8 +- vms/platformvm/txs/executor/export_test.go | 4 +- vms/platformvm/txs/executor/helpers_test.go | 48 ++--------- vms/platformvm/txs/executor/import_test.go | 4 +- vms/platformvm/validator_set_property_test.go | 7 +- vms/platformvm/vm_regression_test.go | 6 +- vms/platformvm/vm_test.go | 85 +++++-------------- 12 files changed, 77 insertions(+), 205 deletions(-) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 412804425921..d2acee3dc0d4 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -4,8 +4,6 @@ package builder import ( - "context" - "errors" "testing" "time" @@ -24,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils" @@ -69,18 +68,13 @@ var ( defaultMinValidatorStake = 5 * units.MilliAvax defaultBalance = 100 * defaultMinValidatorStake preFundedKeys = secp256k1.TestKeys() - avaxAssetID = ids.ID{'y', 'e', 'e', 't'} defaultTxFee = uint64(100) - xChainID = ids.Empty.Prefix(0) - cChainID = ids.Empty.Prefix(1) testSubnet1 *txs.Tx testSubnet1ControlKeys = preFundedKeys[0:3] // Node IDs of genesis validators. Initialized in init function genesisNodeIDs []ids.NodeID - - errMissing = errors.New("missing") ) func init() { @@ -127,7 +121,14 @@ func newEnvironment(t *testing.T) *environment { res.isBootstrapped.Set(true) res.baseDB = versiondb.New(memdb.New()) - res.ctx, res.msm = defaultCtx(res.baseDB) + atomicDB := prefixdb.New([]byte{1}, res.baseDB) + m := atomic.NewMemory(atomicDB) + + res.ctx = snowtest.Context(t, snowtest.PChainID) + res.msm = &mutableSharedMemory{ + SharedMemory: m.NewSharedMemory(res.ctx.ChainID), + } + res.ctx.SharedMemory = res.msm res.ctx.Lock.Lock() defer res.ctx.Lock.Unlock() @@ -264,38 +265,6 @@ func defaultState( return state } -func defaultCtx(db database.Database) (*snow.Context, *mutableSharedMemory) { - ctx := snow.DefaultContextTest() - ctx.NetworkID = 10 - ctx.XChainID = xChainID - ctx.CChainID = cChainID - ctx.AVAXAssetID = avaxAssetID - - atomicDB := prefixdb.New([]byte{1}, db) - m := atomic.NewMemory(atomicDB) - - msm := &mutableSharedMemory{ - SharedMemory: m.NewSharedMemory(ctx.ChainID), - } - ctx.SharedMemory = msm - - ctx.ValidatorState = &validators.TestState{ - GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) { - subnetID, ok := map[ids.ID]ids.ID{ - constants.PlatformChainID: constants.PrimaryNetworkID, - xChainID: constants.PrimaryNetworkID, - cChainID: constants.PrimaryNetworkID, - }[chainID] - if !ok { - return ids.Empty, errMissing - } - return subnetID, nil - }, - } - - return ctx, msm -} - func defaultConfig() *config.Config { return &config.Config{ Chains: chains.TestManager, diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index 74177e1f88b0..cdfe27d662ad 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -42,7 +42,7 @@ func TestAtomicTxImports(t *testing.T) { peerSharedMemory := m.NewSharedMemory(env.ctx.XChainID) utxo := &avax.UTXO{ UTXOID: utxoID, - Asset: avax.Asset{ID: avaxAssetID}, + Asset: avax.Asset{ID: env.ctx.AVAXAssetID}, Out: &secp256k1fx.TransferOutput{ Amt: amount, OutputOwners: secp256k1fx.OutputOwners{ diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 5221f4a97d15..1d7d58217b15 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -4,8 +4,6 @@ package executor import ( - "context" - "errors" "fmt" "testing" "time" @@ -25,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils" @@ -73,16 +72,12 @@ var ( preFundedKeys = secp256k1.TestKeys() avaxAssetID = ids.ID{'y', 'e', 'e', 't'} defaultTxFee = uint64(100) - xChainID = ids.Empty.Prefix(0) - cChainID = ids.Empty.Prefix(1) genesisBlkID ids.ID testSubnet1 *txs.Tx // Node IDs of genesis validators. Initialized in init function genesisNodeIDs []ids.NodeID - - errMissing = errors.New("missing") ) func init() { @@ -138,7 +133,13 @@ func newEnvironment(t *testing.T, ctrl *gomock.Controller) *environment { res.isBootstrapped.Set(true) res.baseDB = versiondb.New(memdb.New()) - res.ctx = defaultCtx(res.baseDB) + atomicDB := prefixdb.New([]byte{1}, res.baseDB) + m := atomic.NewMemory(atomicDB) + + res.ctx = snowtest.Context(t, snowtest.PChainID) + res.ctx.AVAXAssetID = avaxAssetID + res.ctx.SharedMemory = m.NewSharedMemory(res.ctx.ChainID) + res.fx = defaultFx(res.clk, res.ctx.Log, res.isBootstrapped.Get()) rewardsCalc := reward.NewCalculator(res.config.RewardConfig) @@ -293,35 +294,6 @@ func defaultState( return state } -func defaultCtx(db database.Database) *snow.Context { - ctx := snow.DefaultContextTest() - ctx.NetworkID = 10 - ctx.XChainID = xChainID - ctx.CChainID = cChainID - ctx.AVAXAssetID = avaxAssetID - - atomicDB := prefixdb.New([]byte{1}, db) - m := atomic.NewMemory(atomicDB) - - ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) - - ctx.ValidatorState = &validators.TestState{ - GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) { - subnetID, ok := map[ids.ID]ids.ID{ - constants.PlatformChainID: constants.PrimaryNetworkID, - xChainID: constants.PrimaryNetworkID, - cChainID: constants.PrimaryNetworkID, - }[chainID] - if !ok { - return ids.Empty, errMissing - } - return subnetID, nil - }, - } - - return ctx -} - func defaultConfig() *config.Config { return &config.Config{ Chains: chains.TestManager, diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index d6d96e66df41..28a3e80258ed 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -181,7 +181,7 @@ func TestGetTxStatus(t *testing.T) { m := atomic.NewMemory(prefixdb.New([]byte{}, service.vm.db)) sm := m.NewSharedMemory(service.vm.ctx.ChainID) - peerSharedMemory := m.NewSharedMemory(xChainID) + peerSharedMemory := m.NewSharedMemory(service.vm.ctx.XChainID) // #nosec G404 utxo := &avax.UTXO{ @@ -189,7 +189,7 @@ func TestGetTxStatus(t *testing.T) { TxID: ids.GenerateTestID(), OutputIndex: rand.Uint32(), }, - Asset: avax.Asset{ID: avaxAssetID}, + Asset: avax.Asset{ID: service.vm.ctx.AVAXAssetID}, Out: &secp256k1fx.TransferOutput{ Amt: 1234567, OutputOwners: secp256k1fx.OutputOwners{ @@ -220,7 +220,12 @@ func TestGetTxStatus(t *testing.T) { oldSharedMemory := mutableSharedMemory.SharedMemory mutableSharedMemory.SharedMemory = sm - tx, err := service.vm.txBuilder.NewImportTx(xChainID, ids.ShortEmpty, []*secp256k1.PrivateKey{recipientKey}, ids.ShortEmpty) + tx, err := service.vm.txBuilder.NewImportTx( + service.vm.ctx.XChainID, + ids.ShortEmpty, + []*secp256k1.PrivateKey{recipientKey}, + ids.ShortEmpty, + ) require.NoError(err) mutableSharedMemory.SharedMemory = oldSharedMemory @@ -399,7 +404,7 @@ func TestGetBalance(t *testing.T) { }() // Ensure GetStake is correct for each of the genesis validators - genesis, _ := defaultGenesis(t) + genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) for idx, utxo := range genesis.UTXOs { request := GetBalanceRequest{ Addresses: []string{ @@ -433,7 +438,7 @@ func TestGetStake(t *testing.T) { }() // Ensure GetStake is correct for each of the genesis validators - genesis, _ := defaultGenesis(t) + genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) addrsStrs := []string{} for i, validator := range genesis.Validators { addr := fmt.Sprintf("P-%s", validator.RewardOwner.Addresses[0]) @@ -608,7 +613,7 @@ func TestGetCurrentValidators(t *testing.T) { service.vm.ctx.Lock.Unlock() }() - genesis, _ := defaultGenesis(t) + genesis, _ := defaultGenesis(t, service.vm.ctx.AVAXAssetID) // Call getValidators args := GetCurrentValidatorsArgs{SubnetID: constants.PrimaryNetworkID} diff --git a/vms/platformvm/txs/add_delegator_test.go b/vms/platformvm/txs/add_delegator_test.go index cf053d45baba..1989690bb173 100644 --- a/vms/platformvm/txs/add_delegator_test.go +++ b/vms/platformvm/txs/add_delegator_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -23,8 +23,7 @@ var preFundedKeys = secp256k1.TestKeys() func TestAddDelegatorTxSyntacticVerify(t *testing.T) { require := require.New(t) clk := mockable.Clock{} - ctx := snow.DefaultContextTest() - ctx.AVAXAssetID = ids.GenerateTestID() + ctx := snowtest.Context(t, snowtest.PChainID) signers := [][]*secp256k1.PrivateKey{preFundedKeys} var ( @@ -130,8 +129,7 @@ func TestAddDelegatorTxSyntacticVerify(t *testing.T) { func TestAddDelegatorTxSyntacticVerifyNotAVAX(t *testing.T) { require := require.New(t) clk := mockable.Clock{} - ctx := snow.DefaultContextTest() - ctx.AVAXAssetID = ids.GenerateTestID() + ctx := snowtest.Context(t, snowtest.PChainID) signers := [][]*secp256k1.PrivateKey{preFundedKeys} var ( diff --git a/vms/platformvm/txs/add_validator_test.go b/vms/platformvm/txs/add_validator_test.go index 1076b2da69b2..4046d7c0d984 100644 --- a/vms/platformvm/txs/add_validator_test.go +++ b/vms/platformvm/txs/add_validator_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -22,8 +22,7 @@ import ( func TestAddValidatorTxSyntacticVerify(t *testing.T) { require := require.New(t) clk := mockable.Clock{} - ctx := snow.DefaultContextTest() - ctx.AVAXAssetID = ids.GenerateTestID() + ctx := snowtest.Context(t, snowtest.PChainID) signers := [][]*secp256k1.PrivateKey{preFundedKeys} var ( @@ -146,8 +145,7 @@ func TestAddValidatorTxSyntacticVerify(t *testing.T) { func TestAddValidatorTxSyntacticVerifyNotAVAX(t *testing.T) { require := require.New(t) clk := mockable.Clock{} - ctx := snow.DefaultContextTest() - ctx.AVAXAssetID = ids.GenerateTestID() + ctx := snowtest.Context(t, snowtest.PChainID) signers := [][]*secp256k1.PrivateKey{preFundedKeys} var ( diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index ebc64e1ecd1f..1369a5f8bbf3 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -33,13 +33,13 @@ func TestNewExportTx(t *testing.T) { tests := []test{ { description: "P->X export", - destinationChainID: xChainID, + destinationChainID: env.ctx.XChainID, sourceKeys: []*secp256k1.PrivateKey{sourceKey}, timestamp: defaultValidateStartTime, }, { description: "P->C export", - destinationChainID: cChainID, + destinationChainID: env.ctx.CChainID, sourceKeys: []*secp256k1.PrivateKey{sourceKey}, timestamp: env.config.ApricotPhase5Time, }, diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index 1aced0dcbad5..b72c136b5e54 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -4,8 +4,6 @@ package executor import ( - "context" - "errors" "fmt" "math" "testing" @@ -21,10 +19,10 @@ import ( "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/memdb" - "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils" @@ -64,10 +62,7 @@ var ( defaultMinValidatorStake = 5 * units.MilliAvax defaultBalance = 100 * defaultMinValidatorStake preFundedKeys = secp256k1.TestKeys() - avaxAssetID = ids.ID{'y', 'e', 'e', 't'} defaultTxFee = uint64(100) - xChainID = ids.Empty.Prefix(0) - cChainID = ids.Empty.Prefix(1) lastAcceptedID = ids.GenerateTestID() testSubnet1 *txs.Tx @@ -75,8 +70,6 @@ var ( // Node IDs of genesis validators. Initialized in init function genesisNodeIDs []ids.NodeID - - errMissing = errors.New("missing") ) func init() { @@ -127,7 +120,12 @@ func newEnvironment(t *testing.T, postBanff, postCortina, postDurango bool) *env clk := defaultClock(postBanff || postCortina || postDurango) baseDB := versiondb.New(memdb.New()) - ctx, msm := defaultCtx(baseDB) + ctx := snowtest.Context(t, snowtest.PChainID) + m := atomic.NewMemory(baseDB) + msm := &mutableSharedMemory{ + SharedMemory: m.NewSharedMemory(ctx.ChainID), + } + ctx.SharedMemory = msm fx := defaultFx(clk, ctx.Log, isBootstrapped.Get()) @@ -249,38 +247,6 @@ func defaultState( return state } -func defaultCtx(db database.Database) (*snow.Context, *mutableSharedMemory) { - ctx := snow.DefaultContextTest() - ctx.NetworkID = 10 - ctx.XChainID = xChainID - ctx.CChainID = cChainID - ctx.AVAXAssetID = avaxAssetID - - atomicDB := prefixdb.New([]byte{1}, db) - m := atomic.NewMemory(atomicDB) - - msm := &mutableSharedMemory{ - SharedMemory: m.NewSharedMemory(ctx.ChainID), - } - ctx.SharedMemory = msm - - ctx.ValidatorState = &validators.TestState{ - GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) { - subnetID, ok := map[ids.ID]ids.ID{ - constants.PlatformChainID: constants.PrimaryNetworkID, - xChainID: constants.PrimaryNetworkID, - cChainID: constants.PrimaryNetworkID, - }[chainID] - if !ok { - return ids.Empty, errMissing - } - return subnetID, nil - }, - } - - return ctx, msm -} - func defaultConfig(postBanff, postCortina, postDurango bool) *config.Config { banffTime := mockable.MaxTime if postBanff { diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index e35eda20dbba..4ce779a9165e 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -118,9 +118,9 @@ func TestNewImportTx(t *testing.T) { }, { description: "attempting to import from C-chain", - sourceChainID: cChainID, + sourceChainID: env.ctx.CChainID, sharedMemory: fundedSharedMemory( - cChainID, + env.ctx.CChainID, map[ids.ID]uint64{ env.ctx.AVAXAssetID: env.config.TxFee, }, diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 5eff65b68729..3dfb6e456bb2 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" @@ -733,7 +734,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { atomicDB := prefixdb.New([]byte{1}, baseDB) msgChan := make(chan common.Message, 1) - ctx := defaultContext(t) + ctx := snowtest.Context(t, snowtest.PChainID) m := atomic.NewMemory(atomicDB) ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) @@ -746,7 +747,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { return nil } - genesisBytes, err := buildCustomGenesis() + genesisBytes, err := buildCustomGenesis(ctx.AVAXAssetID) if err != nil { return nil, ids.Empty, err } @@ -804,7 +805,7 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { return vm, testSubnet1.ID(), nil } -func buildCustomGenesis() ([]byte, error) { +func buildCustomGenesis(avaxAssetID ids.ID) ([]byte, error) { genesisUTXOs := make([]api.UTXO, len(keys)) for i, key := range keys { id := key.PublicKey().Address() diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index cfc0b20329ca..03725da3a662 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -23,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" @@ -340,7 +341,6 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { // panic. func TestUnverifiedParentPanicRegression(t *testing.T) { require := require.New(t) - _, genesisBytes := defaultGenesis(t) baseDB := memdb.New() atomicDB := prefixdb.New([]byte{1}, baseDB) @@ -357,13 +357,15 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { DurangoTime: mockable.MaxTime, }} - ctx := defaultContext(t) + ctx := snowtest.Context(t, snowtest.PChainID) ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) ctx.Lock.Unlock() }() + _, genesisBytes := defaultGenesis(t, ctx.AVAXAssetID) + msgChan := make(chan common.Message, 1) require.NoError(vm.Initialize( context.Background(), diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 3c3a017ec396..7d24a352ab78 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -6,7 +6,6 @@ package platformvm import ( "bytes" "context" - "errors" "fmt" "testing" "time" @@ -96,9 +95,6 @@ var ( SupplyCap: 720 * units.MegaAvax, } - // AVAX asset ID in tests - avaxAssetID = ids.ID{'y', 'e', 'e', 't'} - defaultTxFee = uint64(100) // chain timestamp at genesis @@ -127,11 +123,6 @@ var ( // Its threshold is 2 testSubnet1 *txs.Tx testSubnet1ControlKeys = keys[0:3] - - xChainID = ids.Empty.Prefix(0) - cChainID = ids.Empty.Prefix(1) - - errMissing = errors.New("missing") ) func init() { @@ -149,45 +140,10 @@ type mutableSharedMemory struct { atomic.SharedMemory } -func defaultContext(t *testing.T) *snow.Context { - require := require.New(t) - - ctx := snow.DefaultContextTest() - ctx.NetworkID = constants.UnitTestID - ctx.XChainID = xChainID - ctx.CChainID = cChainID - ctx.AVAXAssetID = avaxAssetID - aliaser := ids.NewAliaser() - - require.NoError(aliaser.Alias(constants.PlatformChainID, "P")) - require.NoError(aliaser.Alias(constants.PlatformChainID, constants.PlatformChainID.String())) - require.NoError(aliaser.Alias(xChainID, "X")) - require.NoError(aliaser.Alias(xChainID, xChainID.String())) - require.NoError(aliaser.Alias(cChainID, "C")) - require.NoError(aliaser.Alias(cChainID, cChainID.String())) - - ctx.BCLookup = aliaser - - ctx.ValidatorState = &validators.TestState{ - GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) { - subnetID, ok := map[ids.ID]ids.ID{ - constants.PlatformChainID: constants.PrimaryNetworkID, - xChainID: constants.PrimaryNetworkID, - cChainID: constants.PrimaryNetworkID, - }[chainID] - if !ok { - return ids.Empty, errMissing - } - return subnetID, nil - }, - } - return ctx -} - // Returns: // 1) The genesis state // 2) The byte representation of the default genesis for tests -func defaultGenesis(t *testing.T) (*api.BuildGenesisArgs, []byte) { +func defaultGenesis(t *testing.T, avaxAssetID ids.ID) (*api.BuildGenesisArgs, []byte) { require := require.New(t) genesisUTXOs := make([]api.UTXO, len(keys)) @@ -304,7 +260,7 @@ func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableS vm.clock.Set(latestForkTime) msgChan := make(chan common.Message, 1) - ctx := defaultContext(t) + ctx := snowtest.Context(t, snowtest.PChainID) m := atomic.NewMemory(atomicDB) msm := &mutableSharedMemory{ @@ -314,7 +270,7 @@ func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableS ctx.Lock.Lock() defer ctx.Lock.Unlock() - _, genesisBytes := defaultGenesis(t) + _, genesisBytes := defaultGenesis(t, ctx.AVAXAssetID) appSender := &common.SenderTest{} appSender.CantSendAppGossip = true appSender.SendAppGossipF = func(context.Context, []byte) error { @@ -378,7 +334,7 @@ func TestGenesis(t *testing.T) { require.NoError(err) require.Equal(choices.Accepted, genesisBlock.Status()) - genesisState, _ := defaultGenesis(t) + genesisState, _ := defaultGenesis(t, vm.ctx.AVAXAssetID) // Ensure all the genesis UTXOs are there for _, utxo := range genesisState.UTXOs { _, addrBytes, err := address.ParseBech32(utxo.Address) @@ -1030,7 +986,7 @@ func TestAtomicImport(t *testing.T) { utxo := &avax.UTXO{ UTXOID: utxoID, - Asset: avax.Asset{ID: avaxAssetID}, + Asset: avax.Asset{ID: vm.ctx.AVAXAssetID}, Out: &secp256k1fx.TransferOutput{ Amt: amount, OutputOwners: secp256k1fx.OutputOwners{ @@ -1146,7 +1102,6 @@ func TestOptimisticAtomicImport(t *testing.T) { // test restarting the node func TestRestartFullyAccepted(t *testing.T) { require := require.New(t) - _, genesisBytes := defaultGenesis(t) db := memdb.New() firstDB := prefixdb.New([]byte{}, db) @@ -1162,7 +1117,9 @@ func TestRestartFullyAccepted(t *testing.T) { DurangoTime: latestForkTime, }} - firstCtx := defaultContext(t) + firstCtx := snowtest.Context(t, snowtest.PChainID) + + _, genesisBytes := defaultGenesis(t, firstCtx.AVAXAssetID) baseDB := memdb.New() atomicDB := prefixdb.New([]byte{1}, baseDB) @@ -1247,7 +1204,7 @@ func TestRestartFullyAccepted(t *testing.T) { DurangoTime: latestForkTime, }} - secondCtx := defaultContext(t) + secondCtx := snowtest.Context(t, snowtest.PChainID) secondCtx.SharedMemory = firstCtx.SharedMemory secondVM.clock.Set(initialClkTime) secondCtx.Lock.Lock() @@ -1279,8 +1236,6 @@ func TestRestartFullyAccepted(t *testing.T) { func TestBootstrapPartiallyAccepted(t *testing.T) { require := require.New(t) - _, genesisBytes := defaultGenesis(t) - baseDB := memdb.New() vmDB := prefixdb.New([]byte("vm"), baseDB) bootstrappingDB := prefixdb.New([]byte("bootstrapping"), baseDB) @@ -1301,7 +1256,9 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { initialClkTime := latestForkTime.Add(time.Second) vm.clock.Set(initialClkTime) - ctx := defaultContext(t) + ctx := snowtest.Context(t, snowtest.PChainID) + + _, genesisBytes := defaultGenesis(t, ctx.AVAXAssetID) atomicDB := prefixdb.New([]byte{1}, baseDB) m := atomic.NewMemory(atomicDB) @@ -1626,7 +1583,6 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { func TestUnverifiedParent(t *testing.T) { require := require.New(t) - _, genesisBytes := defaultGenesis(t) vm := &VM{Config: config.Config{ Chains: chains.TestManager, @@ -1642,13 +1598,15 @@ func TestUnverifiedParent(t *testing.T) { initialClkTime := latestForkTime.Add(time.Second) vm.clock.Set(initialClkTime) - ctx := defaultContext(t) + ctx := snowtest.Context(t, snowtest.PChainID) ctx.Lock.Lock() defer func() { require.NoError(vm.Shutdown(context.Background())) ctx.Lock.Unlock() }() + _, genesisBytes := defaultGenesis(t, ctx.AVAXAssetID) + msgChan := make(chan common.Message, 1) require.NoError(vm.Initialize( context.Background(), @@ -1786,7 +1744,6 @@ func TestMaxStakeAmount(t *testing.T) { func TestUptimeDisallowedWithRestart(t *testing.T) { require := require.New(t) latestForkTime = defaultValidateStartTime.Add(defaultMinStakingDuration) - _, genesisBytes := defaultGenesis(t) db := memdb.New() firstDB := prefixdb.New([]byte{}, db) @@ -1802,9 +1759,11 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { DurangoTime: latestForkTime, }} - firstCtx := defaultContext(t) + firstCtx := snowtest.Context(t, snowtest.PChainID) firstCtx.Lock.Lock() + _, genesisBytes := defaultGenesis(t, firstCtx.AVAXAssetID) + firstMsgChan := make(chan common.Message, 1) require.NoError(firstVM.Initialize( context.Background(), @@ -1848,7 +1807,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { DurangoTime: latestForkTime, }} - secondCtx := defaultContext(t) + secondCtx := snowtest.Context(t, snowtest.PChainID) secondCtx.Lock.Lock() defer func() { require.NoError(secondVM.Shutdown(context.Background())) @@ -1933,7 +1892,7 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { require := require.New(t) latestForkTime = defaultValidateStartTime.Add(defaultMinStakingDuration) - _, genesisBytes := defaultGenesis(t) + db := memdb.New() vm := &VM{Config: config.Config{ @@ -1947,9 +1906,11 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { DurangoTime: latestForkTime, }} - ctx := defaultContext(t) + ctx := snowtest.Context(t, snowtest.PChainID) ctx.Lock.Lock() + _, genesisBytes := defaultGenesis(t, ctx.AVAXAssetID) + atomicDB := prefixdb.New([]byte{1}, db) m := atomic.NewMemory(atomicDB) ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) From 9a637767f3937f5d7c70e865b861db99164aaeb3 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 21 Dec 2023 16:55:40 -0500 Subject: [PATCH 184/267] Export mempool errors (#2531) --- vms/avm/txs/mempool/mempool.go | 16 ++++++++-------- vms/avm/txs/mempool/mempool_test.go | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index 254313322f9b..b4b05a72d2a3 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -35,10 +35,10 @@ const ( var ( _ Mempool = (*mempool)(nil) - errDuplicateTx = errors.New("duplicate tx") - errTxTooLarge = errors.New("tx too large") - errMempoolFull = errors.New("mempool is full") - errConflictsWithOtherTx = errors.New("tx conflicts with other tx") + ErrDuplicateTx = errors.New("duplicate tx") + ErrTxTooLarge = errors.New("tx too large") + ErrMempoolFull = errors.New("mempool is full") + ErrConflictsWithOtherTx = errors.New("tx conflicts with other tx") ) // Mempool contains transactions that have not yet been put into a block. @@ -114,13 +114,13 @@ func (m *mempool) Add(tx *txs.Tx) error { defer m.lock.Unlock() if _, ok := m.unissuedTxs.Get(txID); ok { - return fmt.Errorf("%w: %s", errDuplicateTx, txID) + return fmt.Errorf("%w: %s", ErrDuplicateTx, txID) } txSize := len(tx.Bytes()) if txSize > MaxTxSize { return fmt.Errorf("%w: %s size (%d) > max size (%d)", - errTxTooLarge, + ErrTxTooLarge, txID, txSize, MaxTxSize, @@ -128,7 +128,7 @@ func (m *mempool) Add(tx *txs.Tx) error { } if txSize > m.bytesAvailable { return fmt.Errorf("%w: %s size (%d) > available space (%d)", - errMempoolFull, + ErrMempoolFull, txID, txSize, m.bytesAvailable, @@ -137,7 +137,7 @@ func (m *mempool) Add(tx *txs.Tx) error { inputs := tx.Unsigned.InputIDs() if m.consumedUTXOs.Overlaps(inputs) { - return fmt.Errorf("%w: %s", errConflictsWithOtherTx, txID) + return fmt.Errorf("%w: %s", ErrConflictsWithOtherTx, txID) } m.bytesAvailable -= txSize diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index fff0f9f21248..ae1a75dbba17 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -37,25 +37,25 @@ func TestAdd(t *testing.T) { name: "attempt adding duplicate tx", initialTxs: []*txs.Tx{tx0}, tx: tx0, - err: errDuplicateTx, + err: ErrDuplicateTx, }, { name: "attempt adding too large tx", initialTxs: nil, tx: newTx(0, MaxTxSize+1), - err: errTxTooLarge, + err: ErrTxTooLarge, }, { name: "attempt adding tx when full", initialTxs: newTxs(maxMempoolSize/MaxTxSize, MaxTxSize), tx: newTx(maxMempoolSize/MaxTxSize, MaxTxSize), - err: errMempoolFull, + err: ErrMempoolFull, }, { name: "attempt adding conflicting tx", initialTxs: []*txs.Tx{tx0}, tx: newTx(0, 32), - err: errConflictsWithOtherTx, + err: ErrConflictsWithOtherTx, }, } for _, test := range tests { From 1f8f10fef3cb8e48bc472f2da61f54ddf33ba2d0 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 21 Dec 2023 18:49:08 -0500 Subject: [PATCH 185/267] Move locking into issueTx (#2532) --- vms/avm/network/network.go | 81 +++++++++------ vms/avm/network/network_test.go | 176 ++++++++++++++++++++++++++------ vms/avm/vm.go | 10 +- vms/avm/wallet_service.go | 17 ++- 4 files changed, 213 insertions(+), 71 deletions(-) diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index 0f4fc6b52de2..1032bfa75df3 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -5,6 +5,7 @@ package network import ( "context" + "fmt" "sync" "go.uber.org/zap" @@ -28,11 +29,25 @@ var _ Network = (*network)(nil) type Network interface { common.AppHandler - // IssueTx verifies the transaction at the currently preferred state, adds - // it to the mempool, and gossips it to the network. + // IssueTx attempts to add a tx to the mempool, after verifying it against + // the preferred state. If the tx is added to the mempool, it will attempt + // to push gossip the tx to random peers in the network. // - // Invariant: Assumes the context lock is held. + // If the tx is already in the mempool, mempool.ErrDuplicateTx will be + // returned. + // If the tx is not added to the mempool, an error will be returned. + // + // Invariant: The context lock is not held IssueTx(context.Context, *txs.Tx) error + + // IssueVerifiedTx attempts to add a tx to the mempool. If the tx is added + // to the mempool, it will attempt to push gossip the tx to random peers in + // the network. + // + // If the tx is already in the mempool, mempool.ErrDuplicateTx will be + // returned. + // If the tx is not added to the mempool, an error will be returned. + IssueVerifiedTx(context.Context, *txs.Tx) error } type network struct { @@ -103,18 +118,10 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b ) return nil } - txID := tx.ID() - // We need to grab the context lock here to avoid racy behavior with - // transaction verification + mempool modifications. - // - // Invariant: tx should not be referenced again without the context lock - // held to avoid any data races. - n.ctx.Lock.Lock() - err = n.issueTx(tx) - n.ctx.Lock.Unlock() - if err == nil { - n.gossipTx(ctx, txID, msgBytes) + if err := n.issueTx(tx); err == nil { + txID := tx.ID() + n.gossipTxMessage(ctx, txID, msgBytes) } return nil } @@ -123,27 +130,20 @@ func (n *network) IssueTx(ctx context.Context, tx *txs.Tx) error { if err := n.issueTx(tx); err != nil { return err } + return n.gossipTx(ctx, tx) +} - txBytes := tx.Bytes() - msg := &message.Tx{ - Tx: txBytes, - } - msgBytes, err := message.Build(msg) - if err != nil { +func (n *network) IssueVerifiedTx(ctx context.Context, tx *txs.Tx) error { + if err := n.issueVerifiedTx(tx); err != nil { return err } - - txID := tx.ID() - n.gossipTx(ctx, txID, msgBytes) - return nil + return n.gossipTx(ctx, tx) } -// returns nil if the tx is in the mempool func (n *network) issueTx(tx *txs.Tx) error { txID := tx.ID() if _, ok := n.mempool.Get(txID); ok { - // The tx is already in the mempool - return nil + return fmt.Errorf("attempted to issue %w: %s ", mempool.ErrDuplicateTx, txID) } if reason := n.mempool.GetDropReason(txID); reason != nil { @@ -155,7 +155,10 @@ func (n *network) issueTx(tx *txs.Tx) error { } // Verify the tx at the currently preferred state - if err := n.manager.VerifyTx(tx); err != nil { + n.ctx.Lock.Lock() + err := n.manager.VerifyTx(tx) + n.ctx.Lock.Unlock() + if err != nil { n.ctx.Log.Debug("tx failed verification", zap.Stringer("txID", txID), zap.Error(err), @@ -165,7 +168,12 @@ func (n *network) issueTx(tx *txs.Tx) error { return err } + return n.issueVerifiedTx(tx) +} + +func (n *network) issueVerifiedTx(tx *txs.Tx) error { if err := n.mempool.Add(tx); err != nil { + txID := tx.ID() n.ctx.Log.Debug("tx failed to be added to the mempool", zap.Stringer("txID", txID), zap.Error(err), @@ -179,7 +187,22 @@ func (n *network) issueTx(tx *txs.Tx) error { return nil } -func (n *network) gossipTx(ctx context.Context, txID ids.ID, msgBytes []byte) { +func (n *network) gossipTx(ctx context.Context, tx *txs.Tx) error { + txBytes := tx.Bytes() + msg := &message.Tx{ + Tx: txBytes, + } + msgBytes, err := message.Build(msg) + if err != nil { + return err + } + + txID := tx.ID() + n.gossipTxMessage(ctx, txID, msgBytes) + return nil +} + +func (n *network) gossipTxMessage(ctx context.Context, txID ids.ID, msgBytes []byte) { n.recentTxsLock.Lock() _, has := n.recentTxs.Get(txID) n.recentTxs.Put(txID, struct{}{}) diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index b900232173f2..1f336853c8e8 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -51,27 +51,27 @@ func TestNetworkAppGossip(t *testing.T) { name string msgBytesFunc func() []byte mempoolFunc func(*gomock.Controller) mempool.Mempool + managerFunc func(*gomock.Controller) executor.Manager appSenderFunc func(*gomock.Controller) common.AppSender } tests := []test{ { - // Shouldn't attempt to issue or gossip the tx name: "invalid message bytes", msgBytesFunc: func() []byte { return []byte{0x00} }, mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { - // Unused in this test - return nil + return mempool.NewMockMempool(ctrl) + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + return executor.NewMockManager(ctrl) }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Unused in this test - return nil + return common.NewMockSender(ctrl) }, }, { - // Shouldn't attempt to issue or gossip the tx name: "invalid tx bytes", msgBytesFunc: func() []byte { msg := message.Tx{ @@ -82,18 +82,17 @@ func TestNetworkAppGossip(t *testing.T) { return msgBytes }, mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { - // Unused in this test return mempool.NewMockMempool(ctrl) }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + return executor.NewMockManager(ctrl) + }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Unused in this test return common.NewMockSender(ctrl) }, }, { - // Issue returns nil because mempool has tx. We haven't gossipped - // the tx recently, so we should gossip it. - name: "issuance succeeds", + name: "tx already in mempool", msgBytesFunc: func() []byte { msg := message.Tx{ Tx: testTx.Bytes(), @@ -107,16 +106,15 @@ func TestNetworkAppGossip(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(testTx, true) return mempool }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + return executor.NewMockManager(ctrl) + }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Times(1) - return appSender + return common.NewMockSender(ctrl) }, }, { - // Issue returns error because tx was dropped. We shouldn't gossip - // the tx. - name: "issuance fails", + name: "tx previously dropped", msgBytesFunc: func() []byte { msg := message.Tx{ Tx: testTx.Bytes(), @@ -131,11 +129,68 @@ func TestNetworkAppGossip(t *testing.T) { mempool.EXPECT().GetDropReason(gomock.Any()).Return(errTest) return mempool }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + return executor.NewMockManager(ctrl) + }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Unused in this test return common.NewMockSender(ctrl) }, }, + { + name: "transaction invalid", + msgBytesFunc: func() []byte { + msg := message.Tx{ + Tx: testTx.Bytes(), + } + msgBytes, err := message.Build(&msg) + require.NoError(t, err) + return msgBytes + }, + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) + mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) + mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) + return mempool + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + manager := executor.NewMockManager(ctrl) + manager.EXPECT().VerifyTx(gomock.Any()).Return(errTest) + return manager + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + return common.NewMockSender(ctrl) + }, + }, + { + name: "happy path", + msgBytesFunc: func() []byte { + msg := message.Tx{ + Tx: testTx.Bytes(), + } + msgBytes, err := message.Build(&msg) + require.NoError(t, err) + return msgBytes + }, + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) + mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) + mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().RequestBuildBlock() + return mempool + }, + managerFunc: func(ctrl *gomock.Controller) executor.Manager { + manager := executor.NewMockManager(ctrl) + manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) + return manager + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + appSender := common.NewMockSender(ctrl) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + return appSender + }, + }, } for _, tt := range tests { @@ -155,7 +210,7 @@ func TestNetworkAppGossip(t *testing.T) { Log: logging.NoLog{}, }, parser, - executor.NewMockManager(ctrl), // Manager is unused in this test + tt.managerFunc(ctrl), tt.mempoolFunc(ctrl), tt.appSenderFunc(ctrl), ) @@ -182,16 +237,12 @@ func TestNetworkIssueTx(t *testing.T) { return mempool }, managerFunc: func(ctrl *gomock.Controller) executor.Manager { - // Unused in this test return executor.NewMockManager(ctrl) }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Should gossip the tx - appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) - return appSender + return common.NewMockSender(ctrl) }, - expectedErr: nil, + expectedErr: mempool.ErrDuplicateTx, }, { name: "transaction marked as dropped in mempool", @@ -202,11 +253,9 @@ func TestNetworkIssueTx(t *testing.T) { return mempool }, managerFunc: func(ctrl *gomock.Controller) executor.Manager { - // Unused in this test return executor.NewMockManager(ctrl) }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Shouldn't gossip the tx return common.NewMockSender(ctrl) }, expectedErr: errTest, @@ -226,7 +275,6 @@ func TestNetworkIssueTx(t *testing.T) { return manager }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Shouldn't gossip the tx return common.NewMockSender(ctrl) }, expectedErr: errTest, @@ -247,7 +295,6 @@ func TestNetworkIssueTx(t *testing.T) { return manager }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Shouldn't gossip the tx return common.NewMockSender(ctrl) }, expectedErr: errTest, @@ -268,7 +315,6 @@ func TestNetworkIssueTx(t *testing.T) { return manager }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Should gossip the tx appSender := common.NewMockSender(ctrl) appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) return appSender @@ -304,6 +350,72 @@ func TestNetworkIssueTx(t *testing.T) { } } +func TestNetworkIssueVerifiedTx(t *testing.T) { + type test struct { + name string + mempoolFunc func(*gomock.Controller) mempool.Mempool + appSenderFunc func(*gomock.Controller) common.AppSender + expectedErr error + } + + tests := []test{ + { + name: "can't add transaction to mempool", + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Add(gomock.Any()).Return(errTest) + mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) + return mempool + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + return common.NewMockSender(ctrl) + }, + expectedErr: errTest, + }, + { + name: "happy path", + mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { + mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().RequestBuildBlock() + return mempool + }, + appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + appSender := common.NewMockSender(ctrl) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + return appSender + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + parser, err := txs.NewParser([]fxs.Fx{ + &secp256k1fx.Fx{}, + &nftfx.Fx{}, + &propertyfx.Fx{}, + }) + require.NoError(err) + + n := New( + &snow.Context{ + Log: logging.NoLog{}, + }, + parser, + executor.NewMockManager(ctrl), // Should never verify a tx + tt.mempoolFunc(ctrl), + tt.appSenderFunc(ctrl), + ) + err = n.IssueVerifiedTx(context.Background(), &txs.Tx{}) + require.ErrorIs(err, tt.expectedErr) + }) + } +} + func TestNetworkGossipTx(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) @@ -330,12 +442,12 @@ func TestNetworkGossipTx(t *testing.T) { // Case: Tx was recently gossiped txID := ids.GenerateTestID() n.recentTxs.Put(txID, struct{}{}) - n.gossipTx(context.Background(), txID, []byte{}) + n.gossipTxMessage(context.Background(), txID, []byte{}) // Didn't make a call to SendAppGossip // Case: Tx was not recently gossiped msgBytes := []byte{1, 2, 3} appSender.EXPECT().SendAppGossip(gomock.Any(), msgBytes).Return(nil) - n.gossipTx(context.Background(), ids.GenerateTestID(), msgBytes) + n.gossipTxMessage(context.Background(), ids.GenerateTestID(), msgBytes) // Did make a call to SendAppGossip } diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 951d6caac19e..81d31e4f67fb 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -482,16 +482,16 @@ func (vm *VM) ParseTx(_ context.Context, bytes []byte) (snowstorm.Tx, error) { // Invariant: The context lock is not held // Invariant: This function is only called after Linearize has been called. func (vm *VM) issueTx(tx *txs.Tx) (ids.ID, error) { - vm.ctx.Lock.Lock() - defer vm.ctx.Lock.Unlock() - + txID := tx.ID() err := vm.network.IssueTx(context.TODO(), tx) - if err != nil { + if err != nil && !errors.Is(err, mempool.ErrDuplicateTx) { vm.ctx.Log.Debug("failed to add tx to mempool", + zap.Stringer("txID", txID), zap.Error(err), ) + return txID, err } - return tx.ID(), err + return txID, nil } /* diff --git a/vms/avm/wallet_service.go b/vms/avm/wallet_service.go index 04e5f423cc6f..91e8b94b8b4c 100644 --- a/vms/avm/wallet_service.go +++ b/vms/avm/wallet_service.go @@ -4,6 +4,7 @@ package avm import ( + "context" "errors" "fmt" "net/http" @@ -19,6 +20,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/vms/avm/txs" + "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) @@ -44,13 +46,14 @@ func (w *WalletService) decided(txID ids.ID) { return } - err := w.vm.mempool.Add(tx) + err := w.vm.network.IssueVerifiedTx(context.TODO(), tx) if err == nil { w.vm.ctx.Log.Info("issued tx to mempool over wallet API", zap.Stringer("txID", txID), ) - - w.vm.mempool.RequestBuildBlock() + return + } + if errors.Is(err, mempool.ErrDuplicateTx) { return } @@ -76,12 +79,16 @@ func (w *WalletService) issue(tx *txs.Tx) (ids.ID, error) { } if w.pendingTxs.Len() == 0 { - if err := w.vm.mempool.Add(tx); err != nil { + if err := w.vm.network.IssueVerifiedTx(context.TODO(), tx); err == nil { + w.vm.ctx.Log.Info("issued tx to mempool over wallet API", + zap.Stringer("txID", txID), + ) + } else if !errors.Is(err, mempool.ErrDuplicateTx) { w.vm.ctx.Log.Warn("failed to issue tx over wallet API", zap.Stringer("txID", txID), zap.Error(err), ) - return ids.ID{}, err + return ids.Empty, err } w.vm.mempool.RequestBuildBlock() From 9830e2d1266b89f4b7e483a4a733e8bb64d6cb25 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 21 Dec 2023 22:24:54 -0500 Subject: [PATCH 186/267] Fix merge in wallet service (#2534) --- vms/avm/wallet_service.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/vms/avm/wallet_service.go b/vms/avm/wallet_service.go index 91e8b94b8b4c..f73c89425ebb 100644 --- a/vms/avm/wallet_service.go +++ b/vms/avm/wallet_service.go @@ -90,12 +90,6 @@ func (w *WalletService) issue(tx *txs.Tx) (ids.ID, error) { ) return ids.Empty, err } - - w.vm.mempool.RequestBuildBlock() - - w.vm.ctx.Log.Info("issued tx to mempool over wallet API", - zap.Stringer("txID", txID), - ) } else { w.vm.ctx.Log.Info("enqueueing tx over wallet API", zap.Stringer("txID", txID), From a4cfbc0aa55d9e7be10d1d0ba0e7e3355e6d4a1e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 22 Dec 2023 10:14:27 -0500 Subject: [PATCH 187/267] Introduce TxVerifier interface to network (#2533) --- vms/avm/network/network.go | 31 +++--- vms/avm/network/network_test.go | 186 ++++++++++++++++---------------- vms/avm/network/tx_verifier.go | 36 +++++++ vms/avm/vm.go | 6 +- 4 files changed, 147 insertions(+), 112 deletions(-) create mode 100644 vms/avm/network/tx_verifier.go diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index 1032bfa75df3..b29e80c98124 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -14,7 +14,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/vms/avm/block/executor" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" "github.com/ava-labs/avalanchego/vms/components/message" @@ -36,8 +35,6 @@ type Network interface { // If the tx is already in the mempool, mempool.ErrDuplicateTx will be // returned. // If the tx is not added to the mempool, an error will be returned. - // - // Invariant: The context lock is not held IssueTx(context.Context, *txs.Tx) error // IssueVerifiedTx attempts to add a tx to the mempool. If the tx is added @@ -54,11 +51,11 @@ type network struct { // We embed a noop handler for all unhandled messages common.AppHandler - ctx *snow.Context - parser txs.Parser - manager executor.Manager - mempool mempool.Mempool - appSender common.AppSender + ctx *snow.Context + parser txs.Parser + txVerifier TxVerifier + mempool mempool.Mempool + appSender common.AppSender // gossip related attributes recentTxsLock sync.Mutex @@ -68,18 +65,18 @@ type network struct { func New( ctx *snow.Context, parser txs.Parser, - manager executor.Manager, + txVerifier TxVerifier, mempool mempool.Mempool, appSender common.AppSender, ) Network { return &network{ AppHandler: common.NewNoOpAppHandler(ctx.Log), - ctx: ctx, - parser: parser, - manager: manager, - mempool: mempool, - appSender: appSender, + ctx: ctx, + parser: parser, + txVerifier: txVerifier, + mempool: mempool, + appSender: appSender, recentTxs: &cache.LRU[ids.ID, struct{}]{ Size: recentTxsCacheSize, @@ -154,11 +151,7 @@ func (n *network) issueTx(tx *txs.Tx) error { return reason } - // Verify the tx at the currently preferred state - n.ctx.Lock.Lock() - err := n.manager.VerifyTx(tx) - n.ctx.Lock.Unlock() - if err != nil { + if err := n.txVerifier.VerifyTx(tx); err != nil { n.ctx.Log.Debug("tx failed verification", zap.Stringer("txID", txID), zap.Error(err), diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index 1f336853c8e8..509b35ec0f13 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -48,11 +48,11 @@ func TestNetworkAppGossip(t *testing.T) { require.NoError(t, testTx.Initialize(parser.Codec())) type test struct { - name string - msgBytesFunc func() []byte - mempoolFunc func(*gomock.Controller) mempool.Mempool - managerFunc func(*gomock.Controller) executor.Manager - appSenderFunc func(*gomock.Controller) common.AppSender + name string + msgBytesFunc func() []byte + mempoolFunc func(*gomock.Controller) mempool.Mempool + txVerifierFunc func(*gomock.Controller) TxVerifier + appSenderFunc func(*gomock.Controller) common.AppSender } tests := []test{ @@ -61,15 +61,6 @@ func TestNetworkAppGossip(t *testing.T) { msgBytesFunc: func() []byte { return []byte{0x00} }, - mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { - return mempool.NewMockMempool(ctrl) - }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - return executor.NewMockManager(ctrl) - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) - }, }, { name: "invalid tx bytes", @@ -81,15 +72,6 @@ func TestNetworkAppGossip(t *testing.T) { require.NoError(t, err) return msgBytes }, - mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { - return mempool.NewMockMempool(ctrl) - }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - return executor.NewMockManager(ctrl) - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) - }, }, { name: "tx already in mempool", @@ -106,12 +88,6 @@ func TestNetworkAppGossip(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(testTx, true) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - return executor.NewMockManager(ctrl) - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) - }, }, { name: "tx previously dropped", @@ -129,12 +105,6 @@ func TestNetworkAppGossip(t *testing.T) { mempool.EXPECT().GetDropReason(gomock.Any()).Return(errTest) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - return executor.NewMockManager(ctrl) - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) - }, }, { name: "transaction invalid", @@ -153,13 +123,10 @@ func TestNetworkAppGossip(t *testing.T) { mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(errTest) - return manager - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) + txVerifierFunc: func(ctrl *gomock.Controller) TxVerifier { + txVerifier := executor.NewMockManager(ctrl) + txVerifier.EXPECT().VerifyTx(gomock.Any()).Return(errTest) + return txVerifier }, }, { @@ -180,10 +147,10 @@ func TestNetworkAppGossip(t *testing.T) { mempool.EXPECT().RequestBuildBlock() return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) - return manager + txVerifierFunc: func(ctrl *gomock.Controller) TxVerifier { + txVerifier := executor.NewMockManager(ctrl) + txVerifier.EXPECT().VerifyTx(gomock.Any()).Return(nil) + return txVerifier }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { appSender := common.NewMockSender(ctrl) @@ -205,14 +172,35 @@ func TestNetworkAppGossip(t *testing.T) { }) require.NoError(err) + mempoolFunc := func(ctrl *gomock.Controller) mempool.Mempool { + return mempool.NewMockMempool(ctrl) + } + if tt.mempoolFunc != nil { + mempoolFunc = tt.mempoolFunc + } + + txVerifierFunc := func(ctrl *gomock.Controller) TxVerifier { + return executor.NewMockManager(ctrl) + } + if tt.txVerifierFunc != nil { + txVerifierFunc = tt.txVerifierFunc + } + + appSenderFunc := func(ctrl *gomock.Controller) common.AppSender { + return common.NewMockSender(ctrl) + } + if tt.appSenderFunc != nil { + appSenderFunc = tt.appSenderFunc + } + n := New( &snow.Context{ Log: logging.NoLog{}, }, parser, - tt.managerFunc(ctrl), - tt.mempoolFunc(ctrl), - tt.appSenderFunc(ctrl), + txVerifierFunc(ctrl), + mempoolFunc(ctrl), + appSenderFunc(ctrl), ) require.NoError(n.AppGossip(context.Background(), ids.GenerateTestNodeID(), tt.msgBytesFunc())) }) @@ -221,11 +209,11 @@ func TestNetworkAppGossip(t *testing.T) { func TestNetworkIssueTx(t *testing.T) { type test struct { - name string - mempoolFunc func(*gomock.Controller) mempool.Mempool - managerFunc func(*gomock.Controller) executor.Manager - appSenderFunc func(*gomock.Controller) common.AppSender - expectedErr error + name string + mempoolFunc func(*gomock.Controller) mempool.Mempool + txVerifierFunc func(*gomock.Controller) TxVerifier + appSenderFunc func(*gomock.Controller) common.AppSender + expectedErr error } tests := []test{ @@ -236,12 +224,6 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(nil, true) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - return executor.NewMockManager(ctrl) - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) - }, expectedErr: mempool.ErrDuplicateTx, }, { @@ -252,12 +234,6 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().GetDropReason(gomock.Any()).Return(errTest) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - return executor.NewMockManager(ctrl) - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) - }, expectedErr: errTest, }, { @@ -269,13 +245,10 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(errTest) - return manager - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) + txVerifierFunc: func(ctrl *gomock.Controller) TxVerifier { + txVerifier := executor.NewMockManager(ctrl) + txVerifier.EXPECT().VerifyTx(gomock.Any()).Return(errTest) + return txVerifier }, expectedErr: errTest, }, @@ -289,13 +262,10 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) - return manager - }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) + txVerifierFunc: func(ctrl *gomock.Controller) TxVerifier { + txVerifier := executor.NewMockManager(ctrl) + txVerifier.EXPECT().VerifyTx(gomock.Any()).Return(nil) + return txVerifier }, expectedErr: errTest, }, @@ -309,10 +279,10 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().RequestBuildBlock() return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) - return manager + txVerifierFunc: func(ctrl *gomock.Controller) TxVerifier { + txVerifier := executor.NewMockManager(ctrl) + txVerifier.EXPECT().VerifyTx(gomock.Any()).Return(nil) + return txVerifier }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { appSender := common.NewMockSender(ctrl) @@ -335,14 +305,35 @@ func TestNetworkIssueTx(t *testing.T) { }) require.NoError(err) + mempoolFunc := func(ctrl *gomock.Controller) mempool.Mempool { + return mempool.NewMockMempool(ctrl) + } + if tt.mempoolFunc != nil { + mempoolFunc = tt.mempoolFunc + } + + txVerifierFunc := func(ctrl *gomock.Controller) TxVerifier { + return executor.NewMockManager(ctrl) + } + if tt.txVerifierFunc != nil { + txVerifierFunc = tt.txVerifierFunc + } + + appSenderFunc := func(ctrl *gomock.Controller) common.AppSender { + return common.NewMockSender(ctrl) + } + if tt.appSenderFunc != nil { + appSenderFunc = tt.appSenderFunc + } + n := New( &snow.Context{ Log: logging.NoLog{}, }, parser, - tt.managerFunc(ctrl), - tt.mempoolFunc(ctrl), - tt.appSenderFunc(ctrl), + txVerifierFunc(ctrl), + mempoolFunc(ctrl), + appSenderFunc(ctrl), ) err = n.IssueTx(context.Background(), &txs.Tx{}) require.ErrorIs(err, tt.expectedErr) @@ -367,9 +358,6 @@ func TestNetworkIssueVerifiedTx(t *testing.T) { mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, - appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - return common.NewMockSender(ctrl) - }, expectedErr: errTest, }, { @@ -401,14 +389,28 @@ func TestNetworkIssueVerifiedTx(t *testing.T) { }) require.NoError(err) + mempoolFunc := func(ctrl *gomock.Controller) mempool.Mempool { + return mempool.NewMockMempool(ctrl) + } + if tt.mempoolFunc != nil { + mempoolFunc = tt.mempoolFunc + } + + appSenderFunc := func(ctrl *gomock.Controller) common.AppSender { + return common.NewMockSender(ctrl) + } + if tt.appSenderFunc != nil { + appSenderFunc = tt.appSenderFunc + } + n := New( &snow.Context{ Log: logging.NoLog{}, }, parser, executor.NewMockManager(ctrl), // Should never verify a tx - tt.mempoolFunc(ctrl), - tt.appSenderFunc(ctrl), + mempoolFunc(ctrl), + appSenderFunc(ctrl), ) err = n.IssueVerifiedTx(context.Background(), &txs.Tx{}) require.ErrorIs(err, tt.expectedErr) diff --git a/vms/avm/network/tx_verifier.go b/vms/avm/network/tx_verifier.go new file mode 100644 index 000000000000..fe76f0c45366 --- /dev/null +++ b/vms/avm/network/tx_verifier.go @@ -0,0 +1,36 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "sync" + + "github.com/ava-labs/avalanchego/vms/avm/txs" +) + +var _ TxVerifier = (*LockedTxVerifier)(nil) + +type TxVerifier interface { + // VerifyTx verifies that the transaction should be issued into the mempool. + VerifyTx(tx *txs.Tx) error +} + +type LockedTxVerifier struct { + lock sync.Locker + txVerifier TxVerifier +} + +func (l *LockedTxVerifier) VerifyTx(tx *txs.Tx) error { + l.lock.Lock() + defer l.lock.Unlock() + + return l.txVerifier.VerifyTx(tx) +} + +func NewLockedTxVerifier(lock sync.Locker, txVerifier TxVerifier) *LockedTxVerifier { + return &LockedTxVerifier{ + lock: lock, + txVerifier: txVerifier, + } +} diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 81d31e4f67fb..93467ad877ef 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -424,10 +424,14 @@ func (vm *VM) Linearize(_ context.Context, stopVertexID ids.ID, toEngine chan<- vm.mempool, ) + // Invariant: The context lock is not held when calling network.IssueTx. vm.network = network.New( vm.ctx, vm.parser, - vm.chainManager, + network.NewLockedTxVerifier( + &vm.ctx.Lock, + vm.chainManager, + ), vm.mempool, vm.appSender, ) From 7e5d1a256f6695df24e6397727084f2e2e98a61e Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Fri, 22 Dec 2023 10:56:54 -0500 Subject: [PATCH 188/267] Export P-Chain Mempool Errors (#2535) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- vms/platformvm/txs/mempool/mempool.go | 24 +++++++++++----------- vms/platformvm/txs/mempool/mempool_test.go | 3 +-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 45412f4ca9d8..37355b017d3f 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -37,12 +37,12 @@ const ( var ( _ Mempool = (*mempool)(nil) - errDuplicateTx = errors.New("duplicate tx") - errTxTooLarge = errors.New("tx too large") - errMempoolFull = errors.New("mempool is full") - errConflictsWithOtherTx = errors.New("tx conflicts with other tx") - errCantIssueAdvanceTimeTx = errors.New("can not issue an advance time tx") - errCantIssueRewardValidatorTx = errors.New("can not issue a reward validator tx") + ErrDuplicateTx = errors.New("duplicate tx") + ErrTxTooLarge = errors.New("tx too large") + ErrMempoolFull = errors.New("mempool is full") + ErrConflictsWithOtherTx = errors.New("tx conflicts with other tx") + ErrCantIssueAdvanceTimeTx = errors.New("can not issue an advance time tx") + ErrCantIssueRewardValidatorTx = errors.New("can not issue a reward validator tx") ) type Mempool interface { @@ -122,22 +122,22 @@ func (m *mempool) Add(tx *txs.Tx) error { switch tx.Unsigned.(type) { case *txs.AdvanceTimeTx: - return errCantIssueAdvanceTimeTx + return ErrCantIssueAdvanceTimeTx case *txs.RewardValidatorTx: - return errCantIssueRewardValidatorTx + return ErrCantIssueRewardValidatorTx default: } // Note: a previously dropped tx can be re-added txID := tx.ID() if _, ok := m.unissuedTxs.Get(txID); ok { - return fmt.Errorf("%w: %s", errDuplicateTx, txID) + return fmt.Errorf("%w: %s", ErrDuplicateTx, txID) } txSize := len(tx.Bytes()) if txSize > MaxTxSize { return fmt.Errorf("%w: %s size (%d) > max size (%d)", - errTxTooLarge, + ErrTxTooLarge, txID, txSize, MaxTxSize, @@ -145,7 +145,7 @@ func (m *mempool) Add(tx *txs.Tx) error { } if txSize > m.bytesAvailable { return fmt.Errorf("%w: %s size (%d) > available space (%d)", - errMempoolFull, + ErrMempoolFull, txID, txSize, m.bytesAvailable, @@ -154,7 +154,7 @@ func (m *mempool) Add(tx *txs.Tx) error { inputs := tx.Unsigned.InputIDs() if m.consumedUTXOs.Overlaps(inputs) { - return fmt.Errorf("%w: %s", errConflictsWithOtherTx, txID) + return fmt.Errorf("%w: %s", ErrConflictsWithOtherTx, txID) } m.unissuedTxs.Put(tx.ID(), tx) diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index 5eb3baa9590b..ffbb00359fc5 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -4,7 +4,6 @@ package mempool import ( - "errors" "testing" "time" @@ -39,7 +38,7 @@ func TestBlockBuilderMaxMempoolSizeHandling(t *testing.T) { mpool.(*mempool).bytesAvailable = len(tx.Bytes()) - 1 err = mpool.Add(tx) - require.True(errors.Is(err, errMempoolFull), err, "max mempool size breached") + require.ErrorIs(err, ErrMempoolFull) // shortcut to simulated almost filled mempool mpool.(*mempool).bytesAvailable = len(tx.Bytes()) From 5ebafd916a34e07513e63920f1936fa5257bda62 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 22 Dec 2023 11:17:39 -0500 Subject: [PATCH 189/267] Rename `Version` message to `Handshake` (#2479) --- message/messages_benchmark_test.go | 30 +- message/messages_test.go | 8 +- message/mock_outbound_message_builder.go | 30 +- message/ops.go | 16 +- message/outbound_msg_builder.go | 8 +- network/README.md | 12 +- network/peer/config.go | 2 +- network/peer/peer.go | 42 +- proto/p2p/p2p.proto | 14 +- proto/pb/p2p/p2p.pb.go | 691 ++++++++++++----------- 10 files changed, 427 insertions(+), 426 deletions(-) diff --git a/message/messages_benchmark_test.go b/message/messages_benchmark_test.go index 8d0939a67348..b3169de9103b 100644 --- a/message/messages_benchmark_test.go +++ b/message/messages_benchmark_test.go @@ -26,29 +26,29 @@ var ( dummyOnFinishedHandling = func() {} ) -// Benchmarks marshal-ing "Version" message. +// Benchmarks marshal-ing "Handshake" message. // // e.g., // // $ go install -v golang.org/x/tools/cmd/benchcmp@latest // $ go install -v golang.org/x/perf/cmd/benchstat@latest // -// $ go test -run=NONE -bench=BenchmarkMarshalVersion > /tmp/cpu.before.txt -// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalVersion > /tmp/cpu.after.txt +// $ go test -run=NONE -bench=BenchmarkMarshalHandshake > /tmp/cpu.before.txt +// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalHandshake > /tmp/cpu.after.txt // $ benchcmp /tmp/cpu.before.txt /tmp/cpu.after.txt // $ benchstat -alpha 0.03 -geomean /tmp/cpu.before.txt /tmp/cpu.after.txt // -// $ go test -run=NONE -bench=BenchmarkMarshalVersion -benchmem > /tmp/mem.before.txt -// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalVersion -benchmem > /tmp/mem.after.txt +// $ go test -run=NONE -bench=BenchmarkMarshalHandshake -benchmem > /tmp/mem.before.txt +// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalHandshake -benchmem > /tmp/mem.after.txt // $ benchcmp /tmp/mem.before.txt /tmp/mem.after.txt // $ benchstat -alpha 0.03 -geomean /tmp/mem.before.txt /tmp/mem.after.txt -func BenchmarkMarshalVersion(b *testing.B) { +func BenchmarkMarshalHandshake(b *testing.B) { require := require.New(b) id := ids.GenerateTestID() msg := p2p.Message{ - Message: &p2p.Message_Version{ - Version: &p2p.Version{ + Message: &p2p.Message_Handshake{ + Handshake: &p2p.Handshake{ NetworkId: uint32(1337), MyTime: uint64(time.Now().Unix()), IpAddr: []byte(net.IPv4(1, 2, 3, 4).To16()), @@ -87,24 +87,24 @@ func BenchmarkMarshalVersion(b *testing.B) { // $ go install -v golang.org/x/tools/cmd/benchcmp@latest // $ go install -v golang.org/x/perf/cmd/benchstat@latest // -// $ go test -run=NONE -bench=BenchmarkUnmarshalVersion > /tmp/cpu.before.txt -// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkUnmarshalVersion > /tmp/cpu.after.txt +// $ go test -run=NONE -bench=BenchmarkUnmarshalHandshake > /tmp/cpu.before.txt +// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkUnmarshalHandshake > /tmp/cpu.after.txt // $ benchcmp /tmp/cpu.before.txt /tmp/cpu.after.txt // $ benchstat -alpha 0.03 -geomean /tmp/cpu.before.txt /tmp/cpu.after.txt // -// $ go test -run=NONE -bench=BenchmarkUnmarshalVersion -benchmem > /tmp/mem.before.txt -// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkUnmarshalVersion -benchmem > /tmp/mem.after.txt +// $ go test -run=NONE -bench=BenchmarkUnmarshalHandshake -benchmem > /tmp/mem.before.txt +// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkUnmarshalHandshake -benchmem > /tmp/mem.after.txt // $ benchcmp /tmp/mem.before.txt /tmp/mem.after.txt // $ benchstat -alpha 0.03 -geomean /tmp/mem.before.txt /tmp/mem.after.txt -func BenchmarkUnmarshalVersion(b *testing.B) { +func BenchmarkUnmarshalHandshake(b *testing.B) { require := require.New(b) b.StopTimer() id := ids.GenerateTestID() msg := p2p.Message{ - Message: &p2p.Message_Version{ - Version: &p2p.Version{ + Message: &p2p.Message_Handshake{ + Handshake: &p2p.Handshake{ NetworkId: uint32(1337), MyTime: uint64(time.Now().Unix()), IpAddr: []byte(net.IPv4(1, 2, 3, 4).To16()), diff --git a/message/messages_test.go b/message/messages_test.go index a7cf74c95c48..de2532661ab3 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -122,11 +122,11 @@ func TestMessage(t *testing.T) { bytesSaved: false, }, { - desc: "version message with no compression", - op: VersionOp, + desc: "Handshake message with no compression", + op: HandshakeOp, msg: &p2p.Message{ - Message: &p2p.Message_Version{ - Version: &p2p.Version{ + Message: &p2p.Message_Handshake{ + Handshake: &p2p.Handshake{ NetworkId: uint32(1337), MyTime: uint64(nowUnix), IpAddr: []byte(net.IPv6zero), diff --git a/message/mock_outbound_message_builder.go b/message/mock_outbound_message_builder.go index baed0d10b9c3..1da9934d177f 100644 --- a/message/mock_outbound_message_builder.go +++ b/message/mock_outbound_message_builder.go @@ -250,6 +250,21 @@ func (mr *MockOutboundMsgBuilderMockRecorder) GetStateSummaryFrontier(arg0, arg1 return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateSummaryFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetStateSummaryFrontier), arg0, arg1, arg2) } +// Handshake mocks base method. +func (m *MockOutboundMsgBuilder) Handshake(arg0 uint32, arg1 uint64, arg2 ips.IPPort, arg3, arg4 string, arg5, arg6, arg7 uint32, arg8 uint64, arg9 []byte, arg10 []ids.ID, arg11, arg12 []uint32) (OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Handshake", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) + ret0, _ := ret[0].(OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Handshake indicates an expected call of Handshake. +func (mr *MockOutboundMsgBuilderMockRecorder) Handshake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Handshake), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) +} + // PeerList mocks base method. func (m *MockOutboundMsgBuilder) PeerList(arg0 []ips.ClaimedIPPort, arg1 bool) (OutboundMessage, error) { m.ctrl.T.Helper() @@ -369,18 +384,3 @@ func (mr *MockOutboundMsgBuilderMockRecorder) StateSummaryFrontier(arg0, arg1, a mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).StateSummaryFrontier), arg0, arg1, arg2) } - -// Version mocks base method. -func (m *MockOutboundMsgBuilder) Version(arg0 uint32, arg1 uint64, arg2 ips.IPPort, arg3, arg4 string, arg5, arg6, arg7 uint32, arg8 uint64, arg9 []byte, arg10 []ids.ID, arg11, arg12 []uint32) (OutboundMessage, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Version", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) - ret0, _ := ret[0].(OutboundMessage) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Version indicates an expected call of Version. -func (mr *MockOutboundMsgBuilderMockRecorder) Version(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Version), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) -} diff --git a/message/ops.go b/message/ops.go index f511ebacac36..2ecae08db396 100644 --- a/message/ops.go +++ b/message/ops.go @@ -21,7 +21,7 @@ const ( // Handshake: PingOp Op = iota PongOp - VersionOp + HandshakeOp PeerListOp PeerListAckOp // State sync: @@ -71,7 +71,7 @@ var ( HandshakeOps = []Op{ PingOp, PongOp, - VersionOp, + HandshakeOp, PeerListOp, PeerListAckOp, } @@ -209,8 +209,8 @@ func (op Op) String() string { return "ping" case PongOp: return "pong" - case VersionOp: - return "version" + case HandshakeOp: + return "handshake" case PeerListOp: return "peerlist" case PeerListAckOp: @@ -303,8 +303,8 @@ func Unwrap(m *p2p.Message) (fmt.Stringer, error) { return msg.Ping, nil case *p2p.Message_Pong: return msg.Pong, nil - case *p2p.Message_Version: - return msg.Version, nil + case *p2p.Message_Handshake: + return msg.Handshake, nil case *p2p.Message_PeerList: return msg.PeerList, nil case *p2p.Message_PeerListAck: @@ -362,8 +362,8 @@ func ToOp(m *p2p.Message) (Op, error) { return PingOp, nil case *p2p.Message_Pong: return PongOp, nil - case *p2p.Message_Version: - return VersionOp, nil + case *p2p.Message_Handshake: + return HandshakeOp, nil case *p2p.Message_PeerList: return PeerListOp, nil case *p2p.Message_PeerListAck: diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index 1705463931cb..8a98477aa4fe 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -18,7 +18,7 @@ var _ OutboundMsgBuilder = (*outMsgBuilder)(nil) // with a reference count of 1. Once the reference count hits 0, the message // bytes should no longer be accessed. type OutboundMsgBuilder interface { - Version( + Handshake( networkID uint32, myTime uint64, ip ips.IPPort, @@ -230,7 +230,7 @@ func (b *outMsgBuilder) Pong( ) } -func (b *outMsgBuilder) Version( +func (b *outMsgBuilder) Handshake( networkID uint32, myTime uint64, ip ips.IPPort, @@ -249,8 +249,8 @@ func (b *outMsgBuilder) Version( encodeIDs(trackedSubnets, subnetIDBytes) return b.builder.createOutbound( &p2p.Message{ - Message: &p2p.Message_Version{ - Version: &p2p.Version{ + Message: &p2p.Message_Handshake{ + Handshake: &p2p.Handshake{ NetworkId: networkID, MyTime: myTime, IpAddr: ip.IP.To16(), diff --git a/network/README.md b/network/README.md index 5364d9db39e5..b62b0ba3769c 100644 --- a/network/README.md +++ b/network/README.md @@ -54,26 +54,26 @@ In Avalanche, nodes connect to an initial set of bootstrapper nodes known as **b Upon connection to any peer, a handshake is performed between the node attempting to establish the outbound connection to the peer and the peer receiving the inbound connection. -When attempting to establish the connection, the first message that the node attempting to connect to the peer in the network is a `Version` message describing compatibility of the candidate node with the peer. As an example, nodes that are attempting to connect with an incompatible version of AvalancheGo or a significantly skewed local clock are rejected by the peer. +When attempting to establish the connection, the first message that the node attempting to connect to the peer in the network is a `Handshake` message describing compatibility of the candidate node with the peer. As an example, nodes that are attempting to connect with an incompatible version of AvalancheGo or a significantly skewed local clock are rejected by the peer. ```mermaid sequenceDiagram Note over Node,Peer: Initiate Handshake Note left of Node: I want to connect to you! -Note over Node,Peer: Version message +Note over Node,Peer: Handshake message Node->>Peer: AvalancheGo v1.0.0 Note right of Peer: My version v1.9.4 is incompatible with your version v1.0.0. Peer-xNode: Connection dropped Note over Node,Peer: Handshake Failed ``` -If the `Version` message is successfully received and the peer decides that it wants a connection with this node, it replies with a `PeerList` message that contains metadata about other peers that allows a node to connect to them. Upon reception of a `PeerList` message, a node will attempt to connect to any peers that the node is not already connected to to allow the node to discover more peers in the network. +If the `Handshake` message is successfully received and the peer decides that it wants a connection with this node, it replies with a `PeerList` message that contains metadata about other peers that allows a node to connect to them. Upon reception of a `PeerList` message, a node will attempt to connect to any peers that the node is not already connected to to allow the node to discover more peers in the network. ```mermaid sequenceDiagram Note over Node,Peer: Initiate Handshake Note left of Node: I want to connect to you! -Note over Node,Peer: Version message +Note over Node,Peer: Handshake message Node->>Peer: AvalancheGo v1.9.4 Note right of Peer: LGTM! Note over Node,Peer: PeerList message @@ -90,11 +90,11 @@ Some peers aren't discovered through the `PeerList` messages exchanged through p ```mermaid sequenceDiagram -Node ->> Peer-1: Version - v1.9.5 +Node ->> Peer-1: Handshake - v1.9.5 Peer-1 ->> Node: PeerList - Peer-2 Node ->> Peer-1: ACK - Peer-2 Note left of Node: Node is connected to Peer-1 and now tries to connect to Peer-2. -Node ->> Peer-2: Version - v1.9.5 +Node ->> Peer-2: Handshake - v1.9.5 Peer-2 ->> Node: PeerList - Peer-1 Node ->> Peer-2: ACK - Peer-1 Note left of Node: Peer-3 was never sampled, so we haven't connected yet! diff --git a/network/peer/config.go b/network/peer/config.go index 1d3d23b7fc36..403ddfeb5334 100644 --- a/network/peer/config.go +++ b/network/peer/config.go @@ -53,6 +53,6 @@ type Config struct { // Calculates uptime of peers UptimeCalculator uptime.Calculator - // Signs my IP so I can send my signed IP address in the Version message + // Signs my IP so I can send my signed IP address in the Handshake message IPSigner *IPSigner } diff --git a/network/peer/peer.go b/network/peer/peer.go index c9182eecb744..28751a42962d 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -120,15 +120,15 @@ type peer struct { // queue of messages to send to this peer. messageQueue MessageQueue - // ip is the claimed IP the peer gave us in the Version message. + // ip is the claimed IP the peer gave us in the Handshake message. ip *SignedIP // version is the claimed version the peer is running that we received in - // the Version message. + // the Handshake message. version *version.Application - // trackedSubnets is the subset of subnetIDs the peer sent us in the Version + // trackedSubnets is the subset of subnetIDs the peer sent us in the Handshake // message that we are also tracking. trackedSubnets set.Set[ids.ID] - // options of ACPs provided in the Version message. + // options of ACPs provided in the Handshake message. supportedACPs set.Set[uint32] objectedACPs set.Set[uint32] @@ -137,13 +137,13 @@ type peer struct { // Subnet ID --> Our uptime for the given subnet as perceived by the peer observedUptimes map[ids.ID]uint32 - // True if this peer has sent us a valid Version message and + // True if this peer has sent us a valid Handshake message and // is running a compatible version. // Only modified on the connection's reader routine. - gotVersion utils.Atomic[bool] + gotHandshake utils.Atomic[bool] // True if the peer: - // * Has sent us a Version message + // * Has sent us a Handshake message // * Has sent us a PeerList message // * Is running a compatible version // Only modified on the connection's reader routine. @@ -491,7 +491,7 @@ func (p *peer) writeMessages() { writer := bufio.NewWriterSize(p.conn, p.Config.WriteBufferSize) - // Make sure that the version is the first message sent + // Make sure that the Handshake is the first message sent mySignedIP, err := p.IPSigner.GetSignedIP() if err != nil { p.Log.Error("failed to get signed IP", @@ -509,7 +509,7 @@ func (p *peer) writeMessages() { Patch: myVersion.Patch, } - msg, err := p.MessageCreator.Version( + msg, err := p.MessageCreator.Handshake( p.NetworkID, p.Clock.Unix(), mySignedIP.IPPort, @@ -526,7 +526,7 @@ func (p *peer) writeMessages() { ) if err != nil { p.Log.Error("failed to create message", - zap.Stringer("messageOp", message.VersionOp), + zap.Stringer("messageOp", message.HandshakeOp), zap.Stringer("nodeID", p.id), zap.Error(err), ) @@ -696,8 +696,8 @@ func (p *peer) handle(msg message.InboundMessage) { p.handlePong(m) msg.OnFinishedHandling() return - case *p2p.Version: - p.handleVersion(m) + case *p2p.Handshake: + p.handleHandshake(m) msg.OnFinishedHandling() return case *p2p.PeerList: @@ -846,10 +846,10 @@ func (p *peer) observeUptime(subnetID ids.ID, uptime uint32) { p.observedUptimesLock.Unlock() } -func (p *peer) handleVersion(msg *p2p.Version) { - if p.gotVersion.Get() { +func (p *peer) handleHandshake(msg *p2p.Handshake) { + if p.gotHandshake.Get() { // TODO: this should never happen, should we close the connection here? - p.Log.Verbo("dropping duplicated version message", + p.Log.Verbo("dropping duplicated handshake message", zap.Stringer("nodeID", p.id), ) return @@ -976,7 +976,7 @@ func (p *peer) handleVersion(msg *p2p.Version) { if p.supportedACPs.Overlaps(p.objectedACPs) { p.Log.Debug("message with invalid field", zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.VersionOp), + zap.Stringer("messageOp", message.HandshakeOp), zap.String("field", "ACPs"), zap.Reflect("supportedACPs", p.supportedACPs), zap.Reflect("objectedACPs", p.objectedACPs), @@ -989,7 +989,7 @@ func (p *peer) handleVersion(msg *p2p.Version) { if ipLen := len(msg.IpAddr); ipLen != net.IPv6len { p.Log.Debug("message with invalid field", zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.VersionOp), + zap.Stringer("messageOp", message.HandshakeOp), zap.String("field", "IP"), zap.Int("ipLen", ipLen), ) @@ -1016,7 +1016,7 @@ func (p *peer) handleVersion(msg *p2p.Version) { return } - p.gotVersion.Set(true) + p.gotHandshake.Set(true) peerIPs, err := p.Network.Peers(p.id) if err != nil { @@ -1027,7 +1027,7 @@ func (p *peer) handleVersion(msg *p2p.Version) { return } - // We bypass throttling here to ensure that the version message is + // We bypass throttling here to ensure that the peerlist message is // acknowledged timely. peerListMsg, err := p.Config.MessageCreator.PeerList(peerIPs, true /*=bypassThrottling*/) if err != nil { @@ -1051,7 +1051,7 @@ func (p *peer) handleVersion(msg *p2p.Version) { func (p *peer) handlePeerList(msg *p2p.PeerList) { if !p.finishedHandshake.Get() { - if !p.gotVersion.Get() { + if !p.gotHandshake.Get() { return } @@ -1079,7 +1079,7 @@ func (p *peer) handlePeerList(msg *p2p.PeerList) { if ipLen := len(claimedIPPort.IpAddr); ipLen != net.IPv6len { p.Log.Debug("message with invalid field", zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.VersionOp), + zap.Stringer("messageOp", message.HandshakeOp), zap.String("field", "IP"), zap.Int("ipLen", ipLen), ) diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index c3a2f71f01ec..969628b2d994 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -28,7 +28,7 @@ message Message { // Network messages: Ping ping = 11; Pong pong = 12; - Version version = 13; + Handshake handshake = 13; PeerList peer_list = 14; // State-sync messages: @@ -91,17 +91,17 @@ message Pong { repeated SubnetUptime subnet_uptimes = 2; } -// Version is the first outbound message sent to a peer when a connection is +// Handshake is the first outbound message sent to a peer when a connection is // established to start the p2p handshake. // -// Peers must respond to a Version message with a PeerList message to allow the +// Peers must respond to a Handshake message with a PeerList message to allow the // peer to connect to other peers in the network. // // Peers should drop connections to peers with incompatible versions. -message Version { +message Handshake { // Network the peer is running on (e.g local, testnet, mainnet) uint32 network_id = 1; - // Unix timestamp when this Version message was created + // Unix timestamp when this Handshake message was created uint64 my_time = 2; // IP address of the peer bytes ip_addr = 3; @@ -148,9 +148,9 @@ message ClaimedIpPort { // PeerList contains network-level metadata for a set of validators. // -// PeerList must be sent in response to an inbound Version message from a +// PeerList must be sent in response to an inbound Handshake message from a // remote peer a peer wants to connect to. Once a PeerList is received after -// a version message, the p2p handshake is complete and the connection is +// a Handshake message, the p2p handshake is complete and the connection is // established. // Peers should periodically send PeerList messages to allow peers to diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index 55c43f3ab1c9..d062ce2a0576 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -88,7 +88,7 @@ type Message struct { // *Message_CompressedZstd // *Message_Ping // *Message_Pong - // *Message_Version + // *Message_Handshake // *Message_PeerList // *Message_GetStateSummaryFrontier // *Message_StateSummaryFrontier_ @@ -180,9 +180,9 @@ func (x *Message) GetPong() *Pong { return nil } -func (x *Message) GetVersion() *Version { - if x, ok := x.GetMessage().(*Message_Version); ok { - return x.Version +func (x *Message) GetHandshake() *Handshake { + if x, ok := x.GetMessage().(*Message_Handshake); ok { + return x.Handshake } return nil } @@ -361,8 +361,8 @@ type Message_Pong struct { Pong *Pong `protobuf:"bytes,12,opt,name=pong,proto3,oneof"` } -type Message_Version struct { - Version *Version `protobuf:"bytes,13,opt,name=version,proto3,oneof"` +type Message_Handshake struct { + Handshake *Handshake `protobuf:"bytes,13,opt,name=handshake,proto3,oneof"` } type Message_PeerList struct { @@ -461,7 +461,7 @@ func (*Message_Ping) isMessage_Message() {} func (*Message_Pong) isMessage_Message() {} -func (*Message_Version) isMessage_Message() {} +func (*Message_Handshake) isMessage_Message() {} func (*Message_PeerList) isMessage_Message() {} @@ -684,21 +684,21 @@ func (x *Pong) GetSubnetUptimes() []*SubnetUptime { return nil } -// Version is the first outbound message sent to a peer when a connection is +// Handshake is the first outbound message sent to a peer when a connection is // established to start the p2p handshake. // -// Peers must respond to a Version message with a PeerList message to allow the +// Peers must respond to a Handshake message with a PeerList message to allow the // peer to connect to other peers in the network. // // Peers should drop connections to peers with incompatible versions. -type Version struct { +type Handshake struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Network the peer is running on (e.g local, testnet, mainnet) NetworkId uint32 `protobuf:"varint,1,opt,name=network_id,json=networkId,proto3" json:"network_id,omitempty"` - // Unix timestamp when this Version message was created + // Unix timestamp when this Handshake message was created MyTime uint64 `protobuf:"varint,2,opt,name=my_time,json=myTime,proto3" json:"my_time,omitempty"` // IP address of the peer IpAddr []byte `protobuf:"bytes,3,opt,name=ip_addr,json=ipAddr,proto3" json:"ip_addr,omitempty"` @@ -717,8 +717,8 @@ type Version struct { ObjectedAcps []uint32 `protobuf:"varint,11,rep,packed,name=objected_acps,json=objectedAcps,proto3" json:"objected_acps,omitempty"` } -func (x *Version) Reset() { - *x = Version{} +func (x *Handshake) Reset() { + *x = Handshake{} if protoimpl.UnsafeEnabled { mi := &file_p2p_p2p_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -726,13 +726,13 @@ func (x *Version) Reset() { } } -func (x *Version) String() string { +func (x *Handshake) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Version) ProtoMessage() {} +func (*Handshake) ProtoMessage() {} -func (x *Version) ProtoReflect() protoreflect.Message { +func (x *Handshake) ProtoReflect() protoreflect.Message { mi := &file_p2p_p2p_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -744,82 +744,82 @@ func (x *Version) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Version.ProtoReflect.Descriptor instead. -func (*Version) Descriptor() ([]byte, []int) { +// Deprecated: Use Handshake.ProtoReflect.Descriptor instead. +func (*Handshake) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{4} } -func (x *Version) GetNetworkId() uint32 { +func (x *Handshake) GetNetworkId() uint32 { if x != nil { return x.NetworkId } return 0 } -func (x *Version) GetMyTime() uint64 { +func (x *Handshake) GetMyTime() uint64 { if x != nil { return x.MyTime } return 0 } -func (x *Version) GetIpAddr() []byte { +func (x *Handshake) GetIpAddr() []byte { if x != nil { return x.IpAddr } return nil } -func (x *Version) GetIpPort() uint32 { +func (x *Handshake) GetIpPort() uint32 { if x != nil { return x.IpPort } return 0 } -func (x *Version) GetMyVersion() string { +func (x *Handshake) GetMyVersion() string { if x != nil { return x.MyVersion } return "" } -func (x *Version) GetMyVersionTime() uint64 { +func (x *Handshake) GetMyVersionTime() uint64 { if x != nil { return x.MyVersionTime } return 0 } -func (x *Version) GetSig() []byte { +func (x *Handshake) GetSig() []byte { if x != nil { return x.Sig } return nil } -func (x *Version) GetTrackedSubnets() [][]byte { +func (x *Handshake) GetTrackedSubnets() [][]byte { if x != nil { return x.TrackedSubnets } return nil } -func (x *Version) GetClient() *Client { +func (x *Handshake) GetClient() *Client { if x != nil { return x.Client } return nil } -func (x *Version) GetSupportedAcps() []uint32 { +func (x *Handshake) GetSupportedAcps() []uint32 { if x != nil { return x.SupportedAcps } return nil } -func (x *Version) GetObjectedAcps() []uint32 { +func (x *Handshake) GetObjectedAcps() []uint32 { if x != nil { return x.ObjectedAcps } @@ -2620,7 +2620,7 @@ var File_p2p_p2p_proto protoreflect.FileDescriptor var file_p2p_p2p_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x03, 0x70, 0x32, 0x70, 0x22, 0x8c, 0x0b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x03, 0x70, 0x32, 0x70, 0x22, 0x92, 0x0b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x7a, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x47, 0x7a, 0x69, 0x70, 0x12, 0x29, 0x0a, 0x0f, 0x63, @@ -2630,336 +2630,337 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x6f, 0x6e, 0x67, - 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x28, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, - 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, - 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x51, 0x0a, - 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, - 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, + 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x2e, 0x0a, 0x09, 0x68, 0x61, 0x6e, 0x64, + 0x73, 0x68, 0x61, 0x6b, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x48, 0x00, 0x52, 0x09, 0x68, + 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x2c, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x70, 0x65, + 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x12, 0x51, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, + 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x41, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x12, 0x51, 0x0a, 0x16, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, + 0x52, 0x14, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x4e, 0x0a, 0x15, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, + 0x00, 0x52, 0x13, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0c, + 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, + 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x12, 0x38, 0x0a, 0x0d, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x67, 0x65, + 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, + 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x67, 0x65, + 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, + 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x18, + 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x74, 0x48, + 0x00, 0x52, 0x03, 0x70, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, + 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x6c, 0x6c, 0x5f, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, + 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x22, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x74, + 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x68, + 0x69, 0x74, 0x73, 0x48, 0x00, 0x52, 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, + 0x61, 0x70, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x35, 0x0a, 0x0c, 0x61, 0x70, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x5f, 0x67, + 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x48, 0x00, 0x52, 0x09, 0x61, + 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, + 0x6b, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, + 0x12, 0x2c, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x22, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x48, 0x00, 0x52, 0x08, 0x61, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x69, 0x6e, + 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, + 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, + 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, + 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x22, 0xe8, 0x02, 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, + 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x06, 0x6d, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, + 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x79, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x79, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, + 0x73, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, + 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x63, 0x70, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, + 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x22, 0x5e, 0x0a, + 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, + 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, + 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0xbd, 0x01, + 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, + 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, + 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, + 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, + 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, + 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, + 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, + 0x63, 0x6b, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3e, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, + 0x65, 0x72, 0x41, 0x63, 0x6b, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x11, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x51, 0x0a, - 0x16, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, - 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x14, 0x61, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x12, 0x4e, 0x0a, 0x15, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, - 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x18, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x13, 0x67, 0x65, 0x74, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x12, 0x44, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, - 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, - 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0c, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, - 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, - 0x52, 0x0b, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x2b, 0x0a, - 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, - 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x0d, 0x67, 0x65, - 0x74, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x67, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, - 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x74, 0x48, 0x00, 0x52, 0x03, 0x70, 0x75, 0x74, - 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x1b, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, - 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x6c, 0x6c, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x12, 0x22, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x68, 0x69, 0x74, 0x73, 0x48, 0x00, 0x52, - 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, - 0x61, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0c, 0x61, 0x70, - 0x70, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x5f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, - 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x47, - 0x6f, 0x73, 0x73, 0x69, 0x70, 0x48, 0x00, 0x52, 0x09, 0x61, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, - 0x69, 0x70, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, - 0x61, 0x63, 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, - 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x0b, 0x70, - 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x2c, 0x0a, 0x09, 0x61, 0x70, - 0x70, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x08, - 0x61, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, - 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, - 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0x43, 0x0a, - 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, - 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, - 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, - 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0xe6, 0x02, 0x0a, - 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x79, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, - 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, - 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x79, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, - 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, - 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, - 0x6e, 0x65, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, - 0x0d, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, - 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, - 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x41, 0x63, 0x70, 0x73, 0x22, 0x5e, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, - 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, - 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, - 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, - 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, - 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, - 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, - 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, - 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, - 0x3c, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, - 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3e, 0x0a, - 0x0b, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x09, - 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x52, 0x08, 0x70, - 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6f, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, - 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, - 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, - 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, - 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, - 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, - 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, - 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, - 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, - 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x75, 0x0a, 0x10, 0x41, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, - 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6f, 0x0a, - 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, + 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, + 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, + 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb9, - 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, - 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x6e, + 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, + 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x75, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x49, 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6f, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, + 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, + 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, - 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, - 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x01, 0x0a, - 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, + 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, - 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x09, - 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, - 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, - 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, - 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, - 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, - 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, - 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, - 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, - 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, - 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, - 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, - 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, - 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x54, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, + 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, + 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, + 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, + 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, + 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, + 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, + 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, + 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, + 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, + 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, + 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -2982,7 +2983,7 @@ var file_p2p_p2p_proto_goTypes = []interface{}{ (*Ping)(nil), // 2: p2p.Ping (*SubnetUptime)(nil), // 3: p2p.SubnetUptime (*Pong)(nil), // 4: p2p.Pong - (*Version)(nil), // 5: p2p.Version + (*Handshake)(nil), // 5: p2p.Handshake (*Client)(nil), // 6: p2p.Client (*ClaimedIpPort)(nil), // 7: p2p.ClaimedIpPort (*PeerList)(nil), // 8: p2p.PeerList @@ -3011,7 +3012,7 @@ var file_p2p_p2p_proto_goTypes = []interface{}{ var file_p2p_p2p_proto_depIdxs = []int32{ 2, // 0: p2p.Message.ping:type_name -> p2p.Ping 4, // 1: p2p.Message.pong:type_name -> p2p.Pong - 5, // 2: p2p.Message.version:type_name -> p2p.Version + 5, // 2: p2p.Message.handshake:type_name -> p2p.Handshake 8, // 3: p2p.Message.peer_list:type_name -> p2p.PeerList 11, // 4: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier 12, // 5: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier @@ -3035,7 +3036,7 @@ var file_p2p_p2p_proto_depIdxs = []int32{ 28, // 23: p2p.Message.app_error:type_name -> p2p.AppError 3, // 24: p2p.Ping.subnet_uptimes:type_name -> p2p.SubnetUptime 3, // 25: p2p.Pong.subnet_uptimes:type_name -> p2p.SubnetUptime - 6, // 26: p2p.Version.client:type_name -> p2p.Client + 6, // 26: p2p.Handshake.client:type_name -> p2p.Client 7, // 27: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort 9, // 28: p2p.PeerListAck.peer_acks:type_name -> p2p.PeerAck 0, // 29: p2p.GetAcceptedFrontier.engine_type:type_name -> p2p.EngineType @@ -3107,7 +3108,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Version); i { + switch v := v.(*Handshake); i { case 0: return &v.state case 1: @@ -3412,7 +3413,7 @@ func file_p2p_p2p_proto_init() { (*Message_CompressedZstd)(nil), (*Message_Ping)(nil), (*Message_Pong)(nil), - (*Message_Version)(nil), + (*Message_Handshake)(nil), (*Message_PeerList)(nil), (*Message_GetStateSummaryFrontier)(nil), (*Message_StateSummaryFrontier_)(nil), From 4458432d3e37f359d5d40f3abfb903b756661353 Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Fri, 22 Dec 2023 12:09:07 -0500 Subject: [PATCH 190/267] Rename myVersionTime to ipSigningTime (#2537) Co-authored-by: Stephen Buttolph --- message/messages_benchmark_test.go | 4 ++-- message/messages_test.go | 2 +- message/outbound_msg_builder.go | 6 +++--- network/peer/peer.go | 8 ++++---- proto/p2p/p2p.proto | 2 +- proto/pb/p2p/p2p.pb.go | 12 ++++++------ 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/message/messages_benchmark_test.go b/message/messages_benchmark_test.go index b3169de9103b..9864e6a231f8 100644 --- a/message/messages_benchmark_test.go +++ b/message/messages_benchmark_test.go @@ -54,7 +54,7 @@ func BenchmarkMarshalHandshake(b *testing.B) { IpAddr: []byte(net.IPv4(1, 2, 3, 4).To16()), IpPort: 0, MyVersion: "v1.2.3", - MyVersionTime: uint64(time.Now().Unix()), + IpSigningTime: uint64(time.Now().Unix()), Sig: []byte{'y', 'e', 'e', 't'}, TrackedSubnets: [][]byte{id[:]}, }, @@ -110,7 +110,7 @@ func BenchmarkUnmarshalHandshake(b *testing.B) { IpAddr: []byte(net.IPv4(1, 2, 3, 4).To16()), IpPort: 0, MyVersion: "v1.2.3", - MyVersionTime: uint64(time.Now().Unix()), + IpSigningTime: uint64(time.Now().Unix()), Sig: []byte{'y', 'e', 'e', 't'}, TrackedSubnets: [][]byte{id[:]}, }, diff --git a/message/messages_test.go b/message/messages_test.go index de2532661ab3..3ae3cf015119 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -132,7 +132,7 @@ func TestMessage(t *testing.T) { IpAddr: []byte(net.IPv6zero), IpPort: 9651, MyVersion: "v1.2.3", - MyVersionTime: uint64(nowUnix), + IpSigningTime: uint64(nowUnix), Sig: []byte{'y', 'e', 'e', 't'}, TrackedSubnets: [][]byte{testID[:]}, }, diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index 8a98477aa4fe..a6149fd35784 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -27,7 +27,7 @@ type OutboundMsgBuilder interface { major uint32, minor uint32, patch uint32, - myVersionTime uint64, + ipSigningTime uint64, sig []byte, trackedSubnets []ids.ID, supportedACPs []uint32, @@ -239,7 +239,7 @@ func (b *outMsgBuilder) Handshake( major uint32, minor uint32, patch uint32, - myVersionTime uint64, + ipSigningTime uint64, sig []byte, trackedSubnets []ids.ID, supportedACPs []uint32, @@ -256,7 +256,7 @@ func (b *outMsgBuilder) Handshake( IpAddr: ip.IP.To16(), IpPort: uint32(ip.Port), MyVersion: myVersion, - MyVersionTime: myVersionTime, + IpSigningTime: ipSigningTime, Sig: sig, TrackedSubnets: subnetIDBytes, Client: &p2p.Client{ diff --git a/network/peer/peer.go b/network/peer/peer.go index 28751a42962d..37824f16990a 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -933,13 +933,13 @@ func (p *peer) handleHandshake(msg *p2p.Handshake) { return } - // Note that it is expected that the [versionTime] can be in the past. We + // Note that it is expected that the [ipSigningTime] can be in the past. We // are just verifying that the claimed signing time isn't too far in the // future here. - if float64(msg.MyVersionTime)-float64(myTime) > p.MaxClockDifference.Seconds() { + if float64(msg.IpSigningTime)-float64(myTime) > p.MaxClockDifference.Seconds() { p.Log.Debug("peer attempting to connect with version timestamp too far in the future", zap.Stringer("nodeID", p.id), - zap.Uint64("versionTime", msg.MyVersionTime), + zap.Uint64("ipSigningTime", msg.IpSigningTime), ) p.StartClose() return @@ -1003,7 +1003,7 @@ func (p *peer) handleHandshake(msg *p2p.Handshake) { IP: msg.IpAddr, Port: uint16(msg.IpPort), }, - Timestamp: msg.MyVersionTime, + Timestamp: msg.IpSigningTime, }, Signature: msg.Sig, } diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 969628b2d994..53a4d3d2126a 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -110,7 +110,7 @@ message Handshake { // Avalanche client version string my_version = 5; // Timestamp of the IP - uint64 my_version_time = 6; + uint64 ip_signing_time = 6; // Signature of the peer IP port pair at a provided timestamp bytes sig = 7; // Subnets the peer is tracking diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index d062ce2a0576..166a8d11f493 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -707,7 +707,7 @@ type Handshake struct { // Avalanche client version MyVersion string `protobuf:"bytes,5,opt,name=my_version,json=myVersion,proto3" json:"my_version,omitempty"` // Timestamp of the IP - MyVersionTime uint64 `protobuf:"varint,6,opt,name=my_version_time,json=myVersionTime,proto3" json:"my_version_time,omitempty"` + IpSigningTime uint64 `protobuf:"varint,6,opt,name=ip_signing_time,json=ipSigningTime,proto3" json:"ip_signing_time,omitempty"` // Signature of the peer IP port pair at a provided timestamp Sig []byte `protobuf:"bytes,7,opt,name=sig,proto3" json:"sig,omitempty"` // Subnets the peer is tracking @@ -784,9 +784,9 @@ func (x *Handshake) GetMyVersion() string { return "" } -func (x *Handshake) GetMyVersionTime() uint64 { +func (x *Handshake) GetIpSigningTime() uint64 { if x != nil { - return x.MyVersionTime + return x.IpSigningTime } return 0 } @@ -2734,9 +2734,9 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x79, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0d, 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, + 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x70, 0x5f, + 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0d, 0x69, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, From b7db25b1acb580cfee98a4a4805a88a21aa63205 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Fri, 22 Dec 2023 13:38:09 -0500 Subject: [PATCH 191/267] Remove resolved TODO (#2540) --- vms/platformvm/block/proposal_block.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/vms/platformvm/block/proposal_block.go b/vms/platformvm/block/proposal_block.go index 1986218aa0a5..8ce59bd0bd68 100644 --- a/vms/platformvm/block/proposal_block.go +++ b/vms/platformvm/block/proposal_block.go @@ -18,12 +18,7 @@ var ( ) type BanffProposalBlock struct { - Time uint64 `serialize:"true" json:"time"` - // Transactions is currently unused. This is populated so that introducing - // them in the future will not require a codec change. - // - // TODO: when Transactions is used, we must correctly verify and apply their - // changes. + Time uint64 `serialize:"true" json:"time"` Transactions []*txs.Tx `serialize:"true" json:"-"` ApricotProposalBlock `serialize:"true"` } From f0c150dddda3e70b380e3d59dc5f6f864469ed8c Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Fri, 22 Dec 2023 14:03:32 -0500 Subject: [PATCH 192/267] Only initialize Txs once (#2538) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Co-authored-by: Stephen Buttolph --- vms/platformvm/block/abort_block.go | 4 +-- vms/platformvm/block/atomic_block.go | 2 +- vms/platformvm/block/block.go | 6 ++-- vms/platformvm/block/commit_block.go | 4 +-- vms/platformvm/block/proposal_block.go | 4 +-- vms/platformvm/block/serialization_test.go | 6 ++-- vms/platformvm/block/standard_block.go | 4 +-- vms/platformvm/state/state_test.go | 38 +++++++++++++--------- vms/platformvm/vm_test.go | 4 +-- 9 files changed, 41 insertions(+), 31 deletions(-) diff --git a/vms/platformvm/block/abort_block.go b/vms/platformvm/block/abort_block.go index cb8efcef144b..27f2ad25a356 100644 --- a/vms/platformvm/block/abort_block.go +++ b/vms/platformvm/block/abort_block.go @@ -43,7 +43,7 @@ func NewBanffAbortBlock( }, }, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } type ApricotAbortBlock struct { @@ -78,5 +78,5 @@ func NewApricotAbortBlock( Hght: height, }, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } diff --git a/vms/platformvm/block/atomic_block.go b/vms/platformvm/block/atomic_block.go index dddddaa43685..470abcbe4674 100644 --- a/vms/platformvm/block/atomic_block.go +++ b/vms/platformvm/block/atomic_block.go @@ -52,5 +52,5 @@ func NewApricotAtomicBlock( }, Tx: tx, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } diff --git a/vms/platformvm/block/block.go b/vms/platformvm/block/block.go index 933667a83f68..5cdc3a90dbc0 100644 --- a/vms/platformvm/block/block.go +++ b/vms/platformvm/block/block.go @@ -36,12 +36,14 @@ type BanffBlock interface { Timestamp() time.Time } -func initialize(blk Block) error { +func initialize(blk Block, commonBlk *CommonBlock) error { // We serialize this block as a pointer so that it can be deserialized into // a Block bytes, err := Codec.Marshal(Version, &blk) if err != nil { return fmt.Errorf("couldn't marshal block: %w", err) } - return blk.initialize(bytes) + + commonBlk.initialize(bytes) + return nil } diff --git a/vms/platformvm/block/commit_block.go b/vms/platformvm/block/commit_block.go index 02cbadb4e1cd..52b260f0f167 100644 --- a/vms/platformvm/block/commit_block.go +++ b/vms/platformvm/block/commit_block.go @@ -43,7 +43,7 @@ func NewBanffCommitBlock( }, }, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } type ApricotCommitBlock struct { @@ -75,5 +75,5 @@ func NewApricotCommitBlock( Hght: height, }, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } diff --git a/vms/platformvm/block/proposal_block.go b/vms/platformvm/block/proposal_block.go index 8ce59bd0bd68..26e77aed757a 100644 --- a/vms/platformvm/block/proposal_block.go +++ b/vms/platformvm/block/proposal_block.go @@ -76,7 +76,7 @@ func NewBanffProposalBlock( Tx: proposalTx, }, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } type ApricotProposalBlock struct { @@ -119,5 +119,5 @@ func NewApricotProposalBlock( }, Tx: tx, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } diff --git a/vms/platformvm/block/serialization_test.go b/vms/platformvm/block/serialization_test.go index 031e527be25f..3b144f0b5d3c 100644 --- a/vms/platformvm/block/serialization_test.go +++ b/vms/platformvm/block/serialization_test.go @@ -105,11 +105,13 @@ func TestBanffBlockSerialization(t *testing.T) { for _, test := range tests { testName := fmt.Sprintf("%T", test.block) + block := test.block t.Run(testName, func(t *testing.T) { require := require.New(t) - require.NoError(initialize(test.block)) - require.Equal(test.bytes, test.block.Bytes()) + got, err := Codec.Marshal(Version, &block) + require.NoError(err) + require.Equal(test.bytes, got) }) } } diff --git a/vms/platformvm/block/standard_block.go b/vms/platformvm/block/standard_block.go index a3a7ee6fed39..cff20c92369b 100644 --- a/vms/platformvm/block/standard_block.go +++ b/vms/platformvm/block/standard_block.go @@ -46,7 +46,7 @@ func NewBanffStandardBlock( Transactions: txs, }, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } type ApricotStandardBlock struct { @@ -93,5 +93,5 @@ func NewApricotStandardBlock( }, Transactions: txs, } - return blk, initialize(blk) + return blk, initialize(blk, &blk.CommonBlock) } diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index 74d0413bb0f7..0f87a6f90b00 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -581,23 +581,25 @@ func TestParsedStateBlock(t *testing.T) { } { - blk, err := block.NewApricotProposalBlock(ids.GenerateTestID(), 1000, &txs.Tx{ + tx := &txs.Tx{ Unsigned: &txs.RewardValidatorTx{ TxID: ids.GenerateTestID(), }, - }) + } + require.NoError(tx.Initialize(txs.Codec)) + blk, err := block.NewApricotProposalBlock(ids.GenerateTestID(), 1000, tx) require.NoError(err) blks = append(blks, blk) } { - blk, err := block.NewApricotStandardBlock(ids.GenerateTestID(), 1000, []*txs.Tx{ - { - Unsigned: &txs.RewardValidatorTx{ - TxID: ids.GenerateTestID(), - }, + tx := &txs.Tx{ + Unsigned: &txs.RewardValidatorTx{ + TxID: ids.GenerateTestID(), }, - }) + } + require.NoError(tx.Initialize(txs.Codec)) + blk, err := block.NewApricotStandardBlock(ids.GenerateTestID(), 1000, []*txs.Tx{tx}) require.NoError(err) blks = append(blks, blk) } @@ -615,23 +617,27 @@ func TestParsedStateBlock(t *testing.T) { } { - blk, err := block.NewBanffProposalBlock(time.Now(), ids.GenerateTestID(), 1000, &txs.Tx{ + tx := &txs.Tx{ Unsigned: &txs.RewardValidatorTx{ TxID: ids.GenerateTestID(), }, - }, []*txs.Tx{}) + } + require.NoError(tx.Initialize(txs.Codec)) + + blk, err := block.NewBanffProposalBlock(time.Now(), ids.GenerateTestID(), 1000, tx, []*txs.Tx{}) require.NoError(err) blks = append(blks, blk) } { - blk, err := block.NewBanffStandardBlock(time.Now(), ids.GenerateTestID(), 1000, []*txs.Tx{ - { - Unsigned: &txs.RewardValidatorTx{ - TxID: ids.GenerateTestID(), - }, + tx := &txs.Tx{ + Unsigned: &txs.RewardValidatorTx{ + TxID: ids.GenerateTestID(), }, - }) + } + require.NoError(tx.Initialize(txs.Codec)) + + blk, err := block.NewBanffStandardBlock(time.Now(), ids.GenerateTestID(), 1000, []*txs.Tx{tx}) require.NoError(err) blks = append(blks, blk) } diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 7d24a352ab78..4ab310da5bb2 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1657,7 +1657,7 @@ func TestUnverifiedParent(t *testing.T) { firstAdvanceTimeBlk := vm.manager.NewBlock(statelessBlk) require.NoError(firstAdvanceTimeBlk.Verify(context.Background())) - // include a tx1 to make the block be accepted + // include a tx2 to make the block be accepted tx2 := &txs.Tx{Unsigned: &txs.ImportTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: vm.ctx.NetworkID, @@ -1675,7 +1675,7 @@ func TestUnverifiedParent(t *testing.T) { }, }}, }} - require.NoError(tx1.Initialize(txs.Codec)) + require.NoError(tx2.Initialize(txs.Codec)) nextChainTime = nextChainTime.Add(time.Second) vm.clock.Set(nextChainTime) statelessSecondAdvanceTimeBlk, err := block.NewBanffStandardBlock( From 762a8cd6651bab3cf39b6d4410d312c5b6091507 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Fri, 22 Dec 2023 14:09:59 -0500 Subject: [PATCH 193/267] JSON marshal the `Transactions` field in `BanffProposalBlocks` (#2541) --- vms/platformvm/block/proposal_block.go | 2 +- vms/platformvm/block/serialization_test.go | 109 +++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/vms/platformvm/block/proposal_block.go b/vms/platformvm/block/proposal_block.go index 26e77aed757a..719bc3a1825a 100644 --- a/vms/platformvm/block/proposal_block.go +++ b/vms/platformvm/block/proposal_block.go @@ -19,7 +19,7 @@ var ( type BanffProposalBlock struct { Time uint64 `serialize:"true" json:"time"` - Transactions []*txs.Tx `serialize:"true" json:"-"` + Transactions []*txs.Tx `serialize:"true" json:"txs"` ApricotProposalBlock `serialize:"true"` } diff --git a/vms/platformvm/block/serialization_test.go b/vms/platformvm/block/serialization_test.go index 3b144f0b5d3c..bfa08684e6f0 100644 --- a/vms/platformvm/block/serialization_test.go +++ b/vms/platformvm/block/serialization_test.go @@ -4,11 +4,15 @@ package block import ( + "encoding/json" "fmt" "testing" "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) @@ -115,3 +119,108 @@ func TestBanffBlockSerialization(t *testing.T) { }) } } + +func TestBanffProposalBlockJSON(t *testing.T) { + require := require.New(t) + + simpleBanffProposalBlock := &BanffProposalBlock{ + Time: 123456, + ApricotProposalBlock: ApricotProposalBlock{ + CommonBlock: CommonBlock{ + PrntID: ids.ID{'p', 'a', 'r', 'e', 'n', 't', 'I', 'D'}, + Hght: 1337, + BlockID: ids.ID{'b', 'l', 'o', 'c', 'k', 'I', 'D'}, + }, + Tx: &txs.Tx{ + Unsigned: &txs.AdvanceTimeTx{ + Time: 123457, + }, + }, + }, + } + + simpleBanffProposalBlockBytes, err := json.MarshalIndent(simpleBanffProposalBlock, "", "\t") + require.NoError(err) + + require.Equal(`{ + "time": 123456, + "txs": null, + "parentID": "rVcYrvnGXdoJBeYQRm5ZNaCGHeVyqcHHJu8Yd89kJcef6V5Eg", + "height": 1337, + "id": "kM6h4d2UKYEDzQXm7KNqyeBJLjhb42J24m4L4WACB5didf3pk", + "tx": { + "unsignedTx": { + "time": 123457 + }, + "credentials": null, + "id": "11111111111111111111111111111111LpoYY" + } +}`, string(simpleBanffProposalBlockBytes)) + + complexBanffProposalBlock := simpleBanffProposalBlock + complexBanffProposalBlock.Transactions = []*txs.Tx{ + { + Unsigned: &txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: constants.MainnetID, + BlockchainID: constants.PlatformChainID, + Outs: []*avax.TransferableOutput{}, + Ins: []*avax.TransferableInput{}, + Memo: []byte("KilroyWasHere"), + }, + }, + }, + { + Unsigned: &txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: constants.MainnetID, + BlockchainID: constants.PlatformChainID, + Outs: []*avax.TransferableOutput{}, + Ins: []*avax.TransferableInput{}, + Memo: []byte("KilroyWasHere2"), + }, + }, + }, + } + + complexBanffProposalBlockBytes, err := json.MarshalIndent(complexBanffProposalBlock, "", "\t") + require.NoError(err) + + require.Equal(`{ + "time": 123456, + "txs": [ + { + "unsignedTx": { + "networkID": 1, + "blockchainID": "11111111111111111111111111111111LpoYY", + "outputs": [], + "inputs": [], + "memo": "0x4b696c726f7957617348657265" + }, + "credentials": null, + "id": "11111111111111111111111111111111LpoYY" + }, + { + "unsignedTx": { + "networkID": 1, + "blockchainID": "11111111111111111111111111111111LpoYY", + "outputs": [], + "inputs": [], + "memo": "0x4b696c726f795761734865726532" + }, + "credentials": null, + "id": "11111111111111111111111111111111LpoYY" + } + ], + "parentID": "rVcYrvnGXdoJBeYQRm5ZNaCGHeVyqcHHJu8Yd89kJcef6V5Eg", + "height": 1337, + "id": "kM6h4d2UKYEDzQXm7KNqyeBJLjhb42J24m4L4WACB5didf3pk", + "tx": { + "unsignedTx": { + "time": 123457 + }, + "credentials": null, + "id": "11111111111111111111111111111111LpoYY" + } +}`, string(complexBanffProposalBlockBytes)) +} From 071a94bca45559df6c40a64c2098e0b2dffa9018 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Fri, 22 Dec 2023 14:55:17 -0500 Subject: [PATCH 194/267] Enable `predeclared` linter (#2539) --- .golangci.yml | 1 + message/inbound_msg_builder.go | 4 ++-- snow/validators/manager_test.go | 20 ++++++++++---------- snow/validators/set_test.go | 20 ++++++++++---------- utils/profiler/continuous.go | 2 +- utils/profiler/profiler.go | 6 ++++-- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b5c99facb2b1..fad97cb63712 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -67,6 +67,7 @@ linters: - nolintlint - perfsprint - prealloc + - predeclared - revive - staticcheck - stylecheck diff --git a/message/inbound_msg_builder.go b/message/inbound_msg_builder.go index e6822bc329d1..8541645840aa 100644 --- a/message/inbound_msg_builder.go +++ b/message/inbound_msg_builder.go @@ -324,7 +324,7 @@ func InboundAppResponse( func encodeIDs(ids []ids.ID, result [][]byte) { for i, id := range ids { - copy := id - result[i] = copy[:] + id := id + result[i] = id[:] } } diff --git a/snow/validators/manager_test.go b/snow/validators/manager_test.go index 1e6fb4a3abb8..6980510fecd1 100644 --- a/snow/validators/manager_test.go +++ b/snow/validators/manager_test.go @@ -216,30 +216,30 @@ func TestLen(t *testing.T) { m := NewManager() subnetID := ids.GenerateTestID() - len := m.Count(subnetID) - require.Zero(len) + count := m.Count(subnetID) + require.Zero(count) nodeID0 := ids.GenerateTestNodeID() require.NoError(m.AddStaker(subnetID, nodeID0, nil, ids.Empty, 1)) - len = m.Count(subnetID) - require.Equal(1, len) + count = m.Count(subnetID) + require.Equal(1, count) nodeID1 := ids.GenerateTestNodeID() require.NoError(m.AddStaker(subnetID, nodeID1, nil, ids.Empty, 1)) - len = m.Count(subnetID) - require.Equal(2, len) + count = m.Count(subnetID) + require.Equal(2, count) require.NoError(m.RemoveWeight(subnetID, nodeID1, 1)) - len = m.Count(subnetID) - require.Equal(1, len) + count = m.Count(subnetID) + require.Equal(1, count) require.NoError(m.RemoveWeight(subnetID, nodeID0, 1)) - len = m.Count(subnetID) - require.Zero(len) + count = m.Count(subnetID) + require.Zero(count) } func TestGetMap(t *testing.T) { diff --git a/snow/validators/set_test.go b/snow/validators/set_test.go index f11a6f92c727..48c19e59b11a 100644 --- a/snow/validators/set_test.go +++ b/snow/validators/set_test.go @@ -166,30 +166,30 @@ func TestSetLen(t *testing.T) { s := newSet() - len := s.Len() - require.Zero(len) + setLen := s.Len() + require.Zero(setLen) nodeID0 := ids.GenerateTestNodeID() require.NoError(s.Add(nodeID0, nil, ids.Empty, 1)) - len = s.Len() - require.Equal(1, len) + setLen = s.Len() + require.Equal(1, setLen) nodeID1 := ids.GenerateTestNodeID() require.NoError(s.Add(nodeID1, nil, ids.Empty, 1)) - len = s.Len() - require.Equal(2, len) + setLen = s.Len() + require.Equal(2, setLen) require.NoError(s.RemoveWeight(nodeID1, 1)) - len = s.Len() - require.Equal(1, len) + setLen = s.Len() + require.Equal(1, setLen) require.NoError(s.RemoveWeight(nodeID0, 1)) - len = s.Len() - require.Zero(len) + setLen = s.Len() + require.Zero(setLen) } func TestSetMap(t *testing.T) { diff --git a/utils/profiler/continuous.go b/utils/profiler/continuous.go index 548e88779b22..c662f172c33d 100644 --- a/utils/profiler/continuous.go +++ b/utils/profiler/continuous.go @@ -37,7 +37,7 @@ type continuousProfiler struct { func NewContinuous(dir string, freq time.Duration, maxNumFiles int) ContinuousProfiler { return &continuousProfiler{ - profiler: new(dir), + profiler: newProfiler(dir), freq: freq, maxNumFiles: maxNumFiles, closer: make(chan struct{}), diff --git a/utils/profiler/profiler.go b/utils/profiler/profiler.go index c35606e7df91..a792b2bbf63f 100644 --- a/utils/profiler/profiler.go +++ b/utils/profiler/profiler.go @@ -23,6 +23,8 @@ const ( ) var ( + _ Profiler = (*profiler)(nil) + errCPUProfilerRunning = errors.New("cpu profiler already running") errCPUProfilerNotRunning = errors.New("cpu profiler doesn't exist") ) @@ -53,10 +55,10 @@ type profiler struct { } func New(dir string) Profiler { - return new(dir) + return newProfiler(dir) } -func new(dir string) *profiler { +func newProfiler(dir string) *profiler { return &profiler{ dir: dir, cpuProfileName: filepath.Join(dir, cpuProfileFile), From 128445448bef9a1fbe9130c272f1cf5f8e1338d9 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Fri, 22 Dec 2023 15:37:25 -0500 Subject: [PATCH 195/267] Move context lock into `network.issueTx` (#2525) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- vms/platformvm/block/builder/builder_test.go | 8 + vms/platformvm/network/network.go | 18 +- vms/platformvm/service.go | 311 ++++++++++-------- vms/platformvm/service_test.go | 6 +- vms/platformvm/validator_set_property_test.go | 11 +- vms/platformvm/vm.go | 14 + vms/platformvm/vm_regression_test.go | 120 +++++-- vms/platformvm/vm_test.go | 60 +++- 8 files changed, 357 insertions(+), 191 deletions(-) diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 51062fa3cdb7..0aae84a294cf 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -52,7 +52,9 @@ func TestBuildBlockBasic(t *testing.T) { txID := tx.ID() // Issue the transaction + env.ctx.Lock.Unlock() require.NoError(env.network.IssueTx(context.Background(), tx)) + env.ctx.Lock.Lock() _, ok := env.mempool.Get(txID) require.True(ok) @@ -125,7 +127,9 @@ func TestBuildBlockShouldReward(t *testing.T) { txID := tx.ID() // Issue the transaction + env.ctx.Lock.Unlock() require.NoError(env.network.IssueTx(context.Background(), tx)) + env.ctx.Lock.Lock() _, ok := env.mempool.Get(txID) require.True(ok) @@ -249,7 +253,9 @@ func TestBuildBlockForceAdvanceTime(t *testing.T) { txID := tx.ID() // Issue the transaction + env.ctx.Lock.Unlock() require.NoError(env.network.IssueTx(context.Background(), tx)) + env.ctx.Lock.Lock() _, ok := env.mempool.Get(txID) require.True(ok) @@ -471,6 +477,7 @@ func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { env := newEnvironment(t) env.ctx.Lock.Lock() defer func() { + env.ctx.Lock.Lock() require.NoError(shutdownEnvironment(env)) env.ctx.Lock.Unlock() }() @@ -500,6 +507,7 @@ func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { require.ErrorIs(reason, errTestingDropped) // Issue the transaction + env.ctx.Lock.Unlock() require.NoError(env.network.IssueTx(context.Background(), tx)) _, ok := env.mempool.Get(txID) require.True(ok) diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index 971ba8aa28f0..bcd6280014ae 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -30,8 +30,6 @@ type Network interface { // IssueTx verifies the transaction at the currently preferred state, adds // it to the mempool, and gossips it to the network. - // - // Invariant: Assumes the context lock is held. IssueTx(context.Context, *txs.Tx) error } @@ -109,14 +107,6 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b } txID := tx.ID() - // We need to grab the context lock here to avoid racy behavior with - // transaction verification + mempool modifications. - // - // Invariant: tx should not be referenced again without the context lock - // held to avoid any data races. - n.ctx.Lock.Lock() - defer n.ctx.Lock.Unlock() - if reason := n.mempool.GetDropReason(txID); reason != nil { // If the tx is being dropped - just ignore it return nil @@ -155,7 +145,13 @@ func (n *network) issueTx(tx *txs.Tx) error { } // Verify the tx at the currently preferred state - if err := n.manager.VerifyTx(tx); err != nil { + // + // We need to grab the context lock here to avoid racy behavior with + // transaction verification + mempool modifications. + n.ctx.Lock.Lock() + err := n.manager.VerifyTx(tx) + n.ctx.Lock.Unlock() + if err != nil { n.ctx.Log.Debug("tx failed verification", zap.Stringer("txID", txID), zap.Error(err), diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 09489dd08209..6331e72a2acc 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -1191,6 +1191,21 @@ func (s *Service) AddValidator(req *http.Request, args *AddValidatorArgs, reply zap.String("method", "addValidator"), ) + tx, changeAddr, err := s.buildAddValidatorTx(args) + if err != nil { + return fmt.Errorf("couldn't create tx: %w", err) + } + + reply.TxID = tx.ID() + reply.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) + if err != nil { + return fmt.Errorf("couldn't format address: %w", err) + } + + return s.vm.issueTx(req.Context(), tx) +} + +func (s *Service) buildAddValidatorTx(args *AddValidatorArgs) (*txs.Tx, ids.ShortID, error) { now := s.vm.clock.Time() minAddStakerTime := now.Add(minAddStakerDelay) minAddStakerUnix := json.Uint64(minAddStakerTime.Unix()) @@ -1203,13 +1218,13 @@ func (s *Service) AddValidator(req *http.Request, args *AddValidatorArgs, reply switch { case args.RewardAddress == "": - return errNoRewardAddress + return nil, ids.ShortEmpty, errNoRewardAddress case args.StartTime < minAddStakerUnix: - return errStartTimeTooSoon + return nil, ids.ShortEmpty, errStartTimeTooSoon case args.StartTime > maxAddStakerUnix: - return errStartTimeTooLate + return nil, ids.ShortEmpty, errStartTimeTooLate case args.DelegationFeeRate < 0 || args.DelegationFeeRate > 100: - return errInvalidDelegationRate + return nil, ids.ShortEmpty, errInvalidDelegationRate } // Parse the node ID @@ -1223,13 +1238,13 @@ func (s *Service) AddValidator(req *http.Request, args *AddValidatorArgs, reply // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.addrManager, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the reward address rewardAddress, err := avax.ParseServiceAddress(s.addrManager, args.RewardAddress) if err != nil { - return fmt.Errorf("problem while parsing reward address: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("problem while parsing reward address: %w", err) } s.vm.ctx.Lock.Lock() @@ -1237,25 +1252,25 @@ func (s *Service) AddValidator(req *http.Request, args *AddValidatorArgs, reply user, err := keystore.NewUserFromKeystore(s.vm.ctx.Keystore, args.Username, args.Password) if err != nil { - return err + return nil, ids.ShortEmpty, err } defer user.Close() // Get the user's keys privKeys, err := keystore.GetKeychain(user, fromAddrs) if err != nil { - return fmt.Errorf("couldn't get addresses controlled by the user: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't get addresses controlled by the user: %w", err) } // Parse the change address. if len(privKeys.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr := privKeys.Keys[0].PublicKey().Address() // By default, use a key controlled by the user if args.ChangeAddr != "" { changeAddr, err = avax.ParseServiceAddress(s.addrManager, args.ChangeAddr) if err != nil { - return fmt.Errorf("couldn't parse changeAddr: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't parse changeAddr: %w", err) } } @@ -1276,17 +1291,10 @@ func (s *Service) AddValidator(req *http.Request, args *AddValidatorArgs, reply changeAddr, ) if err != nil { - return fmt.Errorf("couldn't create tx: %w", err) + return nil, ids.ShortEmpty, err } - reply.TxID = tx.ID() - reply.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) - - return utils.Err( - err, - s.vm.Network.IssueTx(req.Context(), tx), - user.Close(), - ) + return tx, changeAddr, user.Close() } // AddDelegatorArgs are the arguments to AddDelegator @@ -1305,6 +1313,21 @@ func (s *Service) AddDelegator(req *http.Request, args *AddDelegatorArgs, reply zap.String("method", "addDelegator"), ) + tx, changeAddr, err := s.buildAddDelegatorTx(args) + if err != nil { + return fmt.Errorf("couldn't create tx: %w", err) + } + + reply.TxID = tx.ID() + reply.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) + if err != nil { + return fmt.Errorf("couldn't format address: %w", err) + } + + return s.vm.issueTx(req.Context(), tx) +} + +func (s *Service) buildAddDelegatorTx(args *AddDelegatorArgs) (*txs.Tx, ids.ShortID, error) { now := s.vm.clock.Time() minAddStakerTime := now.Add(minAddStakerDelay) minAddStakerUnix := json.Uint64(minAddStakerTime.Unix()) @@ -1317,11 +1340,11 @@ func (s *Service) AddDelegator(req *http.Request, args *AddDelegatorArgs, reply switch { case args.RewardAddress == "": - return errNoRewardAddress + return nil, ids.ShortEmpty, errNoRewardAddress case args.StartTime < minAddStakerUnix: - return errStartTimeTooSoon + return nil, ids.ShortEmpty, errStartTimeTooSoon case args.StartTime > maxAddStakerUnix: - return errStartTimeTooLate + return nil, ids.ShortEmpty, errStartTimeTooLate } var nodeID ids.NodeID @@ -1334,13 +1357,13 @@ func (s *Service) AddDelegator(req *http.Request, args *AddDelegatorArgs, reply // Parse the reward address rewardAddress, err := avax.ParseServiceAddress(s.addrManager, args.RewardAddress) if err != nil { - return fmt.Errorf("problem parsing 'rewardAddress': %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("problem parsing 'rewardAddress': %w", err) } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.addrManager, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1348,25 +1371,25 @@ func (s *Service) AddDelegator(req *http.Request, args *AddDelegatorArgs, reply user, err := keystore.NewUserFromKeystore(s.vm.ctx.Keystore, args.Username, args.Password) if err != nil { - return err + return nil, ids.ShortEmpty, err } defer user.Close() privKeys, err := keystore.GetKeychain(user, fromAddrs) if err != nil { - return fmt.Errorf("couldn't get addresses controlled by the user: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't get addresses controlled by the user: %w", err) } // Parse the change address. Assumes that if the user has no keys, // this operation will fail so the change address can be anything. if len(privKeys.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr := privKeys.Keys[0].PublicKey().Address() // By default, use a key controlled by the user if args.ChangeAddr != "" { changeAddr, err = avax.ParseServiceAddress(s.addrManager, args.ChangeAddr) if err != nil { - return fmt.Errorf("couldn't parse changeAddr: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't parse changeAddr: %w", err) } } @@ -1386,17 +1409,10 @@ func (s *Service) AddDelegator(req *http.Request, args *AddDelegatorArgs, reply changeAddr, // Change address ) if err != nil { - return fmt.Errorf("couldn't create tx: %w", err) + return nil, ids.ShortEmpty, err } - reply.TxID = tx.ID() - reply.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) - - return utils.Err( - err, - s.vm.Network.IssueTx(req.Context(), tx), - user.Close(), - ) + return tx, changeAddr, user.Close() } // AddSubnetValidatorArgs are the arguments to AddSubnetValidator @@ -1416,6 +1432,21 @@ func (s *Service) AddSubnetValidator(req *http.Request, args *AddSubnetValidator zap.String("method", "addSubnetValidator"), ) + tx, changeAddr, err := s.buildAddSubnetValidatorTx(args) + if err != nil { + return fmt.Errorf("couldn't create tx: %w", err) + } + + response.TxID = tx.ID() + response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) + if err != nil { + return fmt.Errorf("couldn't format address: %w", err) + } + + return s.vm.issueTx(req.Context(), tx) +} + +func (s *Service) buildAddSubnetValidatorTx(args *AddSubnetValidatorArgs) (*txs.Tx, ids.ShortID, error) { now := s.vm.clock.Time() minAddStakerTime := now.Add(minAddStakerDelay) minAddStakerUnix := json.Uint64(minAddStakerTime.Unix()) @@ -1428,26 +1459,26 @@ func (s *Service) AddSubnetValidator(req *http.Request, args *AddSubnetValidator switch { case args.SubnetID == "": - return errNoSubnetID + return nil, ids.ShortEmpty, errNoSubnetID case args.StartTime < minAddStakerUnix: - return errStartTimeTooSoon + return nil, ids.ShortEmpty, errStartTimeTooSoon case args.StartTime > maxAddStakerUnix: - return errStartTimeTooLate + return nil, ids.ShortEmpty, errStartTimeTooLate } // Parse the subnet ID subnetID, err := ids.FromString(args.SubnetID) if err != nil { - return fmt.Errorf("problem parsing subnetID %q: %w", args.SubnetID, err) + return nil, ids.ShortEmpty, fmt.Errorf("problem parsing subnetID %q: %w", args.SubnetID, err) } if subnetID == constants.PrimaryNetworkID { - return errNamedSubnetCantBePrimary + return nil, ids.ShortEmpty, errNamedSubnetCantBePrimary } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.addrManager, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1455,24 +1486,24 @@ func (s *Service) AddSubnetValidator(req *http.Request, args *AddSubnetValidator user, err := keystore.NewUserFromKeystore(s.vm.ctx.Keystore, args.Username, args.Password) if err != nil { - return err + return nil, ids.ShortEmpty, err } defer user.Close() keys, err := keystore.GetKeychain(user, fromAddrs) if err != nil { - return fmt.Errorf("couldn't get addresses controlled by the user: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't get addresses controlled by the user: %w", err) } // Parse the change address. if len(keys.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr := keys.Keys[0].PublicKey().Address() // By default, use a key controlled by the user if args.ChangeAddr != "" { changeAddr, err = avax.ParseServiceAddress(s.addrManager, args.ChangeAddr) if err != nil { - return fmt.Errorf("couldn't parse changeAddr: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't parse changeAddr: %w", err) } } @@ -1492,17 +1523,10 @@ func (s *Service) AddSubnetValidator(req *http.Request, args *AddSubnetValidator changeAddr, ) if err != nil { - return fmt.Errorf("couldn't create tx: %w", err) + return nil, ids.ShortEmpty, err } - response.TxID = tx.ID() - response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) - - return utils.Err( - err, - s.vm.Network.IssueTx(req.Context(), tx), - user.Close(), - ) + return tx, changeAddr, user.Close() } // CreateSubnetArgs are the arguments to CreateSubnet @@ -1521,16 +1545,31 @@ func (s *Service) CreateSubnet(req *http.Request, args *CreateSubnetArgs, respon zap.String("method", "createSubnet"), ) + tx, changeAddr, err := s.buildCreateSubnetTx(args) + if err != nil { + return fmt.Errorf("couldn't create tx: %w", err) + } + + response.TxID = tx.ID() + response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) + if err != nil { + return fmt.Errorf("couldn't format address: %w", err) + } + + return s.vm.issueTx(req.Context(), tx) +} + +func (s *Service) buildCreateSubnetTx(args *CreateSubnetArgs) (*txs.Tx, ids.ShortID, error) { // Parse the control keys controlKeys, err := avax.ParseServiceAddresses(s.addrManager, args.ControlKeys) if err != nil { - return err + return nil, ids.ShortEmpty, err } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.addrManager, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1538,25 +1577,25 @@ func (s *Service) CreateSubnet(req *http.Request, args *CreateSubnetArgs, respon user, err := keystore.NewUserFromKeystore(s.vm.ctx.Keystore, args.Username, args.Password) if err != nil { - return err + return nil, ids.ShortEmpty, err } defer user.Close() privKeys, err := keystore.GetKeychain(user, fromAddrs) if err != nil { - return fmt.Errorf("couldn't get addresses controlled by the user: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't get addresses controlled by the user: %w", err) } // Parse the change address. Assumes that if the user has no keys, // this operation will fail so the change address can be anything. if len(privKeys.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr := privKeys.Keys[0].PublicKey().Address() // By default, use a key controlled by the user if args.ChangeAddr != "" { changeAddr, err = avax.ParseServiceAddress(s.addrManager, args.ChangeAddr) if err != nil { - return fmt.Errorf("couldn't parse changeAddr: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't parse changeAddr: %w", err) } } @@ -1568,17 +1607,10 @@ func (s *Service) CreateSubnet(req *http.Request, args *CreateSubnetArgs, respon changeAddr, ) if err != nil { - return fmt.Errorf("couldn't create tx: %w", err) + return nil, ids.ShortEmpty, err } - response.TxID = tx.ID() - response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) - - return utils.Err( - err, - s.vm.Network.IssueTx(req.Context(), tx), - user.Close(), - ) + return tx, changeAddr, user.Close() } // ExportAVAXArgs are the arguments to ExportAVAX @@ -1605,8 +1637,23 @@ func (s *Service) ExportAVAX(req *http.Request, args *ExportAVAXArgs, response * zap.String("method", "exportAVAX"), ) + tx, changeAddr, err := s.buildExportAVAX(args) + if err != nil { + return fmt.Errorf("couldn't create tx: %w", err) + } + + response.TxID = tx.ID() + response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) + if err != nil { + return fmt.Errorf("couldn't format address: %w", err) + } + + return s.vm.issueTx(req.Context(), tx) +} + +func (s *Service) buildExportAVAX(args *ExportAVAXArgs) (*txs.Tx, ids.ShortID, error) { if args.Amount == 0 { - return errNoAmount + return nil, ids.ShortEmpty, errNoAmount } // Get the chainID and parse the to address @@ -1614,18 +1661,18 @@ func (s *Service) ExportAVAX(req *http.Request, args *ExportAVAXArgs, response * if err != nil { chainID, err = s.vm.ctx.BCLookup.Lookup(args.TargetChain) if err != nil { - return err + return nil, ids.ShortEmpty, err } to, err = ids.ShortFromString(args.To) if err != nil { - return err + return nil, ids.ShortEmpty, err } } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.addrManager, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1633,25 +1680,25 @@ func (s *Service) ExportAVAX(req *http.Request, args *ExportAVAXArgs, response * user, err := keystore.NewUserFromKeystore(s.vm.ctx.Keystore, args.Username, args.Password) if err != nil { - return err + return nil, ids.ShortEmpty, err } defer user.Close() privKeys, err := keystore.GetKeychain(user, fromAddrs) if err != nil { - return fmt.Errorf("couldn't get addresses controlled by the user: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't get addresses controlled by the user: %w", err) } // Parse the change address. Assumes that if the user has no keys, // this operation will fail so the change address can be anything. if len(privKeys.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr := privKeys.Keys[0].PublicKey().Address() // By default, use a key controlled by the user if args.ChangeAddr != "" { changeAddr, err = avax.ParseServiceAddress(s.addrManager, args.ChangeAddr) if err != nil { - return fmt.Errorf("couldn't parse changeAddr: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't parse changeAddr: %w", err) } } @@ -1664,17 +1711,10 @@ func (s *Service) ExportAVAX(req *http.Request, args *ExportAVAXArgs, response * changeAddr, // Change address ) if err != nil { - return fmt.Errorf("couldn't create tx: %w", err) + return nil, ids.ShortEmpty, err } - response.TxID = tx.ID() - response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) - - return utils.Err( - err, - s.vm.Network.IssueTx(req.Context(), tx), - user.Close(), - ) + return tx, changeAddr, user.Close() } // ImportAVAXArgs are the arguments to ImportAVAX @@ -1697,22 +1737,37 @@ func (s *Service) ImportAVAX(req *http.Request, args *ImportAVAXArgs, response * zap.String("method", "importAVAX"), ) + tx, changeAddr, err := s.buildImportAVAXTx(args) + if err != nil { + return fmt.Errorf("couldn't create tx: %w", err) + } + + response.TxID = tx.ID() + response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) + if err != nil { + return fmt.Errorf("problem formatting address: %w", err) + } + + return s.vm.issueTx(req.Context(), tx) +} + +func (s *Service) buildImportAVAXTx(args *ImportAVAXArgs) (*txs.Tx, ids.ShortID, error) { // Parse the sourceCHain chainID, err := s.vm.ctx.BCLookup.Lookup(args.SourceChain) if err != nil { - return fmt.Errorf("problem parsing chainID %q: %w", args.SourceChain, err) + return nil, ids.ShortEmpty, fmt.Errorf("problem parsing chainID %q: %w", args.SourceChain, err) } // Parse the to address to, err := avax.ParseServiceAddress(s.addrManager, args.To) if err != nil { // Parse address - return fmt.Errorf("couldn't parse argument 'to' to an address: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't parse argument 'to' to an address: %w", err) } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.addrManager, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1720,25 +1775,25 @@ func (s *Service) ImportAVAX(req *http.Request, args *ImportAVAXArgs, response * user, err := keystore.NewUserFromKeystore(s.vm.ctx.Keystore, args.Username, args.Password) if err != nil { - return err + return nil, ids.ShortEmpty, err } defer user.Close() privKeys, err := keystore.GetKeychain(user, fromAddrs) if err != nil { // Get keys - return fmt.Errorf("couldn't get keys controlled by the user: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't get keys controlled by the user: %w", err) } // Parse the change address. Assumes that if the user has no keys, // this operation will fail so the change address can be anything. if len(privKeys.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr := privKeys.Keys[0].PublicKey().Address() // By default, use a key controlled by the user if args.ChangeAddr != "" { changeAddr, err = avax.ParseServiceAddress(s.addrManager, args.ChangeAddr) if err != nil { - return fmt.Errorf("couldn't parse changeAddr: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't parse changeAddr: %w", err) } } @@ -1749,17 +1804,10 @@ func (s *Service) ImportAVAX(req *http.Request, args *ImportAVAXArgs, response * changeAddr, ) if err != nil { - return err + return nil, ids.ShortEmpty, err } - response.TxID = tx.ID() - response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) - - return utils.Err( - err, - s.vm.Network.IssueTx(req.Context(), tx), - user.Close(), - ) + return tx, changeAddr, user.Close() } /* @@ -1793,28 +1841,43 @@ func (s *Service) CreateBlockchain(req *http.Request, args *CreateBlockchainArgs zap.String("method", "createBlockchain"), ) + tx, changeAddr, err := s.buildCreateBlockchainTx(args) + if err != nil { + return fmt.Errorf("couldn't create tx: %w", err) + } + + response.TxID = tx.ID() + response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) + if err != nil { + return fmt.Errorf("problem formatting address: %w", err) + } + + return s.vm.issueTx(req.Context(), tx) +} + +func (s *Service) buildCreateBlockchainTx(args *CreateBlockchainArgs) (*txs.Tx, ids.ShortID, error) { switch { case args.Name == "": - return errMissingName + return nil, ids.ShortEmpty, errMissingName case args.VMID == "": - return errMissingVMID + return nil, ids.ShortEmpty, errMissingVMID } genesisBytes, err := formatting.Decode(args.Encoding, args.GenesisData) if err != nil { - return fmt.Errorf("problem parsing genesis data: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("problem parsing genesis data: %w", err) } vmID, err := s.vm.Chains.LookupVM(args.VMID) if err != nil { - return fmt.Errorf("no VM with ID '%s' found", args.VMID) + return nil, ids.ShortEmpty, fmt.Errorf("no VM with ID '%s' found", args.VMID) } fxIDs := []ids.ID(nil) for _, fxIDStr := range args.FxIDs { fxID, err := s.vm.Chains.LookupVM(fxIDStr) if err != nil { - return fmt.Errorf("no FX with ID '%s' found", fxIDStr) + return nil, ids.ShortEmpty, fmt.Errorf("no FX with ID '%s' found", fxIDStr) } fxIDs = append(fxIDs, fxID) } @@ -1826,13 +1889,13 @@ func (s *Service) CreateBlockchain(req *http.Request, args *CreateBlockchainArgs } if args.SubnetID == constants.PrimaryNetworkID { - return txs.ErrCantValidatePrimaryNetwork + return nil, ids.ShortEmpty, txs.ErrCantValidatePrimaryNetwork } // Parse the from addresses fromAddrs, err := avax.ParseServiceAddresses(s.addrManager, args.From) if err != nil { - return err + return nil, ids.ShortEmpty, err } s.vm.ctx.Lock.Lock() @@ -1840,25 +1903,25 @@ func (s *Service) CreateBlockchain(req *http.Request, args *CreateBlockchainArgs user, err := keystore.NewUserFromKeystore(s.vm.ctx.Keystore, args.Username, args.Password) if err != nil { - return err + return nil, ids.ShortEmpty, err } defer user.Close() keys, err := keystore.GetKeychain(user, fromAddrs) if err != nil { - return fmt.Errorf("couldn't get addresses controlled by the user: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't get addresses controlled by the user: %w", err) } // Parse the change address. Assumes that if the user has no keys, // this operation will fail so the change address can be anything. if len(keys.Keys) == 0 { - return errNoKeys + return nil, ids.ShortEmpty, errNoKeys } changeAddr := keys.Keys[0].PublicKey().Address() // By default, use a key controlled by the user if args.ChangeAddr != "" { changeAddr, err = avax.ParseServiceAddress(s.addrManager, args.ChangeAddr) if err != nil { - return fmt.Errorf("couldn't parse changeAddr: %w", err) + return nil, ids.ShortEmpty, fmt.Errorf("couldn't parse changeAddr: %w", err) } } @@ -1873,17 +1936,10 @@ func (s *Service) CreateBlockchain(req *http.Request, args *CreateBlockchainArgs changeAddr, // Change address ) if err != nil { - return fmt.Errorf("couldn't create tx: %w", err) + return nil, ids.ShortEmpty, err } - response.TxID = tx.ID() - response.ChangeAddr, err = s.addrManager.FormatLocalAddress(changeAddr) - - return utils.Err( - err, - s.vm.Network.IssueTx(req.Context(), tx), - user.Close(), - ) + return tx, changeAddr, user.Close() } // GetBlockchainStatusArgs is the arguments for calling GetBlockchainStatus @@ -2170,10 +2226,7 @@ func (s *Service) IssueTx(req *http.Request, args *api.FormattedTx, response *ap return fmt.Errorf("couldn't parse tx: %w", err) } - s.vm.ctx.Lock.Lock() - defer s.vm.ctx.Lock.Unlock() - - if err := s.vm.Network.IssueTx(req.Context(), tx); err != nil { + if err := s.vm.issueTx(req.Context(), tx); err != nil { return fmt.Errorf("couldn't issue tx: %w", err) } @@ -2557,7 +2610,7 @@ func (s *Service) GetRewardUTXOs(_ *http.Request, args *api.GetTxArgs, reply *Ge for i, utxo := range utxos { utxoBytes, err := txs.GenesisCodec.Marshal(txs.Version, utxo) if err != nil { - return fmt.Errorf("failed to encode UTXO to bytes: %w", err) + return fmt.Errorf("couldn't encode UTXO to bytes: %w", err) } utxoStr, err := formatting.Encode(args.Encoding, utxoBytes) diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 28a3e80258ed..376b809fa3d8 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -240,8 +240,6 @@ func TestGetTxStatus(t *testing.T) { require.Equal(status.Unknown, resp.Status) require.Zero(resp.Reason) - service.vm.ctx.Lock.Lock() - // put the chain in existing chain list err = service.vm.Network.IssueTx(context.Background(), tx) require.ErrorIs(err, database.ErrNotFound) // Missing shared memory UTXO @@ -249,6 +247,7 @@ func TestGetTxStatus(t *testing.T) { mutableSharedMemory.SharedMemory = sm require.NoError(service.vm.Network.IssueTx(context.Background(), tx)) + service.vm.ctx.Lock.Lock() block, err := service.vm.BuildBlock(context.Background()) require.NoError(err) @@ -342,9 +341,8 @@ func TestGetTx(t *testing.T) { err = service.GetTx(nil, arg, &response) require.ErrorIs(err, database.ErrNotFound) // We haven't issued the tx yet - service.vm.ctx.Lock.Lock() - require.NoError(service.vm.Network.IssueTx(context.Background(), tx)) + service.vm.ctx.Lock.Lock() blk, err := service.vm.BuildBlock(context.Background()) require.NoError(err) diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 3dfb6e456bb2..630124f99009 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -374,7 +374,11 @@ func addPrimaryValidatorWithoutBLSKey(vm *VM, data *validatorInputData) (*state. } func internalAddValidator(vm *VM, signedTx *txs.Tx) (*state.Staker, error) { - if err := vm.Network.IssueTx(context.Background(), signedTx); err != nil { + vm.ctx.Lock.Unlock() + err := vm.issueTx(context.Background(), signedTx) + vm.ctx.Lock.Lock() + + if err != nil { return nil, fmt.Errorf("could not add tx to mempool: %w", err) } @@ -784,7 +788,10 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { if err != nil { return nil, ids.Empty, err } - if err := vm.Network.IssueTx(context.Background(), testSubnet1); err != nil { + vm.ctx.Lock.Unlock() + err = vm.issueTx(context.Background(), testSubnet1) + vm.ctx.Lock.Lock() + if err != nil { return nil, ids.Empty, err } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 8b578c9f621a..012c0a24713b 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -5,6 +5,7 @@ package platformvm import ( "context" + "errors" "fmt" "net/http" @@ -480,3 +481,16 @@ func (vm *VM) VerifyHeightIndex(_ context.Context) error { func (vm *VM) GetBlockIDAtHeight(_ context.Context, height uint64) (ids.ID, error) { return vm.state.GetBlockIDAtHeight(height) } + +func (vm *VM) issueTx(ctx context.Context, tx *txs.Tx) error { + err := vm.Network.IssueTx(ctx, tx) + if err != nil && !errors.Is(err, mempool.ErrDuplicateTx) { + vm.ctx.Log.Debug("failed to add tx to mempool", + zap.Stringer("txID", tx.ID()), + zap.Error(err), + ) + return err + } + + return nil +} diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 03725da3a662..4b820f615913 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -50,6 +50,7 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { vm, _, _ := defaultVM(t, cortinaFork) vm.ctx.Lock.Lock() defer func() { + vm.ctx.Lock.Lock() require.NoError(vm.Shutdown(context.Background())) vm.ctx.Lock.Unlock() }() @@ -74,7 +75,9 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Lock() addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -106,7 +109,9 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Network.IssueTx(context.Background(), addFirstDelegatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addFirstDelegatorTx)) + vm.ctx.Lock.Lock() addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -140,7 +145,9 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Network.IssueTx(context.Background(), addSecondDelegatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addSecondDelegatorTx)) + vm.ctx.Lock.Lock() addSecondDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -164,7 +171,8 @@ func TestAddDelegatorTxOverDelegatedRegression(t *testing.T) { require.NoError(err) // trigger block creation - err = vm.Network.IssueTx(context.Background(), addThirdDelegatorTx) + vm.ctx.Lock.Unlock() + err = vm.issueTx(context.Background(), addThirdDelegatorTx) require.ErrorIs(err, executor.ErrOverDelegated) } @@ -237,7 +245,9 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the add validator tx - require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -259,7 +269,9 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the first add delegator tx - require.NoError(vm.Network.IssueTx(context.Background(), addFirstDelegatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addFirstDelegatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the first add delegator tx addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -281,7 +293,9 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the second add delegator tx - require.NoError(vm.Network.IssueTx(context.Background(), addSecondDelegatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addSecondDelegatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the second add delegator tx addSecondDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -303,7 +317,9 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the third add delegator tx - require.NoError(vm.Network.IssueTx(context.Background(), addThirdDelegatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addThirdDelegatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the third add delegator tx addThirdDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -325,7 +341,9 @@ func TestAddDelegatorTxHeapCorruption(t *testing.T) { require.NoError(err) // issue the fourth add delegator tx - require.NoError(vm.Network.IssueTx(context.Background(), addFourthDelegatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addFourthDelegatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the fourth add delegator tx addFourthDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1133,6 +1151,7 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { vm.ctx.Lock.Lock() defer func() { + vm.ctx.Lock.Lock() require.NoError(vm.Shutdown(context.Background())) vm.ctx.Lock.Unlock() @@ -1159,7 +1178,9 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require.NoError(err) // issue the add validator tx - require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1181,7 +1202,9 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { require.NoError(err) // issue the first add delegator tx - require.NoError(vm.Network.IssueTx(context.Background(), addFirstDelegatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addFirstDelegatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the first add delegator tx addFirstDelegatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1204,7 +1227,8 @@ func TestAddDelegatorTxAddBeforeRemove(t *testing.T) { // attempting to issue the second add delegator tx should fail because the // total stake weight would go over the limit. - err = vm.Network.IssueTx(context.Background(), addSecondDelegatorTx) + vm.ctx.Lock.Unlock() + err = vm.issueTx(context.Background(), addSecondDelegatorTx) require.ErrorIs(err, executor.ErrOverDelegated) } @@ -1241,7 +1265,9 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1258,7 +1284,9 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Lock() // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1278,7 +1306,9 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), addSubnetValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addSubnetValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx addSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1307,7 +1337,9 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionNotTracked(t // validator set into the current validator set. vm.clock.Set(validatorStartTime) - require.NoError(vm.Network.IssueTx(context.Background(), removeSubnetValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), removeSubnetValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx removeSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1359,7 +1391,9 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1376,7 +1410,9 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Lock() // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1396,7 +1432,9 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), addSubnetValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addSubnetValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx addSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1417,7 +1455,9 @@ func TestRemovePermissionedValidatorDuringPendingToCurrentTransitionTracked(t *t // validator set into the current validator set. vm.clock.Set(validatorStartTime) - require.NoError(vm.Network.IssueTx(context.Background(), removeSubnetValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), removeSubnetValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx removeSubnetValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -1511,7 +1551,9 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NoError(primaryTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Network.IssueTx(context.Background(), primaryTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), primaryTx)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1538,7 +1580,9 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), subnetTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), subnetTx)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current @@ -1642,7 +1686,9 @@ func TestSubnetValidatorBLSKeyDiffAfterExpiry(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Network.IssueTx(context.Background(), primaryRestartTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), primaryRestartTx)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -1749,7 +1795,9 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), primaryTx1)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), primaryTx1)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1841,7 +1889,9 @@ func TestPrimaryNetworkValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Network.IssueTx(context.Background(), primaryRestartTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), primaryRestartTx)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -1912,7 +1962,9 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), primaryTx1)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), primaryTx1)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -1939,7 +1991,9 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), subnetTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), subnetTx)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current @@ -2043,7 +2097,9 @@ func TestSubnetValidatorPopulatedToEmptyBLSKeyDiff(t *testing.T) { require.NoError(err) require.NoError(uPrimaryRestartTx.SyntacticVerify(vm.ctx)) - require.NoError(vm.Network.IssueTx(context.Background(), primaryRestartTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), primaryRestartTx)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting restarted primary validator to current @@ -2121,7 +2177,9 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), primaryTx1)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), primaryTx1)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting primary validator to current @@ -2145,7 +2203,9 @@ func TestSubnetValidatorSetAfterPrimaryNetworkValidatorRemoval(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), subnetTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), subnetTx)) + vm.ctx.Lock.Lock() require.NoError(buildAndAcceptStandardBlock(vm)) // move time ahead, promoting the subnet validator to current diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 4ab310da5bb2..3632cbefc10f 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -306,7 +306,9 @@ func defaultVM(t *testing.T, fork activeFork) (*VM, database.Database, *mutableS keys[0].PublicKey().Address(), // change addr ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), testSubnet1)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), testSubnet1)) + vm.ctx.Lock.Lock() blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) require.NoError(blk.Verify(context.Background())) @@ -403,7 +405,9 @@ func TestAddValidatorCommit(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Network.IssueTx(context.Background(), tx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), tx)) + vm.ctx.Lock.Lock() blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -504,7 +508,9 @@ func TestAddValidatorReject(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Network.IssueTx(context.Background(), tx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), tx)) + vm.ctx.Lock.Lock() blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -525,6 +531,7 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { vm, _, _ := defaultVM(t, latestFork) vm.ctx.Lock.Lock() defer func() { + vm.ctx.Lock.Lock() require.NoError(vm.Shutdown(context.Background())) vm.ctx.Lock.Unlock() }() @@ -549,7 +556,8 @@ func TestAddValidatorInvalidNotReissued(t *testing.T) { require.NoError(err) // trigger block creation - err = vm.Network.IssueTx(context.Background(), tx) + vm.ctx.Lock.Unlock() + err = vm.issueTx(context.Background(), tx) require.ErrorIs(err, txexecutor.ErrAlreadyValidator) } @@ -584,7 +592,9 @@ func TestAddSubnetValidatorAccept(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Network.IssueTx(context.Background(), tx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), tx)) + vm.ctx.Lock.Lock() blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -632,7 +642,9 @@ func TestAddSubnetValidatorReject(t *testing.T) { require.NoError(err) // trigger block creation - require.NoError(vm.Network.IssueTx(context.Background(), tx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), tx)) + vm.ctx.Lock.Lock() blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -826,7 +838,9 @@ func TestCreateChain(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), tx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), tx)) + vm.ctx.Lock.Lock() blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) // should contain proposal to create chain @@ -877,7 +891,9 @@ func TestCreateSubnet(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Lock() // should contain the CreateSubnetTx blk, err := vm.Builder.BuildBlock(context.Background()) @@ -918,7 +934,9 @@ func TestCreateSubnet(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Lock() blk, err = vm.Builder.BuildBlock(context.Background()) // should add validator to the new subnet require.NoError(err) @@ -1021,7 +1039,9 @@ func TestAtomicImport(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), tx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), tx)) + vm.ctx.Lock.Lock() blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2026,7 +2046,9 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Lock() // trigger block creation for the validator tx addValidatorBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -2043,7 +2065,9 @@ func TestRemovePermissionedValidatorDuringAddPending(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Lock() // trigger block creation for the subnet tx createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) @@ -2112,7 +2136,9 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { require.NoError(err) subnetID := createSubnetTx.ID() - require.NoError(vm.Network.IssueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), createSubnetTx)) + vm.ctx.Lock.Lock() createSubnetBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2144,7 +2170,9 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), transferSubnetOwnershipTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), transferSubnetOwnershipTx)) + vm.ctx.Lock.Lock() transferSubnetOwnershipBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) @@ -2230,7 +2258,9 @@ func TestBaseTx(t *testing.T) { require.Equal(vm.TxFee, totalInputAmt-totalOutputAmt) require.Equal(sendAmt, key1OutputAmt) - require.NoError(vm.Network.IssueTx(context.Background(), baseTx)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), baseTx)) + vm.ctx.Lock.Lock() baseTxBlock, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) From c950f0f69005dbe3664960a18451ce05ae05a29c Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Fri, 22 Dec 2023 15:39:55 -0500 Subject: [PATCH 196/267] Remove comment on treating failed sends as FATAL (#2544) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- snow/engine/common/sender.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/snow/engine/common/sender.go b/snow/engine/common/sender.go index d596a35bcc2e..885f4d9bd78f 100644 --- a/snow/engine/common/sender.go +++ b/snow/engine/common/sender.go @@ -175,15 +175,12 @@ type NetworkAppSender interface { // * An AppResponse from nodeID with ID [requestID] // * An AppRequestFailed from nodeID with ID [requestID] // Exactly one of the above messages will eventually be received per nodeID. - // A non-nil error should be considered fatal. SendAppRequest(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, appRequestBytes []byte) error // Send an application-level response to a request. // This response must be in response to an AppRequest that the VM corresponding // to this AppSender received from [nodeID] with ID [requestID]. - // A non-nil error should be considered fatal. SendAppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, appResponseBytes []byte) error // Gossip an application-level message. - // A non-nil error should be considered fatal. SendAppGossip(ctx context.Context, appGossipBytes []byte) error SendAppGossipSpecific(ctx context.Context, nodeIDs set.Set[ids.NodeID], appGossipBytes []byte) error } @@ -199,7 +196,6 @@ type CrossChainAppSender interface { // * A CrossChainAppRequestFailed from [chainID] with ID [requestID] // Exactly one of the above messages will eventually be received from // [chainID]. - // A non-nil error should be considered fatal. SendCrossChainAppRequest(ctx context.Context, chainID ids.ID, requestID uint32, appRequestBytes []byte) error // SendCrossChainAppResponse sends an application-level response to a // specific chain @@ -207,7 +203,6 @@ type CrossChainAppSender interface { // This response must be in response to a CrossChainAppRequest that the VM // corresponding to this CrossChainAppSender received from [chainID] with ID // [requestID]. - // A non-nil error should be considered fatal. SendCrossChainAppResponse(ctx context.Context, chainID ids.ID, requestID uint32, appResponseBytes []byte) error } From 5888ac3849f1e71a6081e364e7f71aa183d7a10a Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Fri, 22 Dec 2023 16:18:00 -0500 Subject: [PATCH 197/267] Add TxVerifier interface to network (#2542) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- vms/platformvm/block/builder/helpers_test.go | 3 +- vms/platformvm/network/network.go | 15 ++---- vms/platformvm/network/network_test.go | 53 +++++++------------- vms/platformvm/network/tx_verifier.go | 36 +++++++++++++ vms/platformvm/vm.go | 4 +- 5 files changed, 63 insertions(+), 48 deletions(-) create mode 100644 vms/platformvm/network/tx_verifier.go diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index d2acee3dc0d4..c507413f513a 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -181,9 +181,10 @@ func newEnvironment(t *testing.T) *environment { pvalidators.TestManager, ) + txVerifier := network.NewLockedTxVerifier(&res.ctx.Lock, res.blkManager) res.network = network.New( res.backend.Ctx, - res.blkManager, + txVerifier, res.mempool, res.backend.Config.PartialSyncPrimaryNetwork, res.sender, diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index bcd6280014ae..494150fe1c6f 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -14,7 +14,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/vms/components/message" - "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) @@ -38,7 +37,7 @@ type network struct { common.AppHandler ctx *snow.Context - manager executor.Manager + txVerifier TxVerifier mempool mempool.Mempool partialSyncPrimaryNetwork bool appSender common.AppSender @@ -50,7 +49,7 @@ type network struct { func New( ctx *snow.Context, - manager executor.Manager, + txVerifier TxVerifier, mempool mempool.Mempool, partialSyncPrimaryNetwork bool, appSender common.AppSender, @@ -59,7 +58,7 @@ func New( AppHandler: common.NewNoOpAppHandler(ctx.Log), ctx: ctx, - manager: manager, + txVerifier: txVerifier, mempool: mempool, partialSyncPrimaryNetwork: partialSyncPrimaryNetwork, appSender: appSender, @@ -145,13 +144,7 @@ func (n *network) issueTx(tx *txs.Tx) error { } // Verify the tx at the currently preferred state - // - // We need to grab the context lock here to avoid racy behavior with - // transaction verification + mempool modifications. - n.ctx.Lock.Lock() - err := n.manager.VerifyTx(tx) - n.ctx.Lock.Unlock() - if err != nil { + if err := n.txVerifier.VerifyTx(tx); err != nil { n.ctx.Log.Debug("tx failed verification", zap.Stringer("txID", txID), zap.Error(err), diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go index 1dcdbfdb572d..e1f73ebf112b 100644 --- a/vms/platformvm/network/network_test.go +++ b/vms/platformvm/network/network_test.go @@ -18,12 +18,22 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/message" - "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) -var errTest = errors.New("test error") +var ( + errTest = errors.New("test error") + _ TxVerifier = (*testTxVerifier)(nil) +) + +type testTxVerifier struct { + err error +} + +func (t testTxVerifier) VerifyTx(*txs.Tx) error { + return t.err +} func TestNetworkAppGossip(t *testing.T) { testTx := &txs.Tx{ @@ -159,7 +169,7 @@ func TestNetworkAppGossip(t *testing.T) { &snow.Context{ Log: logging.NoLog{}, }, - executor.NewMockManager(ctrl), // Manager is unused in this test + testTxVerifier{}, tt.mempoolFunc(ctrl), tt.partialSyncPrimaryNetwork, tt.appSenderFunc(ctrl), @@ -175,7 +185,7 @@ func TestNetworkIssueTx(t *testing.T) { type test struct { name string mempoolFunc func(*gomock.Controller) mempool.Mempool - managerFunc func(*gomock.Controller) executor.Manager + txVerifier testTxVerifier partialSyncPrimaryNetwork bool appSenderFunc func(*gomock.Controller) common.AppSender expectedErr error @@ -189,10 +199,6 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(tx, true) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - // Unused in this test - return executor.NewMockManager(ctrl) - }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { // Should gossip the tx appSender := common.NewMockSender(ctrl) @@ -209,11 +215,7 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(errTest) - return manager - }, + txVerifier: testTxVerifier{err: errTest}, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { // Shouldn't gossip the tx return common.NewMockSender(ctrl) @@ -228,11 +230,7 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(errTest) - return manager - }, + txVerifier: testTxVerifier{err: errTest}, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { // Shouldn't gossip the tx return common.NewMockSender(ctrl) @@ -248,11 +246,6 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().MarkDropped(gomock.Any(), errTest) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) - return manager - }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { // Shouldn't gossip the tx return common.NewMockSender(ctrl) @@ -266,11 +259,6 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(nil, false) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) - return manager - }, partialSyncPrimaryNetwork: true, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { // Should gossip the tx @@ -289,11 +277,6 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().RequestBuildBlock(false) return mempool }, - managerFunc: func(ctrl *gomock.Controller) executor.Manager { - manager := executor.NewMockManager(ctrl) - manager.EXPECT().VerifyTx(gomock.Any()).Return(nil) - return manager - }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { // Should gossip the tx appSender := common.NewMockSender(ctrl) @@ -313,7 +296,7 @@ func TestNetworkIssueTx(t *testing.T) { &snow.Context{ Log: logging.NoLog{}, }, - tt.managerFunc(ctrl), + tt.txVerifier, tt.mempoolFunc(ctrl), tt.partialSyncPrimaryNetwork, tt.appSenderFunc(ctrl), @@ -334,7 +317,7 @@ func TestNetworkGossipTx(t *testing.T) { &snow.Context{ Log: logging.NoLog{}, }, - executor.NewMockManager(ctrl), + testTxVerifier{}, mempool.NewMockMempool(ctrl), false, appSender, diff --git a/vms/platformvm/network/tx_verifier.go b/vms/platformvm/network/tx_verifier.go new file mode 100644 index 000000000000..262171d06848 --- /dev/null +++ b/vms/platformvm/network/tx_verifier.go @@ -0,0 +1,36 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "sync" + + "github.com/ava-labs/avalanchego/vms/platformvm/txs" +) + +var _ TxVerifier = (*LockedTxVerifier)(nil) + +type TxVerifier interface { + // VerifyTx verifies that the transaction should be issued into the mempool. + VerifyTx(tx *txs.Tx) error +} + +type LockedTxVerifier struct { + lock sync.Locker + txVerifier TxVerifier +} + +func (l *LockedTxVerifier) VerifyTx(tx *txs.Tx) error { + l.lock.Lock() + defer l.lock.Unlock() + + return l.txVerifier.VerifyTx(tx) +} + +func NewLockedTxVerifier(lock sync.Locker, txVerifier TxVerifier) *LockedTxVerifier { + return &LockedTxVerifier{ + lock: lock, + txVerifier: txVerifier, + } +} diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 012c0a24713b..3bb1bec87825 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -190,9 +190,11 @@ func (vm *VM) Initialize( txExecutorBackend, validatorManager, ) + + txVerifier := network.NewLockedTxVerifier(&txExecutorBackend.Ctx.Lock, vm.manager) vm.Network = network.New( txExecutorBackend.Ctx, - vm.manager, + txVerifier, mempool, txExecutorBackend.Config.PartialSyncPrimaryNetwork, appSender, From 33f74116aafe961a9c72d1f3594573151c6c1ea6 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Fri, 22 Dec 2023 16:21:23 -0500 Subject: [PATCH 198/267] X-chain SDK gossip (#2490) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Signed-off-by: Stephen Buttolph Co-authored-by: Stephen Buttolph Co-authored-by: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> --- vms/avm/config.go | 34 ++++ vms/avm/config_test.go | 67 ++++++++ vms/avm/environment_test.go | 5 +- vms/avm/network/config.go | 66 ++++++++ vms/avm/network/gossip.go | 157 +++++++++++++++++++ vms/avm/network/gossip_test.go | 128 +++++++++++++++ vms/avm/network/network.go | 268 +++++++++++++++++++++----------- vms/avm/network/network_test.go | 48 ++++-- vms/avm/txs/tx.go | 8 + vms/avm/vm.go | 94 +++++++---- vms/avm/vm_test.go | 5 +- 11 files changed, 739 insertions(+), 141 deletions(-) create mode 100644 vms/avm/config.go create mode 100644 vms/avm/config_test.go create mode 100644 vms/avm/network/config.go create mode 100644 vms/avm/network/gossip.go create mode 100644 vms/avm/network/gossip_test.go diff --git a/vms/avm/config.go b/vms/avm/config.go new file mode 100644 index 000000000000..75f0194b15a2 --- /dev/null +++ b/vms/avm/config.go @@ -0,0 +1,34 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package avm + +import ( + "encoding/json" + + "github.com/ava-labs/avalanchego/vms/avm/network" +) + +var DefaultConfig = Config{ + Network: network.DefaultConfig, + IndexTransactions: false, + IndexAllowIncomplete: false, + ChecksumsEnabled: false, +} + +type Config struct { + Network network.Config `json:"network"` + IndexTransactions bool `json:"index-transactions"` + IndexAllowIncomplete bool `json:"index-allow-incomplete"` + ChecksumsEnabled bool `json:"checksums-enabled"` +} + +func ParseConfig(configBytes []byte) (Config, error) { + if len(configBytes) == 0 { + return DefaultConfig, nil + } + + config := DefaultConfig + err := json.Unmarshal(configBytes, &config) + return config, err +} diff --git a/vms/avm/config_test.go b/vms/avm/config_test.go new file mode 100644 index 000000000000..e11115028fd6 --- /dev/null +++ b/vms/avm/config_test.go @@ -0,0 +1,67 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package avm + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/vms/avm/network" +) + +func TestParseConfig(t *testing.T) { + tests := []struct { + name string + configBytes []byte + expectedConfig Config + }{ + { + name: "unspecified config", + configBytes: nil, + expectedConfig: DefaultConfig, + }, + { + name: "manually specified checksums enabled", + configBytes: []byte(`{"checksums-enabled":true}`), + expectedConfig: Config{ + Network: network.DefaultConfig, + IndexTransactions: DefaultConfig.IndexTransactions, + IndexAllowIncomplete: DefaultConfig.IndexAllowIncomplete, + ChecksumsEnabled: true, + }, + }, + { + name: "manually specified checksums enabled", + configBytes: []byte(`{"network":{"max-validator-set-staleness":1}}`), + expectedConfig: Config{ + Network: network.Config{ + MaxValidatorSetStaleness: time.Nanosecond, + TargetGossipSize: network.DefaultConfig.TargetGossipSize, + PullGossipPollSize: network.DefaultConfig.PullGossipPollSize, + PullGossipFrequency: network.DefaultConfig.PullGossipFrequency, + PullGossipThrottlingPeriod: network.DefaultConfig.PullGossipThrottlingPeriod, + PullGossipThrottlingLimit: network.DefaultConfig.PullGossipThrottlingLimit, + ExpectedBloomFilterElements: network.DefaultConfig.ExpectedBloomFilterElements, + ExpectedBloomFilterFalsePositiveProbability: network.DefaultConfig.ExpectedBloomFilterFalsePositiveProbability, + MaxBloomFilterFalsePositiveProbability: network.DefaultConfig.MaxBloomFilterFalsePositiveProbability, + LegacyPushGossipCacheSize: network.DefaultConfig.LegacyPushGossipCacheSize, + }, + IndexTransactions: DefaultConfig.IndexTransactions, + IndexAllowIncomplete: DefaultConfig.IndexAllowIncomplete, + ChecksumsEnabled: DefaultConfig.ChecksumsEnabled, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + config, err := ParseConfig(test.configBytes) + require.NoError(err) + require.Equal(test.expectedConfig, config) + }) + } +} diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index 5616371041ea..7811807521e0 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -157,9 +157,8 @@ func setup(tb testing.TB, c *envConfig) *environment { Config: vmStaticConfig, } - vmDynamicConfig := Config{ - IndexTransactions: true, - } + vmDynamicConfig := DefaultConfig + vmDynamicConfig.IndexTransactions = true if c.vmDynamicConfig != nil { vmDynamicConfig = *c.vmDynamicConfig } diff --git a/vms/avm/network/config.go b/vms/avm/network/config.go new file mode 100644 index 000000000000..2ff7828df2e4 --- /dev/null +++ b/vms/avm/network/config.go @@ -0,0 +1,66 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "time" + + "github.com/ava-labs/avalanchego/utils/units" +) + +var DefaultConfig = Config{ + MaxValidatorSetStaleness: time.Minute, + TargetGossipSize: 20 * units.KiB, + PullGossipPollSize: 1, + PullGossipFrequency: 1500 * time.Millisecond, + PullGossipThrottlingPeriod: 10 * time.Second, + PullGossipThrottlingLimit: 2, + ExpectedBloomFilterElements: 8 * 1024, + ExpectedBloomFilterFalsePositiveProbability: .01, + MaxBloomFilterFalsePositiveProbability: .05, + LegacyPushGossipCacheSize: 512, +} + +type Config struct { + // MaxValidatorSetStaleness limits how old of a validator set the network + // will use for peer sampling and rate limiting. + MaxValidatorSetStaleness time.Duration `json:"max-validator-set-staleness"` + // TargetGossipSize is the number of bytes that will be attempted to be + // sent when pushing transactions and when responded to transaction pull + // requests. + TargetGossipSize int `json:"target-gossip-size"` + // PullGossipPollSize is the number of validators to sample when performing + // a round of pull gossip. + PullGossipPollSize int `json:"pull-gossip-poll-size"` + // PullGossipFrequency is how frequently rounds of pull gossip are + // performed. + PullGossipFrequency time.Duration `json:"pull-gossip-frequency"` + // PullGossipThrottlingPeriod is how large of a window the throttler should + // use. + PullGossipThrottlingPeriod time.Duration `json:"pull-gossip-throttling-period"` + // PullGossipThrottlingLimit is the number of pull querys that are allowed + // by a validator in every throttling window. + PullGossipThrottlingLimit int `json:"pull-gossip-throttling-limit"` + // ExpectedBloomFilterElements is the number of elements to expect when + // creating a new bloom filter. The larger this number is, the larger the + // bloom filter will be. + ExpectedBloomFilterElements uint64 `json:"expected-bloom-filter-elements"` + // ExpectedBloomFilterFalsePositiveProbability is the expected probability + // of a false positive after having inserted ExpectedBloomFilterElements + // into a bloom filter. The smaller this number is, the larger the bloom + // filter will be. + ExpectedBloomFilterFalsePositiveProbability float64 `json:"expected-bloom-filter-false-positive-probability"` + // MaxBloomFilterFalsePositiveProbability is used to determine when the + // bloom filter should be refreshed. Once the expected probability of a + // false positive exceeds this value, the bloom filter will be regenerated. + // The smaller this number is, the more frequently that the bloom filter + // will be regenerated. + MaxBloomFilterFalsePositiveProbability float64 `json:"max-bloom-filter-false-positive-probability"` + // LegacyPushGossipCacheSize tracks the most recently received transactions + // and ensures to only gossip them once. + // + // Deprecated: The legacy push gossip mechanism is deprecated in favor of + // the p2p SDK's push gossip mechanism. + LegacyPushGossipCacheSize int `json:"legacy-push-gossip-cache-size"` +} diff --git a/vms/avm/network/gossip.go b/vms/avm/network/gossip.go new file mode 100644 index 000000000000..e4e145d830eb --- /dev/null +++ b/vms/avm/network/gossip.go @@ -0,0 +1,157 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/network/p2p" + "github.com/ava-labs/avalanchego/network/p2p/gossip" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/avm/txs" + "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" +) + +var ( + _ p2p.Handler = (*txGossipHandler)(nil) + _ gossip.Set[*txs.Tx] = (*gossipMempool)(nil) + _ gossip.Marshaller[*txs.Tx] = (*txParser)(nil) +) + +// txGossipHandler is the handler called when serving gossip messages +type txGossipHandler struct { + p2p.NoOpHandler + appGossipHandler p2p.Handler + appRequestHandler p2p.Handler +} + +func (t txGossipHandler) AppGossip( + ctx context.Context, + nodeID ids.NodeID, + gossipBytes []byte, +) { + t.appGossipHandler.AppGossip(ctx, nodeID, gossipBytes) +} + +func (t txGossipHandler) AppRequest( + ctx context.Context, + nodeID ids.NodeID, + deadline time.Time, + requestBytes []byte, +) ([]byte, error) { + return t.appRequestHandler.AppRequest(ctx, nodeID, deadline, requestBytes) +} + +type txParser struct { + parser txs.Parser +} + +func (*txParser) MarshalGossip(tx *txs.Tx) ([]byte, error) { + return tx.Bytes(), nil +} + +func (g *txParser) UnmarshalGossip(bytes []byte) (*txs.Tx, error) { + return g.parser.ParseTx(bytes) +} + +func newGossipMempool( + mempool mempool.Mempool, + log logging.Logger, + txVerifier TxVerifier, + parser txs.Parser, + maxExpectedElements uint64, + falsePositiveProbability, + maxFalsePositiveProbability float64, +) (*gossipMempool, error) { + bloom, err := gossip.NewBloomFilter(maxExpectedElements, falsePositiveProbability) + return &gossipMempool{ + Mempool: mempool, + log: log, + txVerifier: txVerifier, + parser: parser, + maxFalsePositiveProbability: maxFalsePositiveProbability, + bloom: bloom, + }, err +} + +type gossipMempool struct { + mempool.Mempool + log logging.Logger + txVerifier TxVerifier + parser txs.Parser + maxFalsePositiveProbability float64 + + lock sync.RWMutex + bloom *gossip.BloomFilter +} + +// Add is called by the p2p SDK when handling transactions that were pushed to +// us and when handling transactions that were pulled from a peer. If this +// returns a nil error while handling push gossip, the p2p SDK will queue the +// transaction to push gossip as well. +func (g *gossipMempool) Add(tx *txs.Tx) error { + txID := tx.ID() + if _, ok := g.Mempool.Get(txID); ok { + return fmt.Errorf("attempted to issue %w: %s ", mempool.ErrDuplicateTx, txID) + } + + if reason := g.Mempool.GetDropReason(txID); reason != nil { + // If the tx is being dropped - just ignore it + // + // TODO: Should we allow re-verification of the transaction even if it + // failed previously? + return reason + } + + // Verify the tx at the currently preferred state + if err := g.txVerifier.VerifyTx(tx); err != nil { + g.Mempool.MarkDropped(txID, err) + return err + } + + return g.AddVerified(tx) +} + +func (g *gossipMempool) AddVerified(tx *txs.Tx) error { + if err := g.Mempool.Add(tx); err != nil { + g.Mempool.MarkDropped(tx.ID(), err) + return err + } + + g.lock.Lock() + defer g.lock.Unlock() + + g.bloom.Add(tx) + reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, g.maxFalsePositiveProbability) + if err != nil { + return err + } + + if reset { + g.log.Debug("resetting bloom filter") + g.Mempool.Iterate(func(tx *txs.Tx) bool { + g.bloom.Add(tx) + return true + }) + } + + g.Mempool.RequestBuildBlock() + return nil +} + +func (g *gossipMempool) Iterate(f func(*txs.Tx) bool) { + g.Mempool.Iterate(f) +} + +func (g *gossipMempool) GetFilter() (bloom []byte, salt []byte, err error) { + g.lock.RLock() + defer g.lock.RUnlock() + + bloomBytes, err := g.bloom.Bloom.MarshalBinary() + return bloomBytes, g.bloom.Salt[:], err +} diff --git a/vms/avm/network/gossip_test.go b/vms/avm/network/gossip_test.go new file mode 100644 index 000000000000..a3922a23d812 --- /dev/null +++ b/vms/avm/network/gossip_test.go @@ -0,0 +1,128 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "testing" + + "github.com/prometheus/client_golang/prometheus" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/avm/fxs" + "github.com/ava-labs/avalanchego/vms/avm/txs" + "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +var _ TxVerifier = (*testVerifier)(nil) + +type testVerifier struct { + err error +} + +func (v testVerifier) VerifyTx(*txs.Tx) error { + return v.err +} + +func TestMarshaller(t *testing.T) { + require := require.New(t) + + parser, err := txs.NewParser([]fxs.Fx{ + &secp256k1fx.Fx{}, + }) + require.NoError(err) + + marhsaller := txParser{ + parser: parser, + } + + want := &txs.Tx{Unsigned: &txs.BaseTx{}} + require.NoError(want.Initialize(parser.Codec())) + + bytes, err := marhsaller.MarshalGossip(want) + require.NoError(err) + + got, err := marhsaller.UnmarshalGossip(bytes) + require.NoError(err) + require.Equal(want.GossipID(), got.GossipID()) +} + +func TestGossipMempoolAdd(t *testing.T) { + require := require.New(t) + + metrics := prometheus.NewRegistry() + toEngine := make(chan common.Message, 1) + + baseMempool, err := mempool.New("", metrics, toEngine) + require.NoError(err) + + parser, err := txs.NewParser(nil) + require.NoError(err) + + mempool, err := newGossipMempool( + baseMempool, + logging.NoLog{}, + testVerifier{}, + parser, + DefaultConfig.ExpectedBloomFilterElements, + DefaultConfig.ExpectedBloomFilterFalsePositiveProbability, + DefaultConfig.MaxBloomFilterFalsePositiveProbability, + ) + require.NoError(err) + + tx := &txs.Tx{ + Unsigned: &txs.BaseTx{ + BaseTx: avax.BaseTx{ + Ins: []*avax.TransferableInput{}, + }, + }, + TxID: ids.GenerateTestID(), + } + + require.NoError(mempool.Add(tx)) + require.True(mempool.bloom.Has(tx)) +} + +func TestGossipMempoolAddVerified(t *testing.T) { + require := require.New(t) + + metrics := prometheus.NewRegistry() + toEngine := make(chan common.Message, 1) + + baseMempool, err := mempool.New("", metrics, toEngine) + require.NoError(err) + + parser, err := txs.NewParser(nil) + require.NoError(err) + + mempool, err := newGossipMempool( + baseMempool, + logging.NoLog{}, + testVerifier{ + err: errTest, // We shouldn't be attempting to verify the tx in this flow + }, + parser, + DefaultConfig.ExpectedBloomFilterElements, + DefaultConfig.ExpectedBloomFilterFalsePositiveProbability, + DefaultConfig.MaxBloomFilterFalsePositiveProbability, + ) + require.NoError(err) + + tx := &txs.Tx{ + Unsigned: &txs.BaseTx{ + BaseTx: avax.BaseTx{ + Ins: []*avax.TransferableInput{}, + }, + }, + TxID: ids.GenerateTestID(), + } + + require.NoError(mempool.AddVerified(tx)) + require.True(mempool.bloom.Has(tx)) +} diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index b29e80c98124..9057ba1df346 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -5,57 +5,43 @@ package network import ( "context" - "fmt" "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" "github.com/ava-labs/avalanchego/cache" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/network/p2p" + "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" "github.com/ava-labs/avalanchego/vms/components/message" ) -// We allow [recentTxsCacheSize] to be fairly large because we only store hashes -// in the cache, not entire transactions. -const recentTxsCacheSize = 512 - -var _ Network = (*network)(nil) - -type Network interface { - common.AppHandler - - // IssueTx attempts to add a tx to the mempool, after verifying it against - // the preferred state. If the tx is added to the mempool, it will attempt - // to push gossip the tx to random peers in the network. - // - // If the tx is already in the mempool, mempool.ErrDuplicateTx will be - // returned. - // If the tx is not added to the mempool, an error will be returned. - IssueTx(context.Context, *txs.Tx) error - - // IssueVerifiedTx attempts to add a tx to the mempool. If the tx is added - // to the mempool, it will attempt to push gossip the tx to random peers in - // the network. - // - // If the tx is already in the mempool, mempool.ErrDuplicateTx will be - // returned. - // If the tx is not added to the mempool, an error will be returned. - IssueVerifiedTx(context.Context, *txs.Tx) error -} +const txGossipHandlerID = 0 + +var ( + _ common.AppHandler = (*Network)(nil) + _ validators.Connector = (*Network)(nil) +) -type network struct { - // We embed a noop handler for all unhandled messages - common.AppHandler +type Network struct { + *p2p.Network - ctx *snow.Context - parser txs.Parser - txVerifier TxVerifier - mempool mempool.Mempool - appSender common.AppSender + txPushGossiper gossip.Accumulator[*txs.Tx] + txPullGossiper gossip.Gossiper + txPullGossipFrequency time.Duration + + ctx *snow.Context + parser txs.Parser + mempool *gossipMempool + appSender common.AppSender // gossip related attributes recentTxsLock sync.Mutex @@ -68,23 +54,124 @@ func New( txVerifier TxVerifier, mempool mempool.Mempool, appSender common.AppSender, -) Network { - return &network{ - AppHandler: common.NewNoOpAppHandler(ctx.Log), + registerer prometheus.Registerer, + config Config, +) (*Network, error) { + p2pNetwork, err := p2p.NewNetwork(ctx.Log, appSender, registerer, "p2p") + if err != nil { + return nil, err + } + + marshaller := &txParser{ + parser: parser, + } + validators := p2p.NewValidators( + p2pNetwork.Peers, + ctx.Log, + ctx.SubnetID, + ctx.ValidatorState, + config.MaxValidatorSetStaleness, + ) + txGossipClient := p2pNetwork.NewClient( + txGossipHandlerID, + p2p.WithValidatorSampling(validators), + ) + txGossipMetrics, err := gossip.NewMetrics(registerer, "tx") + if err != nil { + return nil, err + } + + txPushGossiper := gossip.NewPushGossiper[*txs.Tx]( + marshaller, + txGossipClient, + txGossipMetrics, + config.TargetGossipSize, + ) + + gossipMempool, err := newGossipMempool( + mempool, + ctx.Log, + txVerifier, + parser, + config.ExpectedBloomFilterElements, + config.ExpectedBloomFilterFalsePositiveProbability, + config.MaxBloomFilterFalsePositiveProbability, + ) + if err != nil { + return nil, err + } + + var txPullGossiper gossip.Gossiper + txPullGossiper = gossip.NewPullGossiper[*txs.Tx]( + ctx.Log, + marshaller, + gossipMempool, + txGossipClient, + txGossipMetrics, + config.PullGossipPollSize, + ) + + // Gossip requests are only served if a node is a validator + txPullGossiper = gossip.ValidatorGossiper{ + Gossiper: txPullGossiper, + NodeID: ctx.NodeID, + Validators: validators, + } + + handler := gossip.NewHandler[*txs.Tx]( + ctx.Log, + marshaller, + txPushGossiper, + gossipMempool, + txGossipMetrics, + config.TargetGossipSize, + ) + + validatorHandler := p2p.NewValidatorHandler( + p2p.NewThrottlerHandler( + handler, + p2p.NewSlidingWindowThrottler( + config.PullGossipThrottlingPeriod, + config.PullGossipThrottlingLimit, + ), + ctx.Log, + ), + validators, + ctx.Log, + ) + + // We allow pushing txs between all peers, but only serve gossip requests + // from validators + txGossipHandler := txGossipHandler{ + appGossipHandler: handler, + appRequestHandler: validatorHandler, + } + + if err := p2pNetwork.AddHandler(txGossipHandlerID, txGossipHandler); err != nil { + return nil, err + } - ctx: ctx, - parser: parser, - txVerifier: txVerifier, - mempool: mempool, - appSender: appSender, + return &Network{ + Network: p2pNetwork, + txPushGossiper: txPushGossiper, + txPullGossiper: txPullGossiper, + txPullGossipFrequency: config.PullGossipFrequency, + ctx: ctx, + parser: parser, + mempool: gossipMempool, + appSender: appSender, recentTxs: &cache.LRU[ids.ID, struct{}]{ - Size: recentTxsCacheSize, + Size: config.LegacyPushGossipCacheSize, }, - } + }, nil +} + +func (n *Network) Gossip(ctx context.Context) { + gossip.Every(ctx, n.ctx.Log, n.txPullGossiper, n.txPullGossipFrequency) } -func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []byte) error { +func (n *Network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []byte) error { n.ctx.Log.Debug("called AppGossip message handler", zap.Stringer("nodeID", nodeID), zap.Int("messageLen", len(msgBytes)), @@ -92,10 +179,11 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b msgIntf, err := message.Parse(msgBytes) if err != nil { - n.ctx.Log.Debug("dropping AppGossip message", + n.ctx.Log.Debug("forwarding AppGossip message to SDK network", zap.String("reason", "failed to parse message"), ) - return nil + + return n.Network.AppGossip(ctx, nodeID, msgBytes) } msg, ok := msgIntf.(*message.Tx) @@ -116,71 +204,59 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b return nil } - if err := n.issueTx(tx); err == nil { + err = n.mempool.Add(tx) + if err == nil { txID := tx.ID() + n.txPushGossiper.Add(tx) + if err := n.txPushGossiper.Gossip(ctx); err != nil { + n.ctx.Log.Error("failed to gossip tx", + zap.Stringer("txID", tx.ID()), + zap.Error(err), + ) + } n.gossipTxMessage(ctx, txID, msgBytes) } return nil } -func (n *network) IssueTx(ctx context.Context, tx *txs.Tx) error { - if err := n.issueTx(tx); err != nil { +// IssueTx attempts to add a tx to the mempool, after verifying it. If the tx is +// added to the mempool, it will attempt to push gossip the tx to random peers +// in the network using both the legacy and p2p SDK. +// +// If the tx is already in the mempool, mempool.ErrDuplicateTx will be +// returned. +// If the tx is not added to the mempool, an error will be returned. +func (n *Network) IssueTx(ctx context.Context, tx *txs.Tx) error { + if err := n.mempool.Add(tx); err != nil { return err } return n.gossipTx(ctx, tx) } -func (n *network) IssueVerifiedTx(ctx context.Context, tx *txs.Tx) error { - if err := n.issueVerifiedTx(tx); err != nil { +// IssueVerifiedTx attempts to add a tx to the mempool, without first verifying +// it. If the tx is added to the mempool, it will attempt to push gossip the tx +// to random peers in the network using both the legacy and p2p SDK. +// +// If the tx is already in the mempool, mempool.ErrDuplicateTx will be +// returned. +// If the tx is not added to the mempool, an error will be returned. +func (n *Network) IssueVerifiedTx(ctx context.Context, tx *txs.Tx) error { + if err := n.mempool.AddVerified(tx); err != nil { return err } return n.gossipTx(ctx, tx) } -func (n *network) issueTx(tx *txs.Tx) error { - txID := tx.ID() - if _, ok := n.mempool.Get(txID); ok { - return fmt.Errorf("attempted to issue %w: %s ", mempool.ErrDuplicateTx, txID) - } - - if reason := n.mempool.GetDropReason(txID); reason != nil { - // If the tx is being dropped - just ignore it - // - // TODO: Should we allow re-verification of the transaction even if it - // failed previously? - return reason - } - - if err := n.txVerifier.VerifyTx(tx); err != nil { - n.ctx.Log.Debug("tx failed verification", - zap.Stringer("txID", txID), - zap.Error(err), - ) - - n.mempool.MarkDropped(txID, err) - return err - } - - return n.issueVerifiedTx(tx) -} - -func (n *network) issueVerifiedTx(tx *txs.Tx) error { - if err := n.mempool.Add(tx); err != nil { - txID := tx.ID() - n.ctx.Log.Debug("tx failed to be added to the mempool", - zap.Stringer("txID", txID), +// gossipTx pushes the tx to peers using both the legacy and p2p SDK. +func (n *Network) gossipTx(ctx context.Context, tx *txs.Tx) error { + n.txPushGossiper.Add(tx) + if err := n.txPushGossiper.Gossip(ctx); err != nil { + n.ctx.Log.Error("failed to gossip tx", + zap.Stringer("txID", tx.ID()), zap.Error(err), ) - - n.mempool.MarkDropped(txID, err) - return err } - n.mempool.RequestBuildBlock() - return nil -} - -func (n *network) gossipTx(ctx context.Context, tx *txs.Tx) error { txBytes := tx.Bytes() msg := &message.Tx{ Tx: txBytes, @@ -195,7 +271,9 @@ func (n *network) gossipTx(ctx context.Context, tx *txs.Tx) error { return nil } -func (n *network) gossipTxMessage(ctx context.Context, txID ids.ID, msgBytes []byte) { +// gossipTxMessage pushes the tx message to peers using the legacy format. +// If the tx was recently gossiped, this function does nothing. +func (n *Network) gossipTxMessage(ctx context.Context, txID ids.ID, msgBytes []byte) { n.recentTxsLock.Lock() _, has := n.recentTxs.Get(txID) n.recentTxs.Put(txID, struct{}{}) diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index 509b35ec0f13..4250a82b8bcb 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -7,6 +7,9 @@ import ( "context" "errors" "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -27,7 +30,22 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -var errTest = errors.New("test error") +var ( + testConfig = Config{ + MaxValidatorSetStaleness: time.Second, + TargetGossipSize: 1, + PullGossipPollSize: 1, + PullGossipFrequency: time.Second, + PullGossipThrottlingPeriod: time.Second, + PullGossipThrottlingLimit: 1, + ExpectedBloomFilterElements: 10, + ExpectedBloomFilterFalsePositiveProbability: .1, + MaxBloomFilterFalsePositiveProbability: .5, + LegacyPushGossipCacheSize: 512, + } + + errTest = errors.New("test error") +) func TestNetworkAppGossip(t *testing.T) { testTx := &txs.Tx{ @@ -154,7 +172,7 @@ func TestNetworkAppGossip(t *testing.T) { }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil).Times(2) return appSender }, }, @@ -193,7 +211,7 @@ func TestNetworkAppGossip(t *testing.T) { appSenderFunc = tt.appSenderFunc } - n := New( + n, err := New( &snow.Context{ Log: logging.NoLog{}, }, @@ -201,7 +219,10 @@ func TestNetworkAppGossip(t *testing.T) { txVerifierFunc(ctrl), mempoolFunc(ctrl), appSenderFunc(ctrl), + prometheus.NewRegistry(), + testConfig, ) + require.NoError(err) require.NoError(n.AppGossip(context.Background(), ids.GenerateTestNodeID(), tt.msgBytesFunc())) }) } @@ -286,7 +307,7 @@ func TestNetworkIssueTx(t *testing.T) { }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil).Times(2) return appSender }, expectedErr: nil, @@ -326,7 +347,7 @@ func TestNetworkIssueTx(t *testing.T) { appSenderFunc = tt.appSenderFunc } - n := New( + n, err := New( &snow.Context{ Log: logging.NoLog{}, }, @@ -334,7 +355,10 @@ func TestNetworkIssueTx(t *testing.T) { txVerifierFunc(ctrl), mempoolFunc(ctrl), appSenderFunc(ctrl), + prometheus.NewRegistry(), + testConfig, ) + require.NoError(err) err = n.IssueTx(context.Background(), &txs.Tx{}) require.ErrorIs(err, tt.expectedErr) }) @@ -370,7 +394,7 @@ func TestNetworkIssueVerifiedTx(t *testing.T) { }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil).Times(2) return appSender }, expectedErr: nil, @@ -403,7 +427,7 @@ func TestNetworkIssueVerifiedTx(t *testing.T) { appSenderFunc = tt.appSenderFunc } - n := New( + n, err := New( &snow.Context{ Log: logging.NoLog{}, }, @@ -411,7 +435,10 @@ func TestNetworkIssueVerifiedTx(t *testing.T) { executor.NewMockManager(ctrl), // Should never verify a tx mempoolFunc(ctrl), appSenderFunc(ctrl), + prometheus.NewRegistry(), + testConfig, ) + require.NoError(err) err = n.IssueVerifiedTx(context.Background(), &txs.Tx{}) require.ErrorIs(err, tt.expectedErr) }) @@ -429,7 +456,7 @@ func TestNetworkGossipTx(t *testing.T) { appSender := common.NewMockSender(ctrl) - nIntf := New( + n, err := New( &snow.Context{ Log: logging.NoLog{}, }, @@ -437,9 +464,10 @@ func TestNetworkGossipTx(t *testing.T) { executor.NewMockManager(ctrl), mempool.NewMockMempool(ctrl), appSender, + prometheus.NewRegistry(), + testConfig, ) - require.IsType(&network{}, nIntf) - n := nIntf.(*network) + require.NoError(err) // Case: Tx was recently gossiped txID := ids.GenerateTestID() diff --git a/vms/avm/txs/tx.go b/vms/avm/txs/tx.go index 6025828a5dcb..7b900987692a 100644 --- a/vms/avm/txs/tx.go +++ b/vms/avm/txs/tx.go @@ -8,6 +8,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" @@ -19,6 +20,8 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) +var _ gossip.Gossipable = (*Tx)(nil) + type UnsignedTx interface { snow.ContextInitializable @@ -75,6 +78,11 @@ func (t *Tx) ID() ids.ID { return t.TxID } +// GossipID returns the unique ID that this tx should use for mempool gossip +func (t *Tx) GossipID() ids.ID { + return t.TxID +} + // Bytes returns the binary representation of this tx func (t *Tx) Bytes() []byte { return t.bytes diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 93467ad877ef..699f95a6e7be 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -9,8 +9,7 @@ import ( "fmt" "net/http" "reflect" - - stdjson "encoding/json" + "sync" "github.com/gorilla/rpc/v2" @@ -83,6 +82,8 @@ type VM struct { registerer prometheus.Registerer + connectedPeers map[ids.NodeID]*version.Application + parser block.Parser pubsub *pubsub.Server @@ -113,19 +114,35 @@ type VM struct { txBackend *txexecutor.Backend + context context.Context + startShutdown context.CancelFunc + awaitShutdown sync.WaitGroup + + networkConfig network.Config // These values are only initialized after the chain has been linearized. - mempool mempool.Mempool blockbuilder.Builder chainManager blockexecutor.Manager - network network.Network + network *network.Network } -func (*VM) Connected(context.Context, ids.NodeID, *version.Application) error { - return nil +func (vm *VM) Connected(ctx context.Context, nodeID ids.NodeID, version *version.Application) error { + // If the chain isn't linearized yet, we must track the peers externally + // until the network is initialized. + if vm.network == nil { + vm.connectedPeers[nodeID] = version + return nil + } + return vm.network.Connected(ctx, nodeID, version) } -func (*VM) Disconnected(context.Context, ids.NodeID) error { - return nil +func (vm *VM) Disconnected(ctx context.Context, nodeID ids.NodeID) error { + // If the chain isn't linearized yet, we must track the peers externally + // until the network is initialized. + if vm.network == nil { + delete(vm.connectedPeers, nodeID) + return nil + } + return vm.network.Disconnected(ctx, nodeID) } /* @@ -134,12 +151,6 @@ func (*VM) Disconnected(context.Context, ids.NodeID) error { ****************************************************************************** */ -type Config struct { - IndexTransactions bool `json:"index-transactions"` - IndexAllowIncomplete bool `json:"index-allow-incomplete"` - ChecksumsEnabled bool `json:"checksums-enabled"` -} - func (vm *VM) Initialize( _ context.Context, ctx *snow.Context, @@ -154,15 +165,13 @@ func (vm *VM) Initialize( noopMessageHandler := common.NewNoOpAppHandler(ctx.Log) vm.Atomic = network.NewAtomic(noopMessageHandler) - avmConfig := Config{} - if len(configBytes) > 0 { - if err := stdjson.Unmarshal(configBytes, &avmConfig); err != nil { - return err - } - ctx.Log.Info("VM config initialized", - zap.Reflect("config", avmConfig), - ) + avmConfig, err := ParseConfig(configBytes) + if err != nil { + return err } + ctx.Log.Info("VM config initialized", + zap.Reflect("config", avmConfig), + ) registerer := prometheus.NewRegistry() if err := ctx.Metrics.Register(registerer); err != nil { @@ -170,8 +179,9 @@ func (vm *VM) Initialize( } vm.registerer = registerer + vm.connectedPeers = make(map[ids.NodeID]*version.Application) + // Initialize metrics as soon as possible - var err error vm.metrics, err = metrics.New("", registerer) if err != nil { return fmt.Errorf("failed to initialize metrics: %w", err) @@ -264,6 +274,8 @@ func (vm *VM) Initialize( Bootstrapped: false, } + vm.context, vm.startShutdown = context.WithCancel(context.Background()) + vm.networkConfig = avmConfig.Network return vm.state.Commit() } @@ -306,6 +318,9 @@ func (vm *VM) Shutdown(context.Context) error { return nil } + vm.startShutdown() + vm.awaitShutdown.Wait() + return utils.Err( vm.state.Close(), vm.baseDB.Close(), @@ -396,20 +411,20 @@ func (*VM) VerifyHeightIndex(context.Context) error { ****************************************************************************** */ -func (vm *VM) Linearize(_ context.Context, stopVertexID ids.ID, toEngine chan<- common.Message) error { +func (vm *VM) Linearize(ctx context.Context, stopVertexID ids.ID, toEngine chan<- common.Message) error { time := version.GetCortinaTime(vm.ctx.NetworkID) err := vm.state.InitializeChainState(stopVertexID, time) if err != nil { return err } - vm.mempool, err = mempool.New("mempool", vm.registerer, toEngine) + mempool, err := mempool.New("mempool", vm.registerer, toEngine) if err != nil { return fmt.Errorf("failed to create mempool: %w", err) } vm.chainManager = blockexecutor.NewManager( - vm.mempool, + mempool, vm.metrics, vm.state, vm.txBackend, @@ -421,26 +436,47 @@ func (vm *VM) Linearize(_ context.Context, stopVertexID ids.ID, toEngine chan<- vm.txBackend, vm.chainManager, &vm.clock, - vm.mempool, + mempool, ) // Invariant: The context lock is not held when calling network.IssueTx. - vm.network = network.New( + vm.network, err = network.New( vm.ctx, vm.parser, network.NewLockedTxVerifier( &vm.ctx.Lock, vm.chainManager, ), - vm.mempool, + mempool, vm.appSender, + vm.registerer, + vm.networkConfig, ) + if err != nil { + return fmt.Errorf("failed to initialize network: %w", err) + } + + // Notify the network of our current peers + for nodeID, version := range vm.connectedPeers { + if err := vm.network.Connected(ctx, nodeID, version); err != nil { + return err + } + } + vm.connectedPeers = nil // Note: It's important only to switch the networking stack after the full // chainVM has been initialized. Traffic will immediately start being // handled asynchronously. vm.Atomic.Set(vm.network) + vm.awaitShutdown.Add(1) + go func() { + defer vm.awaitShutdown.Done() + + // Invariant: Gossip must never grab the context lock. + vm.network.Gossip(vm.context) + }() + go func() { err := vm.state.Prune(&vm.ctx.Lock, vm.ctx.Log) if err != nil { diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index ae4a2f0c0af0..ce7c6c43ea61 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -35,10 +35,7 @@ func TestInvalidGenesis(t *testing.T) { vm := &VM{} ctx := snowtest.Context(t, snowtest.XChainID) ctx.Lock.Lock() - defer func() { - require.NoError(vm.Shutdown(context.Background())) - ctx.Lock.Unlock() - }() + defer ctx.Lock.Unlock() err := vm.Initialize( context.Background(), From 5717070e633c8e17479ab65c88c876142df6d9fb Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:02:11 -0500 Subject: [PATCH 199/267] Remove network context (#2543) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/network/network.go | 28 ++++++++++---------- vms/platformvm/network/network_test.go | 13 +++------ vms/platformvm/vm.go | 2 +- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index c507413f513a..bd0f58bd449d 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -183,7 +183,7 @@ func newEnvironment(t *testing.T) *environment { txVerifier := network.NewLockedTxVerifier(&res.ctx.Lock, res.blkManager) res.network = network.New( - res.backend.Ctx, + logging.NoLog{}, txVerifier, res.mempool, res.backend.Config.PartialSyncPrimaryNetwork, diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index 494150fe1c6f..e3003768d13f 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -11,8 +11,8 @@ import ( "github.com/ava-labs/avalanchego/cache" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/message" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" @@ -36,7 +36,7 @@ type network struct { // We embed a noop handler for all unhandled messages common.AppHandler - ctx *snow.Context + log logging.Logger txVerifier TxVerifier mempool mempool.Mempool partialSyncPrimaryNetwork bool @@ -48,16 +48,16 @@ type network struct { } func New( - ctx *snow.Context, + log logging.Logger, txVerifier TxVerifier, mempool mempool.Mempool, partialSyncPrimaryNetwork bool, appSender common.AppSender, ) Network { return &network{ - AppHandler: common.NewNoOpAppHandler(ctx.Log), + AppHandler: common.NewNoOpAppHandler(log), - ctx: ctx, + log: log, txVerifier: txVerifier, mempool: mempool, partialSyncPrimaryNetwork: partialSyncPrimaryNetwork, @@ -67,13 +67,13 @@ func New( } func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []byte) error { - n.ctx.Log.Debug("called AppGossip message handler", + n.log.Debug("called AppGossip message handler", zap.Stringer("nodeID", nodeID), zap.Int("messageLen", len(msgBytes)), ) if n.partialSyncPrimaryNetwork { - n.ctx.Log.Debug("dropping AppGossip message", + n.log.Debug("dropping AppGossip message", zap.String("reason", "primary network is not being fully synced"), ) return nil @@ -81,7 +81,7 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b msgIntf, err := message.Parse(msgBytes) if err != nil { - n.ctx.Log.Debug("dropping AppGossip message", + n.log.Debug("dropping AppGossip message", zap.String("reason", "failed to parse message"), ) return nil @@ -89,7 +89,7 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b msg, ok := msgIntf.(*message.Tx) if !ok { - n.ctx.Log.Debug("dropping unexpected message", + n.log.Debug("dropping unexpected message", zap.Stringer("nodeID", nodeID), ) return nil @@ -97,7 +97,7 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b tx, err := txs.Parse(txs.Codec, msg.Tx) if err != nil { - n.ctx.Log.Verbo("received invalid tx", + n.log.Verbo("received invalid tx", zap.Stringer("nodeID", nodeID), zap.Binary("tx", msg.Tx), zap.Error(err), @@ -145,7 +145,7 @@ func (n *network) issueTx(tx *txs.Tx) error { // Verify the tx at the currently preferred state if err := n.txVerifier.VerifyTx(tx); err != nil { - n.ctx.Log.Debug("tx failed verification", + n.log.Debug("tx failed verification", zap.Stringer("txID", txID), zap.Error(err), ) @@ -161,7 +161,7 @@ func (n *network) issueTx(tx *txs.Tx) error { } if err := n.mempool.Add(tx); err != nil { - n.ctx.Log.Debug("tx failed to be added to the mempool", + n.log.Debug("tx failed to be added to the mempool", zap.Stringer("txID", txID), zap.Error(err), ) @@ -186,12 +186,12 @@ func (n *network) gossipTx(ctx context.Context, txID ids.ID, msgBytes []byte) { return } - n.ctx.Log.Debug("gossiping tx", + n.log.Debug("gossiping tx", zap.Stringer("txID", txID), ) if err := n.appSender.SendAppGossip(ctx, msgBytes); err != nil { - n.ctx.Log.Error("failed to gossip tx", + n.log.Error("failed to gossip tx", zap.Stringer("txID", txID), zap.Error(err), ) diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go index e1f73ebf112b..f0b3cc0a87fc 100644 --- a/vms/platformvm/network/network_test.go +++ b/vms/platformvm/network/network_test.go @@ -13,7 +13,6 @@ import ( "go.uber.org/mock/gomock" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -166,9 +165,7 @@ func TestNetworkAppGossip(t *testing.T) { ctrl := gomock.NewController(t) n := New( - &snow.Context{ - Log: logging.NoLog{}, - }, + logging.NoLog{}, testTxVerifier{}, tt.mempoolFunc(ctrl), tt.partialSyncPrimaryNetwork, @@ -293,9 +290,7 @@ func TestNetworkIssueTx(t *testing.T) { ctrl := gomock.NewController(t) n := New( - &snow.Context{ - Log: logging.NoLog{}, - }, + logging.NoLog{}, tt.txVerifier, tt.mempoolFunc(ctrl), tt.partialSyncPrimaryNetwork, @@ -314,9 +309,7 @@ func TestNetworkGossipTx(t *testing.T) { appSender := common.NewMockSender(ctrl) nIntf := New( - &snow.Context{ - Log: logging.NoLog{}, - }, + logging.NoLog{}, testTxVerifier{}, mempool.NewMockMempool(ctrl), false, diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 3bb1bec87825..ef4581b5dac9 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -193,7 +193,7 @@ func (vm *VM) Initialize( txVerifier := network.NewLockedTxVerifier(&txExecutorBackend.Ctx.Lock, vm.manager) vm.Network = network.New( - txExecutorBackend.Ctx, + chainCtx.Log, txVerifier, mempool, txExecutorBackend.Config.PartialSyncPrimaryNetwork, From f59e46f89b02356445805af47176d161f3e7d80b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 22 Dec 2023 15:53:56 -0700 Subject: [PATCH 200/267] Fix windowing when no validator is available (#2529) Co-authored-by: Stephen Buttolph --- vms/proposervm/block.go | 90 +++++++++++------------- vms/proposervm/proposer/windower.go | 14 +++- vms/proposervm/proposer/windower_test.go | 6 +- vms/proposervm/vm.go | 15 ++-- 4 files changed, 69 insertions(+), 56 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 94969a048caa..fa53d2727968 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -142,20 +142,14 @@ func (p *postForkCommonComponents) Verify( ) } - // After Durango, we never allow unsigned blocks. - shouldHaveProposer := true + var shouldHaveProposer bool if p.vm.IsDurangoActivated(parentTimestamp) { - err := p.verifyPostDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) - if err != nil { - return err - } + shouldHaveProposer, err = p.verifyPostDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) } else { - delay, err := p.verifyPreDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) - if err != nil { - return err - } - - shouldHaveProposer = delay < proposer.MaxVerifyDelay + shouldHaveProposer, err = p.verifyPreDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) + } + if err != nil { + return err } // Verify the signature of the node @@ -204,10 +198,9 @@ func (p *postForkCommonComponents) buildChild( return nil, err } - // After Durango, we never allow unsigned blocks. - shouldBuildUnsignedBlock := false + var shouldBuildSignedBlock bool if p.vm.IsDurangoActivated(parentTimestamp) { - err = p.shouldBuildBlockPostDurango( + shouldBuildSignedBlock, err = p.shouldBuildSignedBlockPostDurango( ctx, parentID, parentTimestamp, @@ -215,7 +208,7 @@ func (p *postForkCommonComponents) buildChild( newTimestamp, ) } else { - shouldBuildUnsignedBlock, err = p.shouldBuildUnsignedBlockPreDurango( + shouldBuildSignedBlock, err = p.shouldBuildSignedBlockPreDurango( ctx, parentID, parentTimestamp, @@ -241,22 +234,22 @@ func (p *postForkCommonComponents) buildChild( // Build the child var statelessChild block.SignedBlock - if shouldBuildUnsignedBlock { - statelessChild, err = block.BuildUnsigned( + if shouldBuildSignedBlock { + statelessChild, err = block.Build( parentID, newTimestamp, pChainHeight, + p.vm.StakingCertLeaf, innerBlock.Bytes(), + p.vm.ctx.ChainID, + p.vm.StakingLeafSigner, ) } else { - statelessChild, err = block.Build( + statelessChild, err = block.BuildUnsigned( parentID, newTimestamp, pChainHeight, - p.vm.StakingCertLeaf, innerBlock.Bytes(), - p.vm.ctx.ChainID, - p.vm.StakingLeafSigner, ) } if err != nil { @@ -332,7 +325,7 @@ func (p *postForkCommonComponents) verifyPreDurangoBlockDelay( parentTimestamp time.Time, parentPChainHeight uint64, blk *postForkBlock, -) (time.Duration, error) { +) (bool, error) { var ( blkTimestamp = blk.Timestamp() childHeight = blk.Height() @@ -351,15 +344,15 @@ func (p *postForkCommonComponents) verifyPreDurangoBlockDelay( zap.Stringer("blkID", blk.ID()), zap.Error(err), ) - return 0, err + return false, err } delay := blkTimestamp.Sub(parentTimestamp) if delay < minDelay { - return 0, errProposerWindowNotStarted + return false, errProposerWindowNotStarted } - return delay, nil + return delay < proposer.MaxVerifyDelay, nil } func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( @@ -367,7 +360,7 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( parentTimestamp time.Time, parentPChainHeight uint64, blk *postForkBlock, -) error { +) (bool, error) { var ( blkTimestamp = blk.Timestamp() blkHeight = blk.Height() @@ -380,28 +373,30 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( parentPChainHeight, proposer.TimeToSlot(parentTimestamp, blkTimestamp), ) - if err != nil { + switch { + case errors.Is(err, proposer.ErrAnyoneCanPropose): + return false, nil // block should be unsigned + case err != nil: p.vm.ctx.Log.Error("unexpected block verification failure", zap.String("reason", "failed to calculate expected proposer"), zap.Stringer("blkID", blk.ID()), zap.Error(err), ) - return err - } - if expectedProposerID != proposerID { - return errUnexpectedProposer + return false, err + case expectedProposerID == proposerID: + return true, nil // block should be signed + default: + return false, errUnexpectedProposer } - - return nil } -func (p *postForkCommonComponents) shouldBuildBlockPostDurango( +func (p *postForkCommonComponents) shouldBuildSignedBlockPostDurango( ctx context.Context, parentID ids.ID, parentTimestamp time.Time, parentPChainHeight uint64, newTimestamp time.Time, -) error { +) (bool, error) { parentHeight := p.innerBlk.Height() currentSlot := proposer.TimeToSlot(parentTimestamp, newTimestamp) expectedProposerID, err := p.vm.Windower.ExpectedProposer( @@ -410,16 +405,18 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( parentPChainHeight, currentSlot, ) - if err != nil { + switch { + case errors.Is(err, proposer.ErrAnyoneCanPropose): + return false, nil // build an unsigned block + case err != nil: p.vm.ctx.Log.Error("unexpected build block failure", zap.String("reason", "failed to calculate expected proposer"), zap.Stringer("parentID", parentID), zap.Error(err), ) - return err - } - if expectedProposerID == p.vm.ctx.NodeID { - return nil + return false, err + case expectedProposerID == p.vm.ctx.NodeID: + return true, nil // build a signed block } // It's not our turn to propose a block yet. This is likely caused by having @@ -450,17 +447,17 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( zap.Stringer("parentID", parentID), zap.Error(err), ) - return err + return false, err } p.vm.Scheduler.SetBuildBlockTime(nextStartTime) // In case the inner VM only issued one pendingTxs message, we should // attempt to re-handle that once it is our turn to build the block. p.vm.notifyInnerBlockReady() - return errProposerWindowNotStarted + return false, errProposerWindowNotStarted } -func (p *postForkCommonComponents) shouldBuildUnsignedBlockPreDurango( +func (p *postForkCommonComponents) shouldBuildSignedBlockPreDurango( ctx context.Context, parentID ids.ID, parentTimestamp time.Time, @@ -469,8 +466,7 @@ func (p *postForkCommonComponents) shouldBuildUnsignedBlockPreDurango( ) (bool, error) { delay := newTimestamp.Sub(parentTimestamp) if delay >= proposer.MaxBuildDelay { - // time for any node to build an unsigned block - return true, nil + return false, nil // time for any node to build an unsigned block } parentHeight := p.innerBlk.Height() @@ -488,7 +484,7 @@ func (p *postForkCommonComponents) shouldBuildUnsignedBlockPreDurango( if delay >= minDelay { // it's time for this node to propose a block. It'll be signed or // unsigned depending on the delay - return delay >= proposer.MaxVerifyDelay, nil + return delay < proposer.MaxVerifyDelay, nil } // It's not our turn to propose a block yet. This is likely caused by having diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 6903db785e29..beb4a8253f68 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -37,7 +37,7 @@ const ( var ( _ Windower = (*windower)(nil) - ErrNoProposersAvailable = errors.New("no proposers available") + ErrAnyoneCanPropose = errors.New("anyone can propose") ) type Windower interface { @@ -68,6 +68,8 @@ type Windower interface { // able to propose from a given time on as it happens Pre-Durango). // [ExpectedProposer] calculates which nodeID is scheduled to propose a // block of height [blockHeight] at [slot]. + // If no validators are currently available, [ErrAnyoneCanPropose] is + // returned. ExpectedProposer( ctx context.Context, blockHeight, @@ -82,6 +84,8 @@ type Windower interface { // slot to start. Delay is specified as starting from slot zero start. // (which is parent timestamp). For efficiency reasons, we cap the slot // search to [MaxLookAheadSlots]. + // If no validators are currently available, [ErrAnyoneCanPropose] is + // returned. MinDelayForProposer( ctx context.Context, blockHeight, @@ -171,6 +175,9 @@ func (w *windower) ExpectedProposer( if err != nil { return ids.EmptyNodeID, err } + if len(validators) == 0 { + return ids.EmptyNodeID, ErrAnyoneCanPropose + } return w.expectedProposer( validators, @@ -193,6 +200,9 @@ func (w *windower) MinDelayForProposer( if err != nil { return 0, err } + if len(validators) == 0 { + return 0, ErrAnyoneCanPropose + } maxSlot := startSlot + MaxLookAheadSlots for slot := startSlot; slot < maxSlot; slot++ { @@ -263,7 +273,7 @@ func (w *windower) expectedProposer( source.Seed(w.chainSource ^ blockHeight ^ bits.Reverse64(slot)) indices, err := sampler.Sample(1) if err != nil { - return ids.EmptyNodeID, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) + return ids.EmptyNodeID, fmt.Errorf("failed sampling proposers: %w", err) } return validators[indices[0]].id, nil } diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index bf8786b8b735..5e3434bb9e38 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -41,8 +41,12 @@ func TestWindowerNoValidators(t *testing.T) { require.Zero(delay) expectedProposer, err := w.ExpectedProposer(context.Background(), chainHeight, pChainHeight, slot) - require.ErrorIs(err, ErrNoProposersAvailable) + require.ErrorIs(err, ErrAnyoneCanPropose) require.Equal(ids.EmptyNodeID, expectedProposer) + + delay, err = w.MinDelayForProposer(context.Background(), chainHeight, pChainHeight, nodeID, slot) + require.ErrorIs(err, ErrAnyoneCanPropose) + require.Zero(delay) } func TestWindowerRepeatedValidator(t *testing.T) { diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 2963739ef990..290846abe763 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -411,18 +411,21 @@ func (vm *VM) getPostDurangoSlotTime( vm.ctx.NodeID, slot, ) - if err != nil { - return time.Time{}, err - } - // Note: The P-chain does not currently try to target any block time. It // notifies the consensus engine as soon as a new block may be built. To // avoid fast runs of blocks there is an additional minimum delay that // validators can specify. This delay may be an issue for high performance, // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. - delay = math.Max(delay, vm.MinBlkDelay) - return parentTimestamp.Add(delay), err + switch { + case err == nil: + delay = math.Max(delay, vm.MinBlkDelay) + return parentTimestamp.Add(delay), err + case errors.Is(err, proposer.ErrAnyoneCanPropose): + return parentTimestamp.Add(vm.MinBlkDelay), err + default: + return time.Time{}, err + } } func (vm *VM) LastAccepted(ctx context.Context) (ids.ID, error) { From a809807aa32f7344e434c19e8b8c6d564e8e415a Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:54:18 -0500 Subject: [PATCH 201/267] Remove `snow.DefaultContextTest` (#2518) --- api/server/server_test.go | 4 +- go.mod | 2 +- go.sum | 4 +- indexer/index_test.go | 9 +- indexer/indexer_test.go | 21 +- network/test_network.go | 6 +- snow/consensus/snowman/consensus_test.go | 95 ++++++---- snow/consensus/snowman/network_test.go | 7 +- snow/context.go | 19 -- .../avalanche/bootstrap/bootstrapper_test.go | 3 +- .../avalanche/state/unique_vertex_test.go | 13 +- snow/engine/common/queue/jobs_test.go | 11 +- .../snowman/bootstrap/bootstrapper_test.go | 9 +- snow/engine/snowman/config_test.go | 8 +- .../snowman/syncer/state_syncer_test.go | 48 +++-- snow/engine/snowman/transitive_test.go | 18 +- snow/networking/benchlist/benchlist_test.go | 9 +- snow/networking/handler/handler_test.go | 21 +- snow/networking/handler/health_test.go | 3 +- snow/networking/handler/message_queue_test.go | 3 +- snow/networking/router/chain_router_test.go | 35 ++-- snow/networking/sender/sender_test.go | 179 ++++++++---------- snow/snowtest/snowtest.go | 53 ++++-- .../txs/add_subnet_validator_test.go | 6 +- vms/platformvm/txs/create_chain_test.go | 4 +- .../executor/staker_tx_verification_test.go | 35 ++-- vms/platformvm/utxo/handler_test.go | 6 +- vms/platformvm/vm_test.go | 3 +- vms/proposervm/batched_vm_test.go | 3 +- vms/proposervm/state_syncable_vm_test.go | 3 +- vms/proposervm/vm_regression_test.go | 3 +- vms/proposervm/vm_test.go | 18 +- vms/rpcchainvm/batched_vm_test.go | 4 +- vms/rpcchainvm/state_syncable_vm_test.go | 3 +- vms/rpcchainvm/with_context_vm_test.go | 4 +- 35 files changed, 367 insertions(+), 305 deletions(-) diff --git a/api/server/server_test.go b/api/server/server_test.go index 9f6f3732e591..865e090c10f1 100644 --- a/api/server/server_test.go +++ b/api/server/server_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" ) func TestRejectMiddleware(t *testing.T) { @@ -58,7 +59,8 @@ func TestRejectMiddleware(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - ctx := &snow.ConsensusContext{} + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) ctx.State.Set(snow.EngineState{ State: tt.state, }) diff --git a/go.mod b/go.mod index f165bfa3ed70..4f5855df0c4a 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231219231451-224728dbacb4 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 9c5c86ffbb1d..35f8b1814109 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231219231451-224728dbacb4 h1:LXL5nSxcblyBFR5/zdO4TAqSWqoB15bT3sGb1Nkh7o4= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231219231451-224728dbacb4/go.mod h1:84JZyt3colgzGI/jOYGB5Wzxr/wNP0zjebHiWZjFthk= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 h1:DiJBkm2IJ/My4u5DP4gq2wIbdflFRuZJbDm8DbgNDdg= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9/go.mod h1:Xftjgk8T46k5/pWSQWcmdPanNl68kTcufd9S4kB58bM= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/indexer/index_test.go b/indexer/index_test.go index 7edab5823feb..dbac03430a3f 100644 --- a/indexer/index_test.go +++ b/indexer/index_test.go @@ -28,7 +28,8 @@ func TestIndex(t *testing.T) { require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) baseDB := memdb.New() db := versiondb.New(baseDB) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) indexIntf, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) @@ -116,7 +117,8 @@ func TestIndexGetContainerByRangeMaxPageSize(t *testing.T) { codec := codec.NewDefaultManager() require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) db := memdb.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) indexIntf, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) idx := indexIntf.(*index) @@ -156,7 +158,8 @@ func TestDontIndexSameContainerTwice(t *testing.T) { codec := codec.NewDefaultManager() require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) db := memdb.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) idx, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) diff --git a/indexer/indexer_test.go b/indexer/indexer_test.go index bf651101ed61..fd5abe1ddc6b 100644 --- a/indexer/indexer_test.go +++ b/indexer/indexer_test.go @@ -154,8 +154,8 @@ func TestIndexer(t *testing.T) { idxr.clock.Set(now) // Assert state is right - chain1Ctx := snowtest.ConsensusContext() - chain1Ctx.ChainID = ids.GenerateTestID() + snow1Ctx := snowtest.Context(t, snowtest.CChainID) + chain1Ctx := snowtest.ConsensusContext(snow1Ctx) isIncomplete, err := idxr.isIncomplete(chain1Ctx.ChainID) require.NoError(err) require.False(isIncomplete) @@ -259,8 +259,8 @@ func TestIndexer(t *testing.T) { require.Contains(server.endpoints, "/block") // Register a DAG chain - chain2Ctx := snowtest.ConsensusContext() - chain2Ctx.ChainID = ids.GenerateTestID() + snow2Ctx := snowtest.Context(t, snowtest.XChainID) + chain2Ctx := snowtest.ConsensusContext(snow2Ctx) isIncomplete, err = idxr.isIncomplete(chain2Ctx.ChainID) require.NoError(err) require.False(isIncomplete) @@ -419,8 +419,8 @@ func TestIncompleteIndex(t *testing.T) { require.False(idxr.indexingEnabled) // Register a chain - chain1Ctx := snowtest.ConsensusContext() - chain1Ctx.ChainID = ids.GenerateTestID() + snow1Ctx := snowtest.Context(t, snowtest.CChainID) + chain1Ctx := snowtest.ConsensusContext(snow1Ctx) isIncomplete, err := idxr.isIncomplete(chain1Ctx.ChainID) require.NoError(err) require.False(isIncomplete) @@ -501,10 +501,11 @@ func TestIgnoreNonDefaultChains(t *testing.T) { require.IsType(&indexer{}, idxrIntf) idxr := idxrIntf.(*indexer) - // Assert state is right - chain1Ctx := snowtest.ConsensusContext() - chain1Ctx.ChainID = ids.GenerateTestID() - chain1Ctx.SubnetID = ids.GenerateTestID() + // Create chain1Ctx for a random subnet + chain. + chain1Ctx := snowtest.ConsensusContext(&snow.Context{ + ChainID: ids.GenerateTestID(), + SubnetID: ids.GenerateTestID(), + }) // RegisterChain should return without adding an index for this chain chainVM := mocks.NewMockChainVM(ctrl) diff --git a/network/test_network.go b/network/test_network.go index 4f9b12fa48d8..1d3bcd933844 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -20,7 +20,6 @@ import ( "github.com/ava-labs/avalanchego/network/throttling" "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/ava-labs/avalanchego/snow/networking/tracker" - "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" @@ -187,7 +186,6 @@ func NewTestNetwork( networkConfig.TLSConfig = tlsConfig networkConfig.TLSKey = tlsCert.PrivateKey.(crypto.Signer) - ctx := snowtest.ConsensusContext() beacons := validators.NewManager() networkConfig.Validators = currentValidators networkConfig.Beacons = beacons @@ -207,7 +205,7 @@ func NewTestNetwork( return nil, err } networkConfig.CPUTargeter = tracker.NewTargeter( - ctx.Log, + logging.NoLog{}, &tracker.TargeterConfig{ VdrAlloc: float64(runtime.NumCPU()), MaxNonVdrUsage: .8 * float64(runtime.NumCPU()), @@ -217,7 +215,7 @@ func NewTestNetwork( networkConfig.ResourceTracker.CPUTracker(), ) networkConfig.DiskTargeter = tracker.NewTargeter( - ctx.Log, + logging.NoLog{}, &tracker.TargeterConfig{ VdrAlloc: 1000 * units.GiB, MaxNonVdrUsage: 1000 * units.GiB, diff --git a/snow/consensus/snowman/consensus_test.go b/snow/consensus/snowman/consensus_test.go index 0894f2290b77..375f81d5b3a8 100644 --- a/snow/consensus/snowman/consensus_test.go +++ b/snow/consensus/snowman/consensus_test.go @@ -94,7 +94,8 @@ func InitializeTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -119,7 +120,8 @@ func NumProcessingTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -161,7 +163,8 @@ func AddToTailTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -200,7 +203,8 @@ func AddToNonTailTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -248,7 +252,8 @@ func AddToUnknownTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -288,7 +293,8 @@ func StatusOrProcessingPreviouslyAcceptedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -317,7 +323,8 @@ func StatusOrProcessingPreviouslyRejectedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -354,7 +361,8 @@ func StatusOrProcessingUnissuedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -391,7 +399,8 @@ func StatusOrProcessingIssuedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -430,7 +439,8 @@ func RecordPollAcceptSingleBlockTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -472,7 +482,8 @@ func RecordPollAcceptAndRejectTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -525,7 +536,8 @@ func RecordPollSplitVoteNoChangeTest(t *testing.T, factory Factory) { require := require.New(t) sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) registerer := prometheus.NewRegistry() ctx.Registerer = registerer @@ -588,7 +600,8 @@ func RecordPollWhenFinalizedTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -613,7 +626,8 @@ func RecordPollRejectTransitivelyTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -683,7 +697,8 @@ func RecordPollTransitivelyResetConfidenceTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -775,7 +790,8 @@ func RecordPollInvalidVoteTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -816,7 +832,8 @@ func RecordPollTransitiveVotingTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 3, AlphaPreference: 3, @@ -926,7 +943,8 @@ func RecordPollDivergedVotingTest(t *testing.T, factory Factory) { sm := factory.New() require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1029,7 +1047,8 @@ func RecordPollDivergedVotingWithNoConflictingBitTest(t *testing.T, factory Fact sm := factory.New() require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1133,7 +1152,8 @@ func RecordPollChangePreferredChainTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1240,7 +1260,8 @@ func LastAcceptedTest(t *testing.T, factory Factory) { sm := factory.New() require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1324,7 +1345,8 @@ func MetricsProcessingErrorTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1353,7 +1375,8 @@ func MetricsAcceptedErrorTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1382,7 +1405,8 @@ func MetricsRejectedErrorTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1411,7 +1435,8 @@ func ErrorOnInitialRejectionTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1450,7 +1475,8 @@ func ErrorOnAcceptTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1487,7 +1513,8 @@ func ErrorOnRejectSiblingTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1533,7 +1560,8 @@ func ErrorOnTransitiveRejectionTest(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1609,7 +1637,7 @@ func RandomizedConsistencyTest(t *testing.T, factory Factory) { n := NewNetwork(params, numColors, source) for i := 0; i < numNodes; i++ { - require.NoError(n.AddNode(factory.New())) + require.NoError(n.AddNode(t, factory.New())) } for !n.Finalized() { @@ -1623,7 +1651,8 @@ func ErrorOnAddDecidedBlockTest(t *testing.T, factory Factory) { sm := factory.New() require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1653,7 +1682,8 @@ func ErrorOnAddDuplicateBlockIDTest(t *testing.T, factory Factory) { sm := factory.New() require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.Parameters{ K: 1, AlphaPreference: 1, @@ -1717,7 +1747,8 @@ func RecordPollWithDefaultParameters(t *testing.T, factory Factory) { sm := factory.New() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) params := snowball.DefaultParameters require.NoError(sm.Initialize(ctx, params, GenesisID, GenesisHeight, GenesisTimestamp)) diff --git a/snow/consensus/snowman/network_test.go b/snow/consensus/snowman/network_test.go index 3102c0cae573..9b402450c2de 100644 --- a/snow/consensus/snowman/network_test.go +++ b/snow/consensus/snowman/network_test.go @@ -5,6 +5,7 @@ package snowman import ( "context" + "testing" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/choices" @@ -65,8 +66,10 @@ func (n *Network) shuffleColors() { utils.Sort(n.colors) } -func (n *Network) AddNode(sm Consensus) error { - if err := sm.Initialize(snowtest.ConsensusContext(), n.params, Genesis.ID(), Genesis.Height(), Genesis.Timestamp()); err != nil { +func (n *Network) AddNode(t testing.TB, sm Consensus) error { + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) + if err := sm.Initialize(ctx, n.params, Genesis.ID(), Genesis.Height(), Genesis.Timestamp()); err != nil { return err } diff --git a/snow/context.go b/snow/context.go index 086243868bc2..60e2a305eb2b 100644 --- a/snow/context.go +++ b/snow/context.go @@ -96,22 +96,3 @@ type ConsensusContext struct { // True iff this chain is currently state-syncing StateSyncing utils.Atomic[bool] } - -func DefaultContextTest() *Context { - sk, err := bls.NewSecretKey() - if err != nil { - panic(err) - } - pk := bls.PublicFromSecretKey(sk) - return &Context{ - NetworkID: 0, - SubnetID: ids.Empty, - ChainID: ids.Empty, - NodeID: ids.EmptyNodeID, - PublicKey: pk, - Log: logging.NoLog{}, - BCLookup: ids.NewAliaser(), - Metrics: metrics.NewOptionalGatherer(), - ChainDataDir: "", - } -} diff --git a/snow/engine/avalanche/bootstrap/bootstrapper_test.go b/snow/engine/avalanche/bootstrap/bootstrapper_test.go index 8efaef5ee647..1ef3ef7102ef 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper_test.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper_test.go @@ -56,7 +56,8 @@ func (t *testTx) Accept(ctx context.Context) error { func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *vertex.TestManager, *vertex.TestVM) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() db := memdb.New() diff --git a/snow/engine/avalanche/state/unique_vertex_test.go b/snow/engine/avalanche/state/unique_vertex_test.go index 4d6dcc55e385..cdd503157dbd 100644 --- a/snow/engine/avalanche/state/unique_vertex_test.go +++ b/snow/engine/avalanche/state/unique_vertex_test.go @@ -13,11 +13,11 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowstorm" "github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex" "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/logging" ) var errUnknownTx = errors.New("unknown tx") @@ -29,13 +29,12 @@ func newTestSerializer(t *testing.T, parse func(context.Context, []byte) (snowst vm.ParseTxF = parse baseDB := memdb.New() - ctx := snow.DefaultContextTest() s := NewSerializer( SerializerConfig{ - ChainID: ctx.ChainID, + ChainID: ids.Empty, VM: &vm, DB: baseDB, - Log: ctx.Log, + Log: logging.NoLog{}, }, ) @@ -260,9 +259,9 @@ func TestParseVertexWithIncorrectChainID(t *testing.T) { func TestParseVertexWithInvalidTxs(t *testing.T) { require := require.New(t) - ctx := snow.DefaultContextTest() + chainID := ids.Empty statelessVertex, err := vertex.Build( // regular, non-stop vertex - ctx.ChainID, + chainID, 0, nil, [][]byte{{1}}, @@ -290,7 +289,7 @@ func TestParseVertexWithInvalidTxs(t *testing.T) { require.ErrorIs(err, errUnknownVertex) childStatelessVertex, err := vertex.Build( // regular, non-stop vertex - ctx.ChainID, + chainID, 1, []ids.ID{id}, [][]byte{{2}}, diff --git a/snow/engine/common/queue/jobs_test.go b/snow/engine/common/queue/jobs_test.go index f5db64d66dfc..a50b3cb60e8a 100644 --- a/snow/engine/common/queue/jobs_test.go +++ b/snow/engine/common/queue/jobs_test.go @@ -116,7 +116,8 @@ func TestPushAndExecute(t *testing.T) { return job, nil } - count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(), &common.Halter{}, false) + snowCtx := snowtest.Context(t, snowtest.CChainID) + count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(snowCtx), &common.Halter{}, false) require.NoError(err) require.Equal(1, count) @@ -182,7 +183,8 @@ func TestRemoveDependency(t *testing.T) { } } - count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(), &common.Halter{}, false) + snowCtx := snowtest.Context(t, snowtest.CChainID) + count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(snowCtx), &common.Halter{}, false) require.NoError(err) require.Equal(2, count) require.True(executed0) @@ -355,7 +357,8 @@ func TestHandleJobWithMissingDependencyOnRunnableStack(t *testing.T) { } } - _, err = jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(), &common.Halter{}, false) + snowCtx := snowtest.Context(t, snowtest.CChainID) + _, err = jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(snowCtx), &common.Halter{}, false) // Assert that the database closed error on job1 causes ExecuteAll // to fail in the middle of execution. require.ErrorIs(err, database.ErrClosed) @@ -387,7 +390,7 @@ func TestHandleJobWithMissingDependencyOnRunnableStack(t *testing.T) { require.NoError(err) require.True(hasNext) - count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(), &common.Halter{}, false) + count, err := jobs.ExecuteAll(context.Background(), snowtest.ConsensusContext(snowCtx), &common.Halter{}, false) require.NoError(err) require.Equal(2, count) require.True(executed1) diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index d78ee2fe3e61..363af8c11488 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -39,7 +39,8 @@ var errUnknownBlock = errors.New("unknown block") func newConfig(t *testing.T) (Config, ids.NodeID, *common.SenderTest, *block.TestVM) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() @@ -105,7 +106,8 @@ func TestBootstrapperStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { sender.Default(true) vm.Default(true) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) // create boostrapper configuration peers := validators.NewManager() sampleK := 2 @@ -1315,7 +1317,8 @@ func TestBootstrapContinueAfterHalt(t *testing.T) { func TestBootstrapNoParseOnNew(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) peers := validators.NewManager() sender := &common.SenderTest{} diff --git a/snow/engine/snowman/config_test.go b/snow/engine/snowman/config_test.go index 36e01d0d8f14..2991a092bdfc 100644 --- a/snow/engine/snowman/config_test.go +++ b/snow/engine/snowman/config_test.go @@ -4,6 +4,8 @@ package snowman import ( + "testing" + "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" @@ -13,9 +15,11 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" ) -func DefaultConfig() Config { +func DefaultConfig(t testing.TB) Config { + ctx := snowtest.Context(t, snowtest.PChainID) + return Config{ - Ctx: snowtest.ConsensusContext(), + Ctx: snowtest.ConsensusContext(ctx), VM: &block.TestVM{}, Sender: &common.SenderTest{}, Validators: validators.NewManager(), diff --git a/snow/engine/snowman/syncer/state_syncer_test.go b/snow/engine/snowman/syncer/state_syncer_test.go index 7e6b58694375..bb0ed52e6bae 100644 --- a/snow/engine/snowman/syncer/state_syncer_test.go +++ b/snow/engine/snowman/syncer/state_syncer_test.go @@ -39,7 +39,8 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { require := require.New(t) // Build state syncer - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) sender := &common.SenderTest{T: t} // Non state syncableVM case @@ -109,7 +110,8 @@ func TestStateSyncerIsEnabledIfVMSupportsStateSyncing(t *testing.T) { func TestStateSyncingStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) alpha, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -151,7 +153,8 @@ func TestStateSyncingStartsOnlyIfEnoughStakeIsConnected(t *testing.T) { func TestStateSyncLocalSummaryIsIncludedAmongFrontiersIfAvailable(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -188,7 +191,8 @@ func TestStateSyncLocalSummaryIsIncludedAmongFrontiersIfAvailable(t *testing.T) func TestStateSyncNotFoundOngoingSummaryIsNotIncludedAmongFrontiers(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -218,7 +222,8 @@ func TestStateSyncNotFoundOngoingSummaryIsNotIncludedAmongFrontiers(t *testing.T func TestBeaconsAreReachedForFrontiersUponStartup(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -256,7 +261,8 @@ func TestBeaconsAreReachedForFrontiersUponStartup(t *testing.T) { func TestUnRequestedStateSummaryFrontiersAreDropped(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -345,7 +351,8 @@ func TestUnRequestedStateSummaryFrontiersAreDropped(t *testing.T) { func TestMalformedStateSummaryFrontiersAreDropped(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -413,7 +420,8 @@ func TestMalformedStateSummaryFrontiersAreDropped(t *testing.T) { func TestLateResponsesFromUnresponsiveFrontiersAreNotRecorded(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -495,7 +503,8 @@ func TestLateResponsesFromUnresponsiveFrontiersAreNotRecorded(t *testing.T) { func TestStateSyncIsRestartedIfTooManyFrontierSeedersTimeout(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -583,7 +592,8 @@ func TestStateSyncIsRestartedIfTooManyFrontierSeedersTimeout(t *testing.T) { func TestVoteRequestsAreSentAsAllFrontierBeaconsResponded(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -653,7 +663,8 @@ func TestVoteRequestsAreSentAsAllFrontierBeaconsResponded(t *testing.T) { func TestUnRequestedVotesAreDropped(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -769,7 +780,8 @@ func TestUnRequestedVotesAreDropped(t *testing.T) { func TestVotesForUnknownSummariesAreDropped(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -871,7 +883,8 @@ func TestVotesForUnknownSummariesAreDropped(t *testing.T) { func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -1015,7 +1028,8 @@ func TestStateSummaryIsPassedToVMAsMajorityOfVotesIsCastedForIt(t *testing.T) { func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -1120,7 +1134,8 @@ func TestVotingIsRestartedIfMajorityIsNotReachedDueToTimeouts(t *testing.T) { func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) @@ -1265,7 +1280,8 @@ func TestStateSyncIsStoppedIfEnoughVotesAreCastedWithNoClearMajority(t *testing. func TestStateSyncIsDoneOnceVMNotifies(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) beacons := buildTestPeers(t, ctx.SubnetID) totalWeight, err := beacons.TotalWeight(ctx.SubnetID) require.NoError(err) diff --git a/snow/engine/snowman/transitive_test.go b/snow/engine/snowman/transitive_test.go index 738f20440c58..c06dc5c924cf 100644 --- a/snow/engine/snowman/transitive_test.go +++ b/snow/engine/snowman/transitive_test.go @@ -98,7 +98,7 @@ func setup(t *testing.T, engCfg Config) (ids.NodeID, validators.Manager, *common } func setupDefaultConfig(t *testing.T) (ids.NodeID, validators.Manager, *common.SenderTest, *block.TestVM, *Transitive, snowman.Block) { - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) return setup(t, engCfg) } @@ -328,7 +328,7 @@ func TestEngineQuery(t *testing.T) { func TestEngineMultipleQuery(t *testing.T) { require := require.New(t) - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) engCfg.Params = snowball.Parameters{ K: 3, AlphaPreference: 2, @@ -747,7 +747,7 @@ func TestEngineRepoll(t *testing.T) { func TestVoteCanceling(t *testing.T) { require := require.New(t) - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) engCfg.Params = snowball.Parameters{ K: 3, AlphaPreference: 2, @@ -851,7 +851,7 @@ func TestVoteCanceling(t *testing.T) { func TestEngineNoQuery(t *testing.T) { require := require.New(t) - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) sender := &common.SenderTest{T: t} engCfg.Sender = sender @@ -904,7 +904,7 @@ func TestEngineNoQuery(t *testing.T) { func TestEngineNoRepollQuery(t *testing.T) { require := require.New(t) - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) sender := &common.SenderTest{T: t} engCfg.Sender = sender @@ -1596,7 +1596,7 @@ func TestEnginePushQueryRequestIDConflict(t *testing.T) { func TestEngineAggressivePolling(t *testing.T) { require := require.New(t) - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) engCfg.Params.ConcurrentRepolls = 2 vals := validators.NewManager() @@ -1684,7 +1684,7 @@ func TestEngineAggressivePolling(t *testing.T) { func TestEngineDoubleChit(t *testing.T) { require := require.New(t) - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) engCfg.Params = snowball.Parameters{ K: 2, AlphaPreference: 2, @@ -1794,7 +1794,7 @@ func TestEngineDoubleChit(t *testing.T) { func TestEngineBuildBlockLimit(t *testing.T) { require := require.New(t) - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) engCfg.Params.K = 1 engCfg.Params.AlphaPreference = 1 engCfg.Params.AlphaConfidence = 1 @@ -2816,7 +2816,7 @@ func TestEngineBuildBlockWithCachedNonVerifiedParent(t *testing.T) { func TestEngineApplyAcceptedFrontierInQueryFailed(t *testing.T) { require := require.New(t) - engCfg := DefaultConfig() + engCfg := DefaultConfig(t) engCfg.Params = snowball.Parameters{ K: 1, AlphaPreference: 1, diff --git a/snow/networking/benchlist/benchlist_test.go b/snow/networking/benchlist/benchlist_test.go index aef4513edf6d..5e068e78aef4 100644 --- a/snow/networking/benchlist/benchlist_test.go +++ b/snow/networking/benchlist/benchlist_test.go @@ -20,7 +20,8 @@ var minimumFailingDuration = 5 * time.Minute func TestBenchlistAdd(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() vdrID0 := ids.GenerateTestNodeID() vdrID1 := ids.GenerateTestNodeID() @@ -144,7 +145,8 @@ func TestBenchlistAdd(t *testing.T) { func TestBenchlistMaxStake(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() vdrID0 := ids.GenerateTestNodeID() vdrID1 := ids.GenerateTestNodeID() @@ -257,7 +259,8 @@ func TestBenchlistMaxStake(t *testing.T) { func TestBenchlistRemove(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() vdrID0 := ids.GenerateTestNodeID() vdrID1 := ids.GenerateTestNodeID() diff --git a/snow/networking/handler/handler_test.go b/snow/networking/handler/handler_test.go index 80330f872f45..71c3042c1807 100644 --- a/snow/networking/handler/handler_test.go +++ b/snow/networking/handler/handler_test.go @@ -41,7 +41,8 @@ func TestHandlerDropsTimedOutMessages(t *testing.T) { called := make(chan struct{}) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() vdr0 := ids.GenerateTestNodeID() @@ -136,7 +137,8 @@ func TestHandlerClosesOnError(t *testing.T) { require := require.New(t) closed := make(chan struct{}, 1) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -227,7 +229,8 @@ func TestHandlerDropsGossipDuringBootstrapping(t *testing.T) { require := require.New(t) closed := make(chan struct{}, 1) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -304,7 +307,8 @@ func TestHandlerDropsGossipDuringBootstrapping(t *testing.T) { func TestHandlerDispatchInternal(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) msgFromVMChan := make(chan common.Message) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -373,7 +377,8 @@ func TestHandlerDispatchInternal(t *testing.T) { func TestHandlerSubnetConnector(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -548,7 +553,8 @@ func TestDynamicEngineTypeDispatch(t *testing.T) { require := require.New(t) messageReceived := make(chan struct{}) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -621,7 +627,8 @@ func TestDynamicEngineTypeDispatch(t *testing.T) { func TestHandlerStartError(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) resourceTracker, err := tracker.NewResourceTracker( prometheus.NewRegistry(), resource.NoUsage, diff --git a/snow/networking/handler/health_test.go b/snow/networking/handler/health_test.go index 3b1335417fa1..31c3d35ce348 100644 --- a/snow/networking/handler/health_test.go +++ b/snow/networking/handler/health_test.go @@ -48,7 +48,8 @@ func TestHealthCheckSubnet(t *testing.T) { t.Run(name, func(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() diff --git a/snow/networking/handler/message_queue_test.go b/snow/networking/handler/message_queue_test.go index 3930bcf4522b..266843772c3c 100644 --- a/snow/networking/handler/message_queue_test.go +++ b/snow/networking/handler/message_queue_test.go @@ -26,7 +26,8 @@ func TestQueue(t *testing.T) { ctrl := gomock.NewController(t) require := require.New(t) cpuTracker := tracker.NewMockTracker(ctrl) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() vdr1ID, vdr2ID := ids.GenerateTestNodeID(), ids.GenerateTestNodeID() require.NoError(vdrs.AddStaker(ctx.SubnetID, vdr1ID, nil, ids.Empty, 1)) diff --git a/snow/networking/router/chain_router_test.go b/snow/networking/router/chain_router_test.go index 6e08f8e7b7c2..d99fecd1af00 100644 --- a/snow/networking/router/chain_router_test.go +++ b/snow/networking/router/chain_router_test.go @@ -15,7 +15,6 @@ import ( "go.uber.org/mock/gomock" - "github.com/ava-labs/avalanchego/api/metrics" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/proto/pb/p2p" @@ -49,7 +48,8 @@ const ( func TestShutdown(t *testing.T) { require := require.New(t) - chainCtx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + chainCtx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(chainCtx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) benchlist := benchlist.NewNoBenchlist() @@ -184,7 +184,8 @@ func TestShutdown(t *testing.T) { func TestShutdownTimesOut(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) nodeID := ids.EmptyNodeID vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -378,7 +379,8 @@ func TestRouterTimeout(t *testing.T) { wg = sync.WaitGroup{} ) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) @@ -727,7 +729,8 @@ func TestRouterHonorsRequestedEngine(t *testing.T) { h := handler.NewMockHandler(ctrl) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) h.EXPECT().Context().Return(ctx).AnyTimes() h.EXPECT().SetOnStopped(gomock.Any()).AnyTimes() h.EXPECT().Stop(gomock.Any()).AnyTimes() @@ -951,7 +954,8 @@ func TestValidatorOnlyMessageDrops(t *testing.T) { calledF := false wg := sync.WaitGroup{} - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) sb := subnets.New(ctx.NodeID, subnets.Config{ValidatorOnly: true}) vdrs := validators.NewManager() vID := ids.GenerateTestNodeID() @@ -1103,13 +1107,10 @@ func TestConnectedSubnet(t *testing.T) { )) // Create bootstrapper, engine and handler - platform := snowtest.ConsensusContext() - platform.ChainID = constants.PlatformChainID - platform.SubnetID = constants.PrimaryNetworkID - platform.Registerer = prometheus.NewRegistry() - platform.Metrics = metrics.NewOptionalGatherer() - platform.Executing.Set(false) - platform.State.Set(snow.EngineState{ + snowCtx := snowtest.Context(t, snowtest.PChainID) + ctx := snowtest.ConsensusContext(snowCtx) + ctx.Executing.Set(false) + ctx.State.Set(snow.EngineState{ Type: engineType, State: snow.NormalOp, }) @@ -1128,7 +1129,7 @@ func TestConnectedSubnet(t *testing.T) { } platformHandler := handler.NewMockHandler(ctrl) - platformHandler.EXPECT().Context().Return(platform).AnyTimes() + platformHandler.EXPECT().Context().Return(ctx).AnyTimes() platformHandler.EXPECT().SetOnStopped(gomock.Any()).AnyTimes() platformHandler.EXPECT().Push(gomock.Any(), myConnectedMsg).Times(1) platformHandler.EXPECT().Push(gomock.Any(), mySubnetConnectedMsg0).Times(1) @@ -1222,7 +1223,8 @@ func TestValidatorOnlyAllowedNodeMessageDrops(t *testing.T) { calledF := false wg := sync.WaitGroup{} - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) allowedID := ids.GenerateTestNodeID() allowedSet := set.Of(allowedID) sb := subnets.New(ctx.NodeID, subnets.Config{ValidatorOnly: true, AllowedNodes: allowedSet}) @@ -1547,7 +1549,8 @@ func newChainRouterTest(t *testing.T) (*ChainRouter, *common.EngineTest) { )) // Create bootstrapper, engine and handler - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.PChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(t, vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index b4ba9db4f89a..69363b2eeb67 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -54,7 +54,8 @@ var defaultSubnetConfig = subnets.Config{ func TestTimeout(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) benchlist := benchlist.NewNoBenchlist() @@ -113,7 +114,7 @@ func TestTimeout(t *testing.T) { ) require.NoError(err) - ctx2 := snowtest.ConsensusContext() + ctx2 := snowtest.ConsensusContext(snowCtx) resourceTracker, err := tracker.NewResourceTracker( prometheus.NewRegistry(), resource.NoUsage, @@ -318,7 +319,8 @@ func TestTimeout(t *testing.T) { func TestReliableMessages(t *testing.T) { require := require.New(t) - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.BuildTestNodeID([]byte{1}), nil, ids.Empty, 1)) benchlist := benchlist.NewNoBenchlist() @@ -378,7 +380,7 @@ func TestReliableMessages(t *testing.T) { ) require.NoError(err) - ctx2 := snowtest.ConsensusContext() + ctx2 := snowtest.ConsensusContext(snowCtx) resourceTracker, err := tracker.NewResourceTracker( prometheus.NewRegistry(), resource.NoUsage, @@ -464,7 +466,8 @@ func TestReliableMessagesToMyself(t *testing.T) { require := require.New(t) benchlist := benchlist.NewNoBenchlist() - ctx := snowtest.ConsensusContext() + snowCtx := snowtest.Context(t, snowtest.CChainID) + ctx := snowtest.ConsensusContext(snowCtx) vdrs := validators.NewManager() require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) tm, err := timeout.NewManager( @@ -523,7 +526,7 @@ func TestReliableMessagesToMyself(t *testing.T) { ) require.NoError(err) - ctx2 := snowtest.ConsensusContext() + ctx2 := snowtest.ConsensusContext(snowCtx) resourceTracker, err := tracker.NewResourceTracker( prometheus.NewRegistry(), resource.NoUsage, @@ -607,26 +610,16 @@ func TestReliableMessagesToMyself(t *testing.T) { func TestSender_Bootstrap_Requests(t *testing.T) { var ( - chainID = ids.GenerateTestID() - subnetID = ids.GenerateTestID() - myNodeID = ids.GenerateTestNodeID() successNodeID = ids.GenerateTestNodeID() failedNodeID = ids.GenerateTestNodeID() deadline = time.Second requestID = uint32(1337) - ctx = snow.DefaultContextTest() heights = []uint64{1, 2, 3} containerIDs = []ids.ID{ids.GenerateTestID(), ids.GenerateTestID()} engineType = p2p.EngineType_ENGINE_TYPE_SNOWMAN ) - ctx.ChainID = chainID - ctx.SubnetID = subnetID - ctx.NodeID = myNodeID - snowCtx := &snow.ConsensusContext{ - Context: ctx, - Registerer: prometheus.NewRegistry(), - AvalancheRegisterer: prometheus.NewRegistry(), - } + snowCtx := snowtest.Context(t, snowtest.PChainID) + ctx := snowtest.ConsensusContext(snowCtx) type test struct { name string @@ -645,21 +638,21 @@ func TestSender_Bootstrap_Requests(t *testing.T) { failedMsgF: func(nodeID ids.NodeID) message.InboundMessage { return message.InternalGetStateSummaryFrontierFailed( nodeID, - chainID, + ctx.ChainID, requestID, ) }, assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&p2p.GetStateSummaryFrontier{}, msg.Message()) innerMsg := msg.Message().(*p2p.GetStateSummaryFrontier) - require.Equal(chainID[:], innerMsg.ChainId) + require.Equal(ctx.ChainID[:], innerMsg.ChainId) require.Equal(requestID, innerMsg.RequestId) require.Equal(uint64(deadline), innerMsg.Deadline) }, expectedResponseOp: message.StateSummaryFrontierOp, setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().GetStateSummaryFrontier( - chainID, + ctx.ChainID, requestID, deadline, ).Return(nil, nil) @@ -669,7 +662,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { gomock.Any(), // Outbound message // Note [myNodeID] is not in this set set.Of(successNodeID, failedNodeID), - subnetID, // Subnet ID + ctx.SubnetID, // Subnet ID gomock.Any(), ).Return(set.Of(successNodeID)) }, @@ -686,14 +679,14 @@ func TestSender_Bootstrap_Requests(t *testing.T) { failedMsgF: func(nodeID ids.NodeID) message.InboundMessage { return message.InternalGetAcceptedStateSummaryFailed( nodeID, - chainID, + ctx.ChainID, requestID, ) }, assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&p2p.GetAcceptedStateSummary{}, msg.Message()) innerMsg := msg.Message().(*p2p.GetAcceptedStateSummary) - require.Equal(chainID[:], innerMsg.ChainId) + require.Equal(ctx.ChainID[:], innerMsg.ChainId) require.Equal(requestID, innerMsg.RequestId) require.Equal(uint64(deadline), innerMsg.Deadline) require.Equal(heights, innerMsg.Heights) @@ -701,7 +694,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { expectedResponseOp: message.AcceptedStateSummaryOp, setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().GetAcceptedStateSummary( - chainID, + ctx.ChainID, requestID, deadline, heights, @@ -712,7 +705,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { gomock.Any(), // Outbound message // Note [myNodeID] is not in this set set.Of(successNodeID, failedNodeID), - subnetID, // Subnet ID + ctx.SubnetID, // Subnet ID gomock.Any(), ).Return(set.Of(successNodeID)) }, @@ -725,7 +718,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { failedMsgF: func(nodeID ids.NodeID) message.InboundMessage { return message.InternalGetAcceptedFrontierFailed( nodeID, - chainID, + ctx.ChainID, requestID, engineType, ) @@ -733,7 +726,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&p2p.GetAcceptedFrontier{}, msg.Message()) innerMsg := msg.Message().(*p2p.GetAcceptedFrontier) - require.Equal(chainID[:], innerMsg.ChainId) + require.Equal(ctx.ChainID[:], innerMsg.ChainId) require.Equal(requestID, innerMsg.RequestId) require.Equal(uint64(deadline), innerMsg.Deadline) require.Equal(engineType, innerMsg.EngineType) @@ -741,7 +734,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { expectedResponseOp: message.AcceptedFrontierOp, setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().GetAcceptedFrontier( - chainID, + ctx.ChainID, requestID, deadline, engineType, @@ -752,7 +745,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { gomock.Any(), // Outbound message // Note [myNodeID] is not in this set set.Of(successNodeID, failedNodeID), - subnetID, // Subnet ID + ctx.SubnetID, // Subnet ID gomock.Any(), ).Return(set.Of(successNodeID)) }, @@ -766,7 +759,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { failedMsgF: func(nodeID ids.NodeID) message.InboundMessage { return message.InternalGetAcceptedFailed( nodeID, - chainID, + ctx.ChainID, requestID, engineType, ) @@ -774,7 +767,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&p2p.GetAccepted{}, msg.Message()) innerMsg := msg.Message().(*p2p.GetAccepted) - require.Equal(chainID[:], innerMsg.ChainId) + require.Equal(ctx.ChainID[:], innerMsg.ChainId) require.Equal(requestID, innerMsg.RequestId) require.Equal(uint64(deadline), innerMsg.Deadline) require.Equal(engineType, innerMsg.EngineType) @@ -782,7 +775,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { expectedResponseOp: message.AcceptedOp, setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().GetAccepted( - chainID, + ctx.ChainID, requestID, deadline, containerIDs, @@ -794,7 +787,7 @@ func TestSender_Bootstrap_Requests(t *testing.T) { gomock.Any(), // Outbound message // Note [myNodeID] is not in this set set.Of(successNodeID, failedNodeID), - subnetID, // Subnet ID + ctx.SubnetID, // Subnet ID gomock.Any(), ).Return(set.Of(successNodeID)) }, @@ -815,14 +808,17 @@ func TestSender_Bootstrap_Requests(t *testing.T) { externalSender = NewMockExternalSender(ctrl) timeoutManager = timeout.NewMockManager(ctrl) router = router.NewMockRouter(ctrl) - nodeIDs = set.Of(successNodeID, failedNodeID, myNodeID) + nodeIDs = set.Of(successNodeID, failedNodeID, ctx.NodeID) nodeIDsCopy set.Set[ids.NodeID] ) nodeIDsCopy.Union(nodeIDs) - snowCtx.Registerer = prometheus.NewRegistry() + + // Instantiate new registerers to avoid duplicate metrics + // registration + ctx.Registerer = prometheus.NewRegistry() sender, err := New( - snowCtx, + ctx, msgCreator, externalSender, router, @@ -841,8 +837,8 @@ func TestSender_Bootstrap_Requests(t *testing.T) { router.EXPECT().RegisterRequest( gomock.Any(), // Context nodeID, // Node ID - chainID, // Source Chain - chainID, // Destination Chain + ctx.ChainID, // Source Chain + ctx.ChainID, // Destination Chain requestID, // Request ID tt.expectedResponseOp, // Operation expectedFailedMsg, // Failure Message @@ -879,25 +875,15 @@ func TestSender_Bootstrap_Requests(t *testing.T) { func TestSender_Bootstrap_Responses(t *testing.T) { var ( - chainID = ids.GenerateTestID() - subnetID = ids.GenerateTestID() - myNodeID = ids.GenerateTestNodeID() destinationNodeID = ids.GenerateTestNodeID() deadline = time.Second requestID = uint32(1337) - ctx = snow.DefaultContextTest() summaryIDs = []ids.ID{ids.GenerateTestID(), ids.GenerateTestID()} summary = []byte{1, 2, 3} engineType = p2p.EngineType_ENGINE_TYPE_AVALANCHE ) - ctx.ChainID = chainID - ctx.SubnetID = subnetID - ctx.NodeID = myNodeID - snowCtx := &snow.ConsensusContext{ - Context: ctx, - Registerer: prometheus.NewRegistry(), - AvalancheRegisterer: prometheus.NewRegistry(), - } + snowCtx := snowtest.Context(t, snowtest.PChainID) + ctx := snowtest.ConsensusContext(snowCtx) type test struct { name string @@ -912,7 +898,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { name: "StateSummaryFrontier", setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().StateSummaryFrontier( - chainID, + ctx.ChainID, requestID, summary, ).Return(nil, nil) // Don't care about the message @@ -920,7 +906,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&p2p.StateSummaryFrontier{}, msg.Message()) innerMsg := msg.Message().(*p2p.StateSummaryFrontier) - require.Equal(chainID[:], innerMsg.ChainId) + require.Equal(ctx.ChainID[:], innerMsg.ChainId) require.Equal(requestID, innerMsg.RequestId) require.Equal(summary, innerMsg.Summary) }, @@ -928,7 +914,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { externalSender.EXPECT().Send( gomock.Any(), // Outbound message set.Of(destinationNodeID), // Node IDs - subnetID, // Subnet ID + ctx.SubnetID, // Subnet ID gomock.Any(), ).Return(nil) }, @@ -940,7 +926,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { name: "AcceptedStateSummary", setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().AcceptedStateSummary( - chainID, + ctx.ChainID, requestID, summaryIDs, ).Return(nil, nil) // Don't care about the message @@ -948,7 +934,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&p2p.AcceptedStateSummary{}, msg.Message()) innerMsg := msg.Message().(*p2p.AcceptedStateSummary) - require.Equal(chainID[:], innerMsg.ChainId) + require.Equal(ctx.ChainID[:], innerMsg.ChainId) require.Equal(requestID, innerMsg.RequestId) for i, summaryID := range summaryIDs { require.Equal(summaryID[:], innerMsg.SummaryIds[i]) @@ -958,7 +944,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { externalSender.EXPECT().Send( gomock.Any(), // Outbound message set.Of(destinationNodeID), // Node IDs - subnetID, // Subnet ID + ctx.SubnetID, // Subnet ID gomock.Any(), ).Return(nil) }, @@ -970,7 +956,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { name: "AcceptedFrontier", setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().AcceptedFrontier( - chainID, + ctx.ChainID, requestID, summaryIDs[0], ).Return(nil, nil) // Don't care about the message @@ -978,7 +964,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&p2p.AcceptedFrontier{}, msg.Message()) innerMsg := msg.Message().(*p2p.AcceptedFrontier) - require.Equal(chainID[:], innerMsg.ChainId) + require.Equal(ctx.ChainID[:], innerMsg.ChainId) require.Equal(requestID, innerMsg.RequestId) require.Equal(summaryIDs[0][:], innerMsg.ContainerId) }, @@ -986,7 +972,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { externalSender.EXPECT().Send( gomock.Any(), // Outbound message set.Of(destinationNodeID), // Node IDs - subnetID, // Subnet ID + ctx.SubnetID, // Subnet ID gomock.Any(), ).Return(nil) }, @@ -998,7 +984,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { name: "Accepted", setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().Accepted( - chainID, + ctx.ChainID, requestID, summaryIDs, ).Return(nil, nil) // Don't care about the message @@ -1006,7 +992,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&p2p.Accepted{}, msg.Message()) innerMsg := msg.Message().(*p2p.Accepted) - require.Equal(chainID[:], innerMsg.ChainId) + require.Equal(ctx.ChainID[:], innerMsg.ChainId) require.Equal(requestID, innerMsg.RequestId) for i, summaryID := range summaryIDs { require.Equal(summaryID[:], innerMsg.ContainerIds[i]) @@ -1016,7 +1002,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { externalSender.EXPECT().Send( gomock.Any(), // Outbound message set.Of(destinationNodeID), // Node IDs - subnetID, // Subnet ID + ctx.SubnetID, // Subnet ID gomock.Any(), ).Return(nil) }, @@ -1040,11 +1026,11 @@ func TestSender_Bootstrap_Responses(t *testing.T) { // Instantiate new registerers to avoid duplicate metrics // registration - snowCtx.Registerer = prometheus.NewRegistry() - snowCtx.AvalancheRegisterer = prometheus.NewRegistry() + ctx.Registerer = prometheus.NewRegistry() + ctx.AvalancheRegisterer = prometheus.NewRegistry() sender, err := New( - snowCtx, + ctx, msgCreator, externalSender, router, @@ -1068,7 +1054,7 @@ func TestSender_Bootstrap_Responses(t *testing.T) { close(calledHandleInbound) }, ) - tt.sendF(require, sender, myNodeID) + tt.sendF(require, sender, ctx.NodeID) <-calledHandleInbound } @@ -1087,24 +1073,14 @@ func TestSender_Bootstrap_Responses(t *testing.T) { func TestSender_Single_Request(t *testing.T) { var ( - chainID = ids.GenerateTestID() - subnetID = ids.GenerateTestID() - myNodeID = ids.GenerateTestNodeID() destinationNodeID = ids.GenerateTestNodeID() deadline = time.Second requestID = uint32(1337) - ctx = snow.DefaultContextTest() containerID = ids.GenerateTestID() engineType = p2p.EngineType_ENGINE_TYPE_SNOWMAN ) - ctx.ChainID = chainID - ctx.SubnetID = subnetID - ctx.NodeID = myNodeID - snowCtx := &snow.ConsensusContext{ - Context: ctx, - Registerer: prometheus.NewRegistry(), - AvalancheRegisterer: prometheus.NewRegistry(), - } + snowCtx := snowtest.Context(t, snowtest.PChainID) + ctx := snowtest.ConsensusContext(snowCtx) type test struct { name string @@ -1122,7 +1098,7 @@ func TestSender_Single_Request(t *testing.T) { failedMsgF: func(nodeID ids.NodeID) message.InboundMessage { return message.InternalGetAncestorsFailed( nodeID, - chainID, + ctx.ChainID, requestID, engineType, ) @@ -1130,14 +1106,14 @@ func TestSender_Single_Request(t *testing.T) { assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&message.GetAncestorsFailed{}, msg.Message()) innerMsg := msg.Message().(*message.GetAncestorsFailed) - require.Equal(chainID, innerMsg.ChainID) + require.Equal(ctx.ChainID, innerMsg.ChainID) require.Equal(requestID, innerMsg.RequestID) require.Equal(engineType, innerMsg.EngineType) }, expectedResponseOp: message.AncestorsOp, setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().GetAncestors( - chainID, + ctx.ChainID, requestID, deadline, containerID, @@ -1148,7 +1124,7 @@ func TestSender_Single_Request(t *testing.T) { externalSender.EXPECT().Send( gomock.Any(), // Outbound message set.Of(destinationNodeID), // Node IDs - subnetID, + ctx.SubnetID, gomock.Any(), ).Return(sentTo) }, @@ -1161,7 +1137,7 @@ func TestSender_Single_Request(t *testing.T) { failedMsgF: func(nodeID ids.NodeID) message.InboundMessage { return message.InternalGetFailed( nodeID, - chainID, + ctx.ChainID, requestID, engineType, ) @@ -1169,14 +1145,14 @@ func TestSender_Single_Request(t *testing.T) { assertMsgToMyself: func(require *require.Assertions, msg message.InboundMessage) { require.IsType(&message.GetFailed{}, msg.Message()) innerMsg := msg.Message().(*message.GetFailed) - require.Equal(chainID, innerMsg.ChainID) + require.Equal(ctx.ChainID, innerMsg.ChainID) require.Equal(requestID, innerMsg.RequestID) require.Equal(engineType, innerMsg.EngineType) }, expectedResponseOp: message.PutOp, setMsgCreatorExpect: func(msgCreator *message.MockOutboundMsgBuilder) { msgCreator.EXPECT().Get( - chainID, + ctx.ChainID, requestID, deadline, containerID, @@ -1187,7 +1163,7 @@ func TestSender_Single_Request(t *testing.T) { externalSender.EXPECT().Send( gomock.Any(), // Outbound message set.Of(destinationNodeID), // Node IDs - subnetID, + ctx.SubnetID, gomock.Any(), ).Return(sentTo) }, @@ -1208,10 +1184,13 @@ func TestSender_Single_Request(t *testing.T) { timeoutManager = timeout.NewMockManager(ctrl) router = router.NewMockRouter(ctrl) ) - snowCtx.Registerer = prometheus.NewRegistry() + + // Instantiate new registerers to avoid duplicate metrics + // registration + ctx.Registerer = prometheus.NewRegistry() sender, err := New( - snowCtx, + ctx, msgCreator, externalSender, router, @@ -1227,12 +1206,12 @@ func TestSender_Single_Request(t *testing.T) { // Case: sending to myself { // Make sure we register requests with the router - expectedFailedMsg := tt.failedMsgF(myNodeID) + expectedFailedMsg := tt.failedMsgF(ctx.NodeID) router.EXPECT().RegisterRequest( gomock.Any(), // Context - myNodeID, // Node ID - chainID, // Source Chain - chainID, // Destination Chain + ctx.NodeID, // Node ID + ctx.ChainID, // Source Chain + ctx.ChainID, // Destination Chain requestID, // Request ID tt.expectedResponseOp, // Operation expectedFailedMsg, // Failure Message @@ -1251,14 +1230,14 @@ func TestSender_Single_Request(t *testing.T) { }, ) - tt.sendF(require, sender, myNodeID) + tt.sendF(require, sender, ctx.NodeID) <-calledHandleInbound } // Case: Node is benched { - timeoutManager.EXPECT().IsBenched(destinationNodeID, chainID).Return(true) + timeoutManager.EXPECT().IsBenched(destinationNodeID, ctx.ChainID).Return(true) timeoutManager.EXPECT().RegisterRequestToUnreachableValidator() @@ -1267,8 +1246,8 @@ func TestSender_Single_Request(t *testing.T) { router.EXPECT().RegisterRequest( gomock.Any(), // Context destinationNodeID, // Node ID - chainID, // Source Chain - chainID, // Destination Chain + ctx.ChainID, // Source Chain + ctx.ChainID, // Destination Chain requestID, // Request ID tt.expectedResponseOp, // Operation expectedFailedMsg, // Failure Message @@ -1294,7 +1273,7 @@ func TestSender_Single_Request(t *testing.T) { // Case: Node is not myself, not benched and send fails { - timeoutManager.EXPECT().IsBenched(destinationNodeID, chainID).Return(false) + timeoutManager.EXPECT().IsBenched(destinationNodeID, ctx.ChainID).Return(false) timeoutManager.EXPECT().RegisterRequestToUnreachableValidator() @@ -1303,8 +1282,8 @@ func TestSender_Single_Request(t *testing.T) { router.EXPECT().RegisterRequest( gomock.Any(), // Context destinationNodeID, // Node ID - chainID, // Source Chain - chainID, // Destination Chain + ctx.ChainID, // Source Chain + ctx.ChainID, // Destination Chain requestID, // Request ID tt.expectedResponseOp, // Operation expectedFailedMsg, // Failure Message diff --git a/snow/snowtest/snowtest.go b/snow/snowtest/snowtest.go index 2c103214688b..2450ebaf941d 100644 --- a/snow/snowtest/snowtest.go +++ b/snow/snowtest/snowtest.go @@ -12,10 +12,13 @@ import ( "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/api/metrics" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/logging" ) var ( @@ -35,9 +38,9 @@ func (noOpAcceptor) Accept(*snow.ConsensusContext, ids.ID, []byte) error { return nil } -func ConsensusContext() *snow.ConsensusContext { +func ConsensusContext(ctx *snow.Context) *snow.ConsensusContext { return &snow.ConsensusContext{ - Context: snow.DefaultContextTest(), + Context: ctx, Registerer: prometheus.NewRegistry(), AvalancheRegisterer: prometheus.NewRegistry(), BlockAcceptor: noOpAcceptor{}, @@ -49,29 +52,24 @@ func ConsensusContext() *snow.ConsensusContext { func Context(tb testing.TB, chainID ids.ID) *snow.Context { require := require.New(tb) - ctx := snow.DefaultContextTest() + secretKey, err := bls.NewSecretKey() + require.NoError(err) + publicKey := bls.PublicFromSecretKey(secretKey) - ctx.NetworkID = constants.UnitTestID - ctx.SubnetID = constants.PrimaryNetworkID - ctx.ChainID = chainID - ctx.XChainID = XChainID - ctx.CChainID = CChainID - ctx.AVAXAssetID = AVAXAssetID - - aliaser := ctx.BCLookup.(ids.Aliaser) + aliaser := ids.NewAliaser() require.NoError(aliaser.Alias(constants.PlatformChainID, "P")) require.NoError(aliaser.Alias(constants.PlatformChainID, constants.PlatformChainID.String())) - require.NoError(aliaser.Alias(ctx.XChainID, "X")) - require.NoError(aliaser.Alias(ctx.XChainID, ctx.XChainID.String())) - require.NoError(aliaser.Alias(ctx.CChainID, "C")) - require.NoError(aliaser.Alias(ctx.CChainID, ctx.CChainID.String())) + require.NoError(aliaser.Alias(XChainID, "X")) + require.NoError(aliaser.Alias(XChainID, XChainID.String())) + require.NoError(aliaser.Alias(CChainID, "C")) + require.NoError(aliaser.Alias(CChainID, CChainID.String())) - ctx.ValidatorState = &validators.TestState{ + validatorState := &validators.TestState{ GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) { subnetID, ok := map[ids.ID]ids.ID{ constants.PlatformChainID: constants.PrimaryNetworkID, - ctx.XChainID: constants.PrimaryNetworkID, - ctx.CChainID: constants.PrimaryNetworkID, + XChainID: constants.PrimaryNetworkID, + CChainID: constants.PrimaryNetworkID, }[chainID] if !ok { return ids.Empty, errMissing @@ -80,5 +78,22 @@ func Context(tb testing.TB, chainID ids.ID) *snow.Context { }, } - return ctx + return &snow.Context{ + NetworkID: constants.UnitTestID, + SubnetID: constants.PrimaryNetworkID, + ChainID: chainID, + NodeID: ids.EmptyNodeID, + PublicKey: publicKey, + + XChainID: XChainID, + CChainID: CChainID, + AVAXAssetID: AVAXAssetID, + + Log: logging.NoLog{}, + BCLookup: aliaser, + Metrics: metrics.NewOptionalGatherer(), + + ValidatorState: validatorState, + ChainDataDir: "", + } } diff --git a/vms/platformvm/txs/add_subnet_validator_test.go b/vms/platformvm/txs/add_subnet_validator_test.go index 8e07469ea2a0..e5f0684b25d7 100644 --- a/vms/platformvm/txs/add_subnet_validator_test.go +++ b/vms/platformvm/txs/add_subnet_validator_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/timer/mockable" @@ -22,7 +22,7 @@ import ( func TestAddSubnetValidatorTxSyntacticVerify(t *testing.T) { require := require.New(t) clk := mockable.Clock{} - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.PChainID) signers := [][]*secp256k1.PrivateKey{preFundedKeys} var ( @@ -140,7 +140,7 @@ func TestAddSubnetValidatorTxSyntacticVerify(t *testing.T) { func TestAddSubnetValidatorMarshal(t *testing.T) { require := require.New(t) clk := mockable.Clock{} - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.PChainID) signers := [][]*secp256k1.PrivateKey{preFundedKeys} var ( diff --git a/vms/platformvm/txs/create_chain_test.go b/vms/platformvm/txs/create_chain_test.go index 7154072bd8a9..ae2217c5b605 100644 --- a/vms/platformvm/txs/create_chain_test.go +++ b/vms/platformvm/txs/create_chain_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -17,7 +17,7 @@ import ( ) func TestUnsignedCreateChainTxVerify(t *testing.T) { - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.PChainID) testSubnet1ID := ids.GenerateTestID() testSubnet1ControlKeys := []*secp256k1.PrivateKey{ preFundedKeys[0], diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index 231b34a9e30d..065e2cb54707 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/timer/mockable" @@ -27,6 +28,8 @@ import ( ) func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { + ctx := snowtest.Context(t, snowtest.PChainID) + type test struct { name string backendF func(*gomock.Controller) *Backend @@ -64,8 +67,8 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { BaseTx: txs.BaseTx{ SyntacticallyVerified: true, BaseTx: avax.BaseTx{ - NetworkID: 1, - BlockchainID: ids.GenerateTestID(), + NetworkID: ctx.NetworkID, + BlockchainID: ctx.ChainID, Outs: []*avax.TransferableOutput{}, Ins: []*avax.TransferableInput{}, }, @@ -107,7 +110,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { name: "fail syntactic verification", backendF: func(*gomock.Controller) *Backend { return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -128,7 +131,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { name: "not bootstrapped", backendF: func(*gomock.Controller) *Backend { return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -152,7 +155,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ CortinaTime: activeForkTime, DurangoTime: mockable.MaxTime, @@ -179,7 +182,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -208,7 +211,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -237,7 +240,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -267,7 +270,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -300,7 +303,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -333,7 +336,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -368,7 +371,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -397,7 +400,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { bootstrapped := &utils.Atomic[bool]{} bootstrapped.Set(true) return &Backend{ - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Config: &config.Config{ DurangoTime: activeForkTime, // activate latest fork }, @@ -447,7 +450,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { AddSubnetValidatorFee: 1, DurangoTime: activeForkTime, // activate latest fork, }, - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Bootstrapped: bootstrapped, } }, @@ -494,7 +497,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { DurangoTime: mockable.MaxTime, AddSubnetValidatorFee: 1, }, - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Bootstrapped: bootstrapped, } }, @@ -545,7 +548,7 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) { AddSubnetValidatorFee: 1, DurangoTime: activeForkTime, // activate latest fork, }, - Ctx: snow.DefaultContextTest(), + Ctx: ctx, Bootstrapped: bootstrapped, } }, diff --git a/vms/platformvm/utxo/handler_test.go b/vms/platformvm/utxo/handler_test.go index f74286987d32..4f1e2e00e8d7 100644 --- a/vms/platformvm/utxo/handler_test.go +++ b/vms/platformvm/utxo/handler_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -39,8 +39,10 @@ func TestVerifySpendUTXOs(t *testing.T) { require.NoError(t, fx.InitializeVM(&secp256k1fx.TestVM{})) require.NoError(t, fx.Bootstrapped()) + ctx := snowtest.Context(t, snowtest.PChainID) + h := &handler{ - ctx: snow.DefaultContextTest(), + ctx: ctx, clk: &mockable.Clock{}, fx: fx, } diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 3632cbefc10f..746d9e105968 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1284,8 +1284,7 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { m := atomic.NewMemory(atomicDB) ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) - consensusCtx := snowtest.ConsensusContext() - consensusCtx.Context = ctx + consensusCtx := snowtest.ConsensusContext(ctx) ctx.Lock.Lock() msgChan := make(chan common.Message, 1) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 9934e8f13811..476b12e32bc3 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -20,6 +20,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/timer/mockable" @@ -1084,7 +1085,7 @@ func initTestRemoteProposerVM( }, nil } - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) ctx.NodeID = ids.NodeIDFromCert(pTestCert) ctx.ValidatorState = valState diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 0a4ba6d3bfe1..2e80c5973e86 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/proposervm/summary" statelessblock "github.com/ava-labs/avalanchego/vms/proposervm/block" @@ -81,7 +82,7 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { }, ) - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) ctx.NodeID = ids.NodeIDFromCert(pTestCert) require.NoError(vm.Initialize( diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index d8b6ea195001..cebc07b3ef43 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/snow/snowtest" ) func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *testing.T) { @@ -62,7 +63,7 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test require.NoError(proVM.Shutdown(context.Background())) }() - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) initialState := []byte("genesis state") err := proVM.Initialize( diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 97216d9c0905..8308141b6622 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -26,6 +26,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils" @@ -182,8 +183,7 @@ func initTestProposerVM( }, nil } - ctx := snow.DefaultContextTest() - ctx.ChainID = ids.ID{1} + ctx := snowtest.Context(t, ids.ID{1}) ctx.NodeID = ids.NodeIDFromCert(pTestCert) ctx.ValidatorState = valState @@ -978,7 +978,7 @@ func TestExpiredBuildBlock(t *testing.T) { }, nil } - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) ctx.NodeID = ids.NodeIDFromCert(pTestCert) ctx.ValidatorState = valState @@ -1273,7 +1273,7 @@ func TestInnerVMRollback(t *testing.T) { } } - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) ctx.NodeID = ids.NodeIDFromCert(pTestCert) ctx.ValidatorState = valState @@ -1942,7 +1942,7 @@ func TestRejectedHeightNotIndexed(t *testing.T) { }, nil } - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) ctx.NodeID = ids.NodeIDFromCert(pTestCert) ctx.ValidatorState = valState @@ -2152,7 +2152,7 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { }, nil } - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) ctx.NodeID = ids.NodeIDFromCert(pTestCert) ctx.ValidatorState = valState @@ -2303,7 +2303,7 @@ func TestVMInnerBlkCache(t *testing.T) { innerVM.EXPECT().GetBlock(gomock.Any(), innerBlkID).Return(innerBlk, nil) } - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) ctx.NodeID = ids.NodeIDFromCert(pTestCert) require.NoError(vm.Initialize( @@ -2544,7 +2544,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { innerVM.EXPECT().GetBlock(gomock.Any(), innerBlkID).Return(innerBlk, nil) } - snowCtx := snow.DefaultContextTest() + snowCtx := snowtest.Context(t, snowtest.CChainID) snowCtx.NodeID = ids.NodeIDFromCert(pTestCert) require.NoError(vm.Initialize( @@ -2703,7 +2703,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { }, } - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) ctx.NodeID = ids.NodeIDFromCert(pTestCert) ctx.ValidatorState = &validators.TestState{ T: t, diff --git a/vms/rpcchainvm/batched_vm_test.go b/vms/rpcchainvm/batched_vm_test.go index 817037dc6e3e..c00ca4e6fc60 100644 --- a/vms/rpcchainvm/batched_vm_test.go +++ b/vms/rpcchainvm/batched_vm_test.go @@ -14,11 +14,11 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/chain" ) @@ -86,7 +86,7 @@ func TestBatchedParseBlockCaching(t *testing.T) { vm, stopper := buildClientHelper(require, testKey) defer stopper.Stop(context.Background()) - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) require.NoError(vm.Initialize(context.Background(), ctx, memdb.New(), nil, nil, nil, nil, nil, nil)) diff --git a/vms/rpcchainvm/state_syncable_vm_test.go b/vms/rpcchainvm/state_syncable_vm_test.go index 241062616c9b..640255e80ee4 100644 --- a/vms/rpcchainvm/state_syncable_vm_test.go +++ b/vms/rpcchainvm/state_syncable_vm_test.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/rpcchainvm/grpcutils" "github.com/ava-labs/avalanchego/vms/rpcchainvm/runtime" @@ -470,7 +471,7 @@ func TestLastAcceptedBlockPostStateSummaryAccept(t *testing.T) { defer stopper.Stop(context.Background()) // Step 1: initialize VM and check initial LastAcceptedBlock - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) require.NoError(vm.Initialize(context.Background(), ctx, prefixdb.New([]byte{}, memdb.New()), nil, nil, nil, nil, nil, nil)) diff --git a/vms/rpcchainvm/with_context_vm_test.go b/vms/rpcchainvm/with_context_vm_test.go index 65d1e4396964..192a7658e451 100644 --- a/vms/rpcchainvm/with_context_vm_test.go +++ b/vms/rpcchainvm/with_context_vm_test.go @@ -14,10 +14,10 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" + "github.com/ava-labs/avalanchego/snow/snowtest" ) var ( @@ -98,7 +98,7 @@ func TestContextVMSummary(t *testing.T) { vm, stopper := buildClientHelper(require, testKey) defer stopper.Stop(context.Background()) - ctx := snow.DefaultContextTest() + ctx := snowtest.Context(t, snowtest.CChainID) require.NoError(vm.Initialize(context.Background(), ctx, memdb.New(), nil, nil, nil, nil, nil, nil)) From 653c2f1c12e1a7cda66000777d64a447a1e607db Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 23 Dec 2023 17:07:47 -0500 Subject: [PATCH 202/267] Unexport fields from gossip.BloomFilter (#2547) --- go.mod | 2 +- go.sum | 4 ++-- network/p2p/gossip/bloom.go | 34 +++++++++++++++++++------------ network/p2p/gossip/bloom_test.go | 15 ++++++++++++-- network/p2p/gossip/handler.go | 6 +++--- network/p2p/gossip/test_gossip.go | 3 +-- vms/avm/network/gossip.go | 3 +-- 7 files changed, 42 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 4f5855df0c4a..c1b6367a5223 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 + github.com/ava-labs/coreth v0.12.10-rc.2 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 35f8b1814109..d83821fc4ceb 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9 h1:DiJBkm2IJ/My4u5DP4gq2wIbdflFRuZJbDm8DbgNDdg= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231222191417-2e3f762373e9/go.mod h1:Xftjgk8T46k5/pWSQWcmdPanNl68kTcufd9S4kB58bM= +github.com/ava-labs/coreth v0.12.10-rc.2 h1:+2YK7PzStcLCHtsBb1VQjw6DyMl1sMZatReZAyIy7w8= +github.com/ava-labs/coreth v0.12.10-rc.2/go.mod h1:RIbv14KMyWSj4hB1danS+vEPCUsgArZUEo99SaP5nW8= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/network/p2p/gossip/bloom.go b/network/p2p/gossip/bloom.go index c113396bf0b3..bb588b23bb4f 100644 --- a/network/p2p/gossip/bloom.go +++ b/network/p2p/gossip/bloom.go @@ -32,35 +32,43 @@ func NewBloomFilter( salt, err := randomSalt() return &BloomFilter{ - Bloom: bloom, - Salt: salt, + bloom: bloom, + salt: salt, }, err } type BloomFilter struct { - Bloom *bloomfilter.Filter - // Salt is provided to eventually unblock collisions in Bloom. It's possible + bloom *bloomfilter.Filter + // salt is provided to eventually unblock collisions in Bloom. It's possible // that conflicting Gossipable items collide in the bloom filter, so a salt // is generated to eventually resolve collisions. - Salt ids.ID + salt ids.ID } func (b *BloomFilter) Add(gossipable Gossipable) { h := gossipable.GossipID() salted := &hasher{ hash: h[:], - salt: b.Salt, + salt: b.salt, } - b.Bloom.Add(salted) + b.bloom.Add(salted) } func (b *BloomFilter) Has(gossipable Gossipable) bool { h := gossipable.GossipID() salted := &hasher{ hash: h[:], - salt: b.Salt, + salt: b.salt, } - return b.Bloom.Contains(salted) + return b.bloom.Contains(salted) +} + +func (b *BloomFilter) Marshal() ([]byte, []byte, error) { + bloomBytes, err := b.bloom.MarshalBinary() + // salt must be copied here to ensure the bytes aren't overwritten if salt + // is later modified. + salt := b.salt + return bloomBytes, salt[:], err } // ResetBloomFilterIfNeeded resets a bloom filter if it breaches a target false @@ -69,11 +77,11 @@ func ResetBloomFilterIfNeeded( bloomFilter *BloomFilter, falsePositiveProbability float64, ) (bool, error) { - if bloomFilter.Bloom.FalsePosititveProbability() < falsePositiveProbability { + if bloomFilter.bloom.FalsePosititveProbability() < falsePositiveProbability { return false, nil } - newBloom, err := bloomfilter.New(bloomFilter.Bloom.M(), bloomFilter.Bloom.K()) + newBloom, err := bloomfilter.New(bloomFilter.bloom.M(), bloomFilter.bloom.K()) if err != nil { return false, err } @@ -82,8 +90,8 @@ func ResetBloomFilterIfNeeded( return false, err } - bloomFilter.Bloom = newBloom - bloomFilter.Salt = salt + bloomFilter.bloom = newBloom + bloomFilter.salt = salt return true, nil } diff --git a/network/p2p/gossip/bloom_test.go b/network/p2p/gossip/bloom_test.go index 860d2d5e936e..1a05a7eb9bd5 100644 --- a/network/p2p/gossip/bloom_test.go +++ b/network/p2p/gossip/bloom_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/require" + "golang.org/x/exp/slices" + "github.com/ava-labs/avalanchego/ids" ) @@ -49,16 +51,25 @@ func TestBloomFilterRefresh(t *testing.T) { b, err := bloomfilter.New(10, 1) require.NoError(err) bloom := BloomFilter{ - Bloom: b, + bloom: b, } for _, item := range tt.add { + bloomBytes, saltBytes, err := bloom.Marshal() + require.NoError(err) + + initialBloomBytes := slices.Clone(bloomBytes) + initialSaltBytes := slices.Clone(saltBytes) + _, err = ResetBloomFilterIfNeeded(&bloom, tt.falsePositiveProbability) require.NoError(err) bloom.Add(item) + + require.Equal(initialBloomBytes, bloomBytes) + require.Equal(initialSaltBytes, saltBytes) } - require.Equal(uint64(len(tt.expected)), bloom.Bloom.N()) + require.Equal(uint64(len(tt.expected)), bloom.bloom.N()) for _, expected := range tt.expected { require.True(bloom.Has(expected)) diff --git a/network/p2p/gossip/handler.go b/network/p2p/gossip/handler.go index de74d78169cf..0cea0c98ab71 100644 --- a/network/p2p/gossip/handler.go +++ b/network/p2p/gossip/handler.go @@ -71,10 +71,10 @@ func (h Handler[T]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, req } filter := &BloomFilter{ - Bloom: &bloomfilter.Filter{}, - Salt: salt, + bloom: &bloomfilter.Filter{}, + salt: salt, } - if err := filter.Bloom.UnmarshalBinary(request.Filter); err != nil { + if err := filter.bloom.UnmarshalBinary(request.Filter); err != nil { return nil, err } diff --git a/network/p2p/gossip/test_gossip.go b/network/p2p/gossip/test_gossip.go index 83021730d444..4603333ba28f 100644 --- a/network/p2p/gossip/test_gossip.go +++ b/network/p2p/gossip/test_gossip.go @@ -65,6 +65,5 @@ func (t *testSet) Iterate(f func(gossipable *testTx) bool) { } func (t *testSet) GetFilter() ([]byte, []byte, error) { - bloom, err := t.bloom.Bloom.MarshalBinary() - return bloom, t.bloom.Salt[:], err + return t.bloom.Marshal() } diff --git a/vms/avm/network/gossip.go b/vms/avm/network/gossip.go index e4e145d830eb..ad5d1589d25d 100644 --- a/vms/avm/network/gossip.go +++ b/vms/avm/network/gossip.go @@ -152,6 +152,5 @@ func (g *gossipMempool) GetFilter() (bloom []byte, salt []byte, err error) { g.lock.RLock() defer g.lock.RUnlock() - bloomBytes, err := g.bloom.Bloom.MarshalBinary() - return bloomBytes, g.bloom.Salt[:], err + return g.bloom.Marshal() } From 9fb61abc54c034708c22a6d685c9c185d5e7830f Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Sat, 23 Dec 2023 17:20:42 -0500 Subject: [PATCH 203/267] P-Chain SDK Gossip (#2487) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Signed-off-by: Stephen Buttolph Co-authored-by: Stephen Buttolph Co-authored-by: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> --- vms/platformvm/block/builder/builder_test.go | 20 +- vms/platformvm/block/builder/helpers_test.go | 14 +- vms/platformvm/config/execution_config.go | 21 +- .../config/execution_config_test.go | 74 +++++++ vms/platformvm/network/config.go | 66 +++++++ vms/platformvm/network/gossip.go | 138 +++++++++++++ vms/platformvm/network/gossip_test.go | 147 ++++++++++++++ vms/platformvm/network/network.go | 184 +++++++++++++----- vms/platformvm/network/network_test.go | 105 +++++++--- vms/platformvm/service_test.go | 8 - vms/platformvm/txs/tx.go | 7 + vms/platformvm/vm.go | 26 ++- 12 files changed, 706 insertions(+), 104 deletions(-) create mode 100644 vms/platformvm/network/config.go create mode 100644 vms/platformvm/network/gossip.go create mode 100644 vms/platformvm/network/gossip_test.go diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index 0aae84a294cf..bba4acbd8832 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -471,7 +471,7 @@ func TestBuildBlockInvalidStakingDurations(t *testing.T) { require.ErrorIs(tx2DropReason, txexecutor.ErrStakeTooLong) } -func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { +func TestPreviouslyDroppedTxsCannotBeReAddedToMempool(t *testing.T) { require := require.New(t) env := newEnvironment(t) @@ -497,24 +497,24 @@ func TestPreviouslyDroppedTxsCanBeReAddedToMempool(t *testing.T) { // Transaction should not be marked as dropped before being added to the // mempool - reason := env.mempool.GetDropReason(txID) - require.NoError(reason) + require.NoError(env.mempool.GetDropReason(txID)) // Mark the transaction as dropped errTestingDropped := errors.New("testing dropped") env.mempool.MarkDropped(txID, errTestingDropped) - reason = env.mempool.GetDropReason(txID) - require.ErrorIs(reason, errTestingDropped) + err = env.mempool.GetDropReason(txID) + require.ErrorIs(err, errTestingDropped) // Issue the transaction env.ctx.Lock.Unlock() - require.NoError(env.network.IssueTx(context.Background(), tx)) + err = env.network.IssueTx(context.Background(), tx) + require.ErrorIs(err, errTestingDropped) _, ok := env.mempool.Get(txID) - require.True(ok) + require.False(ok) - // When issued again, the mempool should not be marked as dropped - reason = env.mempool.GetDropReason(txID) - require.NoError(reason) + // When issued again, the mempool should still be marked as dropped + err = env.mempool.GetDropReason(txID) + require.ErrorIs(err, errTestingDropped) } func TestNoErrorOnUnexpectedSetPreferenceDuringBootstrapping(t *testing.T) { diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index bd0f58bd449d..6c0c5d6fe16d 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -4,6 +4,7 @@ package builder import ( + "context" "testing" "time" @@ -166,6 +167,9 @@ func newEnvironment(t *testing.T) *environment { registerer := prometheus.NewRegistry() res.sender = &common.SenderTest{T: t} + res.sender.SendAppGossipF = func(context.Context, []byte) error { + return nil + } metrics, err := metrics.New("", registerer) require.NoError(err) @@ -182,13 +186,19 @@ func newEnvironment(t *testing.T) *environment { ) txVerifier := network.NewLockedTxVerifier(&res.ctx.Lock, res.blkManager) - res.network = network.New( - logging.NoLog{}, + res.network, err = network.New( + res.backend.Ctx.Log, + res.backend.Ctx.NodeID, + res.backend.Ctx.SubnetID, + res.backend.Ctx.ValidatorState, txVerifier, res.mempool, res.backend.Config.PartialSyncPrimaryNetwork, res.sender, + registerer, + network.DefaultConfig, ) + require.NoError(err) res.Builder = New( res.mempool, diff --git a/vms/platformvm/config/execution_config.go b/vms/platformvm/config/execution_config.go index bfdb191f1281..964e72f51a57 100644 --- a/vms/platformvm/config/execution_config.go +++ b/vms/platformvm/config/execution_config.go @@ -7,9 +7,11 @@ import ( "encoding/json" "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/platformvm/network" ) var DefaultExecutionConfig = ExecutionConfig{ + Network: network.DefaultConfig, BlockCacheSize: 64 * units.MiB, TxCacheSize: 128 * units.MiB, TransformedSubnetTxCacheSize: 4 * units.MiB, @@ -23,15 +25,16 @@ var DefaultExecutionConfig = ExecutionConfig{ // ExecutionConfig provides execution parameters of PlatformVM type ExecutionConfig struct { - BlockCacheSize int `json:"block-cache-size"` - TxCacheSize int `json:"tx-cache-size"` - TransformedSubnetTxCacheSize int `json:"transformed-subnet-tx-cache-size"` - RewardUTXOsCacheSize int `json:"reward-utxos-cache-size"` - ChainCacheSize int `json:"chain-cache-size"` - ChainDBCacheSize int `json:"chain-db-cache-size"` - BlockIDCacheSize int `json:"block-id-cache-size"` - FxOwnerCacheSize int `json:"fx-owner-cache-size"` - ChecksumsEnabled bool `json:"checksums-enabled"` + Network network.Config `json:"network"` + BlockCacheSize int `json:"block-cache-size"` + TxCacheSize int `json:"tx-cache-size"` + TransformedSubnetTxCacheSize int `json:"transformed-subnet-tx-cache-size"` + RewardUTXOsCacheSize int `json:"reward-utxos-cache-size"` + ChainCacheSize int `json:"chain-cache-size"` + ChainDBCacheSize int `json:"chain-db-cache-size"` + BlockIDCacheSize int `json:"block-id-cache-size"` + FxOwnerCacheSize int `json:"fx-owner-cache-size"` + ChecksumsEnabled bool `json:"checksums-enabled"` } // GetExecutionConfig returns an ExecutionConfig diff --git a/vms/platformvm/config/execution_config_test.go b/vms/platformvm/config/execution_config_test.go index 0adbd862bd2d..6ba78df133ed 100644 --- a/vms/platformvm/config/execution_config_test.go +++ b/vms/platformvm/config/execution_config_test.go @@ -7,6 +7,8 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/vms/platformvm/network" ) func TestExecutionConfigUnmarshal(t *testing.T) { @@ -39,6 +41,66 @@ func TestExecutionConfigUnmarshal(t *testing.T) { t.Run("all values extracted from json", func(t *testing.T) { require := require.New(t) b := []byte(`{ + "network": { + "max-validator-set-staleness": 1, + "target-gossip-size": 2, + "pull-gossip-poll-size": 3, + "pull-gossip-frequency": 4, + "pull-gossip-throttling-period": 5, + "pull-gossip-throttling-limit": 6, + "expected-bloom-filter-elements":7, + "expected-bloom-filter-false-positive-probability": 8, + "max-bloom-filter-false-positive-probability": 9, + "legacy-push-gossip-cache-size": 10 + }, + "block-cache-size": 1, + "tx-cache-size": 2, + "transformed-subnet-tx-cache-size": 3, + "reward-utxos-cache-size": 5, + "chain-cache-size": 6, + "chain-db-cache-size": 7, + "block-id-cache-size": 8, + "fx-owner-cache-size": 9, + "checksums-enabled": true + }`) + ec, err := GetExecutionConfig(b) + require.NoError(err) + expected := &ExecutionConfig{ + Network: network.Config{ + MaxValidatorSetStaleness: 1, + TargetGossipSize: 2, + PullGossipPollSize: 3, + PullGossipFrequency: 4, + PullGossipThrottlingPeriod: 5, + PullGossipThrottlingLimit: 6, + ExpectedBloomFilterElements: 7, + ExpectedBloomFilterFalsePositiveProbability: 8, + MaxBloomFilterFalsePositiveProbability: 9, + LegacyPushGossipCacheSize: 10, + }, + BlockCacheSize: 1, + TxCacheSize: 2, + TransformedSubnetTxCacheSize: 3, + RewardUTXOsCacheSize: 5, + ChainCacheSize: 6, + ChainDBCacheSize: 7, + BlockIDCacheSize: 8, + FxOwnerCacheSize: 9, + ChecksumsEnabled: true, + } + require.Equal(expected, ec) + }) + + t.Run("default values applied correctly", func(t *testing.T) { + require := require.New(t) + b := []byte(`{ + "network": { + "max-validator-set-staleness": 1, + "target-gossip-size": 2, + "pull-gossip-poll-size": 3, + "pull-gossip-frequency": 4, + "pull-gossip-throttling-period": 5 + }, "block-cache-size": 1, "tx-cache-size": 2, "transformed-subnet-tx-cache-size": 3, @@ -52,6 +114,18 @@ func TestExecutionConfigUnmarshal(t *testing.T) { ec, err := GetExecutionConfig(b) require.NoError(err) expected := &ExecutionConfig{ + Network: network.Config{ + MaxValidatorSetStaleness: 1, + TargetGossipSize: 2, + PullGossipPollSize: 3, + PullGossipFrequency: 4, + PullGossipThrottlingPeriod: 5, + PullGossipThrottlingLimit: DefaultExecutionConfig.Network.PullGossipThrottlingLimit, + ExpectedBloomFilterElements: DefaultExecutionConfig.Network.ExpectedBloomFilterElements, + ExpectedBloomFilterFalsePositiveProbability: DefaultExecutionConfig.Network.ExpectedBloomFilterFalsePositiveProbability, + MaxBloomFilterFalsePositiveProbability: DefaultExecutionConfig.Network.MaxBloomFilterFalsePositiveProbability, + LegacyPushGossipCacheSize: DefaultExecutionConfig.Network.LegacyPushGossipCacheSize, + }, BlockCacheSize: 1, TxCacheSize: 2, TransformedSubnetTxCacheSize: 3, diff --git a/vms/platformvm/network/config.go b/vms/platformvm/network/config.go new file mode 100644 index 000000000000..2ff7828df2e4 --- /dev/null +++ b/vms/platformvm/network/config.go @@ -0,0 +1,66 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "time" + + "github.com/ava-labs/avalanchego/utils/units" +) + +var DefaultConfig = Config{ + MaxValidatorSetStaleness: time.Minute, + TargetGossipSize: 20 * units.KiB, + PullGossipPollSize: 1, + PullGossipFrequency: 1500 * time.Millisecond, + PullGossipThrottlingPeriod: 10 * time.Second, + PullGossipThrottlingLimit: 2, + ExpectedBloomFilterElements: 8 * 1024, + ExpectedBloomFilterFalsePositiveProbability: .01, + MaxBloomFilterFalsePositiveProbability: .05, + LegacyPushGossipCacheSize: 512, +} + +type Config struct { + // MaxValidatorSetStaleness limits how old of a validator set the network + // will use for peer sampling and rate limiting. + MaxValidatorSetStaleness time.Duration `json:"max-validator-set-staleness"` + // TargetGossipSize is the number of bytes that will be attempted to be + // sent when pushing transactions and when responded to transaction pull + // requests. + TargetGossipSize int `json:"target-gossip-size"` + // PullGossipPollSize is the number of validators to sample when performing + // a round of pull gossip. + PullGossipPollSize int `json:"pull-gossip-poll-size"` + // PullGossipFrequency is how frequently rounds of pull gossip are + // performed. + PullGossipFrequency time.Duration `json:"pull-gossip-frequency"` + // PullGossipThrottlingPeriod is how large of a window the throttler should + // use. + PullGossipThrottlingPeriod time.Duration `json:"pull-gossip-throttling-period"` + // PullGossipThrottlingLimit is the number of pull querys that are allowed + // by a validator in every throttling window. + PullGossipThrottlingLimit int `json:"pull-gossip-throttling-limit"` + // ExpectedBloomFilterElements is the number of elements to expect when + // creating a new bloom filter. The larger this number is, the larger the + // bloom filter will be. + ExpectedBloomFilterElements uint64 `json:"expected-bloom-filter-elements"` + // ExpectedBloomFilterFalsePositiveProbability is the expected probability + // of a false positive after having inserted ExpectedBloomFilterElements + // into a bloom filter. The smaller this number is, the larger the bloom + // filter will be. + ExpectedBloomFilterFalsePositiveProbability float64 `json:"expected-bloom-filter-false-positive-probability"` + // MaxBloomFilterFalsePositiveProbability is used to determine when the + // bloom filter should be refreshed. Once the expected probability of a + // false positive exceeds this value, the bloom filter will be regenerated. + // The smaller this number is, the more frequently that the bloom filter + // will be regenerated. + MaxBloomFilterFalsePositiveProbability float64 `json:"max-bloom-filter-false-positive-probability"` + // LegacyPushGossipCacheSize tracks the most recently received transactions + // and ensures to only gossip them once. + // + // Deprecated: The legacy push gossip mechanism is deprecated in favor of + // the p2p SDK's push gossip mechanism. + LegacyPushGossipCacheSize int `json:"legacy-push-gossip-cache-size"` +} diff --git a/vms/platformvm/network/gossip.go b/vms/platformvm/network/gossip.go new file mode 100644 index 000000000000..5c12ee7a83bc --- /dev/null +++ b/vms/platformvm/network/gossip.go @@ -0,0 +1,138 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/network/p2p" + "github.com/ava-labs/avalanchego/network/p2p/gossip" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" +) + +var ( + _ p2p.Handler = (*txGossipHandler)(nil) + _ gossip.Marshaller[*txs.Tx] = (*txMarshaller)(nil) + _ gossip.Gossipable = (*txs.Tx)(nil) +) + +// txGossipHandler is the handler called when serving gossip messages +type txGossipHandler struct { + p2p.NoOpHandler + appGossipHandler p2p.Handler + appRequestHandler p2p.Handler +} + +func (t txGossipHandler) AppGossip( + ctx context.Context, + nodeID ids.NodeID, + gossipBytes []byte, +) { + t.appGossipHandler.AppGossip(ctx, nodeID, gossipBytes) +} + +func (t txGossipHandler) AppRequest( + ctx context.Context, + nodeID ids.NodeID, + deadline time.Time, + requestBytes []byte, +) ([]byte, error) { + return t.appRequestHandler.AppRequest(ctx, nodeID, deadline, requestBytes) +} + +type txMarshaller struct{} + +func (txMarshaller) MarshalGossip(tx *txs.Tx) ([]byte, error) { + return tx.Bytes(), nil +} + +func (txMarshaller) UnmarshalGossip(bytes []byte) (*txs.Tx, error) { + return txs.Parse(txs.Codec, bytes) +} + +func newGossipMempool( + mempool mempool.Mempool, + log logging.Logger, + txVerifier TxVerifier, + maxExpectedElements uint64, + falsePositiveProbability float64, + maxFalsePositiveProbability float64, +) (*gossipMempool, error) { + bloom, err := gossip.NewBloomFilter(maxExpectedElements, falsePositiveProbability) + return &gossipMempool{ + Mempool: mempool, + log: log, + txVerifier: txVerifier, + bloom: bloom, + maxFalsePositiveProbability: maxFalsePositiveProbability, + }, err +} + +type gossipMempool struct { + mempool.Mempool + log logging.Logger + txVerifier TxVerifier + maxFalsePositiveProbability float64 + + lock sync.RWMutex + bloom *gossip.BloomFilter +} + +func (g *gossipMempool) Add(tx *txs.Tx) error { + txID := tx.ID() + if _, ok := g.Mempool.Get(txID); ok { + return fmt.Errorf("tx %s dropped: %w", txID, mempool.ErrDuplicateTx) + } + + if reason := g.Mempool.GetDropReason(txID); reason != nil { + // If the tx is being dropped - just ignore it + // + // TODO: Should we allow re-verification of the transaction even if it + // failed previously? + return reason + } + + if err := g.txVerifier.VerifyTx(tx); err != nil { + g.Mempool.MarkDropped(txID, err) + return err + } + + if err := g.Mempool.Add(tx); err != nil { + g.Mempool.MarkDropped(txID, err) + return err + } + + g.lock.Lock() + defer g.lock.Unlock() + + g.bloom.Add(tx) + reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, g.maxFalsePositiveProbability) + if err != nil { + return err + } + + if reset { + g.log.Debug("resetting bloom filter") + g.Mempool.Iterate(func(tx *txs.Tx) bool { + g.bloom.Add(tx) + return true + }) + } + + g.Mempool.RequestBuildBlock(false) + return nil +} + +func (g *gossipMempool) GetFilter() (bloom []byte, salt []byte, err error) { + g.lock.RLock() + defer g.lock.RUnlock() + + return g.bloom.Marshal() +} diff --git a/vms/platformvm/network/gossip_test.go b/vms/platformvm/network/gossip_test.go new file mode 100644 index 000000000000..9c3fff9b5ff9 --- /dev/null +++ b/vms/platformvm/network/gossip_test.go @@ -0,0 +1,147 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/require" + + "go.uber.org/mock/gomock" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" +) + +var errFoo = errors.New("foo") + +// Add should error if verification errors +func TestGossipMempoolAddVerificationError(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + txID := ids.GenerateTestID() + tx := &txs.Tx{ + TxID: txID, + } + + mempool := mempool.NewMockMempool(ctrl) + txVerifier := testTxVerifier{err: errFoo} + + mempool.EXPECT().Get(txID).Return(nil, false) + mempool.EXPECT().GetDropReason(txID).Return(nil) + mempool.EXPECT().MarkDropped(txID, errFoo) + + gossipMempool, err := newGossipMempool( + mempool, + logging.NoLog{}, + txVerifier, + testConfig.ExpectedBloomFilterElements, + testConfig.ExpectedBloomFilterFalsePositiveProbability, + testConfig.MaxBloomFilterFalsePositiveProbability, + ) + require.NoError(err) + + err = gossipMempool.Add(tx) + require.ErrorIs(err, errFoo) + require.False(gossipMempool.bloom.Has(tx)) +} + +// Add should error if adding to the mempool errors +func TestGossipMempoolAddError(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + txID := ids.GenerateTestID() + tx := &txs.Tx{ + TxID: txID, + } + + txVerifier := testTxVerifier{} + mempool := mempool.NewMockMempool(ctrl) + + mempool.EXPECT().Get(txID).Return(nil, false) + mempool.EXPECT().GetDropReason(txID).Return(nil) + mempool.EXPECT().Add(tx).Return(errFoo) + mempool.EXPECT().MarkDropped(txID, errFoo).AnyTimes() + + gossipMempool, err := newGossipMempool( + mempool, + logging.NoLog{}, + txVerifier, + testConfig.ExpectedBloomFilterElements, + testConfig.ExpectedBloomFilterFalsePositiveProbability, + testConfig.MaxBloomFilterFalsePositiveProbability, + ) + require.NoError(err) + + err = gossipMempool.Add(tx) + require.ErrorIs(err, errFoo) + require.False(gossipMempool.bloom.Has(tx)) +} + +// Adding a duplicate to the mempool should return an error +func TestMempoolDuplicate(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + testMempool := mempool.NewMockMempool(ctrl) + txVerifier := testTxVerifier{} + + txID := ids.GenerateTestID() + tx := &txs.Tx{ + TxID: txID, + } + + testMempool.EXPECT().Get(txID).Return(tx, true) + + gossipMempool, err := newGossipMempool( + testMempool, + logging.NoLog{}, + txVerifier, + testConfig.ExpectedBloomFilterElements, + testConfig.ExpectedBloomFilterFalsePositiveProbability, + testConfig.MaxBloomFilterFalsePositiveProbability, + ) + require.NoError(err) + + err = gossipMempool.Add(tx) + require.ErrorIs(err, mempool.ErrDuplicateTx) + require.False(gossipMempool.bloom.Has(tx)) +} + +// Adding a tx to the mempool should add it to the bloom filter +func TestGossipAddBloomFilter(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + txID := ids.GenerateTestID() + tx := &txs.Tx{ + TxID: txID, + } + + txVerifier := testTxVerifier{} + mempool := mempool.NewMockMempool(ctrl) + + mempool.EXPECT().Get(txID).Return(nil, false) + mempool.EXPECT().GetDropReason(txID).Return(nil) + mempool.EXPECT().Add(tx).Return(nil) + mempool.EXPECT().RequestBuildBlock(false) + + gossipMempool, err := newGossipMempool( + mempool, + logging.NoLog{}, + txVerifier, + testConfig.ExpectedBloomFilterElements, + testConfig.ExpectedBloomFilterFalsePositiveProbability, + testConfig.MaxBloomFilterFalsePositiveProbability, + ) + require.NoError(err) + + require.NoError(gossipMempool.Add(tx)) + require.True(gossipMempool.bloom.Has(tx)) +} diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index e3003768d13f..58fb0ec156eb 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -6,42 +6,49 @@ package network import ( "context" "sync" + "time" + + "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" "github.com/ava-labs/avalanchego/cache" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/network/p2p" + "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/message" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) -// We allow [recentCacheSize] to be fairly large because we only store hashes -// in the cache, not entire transactions. -const recentCacheSize = 512 - -var _ Network = (*network)(nil) +const txGossipHandlerID = 0 type Network interface { common.AppHandler + // Gossip starts gossiping transactions and blocks until it completes. + Gossip(ctx context.Context) // IssueTx verifies the transaction at the currently preferred state, adds // it to the mempool, and gossips it to the network. IssueTx(context.Context, *txs.Tx) error } type network struct { - // We embed a noop handler for all unhandled messages - common.AppHandler + *p2p.Network log logging.Logger txVerifier TxVerifier - mempool mempool.Mempool + mempool *gossipMempool partialSyncPrimaryNetwork bool appSender common.AppSender + txPushGossiper gossip.Accumulator[*txs.Tx] + txPullGossiper gossip.Gossiper + txGossipFrequency time.Duration + // gossip related attributes recentTxsLock sync.Mutex recentTxs *cache.LRU[ids.ID, struct{}] @@ -49,21 +56,129 @@ type network struct { func New( log logging.Logger, + nodeID ids.NodeID, + subnetID ids.ID, + vdrs validators.State, txVerifier TxVerifier, mempool mempool.Mempool, partialSyncPrimaryNetwork bool, appSender common.AppSender, -) Network { - return &network{ - AppHandler: common.NewNoOpAppHandler(log), + registerer prometheus.Registerer, + config Config, +) (Network, error) { + p2pNetwork, err := p2p.NewNetwork(log, appSender, registerer, "p2p") + if err != nil { + return nil, err + } + + marshaller := txMarshaller{} + validators := p2p.NewValidators( + p2pNetwork.Peers, + log, + subnetID, + vdrs, + config.MaxValidatorSetStaleness, + ) + txGossipClient := p2pNetwork.NewClient( + txGossipHandlerID, + p2p.WithValidatorSampling(validators), + ) + txGossipMetrics, err := gossip.NewMetrics(registerer, "tx") + if err != nil { + return nil, err + } + + txPushGossiper := gossip.NewPushGossiper[*txs.Tx]( + marshaller, + txGossipClient, + txGossipMetrics, + config.TargetGossipSize, + ) + + gossipMempool, err := newGossipMempool( + mempool, + log, + txVerifier, + config.ExpectedBloomFilterElements, + config.ExpectedBloomFilterFalsePositiveProbability, + config.MaxBloomFilterFalsePositiveProbability, + ) + if err != nil { + return nil, err + } + + var txPullGossiper gossip.Gossiper + txPullGossiper = gossip.NewPullGossiper[*txs.Tx]( + log, + marshaller, + gossipMempool, + txGossipClient, + txGossipMetrics, + config.PullGossipPollSize, + ) + + // Gossip requests are only served if a node is a validator + txPullGossiper = gossip.ValidatorGossiper{ + Gossiper: txPullGossiper, + NodeID: nodeID, + Validators: validators, + } + + handler := gossip.NewHandler[*txs.Tx]( + log, + marshaller, + txPushGossiper, + gossipMempool, + txGossipMetrics, + config.TargetGossipSize, + ) + + validatorHandler := p2p.NewValidatorHandler( + p2p.NewThrottlerHandler( + handler, + p2p.NewSlidingWindowThrottler( + config.PullGossipThrottlingPeriod, + config.PullGossipThrottlingLimit, + ), + log, + ), + validators, + log, + ) + + // We allow pushing txs between all peers, but only serve gossip requests + // from validators + txGossipHandler := txGossipHandler{ + appGossipHandler: handler, + appRequestHandler: validatorHandler, + } + if err := p2pNetwork.AddHandler(txGossipHandlerID, txGossipHandler); err != nil { + return nil, err + } + + return &network{ + Network: p2pNetwork, log: log, txVerifier: txVerifier, - mempool: mempool, + mempool: gossipMempool, partialSyncPrimaryNetwork: partialSyncPrimaryNetwork, appSender: appSender, - recentTxs: &cache.LRU[ids.ID, struct{}]{Size: recentCacheSize}, + txPushGossiper: txPushGossiper, + txPullGossiper: txPullGossiper, + txGossipFrequency: config.PullGossipFrequency, + recentTxs: &cache.LRU[ids.ID, struct{}]{Size: config.LegacyPushGossipCacheSize}, + }, nil +} + +func (n *network) Gossip(ctx context.Context) { + // If the node is running partial sync, we should not perform any pull + // gossip. + if n.partialSyncPrimaryNetwork { + return } + + gossip.Every(ctx, n.log, n.txPullGossiper, n.txGossipFrequency) } func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []byte) error { @@ -81,10 +196,11 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b msgIntf, err := message.Parse(msgBytes) if err != nil { - n.log.Debug("dropping AppGossip message", + n.log.Debug("forwarding AppGossip to p2p network", zap.String("reason", "failed to parse message"), ) - return nil + + return n.Network.AppGossip(ctx, nodeID, msgBytes) } msg, ok := msgIntf.(*message.Tx) @@ -106,12 +222,11 @@ func (n *network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b } txID := tx.ID() - if reason := n.mempool.GetDropReason(txID); reason != nil { - // If the tx is being dropped - just ignore it - return nil - } if err := n.issueTx(tx); err == nil { - n.gossipTx(ctx, txID, msgBytes) + n.legacyGossipTx(ctx, txID, msgBytes) + + n.txPushGossiper.Add(tx) + return n.txPushGossiper.Gossip(ctx) } return nil } @@ -131,29 +246,13 @@ func (n *network) IssueTx(ctx context.Context, tx *txs.Tx) error { } txID := tx.ID() - n.gossipTx(ctx, txID, msgBytes) - return nil + n.legacyGossipTx(ctx, txID, msgBytes) + n.txPushGossiper.Add(tx) + return n.txPushGossiper.Gossip(ctx) } // returns nil if the tx is in the mempool func (n *network) issueTx(tx *txs.Tx) error { - txID := tx.ID() - if _, ok := n.mempool.Get(txID); ok { - // The tx is already in the mempool - return nil - } - - // Verify the tx at the currently preferred state - if err := n.txVerifier.VerifyTx(tx); err != nil { - n.log.Debug("tx failed verification", - zap.Stringer("txID", txID), - zap.Error(err), - ) - - n.mempool.MarkDropped(txID, err) - return err - } - // If we are partially syncing the Primary Network, we should not be // maintaining the transaction mempool locally. if n.partialSyncPrimaryNetwork { @@ -162,20 +261,17 @@ func (n *network) issueTx(tx *txs.Tx) error { if err := n.mempool.Add(tx); err != nil { n.log.Debug("tx failed to be added to the mempool", - zap.Stringer("txID", txID), + zap.Stringer("txID", tx.ID()), zap.Error(err), ) - n.mempool.MarkDropped(txID, err) return err } - n.mempool.RequestBuildBlock(false /*=emptyBlockPermitted*/) - return nil } -func (n *network) gossipTx(ctx context.Context, txID ids.ID, msgBytes []byte) { +func (n *network) legacyGossipTx(ctx context.Context, txID ids.ID, msgBytes []byte) { n.recentTxsLock.Lock() _, has := n.recentTxs.Get(txID) n.recentTxs.Put(txID, struct{}{}) diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go index f0b3cc0a87fc..32e224d971e1 100644 --- a/vms/platformvm/network/network_test.go +++ b/vms/platformvm/network/network_test.go @@ -7,6 +7,9 @@ import ( "context" "errors" "testing" + "time" + + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" @@ -14,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/message" @@ -22,10 +26,24 @@ import ( ) var ( - errTest = errors.New("test error") - _ TxVerifier = (*testTxVerifier)(nil) + errTest = errors.New("test error") + + testConfig = Config{ + MaxValidatorSetStaleness: time.Second, + TargetGossipSize: 1, + PullGossipPollSize: 1, + PullGossipFrequency: time.Second, + PullGossipThrottlingPeriod: time.Second, + PullGossipThrottlingLimit: 1, + ExpectedBloomFilterElements: 10, + ExpectedBloomFilterFalsePositiveProbability: .1, + MaxBloomFilterFalsePositiveProbability: .5, + LegacyPushGossipCacheSize: 512, + } ) +var _ TxVerifier = (*testTxVerifier)(nil) + type testTxVerifier struct { err error } @@ -92,7 +110,6 @@ func TestNetworkAppGossip(t *testing.T) { }, }, { - // Issue returns nil because mempool has tx. We should gossip the tx. name: "issuance succeeds", msgBytesFunc: func() []byte { msg := message.Tx{ @@ -104,13 +121,17 @@ func TestNetworkAppGossip(t *testing.T) { }, mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Get(gomock.Any()).Return(testTx, true) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) + mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().RequestBuildBlock(false) return mempool }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { + // we should gossip the tx twice because sdk and legacy gossip + // currently runs together appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Times(2) return appSender }, }, @@ -127,6 +148,7 @@ func TestNetworkAppGossip(t *testing.T) { }, mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(errTest) return mempool }, @@ -162,16 +184,25 @@ func TestNetworkAppGossip(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { require := require.New(t) + ctx := context.Background() ctrl := gomock.NewController(t) - n := New( + snowCtx := snowtest.Context(t, ids.Empty) + n, err := New( logging.NoLog{}, + ids.EmptyNodeID, + ids.Empty, + snowCtx.ValidatorState, testTxVerifier{}, tt.mempoolFunc(ctrl), tt.partialSyncPrimaryNetwork, tt.appSenderFunc(ctrl), + prometheus.NewRegistry(), + DefaultConfig, ) - require.NoError(n.AppGossip(context.Background(), ids.GenerateTestNodeID(), tt.msgBytesFunc())) + require.NoError(err) + + require.NoError(n.AppGossip(ctx, ids.GenerateTestNodeID(), tt.msgBytesFunc())) }) } } @@ -197,22 +228,18 @@ func TestNetworkIssueTx(t *testing.T) { return mempool }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Should gossip the tx - appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) - return appSender + return common.NewMockSender(ctrl) }, - expectedErr: nil, + expectedErr: mempool.ErrDuplicateTx, }, { name: "transaction marked as dropped in mempool", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Get(gomock.Any()).Return(nil, false) - mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) + mempool.EXPECT().GetDropReason(gomock.Any()).Return(errTest) return mempool }, - txVerifier: testTxVerifier{err: errTest}, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { // Shouldn't gossip the tx return common.NewMockSender(ctrl) @@ -224,6 +251,7 @@ func TestNetworkIssueTx(t *testing.T) { mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Get(gomock.Any()).Return(nil, false) + mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, @@ -239,8 +267,9 @@ func TestNetworkIssueTx(t *testing.T) { mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Get(gomock.Any()).Return(nil, false) + mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().Add(gomock.Any()).Return(errTest) - mempool.EXPECT().MarkDropped(gomock.Any(), errTest) + mempool.EXPECT().MarkDropped(gomock.Any(), gomock.Any()) return mempool }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { @@ -252,15 +281,14 @@ func TestNetworkIssueTx(t *testing.T) { { name: "AppGossip tx but do not add to mempool if primary network is not being fully synced", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { - mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Get(gomock.Any()).Return(nil, false) - return mempool + return mempool.NewMockMempool(ctrl) }, partialSyncPrimaryNetwork: true, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Should gossip the tx + // we should gossip the tx twice because sdk and legacy gossip + // currently runs together appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil).Times(2) return appSender }, expectedErr: nil, @@ -269,15 +297,17 @@ func TestNetworkIssueTx(t *testing.T) { name: "happy path", mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) - mempool.EXPECT().Get(gomock.Any()).Return(tx, false) + mempool.EXPECT().Get(gomock.Any()).Return(nil, false) + mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().Add(gomock.Any()).Return(nil) mempool.EXPECT().RequestBuildBlock(false) return mempool }, appSenderFunc: func(ctrl *gomock.Controller) common.AppSender { - // Should gossip the tx + // we should gossip the tx twice because sdk and legacy gossip + // currently runs together appSender := common.NewMockSender(ctrl) - appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil) + appSender.EXPECT().SendAppGossip(gomock.Any(), gomock.Any()).Return(nil).Times(2) return appSender }, expectedErr: nil, @@ -289,14 +319,22 @@ func TestNetworkIssueTx(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - n := New( - logging.NoLog{}, + snowCtx := snowtest.Context(t, ids.Empty) + n, err := New( + snowCtx.Log, + snowCtx.NodeID, + snowCtx.SubnetID, + snowCtx.ValidatorState, tt.txVerifier, tt.mempoolFunc(ctrl), tt.partialSyncPrimaryNetwork, tt.appSenderFunc(ctrl), + prometheus.NewRegistry(), + testConfig, ) - err := n.IssueTx(context.Background(), tx) + require.NoError(err) + + err = n.IssueTx(context.Background(), tx) require.ErrorIs(err, tt.expectedErr) }) } @@ -308,25 +346,32 @@ func TestNetworkGossipTx(t *testing.T) { appSender := common.NewMockSender(ctrl) - nIntf := New( - logging.NoLog{}, + snowCtx := snowtest.Context(t, ids.Empty) + nIntf, err := New( + snowCtx.Log, + snowCtx.NodeID, + snowCtx.SubnetID, + snowCtx.ValidatorState, testTxVerifier{}, mempool.NewMockMempool(ctrl), false, appSender, + prometheus.NewRegistry(), + testConfig, ) + require.NoError(err) require.IsType(&network{}, nIntf) n := nIntf.(*network) // Case: Tx was recently gossiped txID := ids.GenerateTestID() n.recentTxs.Put(txID, struct{}{}) - n.gossipTx(context.Background(), txID, []byte{}) + n.legacyGossipTx(context.Background(), txID, []byte{}) // Didn't make a call to SendAppGossip // Case: Tx was not recently gossiped msgBytes := []byte{1, 2, 3} appSender.EXPECT().SendAppGossip(gomock.Any(), msgBytes).Return(nil) - n.gossipTx(context.Background(), ids.GenerateTestID(), msgBytes) + n.legacyGossipTx(context.Background(), ids.GenerateTestID(), msgBytes) // Did make a call to SendAppGossip } diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index 376b809fa3d8..de0c16718b9a 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -217,7 +217,6 @@ func TestGetTxStatus(t *testing.T) { }, })) - oldSharedMemory := mutableSharedMemory.SharedMemory mutableSharedMemory.SharedMemory = sm tx, err := service.vm.txBuilder.NewImportTx( @@ -228,8 +227,6 @@ func TestGetTxStatus(t *testing.T) { ) require.NoError(err) - mutableSharedMemory.SharedMemory = oldSharedMemory - service.vm.ctx.Lock.Unlock() var ( @@ -241,11 +238,6 @@ func TestGetTxStatus(t *testing.T) { require.Zero(resp.Reason) // put the chain in existing chain list - err = service.vm.Network.IssueTx(context.Background(), tx) - require.ErrorIs(err, database.ErrNotFound) // Missing shared memory UTXO - - mutableSharedMemory.SharedMemory = sm - require.NoError(service.vm.Network.IssueTx(context.Background(), tx)) service.vm.ctx.Lock.Lock() diff --git a/vms/platformvm/txs/tx.go b/vms/platformvm/txs/tx.go index 27cc812e5a79..c9713ffe09c3 100644 --- a/vms/platformvm/txs/tx.go +++ b/vms/platformvm/txs/tx.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" @@ -18,6 +19,8 @@ import ( ) var ( + _ gossip.Gossipable = (*Tx)(nil) + ErrNilSignedTx = errors.New("nil signed tx is not valid") errSignedTxNotInitialized = errors.New("signed tx was never initialized and is not valid") @@ -93,6 +96,10 @@ func (tx *Tx) ID() ids.ID { return tx.TxID } +func (tx *Tx) GossipID() ids.ID { + return tx.TxID +} + // UTXOs returns the UTXOs transaction is producing. func (tx *Tx) UTXOs() []*avax.UTXO { outs := tx.Unsigned.Outputs() diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index ef4581b5dac9..e9885a9bad94 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "net/http" + "sync" "github.com/gorilla/rpc/v2" @@ -89,6 +90,9 @@ type VM struct { txBuilder txbuilder.Builder manager blockexecutor.Manager + startShutdown context.CancelFunc + awaitShutdown sync.WaitGroup + // TODO: Remove after v1.11.x is activated pruned utils.Atomic[bool] } @@ -192,13 +196,30 @@ func (vm *VM) Initialize( ) txVerifier := network.NewLockedTxVerifier(&txExecutorBackend.Ctx.Lock, vm.manager) - vm.Network = network.New( + vm.Network, err = network.New( chainCtx.Log, + chainCtx.NodeID, + chainCtx.SubnetID, + chainCtx.ValidatorState, txVerifier, mempool, txExecutorBackend.Config.PartialSyncPrimaryNetwork, appSender, + registerer, + execConfig.Network, ) + if err != nil { + return fmt.Errorf("failed to initialize network: %w", err) + } + + vmCtx, cancel := context.WithCancel(context.Background()) + vm.startShutdown = cancel + vm.awaitShutdown.Add(1) + go func() { + defer vm.awaitShutdown.Done() + vm.Network.Gossip(vmCtx) + }() + vm.Builder = blockbuilder.New( mempool, vm.txBuilder, @@ -354,6 +375,9 @@ func (vm *VM) Shutdown(context.Context) error { return nil } + vm.startShutdown() + vm.awaitShutdown.Wait() + vm.Builder.ShutdownBlockTimer() if vm.bootstrapped.Get() { From ee10054e2c7af3c73880bce4e795ebb85f3bf668 Mon Sep 17 00:00:00 2001 From: joao <22820692+joaolago1113@users.noreply.github.com> Date: Mon, 25 Dec 2023 18:17:14 +0000 Subject: [PATCH 204/267] Documentation Fixes: Grammatical Corrections and Typo Fixes Across Multiple Files (#2550) --- CONTRIBUTING.md | 2 +- network/README.md | 2 +- tests/e2e/README.md | 2 +- vms/example/xsvm/README.md | 2 +- vms/platformvm/docs/validators_versioning.md | 4 ++-- vms/proposervm/README.md | 2 +- vms/rpcchainvm/runtime/README.md | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4abb6a4d82ff..affb43575fca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,7 +25,7 @@ To start developing on AvalancheGo, you'll need a few things installed. ## Features -- If you want to start a discussion about the development of a new feature or the modfiication of an existing one, start a thread under GitHub [discussions](https://github.com/ava-labs/avalanchego/discussions/categories/ideas). +- If you want to start a discussion about the development of a new feature or the modification of an existing one, start a thread under GitHub [discussions](https://github.com/ava-labs/avalanchego/discussions/categories/ideas). - Post a thread about your idea and why it should be added to AvalancheGo. - Don't start working on a pull request until you've received positive feedback from the maintainers. diff --git a/network/README.md b/network/README.md index b62b0ba3769c..5e66e2e25f4f 100644 --- a/network/README.md +++ b/network/README.md @@ -128,7 +128,7 @@ To optimize bandwidth usage, each node tracks which peers are guaranteed to know To efficiently track which peers know of which peers, the peers that each peer is aware of is represented in a [bit set](https://en.wikipedia.org/wiki/Bit_array). A peer is represented by either a `0` if it isn't known by the peer yet, or a `1` if it is known by the peer. -An node follows the following steps for every cycle of `PeerList` gossip: +A node follows the following steps for every cycle of `PeerList` gossip: 1. Get a sample of peers in the network that the node is connected to 2. For each peer: diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 032795b6436e..41c724a15051 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -66,7 +66,7 @@ across multiple test runs. This can increase the speed of iteration by removing the requirement to start a new network for every invocation of the test under development. -To create an temporary network for use across test runs: +To create a temporary network for use across test runs: ```bash # From the root of the avalanchego repo diff --git a/vms/example/xsvm/README.md b/vms/example/xsvm/README.md index 6f30f7b7e756..53548228a989 100644 --- a/vms/example/xsvm/README.md +++ b/vms/example/xsvm/README.md @@ -18,7 +18,7 @@ Avalanche is a network composed of multiple sub-networks (called [subnets][Subne ## Introduction -Just as [Coreth] powers the [C-Chain], XSVM can be used to power its own blockchain in an Avalanche [Subnet]. Instead of providing a place to execute Solidity smart contracts, however, XSVM enables asset transfers for assets originating on it's own chain or other XSVM chains on other subnets. +Just as [Coreth] powers the [C-Chain], XSVM can be used to power its own blockchain in an Avalanche [Subnet]. Instead of providing a place to execute Solidity smart contracts, however, XSVM enables asset transfers for assets originating on its own chain or other XSVM chains on other subnets. ## How it Works diff --git a/vms/platformvm/docs/validators_versioning.md b/vms/platformvm/docs/validators_versioning.md index c4fce00399c5..7db716d12677 100644 --- a/vms/platformvm/docs/validators_versioning.md +++ b/vms/platformvm/docs/validators_versioning.md @@ -18,7 +18,7 @@ GetValidatorSet(ctx context.Context, height uint64, subnetID ids.ID) (map[ids.No Validator data are collected in a struct named `validators.GetValidatorOutput` which holds for each active validator, its `NodeID`, its `Weight` and its `BLS Public Key` if it was registered. -Note that a validator `Weight` is not just its stake; its the aggregate value of the validator's own stake and all of its delegators' stake. A validator's `Weight` gauges how relevant its preference should be in consensus or Warp operations. +Note that a validator `Weight` is not just its stake; it's the aggregate value of the validator's own stake and all of its delegators' stake. A validator's `Weight` gauges how relevant its preference should be in consensus or Warp operations. We will see in the next section how the P-chain keeps track of this information over time as the validator set changes. @@ -35,7 +35,7 @@ These diffs are key to rebuilding the validator set at a given past height. In t The validators diffs track changes in a validator's `Weight` and `BLS Public key`. Along with the `NodeID` this is the data exposed by the `GetValidatorSet` method. -Note that `Weight` and `BLS Public key` behave differently throughout the validator lifetime: +Note that `Weight` and `BLS Public key` behave differently throughout the validator's lifetime: 1. `BLS Public key` cannot change through a validator's lifetime. It can only change when a validator is added/re-added and removed. 2. `Weight` can change throughout a validator's lifetime by the creation and removal of its delegators as well as by validator's own creation and removal. diff --git a/vms/proposervm/README.md b/vms/proposervm/README.md index e01a014f1156..6dec4fe9d932 100644 --- a/vms/proposervm/README.md +++ b/vms/proposervm/README.md @@ -47,7 +47,7 @@ A proposer in position `i` in the proposers list has its submission windows star The following validation rules are enforced: - Given a `proposervm.Block` **C** and its parent block **P**, **P**'s inner block must be **C**'s inner block's parent. -- A block must have a `PChainHeight` is larger or equal to its parent's `PChainHeight` (`PChainHeight` is monotonic). +- A block must have a `PChainHeight` that is larger or equal to its parent's `PChainHeight` (`PChainHeight` is monotonic). - A block must have a `PChainHeight` that is less or equal to current P-Chain height. - A block must have a `Timestamp` larger or equal to its parent's `Timestamp` (`Timestamp` is monotonic) - A block received by a node at time `t_local` must have a `Timestamp` such that `Timestamp < t_local + maxSkew` (a block too far in the future is invalid). `maxSkew` is currently set to `10 seconds`. diff --git a/vms/rpcchainvm/runtime/README.md b/vms/rpcchainvm/runtime/README.md index 6e09e41f8ace..1a2fe264bc1c 100644 --- a/vms/rpcchainvm/runtime/README.md +++ b/vms/rpcchainvm/runtime/README.md @@ -17,7 +17,7 @@ It works by starting the VM's as a subprocess of AvalancheGo by `os.Exec`. ## Workflow - `VMRegistry` calls the RPC Chain VM `Factory`. -- Factory Starts an instanace of a `VMRE` server that consumes a `runtime.Initializer` interface implementation. +- Factory Starts an instance of a `VMRE` server that consumes a `runtime.Initializer` interface implementation. - The address of this server is passed as a ENV variable `AVALANCHE_VM_RUNTIME_ENGINE_ADDR` via `os.Exec` which starts the VM binary. - The VM uses the address of the `VMRE` server to create a client. - Client sends a `Initialize` RPC informing the server of the `Protocol Version` and future `Address` of the RPC Chain VM server allowing it to perform a validation `Handshake`. From 332a1b3d02573892c6f39834c3d15a0198ee94ed Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 27 Dec 2023 10:59:16 -0500 Subject: [PATCH 205/267] Notify block builder of txs after reject (#2549) --- vms/avm/block/executor/block.go | 4 ++++ vms/avm/block/executor/block_test.go | 2 ++ 2 files changed, 6 insertions(+) diff --git a/vms/avm/block/executor/block.go b/vms/avm/block/executor/block.go index 439e7f009d53..ebad27c2b67f 100644 --- a/vms/avm/block/executor/block.go +++ b/vms/avm/block/executor/block.go @@ -290,6 +290,10 @@ func (b *Block) Reject(context.Context) error { } } + // If we added transactions to the mempool, we should be willing to build a + // block. + b.manager.mempool.RequestBuildBlock() + b.rejected = true return nil } diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index da965884ae58..a235377164b9 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -857,6 +857,7 @@ func TestBlockReject(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Add(validTx).Return(nil) // Only add the one that passes verification + mempool.EXPECT().RequestBuildBlock() preferredID := ids.GenerateTestID() mockPreferredState := state.NewMockDiff(ctrl) @@ -916,6 +917,7 @@ func TestBlockReject(t *testing.T) { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Add(tx1).Return(nil) mempool.EXPECT().Add(tx2).Return(nil) + mempool.EXPECT().RequestBuildBlock() preferredID := ids.GenerateTestID() mockPreferredState := state.NewMockDiff(ctrl) From 1bc0378202d8c8cc6fef7543544e19f6f8cbea98 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 27 Dec 2023 14:36:55 -0500 Subject: [PATCH 206/267] Set dependabot target branch to `dev` (#2553) --- .github/dependabot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b444581e62d0..39bc8b683ea0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,4 @@ updates: directory: "/" # Location of package manifests schedule: interval: "daily" + target-branch: "dev" From aa509e78537f9d81496792fdf486c0a95b4a3d49 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 27 Dec 2023 17:10:18 -0500 Subject: [PATCH 207/267] Remove `MockLogger` (#2554) --- api/admin/service_test.go | 8 +- api/info/service_test.go | 19 +-- scripts/mocks.mockgen.txt | 1 - utils/logging/mock_logger.go | 246 ----------------------------- vms/registry/vm_registerer_test.go | 12 +- 5 files changed, 8 insertions(+), 278 deletions(-) delete mode 100644 utils/logging/mock_logger.go diff --git a/api/admin/service_test.go b/api/admin/service_test.go index 09665a52c9d9..774c93440bc9 100644 --- a/api/admin/service_test.go +++ b/api/admin/service_test.go @@ -20,7 +20,6 @@ import ( type loadVMsTest struct { admin *Admin ctrl *gomock.Controller - mockLog *logging.MockLogger mockVMManager *vms.MockManager mockVMRegistry *registry.MockVMRegistry } @@ -28,18 +27,16 @@ type loadVMsTest struct { func initLoadVMsTest(t *testing.T) *loadVMsTest { ctrl := gomock.NewController(t) - mockLog := logging.NewMockLogger(ctrl) mockVMRegistry := registry.NewMockVMRegistry(ctrl) mockVMManager := vms.NewMockManager(ctrl) return &loadVMsTest{ admin: &Admin{Config: Config{ - Log: mockLog, + Log: logging.NoLog{}, VMRegistry: mockVMRegistry, VMManager: mockVMManager, }}, ctrl: ctrl, - mockLog: mockLog, mockVMManager: mockVMManager, mockVMRegistry: mockVMRegistry, } @@ -67,7 +64,6 @@ func TestLoadVMsSuccess(t *testing.T) { id2: alias2[1:], } - resources.mockLog.EXPECT().Debug(gomock.Any(), gomock.Any()).Times(1) resources.mockVMRegistry.EXPECT().ReloadWithReadLock(gomock.Any()).Times(1).Return(newVMs, failedVMs, nil) resources.mockVMManager.EXPECT().Aliases(id1).Times(1).Return(alias1, nil) resources.mockVMManager.EXPECT().Aliases(id2).Times(1).Return(alias2, nil) @@ -84,7 +80,6 @@ func TestLoadVMsReloadFails(t *testing.T) { resources := initLoadVMsTest(t) - resources.mockLog.EXPECT().Debug(gomock.Any(), gomock.Any()).Times(1) // Reload fails resources.mockVMRegistry.EXPECT().ReloadWithReadLock(gomock.Any()).Times(1).Return(nil, nil, errTest) @@ -108,7 +103,6 @@ func TestLoadVMsGetAliasesFails(t *testing.T) { // every vm is at least aliased to itself. alias1 := []string{id1.String(), "vm1-alias-1", "vm1-alias-2"} - resources.mockLog.EXPECT().Debug(gomock.Any(), gomock.Any()).Times(1) resources.mockVMRegistry.EXPECT().ReloadWithReadLock(gomock.Any()).Times(1).Return(newVMs, failedVMs, nil) resources.mockVMManager.EXPECT().Aliases(id1).Times(1).Return(alias1, nil) resources.mockVMManager.EXPECT().Aliases(id2).Times(1).Return(nil, errTest) diff --git a/api/info/service_test.go b/api/info/service_test.go index 312d8182ea83..ad6320df5a90 100644 --- a/api/info/service_test.go +++ b/api/info/service_test.go @@ -21,24 +21,20 @@ var errTest = errors.New("non-nil error") type getVMsTest struct { info *Info ctrl *gomock.Controller - mockLog *logging.MockLogger mockVMManager *vms.MockManager } func initGetVMsTest(t *testing.T) *getVMsTest { ctrl := gomock.NewController(t) - - service := Info{} - mockLog := logging.NewMockLogger(ctrl) mockVMManager := vms.NewMockManager(ctrl) - - service.log = mockLog - service.VMManager = mockVMManager - return &getVMsTest{ - info: &service, + info: &Info{ + Parameters: Parameters{ + VMManager: mockVMManager, + }, + log: logging.NoLog{}, + }, ctrl: ctrl, - mockLog: mockLog, mockVMManager: mockVMManager, } } @@ -62,7 +58,6 @@ func TestGetVMsSuccess(t *testing.T) { id2: alias2[1:], } - resources.mockLog.EXPECT().Debug(gomock.Any(), gomock.Any()).Times(1) resources.mockVMManager.EXPECT().ListFactories().Times(1).Return(vmIDs, nil) resources.mockVMManager.EXPECT().Aliases(id1).Times(1).Return(alias1, nil) resources.mockVMManager.EXPECT().Aliases(id2).Times(1).Return(alias2, nil) @@ -76,7 +71,6 @@ func TestGetVMsSuccess(t *testing.T) { func TestGetVMsVMsListFactoriesFails(t *testing.T) { resources := initGetVMsTest(t) - resources.mockLog.EXPECT().Debug(gomock.Any(), gomock.Any()).Times(1) resources.mockVMManager.EXPECT().ListFactories().Times(1).Return(nil, errTest) reply := GetVMsReply{} @@ -93,7 +87,6 @@ func TestGetVMsGetAliasesFails(t *testing.T) { vmIDs := []ids.ID{id1, id2} alias1 := []string{id1.String(), "vm1-alias-1", "vm1-alias-2"} - resources.mockLog.EXPECT().Debug(gomock.Any(), gomock.Any()).Times(1) resources.mockVMManager.EXPECT().ListFactories().Times(1).Return(vmIDs, nil) resources.mockVMManager.EXPECT().Aliases(id1).Times(1).Return(alias1, nil) resources.mockVMManager.EXPECT().Aliases(id2).Times(1).Return(nil, errTest) diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index c01efb8e5869..2fbfa5b255ab 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -21,7 +21,6 @@ github.com/ava-labs/avalanchego/snow/validators=SubnetConnector=snow/validators/ github.com/ava-labs/avalanchego/utils/crypto/keychain=Ledger=utils/crypto/keychain/mock_ledger.go github.com/ava-labs/avalanchego/utils/filesystem=Reader=utils/filesystem/mock_io.go github.com/ava-labs/avalanchego/utils/hashing=Hasher=utils/hashing/mock_hasher.go -github.com/ava-labs/avalanchego/utils/logging=Logger=utils/logging/mock_logger.go github.com/ava-labs/avalanchego/utils/resource=User=utils/resource/mock_user.go github.com/ava-labs/avalanchego/vms/avm/block=Block=vms/avm/block/mock_block.go github.com/ava-labs/avalanchego/vms/avm/metrics=Metrics=vms/avm/metrics/mock_metrics.go diff --git a/utils/logging/mock_logger.go b/utils/logging/mock_logger.go deleted file mode 100644 index ba1079d30a09..000000000000 --- a/utils/logging/mock_logger.go +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/utils/logging (interfaces: Logger) - -// Package logging is a generated GoMock package. -package logging - -import ( - reflect "reflect" - - gomock "go.uber.org/mock/gomock" - zapcore "go.uber.org/zap/zapcore" -) - -// MockLogger is a mock of Logger interface. -type MockLogger struct { - ctrl *gomock.Controller - recorder *MockLoggerMockRecorder -} - -// MockLoggerMockRecorder is the mock recorder for MockLogger. -type MockLoggerMockRecorder struct { - mock *MockLogger -} - -// NewMockLogger creates a new mock instance. -func NewMockLogger(ctrl *gomock.Controller) *MockLogger { - mock := &MockLogger{ctrl: ctrl} - mock.recorder = &MockLoggerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockLogger) EXPECT() *MockLoggerMockRecorder { - return m.recorder -} - -// Debug mocks base method. -func (m *MockLogger) Debug(arg0 string, arg1 ...zapcore.Field) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - m.ctrl.Call(m, "Debug", varargs...) -} - -// Debug indicates an expected call of Debug. -func (mr *MockLoggerMockRecorder) Debug(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockLogger)(nil).Debug), varargs...) -} - -// Enabled mocks base method. -func (m *MockLogger) Enabled(arg0 Level) bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Enabled", arg0) - ret0, _ := ret[0].(bool) - return ret0 -} - -// Enabled indicates an expected call of Enabled. -func (mr *MockLoggerMockRecorder) Enabled(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Enabled", reflect.TypeOf((*MockLogger)(nil).Enabled), arg0) -} - -// Error mocks base method. -func (m *MockLogger) Error(arg0 string, arg1 ...zapcore.Field) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - m.ctrl.Call(m, "Error", varargs...) -} - -// Error indicates an expected call of Error. -func (mr *MockLoggerMockRecorder) Error(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockLogger)(nil).Error), varargs...) -} - -// Fatal mocks base method. -func (m *MockLogger) Fatal(arg0 string, arg1 ...zapcore.Field) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - m.ctrl.Call(m, "Fatal", varargs...) -} - -// Fatal indicates an expected call of Fatal. -func (mr *MockLoggerMockRecorder) Fatal(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Fatal", reflect.TypeOf((*MockLogger)(nil).Fatal), varargs...) -} - -// Info mocks base method. -func (m *MockLogger) Info(arg0 string, arg1 ...zapcore.Field) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - m.ctrl.Call(m, "Info", varargs...) -} - -// Info indicates an expected call of Info. -func (mr *MockLoggerMockRecorder) Info(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockLogger)(nil).Info), varargs...) -} - -// RecoverAndExit mocks base method. -func (m *MockLogger) RecoverAndExit(arg0, arg1 func()) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RecoverAndExit", arg0, arg1) -} - -// RecoverAndExit indicates an expected call of RecoverAndExit. -func (mr *MockLoggerMockRecorder) RecoverAndExit(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecoverAndExit", reflect.TypeOf((*MockLogger)(nil).RecoverAndExit), arg0, arg1) -} - -// RecoverAndPanic mocks base method. -func (m *MockLogger) RecoverAndPanic(arg0 func()) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RecoverAndPanic", arg0) -} - -// RecoverAndPanic indicates an expected call of RecoverAndPanic. -func (mr *MockLoggerMockRecorder) RecoverAndPanic(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecoverAndPanic", reflect.TypeOf((*MockLogger)(nil).RecoverAndPanic), arg0) -} - -// SetLevel mocks base method. -func (m *MockLogger) SetLevel(arg0 Level) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetLevel", arg0) -} - -// SetLevel indicates an expected call of SetLevel. -func (mr *MockLoggerMockRecorder) SetLevel(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLevel", reflect.TypeOf((*MockLogger)(nil).SetLevel), arg0) -} - -// Stop mocks base method. -func (m *MockLogger) Stop() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Stop") -} - -// Stop indicates an expected call of Stop. -func (mr *MockLoggerMockRecorder) Stop() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockLogger)(nil).Stop)) -} - -// StopOnPanic mocks base method. -func (m *MockLogger) StopOnPanic() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "StopOnPanic") -} - -// StopOnPanic indicates an expected call of StopOnPanic. -func (mr *MockLoggerMockRecorder) StopOnPanic() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopOnPanic", reflect.TypeOf((*MockLogger)(nil).StopOnPanic)) -} - -// Trace mocks base method. -func (m *MockLogger) Trace(arg0 string, arg1 ...zapcore.Field) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - m.ctrl.Call(m, "Trace", varargs...) -} - -// Trace indicates an expected call of Trace. -func (mr *MockLoggerMockRecorder) Trace(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trace", reflect.TypeOf((*MockLogger)(nil).Trace), varargs...) -} - -// Verbo mocks base method. -func (m *MockLogger) Verbo(arg0 string, arg1 ...zapcore.Field) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - m.ctrl.Call(m, "Verbo", varargs...) -} - -// Verbo indicates an expected call of Verbo. -func (mr *MockLoggerMockRecorder) Verbo(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verbo", reflect.TypeOf((*MockLogger)(nil).Verbo), varargs...) -} - -// Warn mocks base method. -func (m *MockLogger) Warn(arg0 string, arg1 ...zapcore.Field) { - m.ctrl.T.Helper() - varargs := []interface{}{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - m.ctrl.Call(m, "Warn", varargs...) -} - -// Warn indicates an expected call of Warn. -func (mr *MockLoggerMockRecorder) Warn(arg0 interface{}, arg1 ...interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Warn", reflect.TypeOf((*MockLogger)(nil).Warn), varargs...) -} - -// Write mocks base method. -func (m *MockLogger) Write(arg0 []byte) (int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Write", arg0) - ret0, _ := ret[0].(int) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Write indicates an expected call of Write. -func (mr *MockLoggerMockRecorder) Write(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockLogger)(nil).Write), arg0) -} diff --git a/vms/registry/vm_registerer_test.go b/vms/registry/vm_registerer_test.go index baaa569a89ba..f5ad6c2f1349 100644 --- a/vms/registry/vm_registerer_test.go +++ b/vms/registry/vm_registerer_test.go @@ -411,7 +411,6 @@ type vmRegistererTestResources struct { ctrl *gomock.Controller mockManager *vms.MockManager mockServer *server.MockServer - mockLogger *logging.MockLogger registerer VMRegisterer } @@ -420,27 +419,18 @@ func initRegistererTest(t *testing.T) *vmRegistererTestResources { mockManager := vms.NewMockManager(ctrl) mockServer := server.NewMockServer(ctrl) - mockLog := logging.NewMockLogger(ctrl) registerer := NewVMRegisterer(VMRegistererConfig{ APIServer: mockServer, - Log: mockLog, + Log: logging.NoLog{}, VMFactoryLog: logging.NoLog{}, VMManager: mockManager, }) - mockLog.EXPECT().Error(gomock.Any(), gomock.Any()).AnyTimes() - mockLog.EXPECT().Warn(gomock.Any(), gomock.Any()).AnyTimes() - mockLog.EXPECT().Info(gomock.Any(), gomock.Any()).AnyTimes() - mockLog.EXPECT().Debug(gomock.Any(), gomock.Any()).AnyTimes() - mockLog.EXPECT().Trace(gomock.Any(), gomock.Any()).AnyTimes() - mockLog.EXPECT().Verbo(gomock.Any(), gomock.Any()).AnyTimes() - return &vmRegistererTestResources{ ctrl: ctrl, mockManager: mockManager, mockServer: mockServer, - mockLogger: mockLog, registerer: registerer, } } From 0c7ff5a468b527cc6d3a2ea893ecc5b093c5c98e Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Thu, 28 Dec 2023 12:41:54 -0500 Subject: [PATCH 208/267] Clean up merkleDB interface and duplicate code (#2445) Co-authored-by: Dan Laine --- x/merkledb/README.md | 12 +- x/merkledb/db.go | 125 +++--- x/merkledb/db_test.go | 40 +- x/merkledb/mock_db.go | 445 ++++++++++++---------- x/merkledb/proof.go | 18 +- x/merkledb/trie.go | 244 ++++++++++-- x/merkledb/trie_test.go | 160 ++++---- x/merkledb/{trieview.go => view.go} | 569 ++++++++++------------------ x/merkledb/view_iterator.go | 24 +- x/merkledb/view_iterator_test.go | 18 +- 10 files changed, 853 insertions(+), 802 deletions(-) rename x/merkledb/{trieview.go => view.go} (54%) diff --git a/x/merkledb/README.md b/x/merkledb/README.md index a84a1f8ab8d9..29c9f0a73247 100644 --- a/x/merkledb/README.md +++ b/x/merkledb/README.md @@ -427,18 +427,18 @@ Not using extension nodes results in worse storage efficiency (some nodes may ha `merkleDB` has a `RWMutex` named `lock`. Its read operations don't store data in a map, so a read lock suffices for read operations. `merkleDB` has a `Mutex` named `commitLock`. It enforces that only a single view/batch is attempting to commit to the database at one time. `lock` is insufficient because there is a period of view preparation where read access should still be allowed, followed by a period where a full write lock is needed. The `commitLock` ensures that only a single goroutine makes the transition from read => write. -A `trieView` is built atop another trie, which may be the underlying `merkleDB` or another `trieView`. +A `view` is built atop another trie, which may be the underlying `merkleDB` or another `view`. We use locking to guarantee atomicity/consistency of trie operations. -`trieView` has a `RWMutex` named `commitLock` which ensures that we don't create a view atop the `trieView` while it's being committed. -It also has a `RWMutex` named `validityTrackingLock` that is held during methods that change the view's validity, tracking of child views' validity, or of the `trieView` parent trie. This lock ensures that writing/reading from `trieView` or any of its descendants is safe. -The `CommitToDB` method grabs the `merkleDB`'s `commitLock`. This is the only `trieView` method that modifies the underlying `merkleDB`. +`view` has a `RWMutex` named `commitLock` which ensures that we don't create a view atop the `view` while it's being committed. +It also has a `RWMutex` named `validityTrackingLock` that is held during methods that change the view's validity, tracking of child views' validity, or of the `view` parent trie. This lock ensures that writing/reading from `view` or any of its descendants is safe. +The `CommitToDB` method grabs the `merkleDB`'s `commitLock`. This is the only `view` method that modifies the underlying `merkleDB`. -In some of `merkleDB`'s methods, we create a `trieView` and call unexported methods on it without locking it. +In some of `merkleDB`'s methods, we create a `view` and call unexported methods on it without locking it. We do so because the exported counterpart of the method read locks the `merkleDB`, which is already locked. This pattern is safe because the `merkleDB` is locked, so no data under the view is changing, and nobody else has a reference to the view, so there can't be any concurrent access. -To prevent deadlocks, `trieView` and `merkleDB` never acquire the `commitLock` of descendant views. +To prevent deadlocks, `view` and `merkleDB` never acquire the `commitLock` of descendant views. That is, locking is always done from a view toward to the underlying `merkleDB`, never the other way around. The `validityTrackingLock` goes the opposite way. A view can lock the `validityTrackingLock` of its children, but not its ancestors. Because of this, any function that takes the `validityTrackingLock` must not take the `commitLock` as this may cause a deadlock. Keeping `commitLock` solely in the ancestor direction and `validityTrackingLock` solely in the descendant direction prevents deadlocks from occurring. diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 211c11950bba..e3319aee972b 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -179,7 +179,7 @@ type Config struct { Tracer trace.Tracer } -// merkleDB can only be edited by committing changes from a trieView. +// merkleDB can only be edited by committing changes from a view. type merkleDB struct { // Must be held when reading/writing fields. lock sync.RWMutex @@ -216,7 +216,7 @@ type merkleDB struct { rootID ids.ID // Valid children of this trie. - childViews []*trieView + childViews []*view // calculateNodeIDsSema controls the number of goroutines inside // [calculateNodeIDsHelper] at any given time. @@ -264,7 +264,7 @@ func newDatabase( history: newTrieHistory(int(config.HistoryLength)), debugTracer: getTracerIfEnabled(config.TraceLevel, DebugTrace, config.Tracer), infoTracer: getTracerIfEnabled(config.TraceLevel, InfoTrace, config.Tracer), - childViews: make([]*trieView, 0, defaultPreallocationSize), + childViews: make([]*view, 0, defaultPreallocationSize), calculateNodeIDsSema: semaphore.NewWeighted(int64(rootGenConcurrency)), tokenSize: BranchFactorToTokenSize[config.BranchFactor], } @@ -324,7 +324,7 @@ func (db *merkleDB) rebuild(ctx context.Context, cacheSize int) error { defer valueIt.Release() for valueIt.Next() { if len(currentOps) >= opsSizeLimit { - view, err := newTrieView(db, db, ViewChanges{BatchOps: currentOps, ConsumeBytes: true}) + view, err := newView(db, db, ViewChanges{BatchOps: currentOps, ConsumeBytes: true}) if err != nil { return err } @@ -347,7 +347,7 @@ func (db *merkleDB) rebuild(ctx context.Context, cacheSize int) error { if err := valueIt.Error(); err != nil { return err } - view, err := newTrieView(db, db, ViewChanges{BatchOps: currentOps, ConsumeBytes: true}) + view, err := newView(db, db, ViewChanges{BatchOps: currentOps, ConsumeBytes: true}) if err != nil { return err } @@ -373,7 +373,7 @@ func (db *merkleDB) CommitChangeProof(ctx context.Context, proof *ChangeProof) e } } - view, err := newTrieView(db, db, ViewChanges{BatchOps: ops}) + view, err := newView(db, db, ViewChanges{BatchOps: ops}) if err != nil { return err } @@ -414,7 +414,7 @@ func (db *merkleDB) CommitRangeProof(ctx context.Context, start, end maybe.Maybe } // Don't need to lock [view] because nobody else has a reference to it. - view, err := newTrieView(db, db, ViewChanges{BatchOps: ops}) + view, err := newView(db, db, ViewChanges{BatchOps: ops}) if err != nil { return err } @@ -462,13 +462,8 @@ func (db *merkleDB) PrefetchPaths(keys [][]byte) error { return database.ErrClosed } - // reuse the view so that it can keep repeated nodes in memory - tempView, err := newTrieView(db, db, ViewChanges{}) - if err != nil { - return err - } for _, key := range keys { - if err := db.prefetchPath(tempView, key); err != nil { + if err := db.prefetchPath(key); err != nil { return err } } @@ -483,16 +478,11 @@ func (db *merkleDB) PrefetchPath(key []byte) error { if db.closed { return database.ErrClosed } - tempView, err := newTrieView(db, db, ViewChanges{}) - if err != nil { - return err - } - - return db.prefetchPath(tempView, key) + return db.prefetchPath(key) } -func (db *merkleDB) prefetchPath(view *trieView, keyBytes []byte) error { - return view.visitPathToKey(ToKey(keyBytes), func(n *node) error { +func (db *merkleDB) prefetchPath(keyBytes []byte) error { + return visitPathToKey(db, ToKey(keyBytes), func(n *node) error { if !n.hasValue() { // this value is already in the cache, so skip writing // to avoid grabbing the cache write lock @@ -599,7 +589,7 @@ func (db *merkleDB) GetMerkleRoot(ctx context.Context) (ids.ID, error) { return db.getMerkleRoot(), nil } -// Assumes [db.lock] is read locked. +// Assumes [db.lock] or [db.commitLock] is read locked. func (db *merkleDB) getMerkleRoot() ids.ID { return db.rootID } @@ -608,21 +598,14 @@ func (db *merkleDB) GetProof(ctx context.Context, key []byte) (*Proof, error) { db.commitLock.RLock() defer db.commitLock.RUnlock() - return db.getProof(ctx, key) -} + _, span := db.infoTracer.Start(ctx, "MerkleDB.GetProof") + defer span.End() -// Assumes [db.commitLock] is read locked. -func (db *merkleDB) getProof(ctx context.Context, key []byte) (*Proof, error) { if db.closed { return nil, database.ErrClosed } - view, err := newTrieView(db, db, ViewChanges{}) - if err != nil { - return nil, err - } - // Don't need to lock [view] because nobody else has a reference to it. - return view.getProof(ctx, key) + return getProof(db, key) } func (db *merkleDB) GetRangeProof( @@ -634,7 +617,14 @@ func (db *merkleDB) GetRangeProof( db.commitLock.RLock() defer db.commitLock.RUnlock() - return db.getRangeProofAtRoot(ctx, db.getMerkleRoot(), start, end, maxLength) + _, span := db.infoTracer.Start(ctx, "MerkleDB.GetRangeProof") + defer span.End() + + if db.closed { + return nil, database.ErrClosed + } + + return getRangeProof(db, start, end, maxLength) } func (db *merkleDB) GetRangeProofAtRoot( @@ -647,18 +637,9 @@ func (db *merkleDB) GetRangeProofAtRoot( db.commitLock.RLock() defer db.commitLock.RUnlock() - return db.getRangeProofAtRoot(ctx, rootID, start, end, maxLength) -} + _, span := db.infoTracer.Start(ctx, "MerkleDB.GetRangeProofAtRoot") + defer span.End() -// Assumes [db.commitLock] is read locked. -// Assumes [db.lock] is not held -func (db *merkleDB) getRangeProofAtRoot( - ctx context.Context, - rootID ids.ID, - start maybe.Maybe[[]byte], - end maybe.Maybe[[]byte], - maxLength int, -) (*RangeProof, error) { switch { case db.closed: return nil, database.ErrClosed @@ -668,11 +649,11 @@ func (db *merkleDB) getRangeProofAtRoot( return nil, ErrEmptyProof } - historicalView, err := db.getHistoricalViewForRange(rootID, start, end) + historicalTrie, err := db.getTrieAtRootForRange(rootID, start, end) if err != nil { return nil, err } - return historicalView.GetRangeProof(ctx, start, end, maxLength) + return getRangeProof(historicalTrie, start, end, maxLength) } func (db *merkleDB) GetChangeProof( @@ -683,6 +664,9 @@ func (db *merkleDB) GetChangeProof( end maybe.Maybe[[]byte], maxLength int, ) (*ChangeProof, error) { + _, span := db.infoTracer.Start(ctx, "MerkleDB.GetChangeProof") + defer span.End() + switch { case start.HasValue() && end.HasValue() && bytes.Compare(start.Value(), end.Value()) == 1: return nil, ErrStartAfterEnd @@ -731,13 +715,13 @@ func (db *merkleDB) GetChangeProof( // Since we hold [db.commitlock] we must still have sufficient // history to recreate the trie at [endRootID]. - historicalView, err := db.getHistoricalViewForRange(endRootID, start, largestKey) + historicalTrie, err := db.getTrieAtRootForRange(endRootID, start, largestKey) if err != nil { return nil, err } if largestKey.HasValue() { - endProof, err := historicalView.getProof(ctx, largestKey.Value()) + endProof, err := getProof(historicalTrie, largestKey.Value()) if err != nil { return nil, err } @@ -745,7 +729,7 @@ func (db *merkleDB) GetChangeProof( } if start.HasValue() { - startProof, err := historicalView.getProof(ctx, start.Value()) + startProof, err := getProof(historicalTrie, start.Value()) if err != nil { return nil, err } @@ -782,7 +766,7 @@ func (db *merkleDB) GetChangeProof( func (db *merkleDB) NewView( _ context.Context, changes ViewChanges, -) (TrieView, error) { +) (View, error) { // ensure the db doesn't change while creating the new view db.commitLock.RLock() defer db.commitLock.RUnlock() @@ -791,7 +775,7 @@ func (db *merkleDB) NewView( return nil, database.ErrClosed } - newView, err := newTrieView(db, db, changes) + newView, err := newView(db, db, changes) if err != nil { return nil, err } @@ -864,7 +848,7 @@ func (db *merkleDB) PutContext(ctx context.Context, k, v []byte) error { return database.ErrClosed } - view, err := newTrieView(db, db, ViewChanges{BatchOps: []database.BatchOp{{Key: k, Value: v}}}) + view, err := newView(db, db, ViewChanges{BatchOps: []database.BatchOp{{Key: k, Value: v}}}) if err != nil { return err } @@ -883,7 +867,7 @@ func (db *merkleDB) DeleteContext(ctx context.Context, key []byte) error { return database.ErrClosed } - view, err := newTrieView(db, db, + view, err := newView(db, db, ViewChanges{ BatchOps: []database.BatchOp{{ Key: key, @@ -907,7 +891,7 @@ func (db *merkleDB) commitBatch(ops []database.BatchOp) error { return database.ErrClosed } - view, err := newTrieView(db, db, ViewChanges{BatchOps: ops, ConsumeBytes: true}) + view, err := newView(db, db, ViewChanges{BatchOps: ops, ConsumeBytes: true}) if err != nil { return err } @@ -916,7 +900,8 @@ func (db *merkleDB) commitBatch(ops []database.BatchOp) error { // commitChanges commits the changes in [trieToCommit] to [db]. // Assumes [trieToCommit]'s node IDs have been calculated. -func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *trieView) error { +// Assumes [db.commitLock] is held. +func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *view) error { db.lock.Lock() defer db.lock.Unlock() @@ -1002,7 +987,7 @@ func (db *merkleDB) commitChanges(ctx context.Context, trieToCommit *trieView) e // moveChildViewsToDB removes any child views from the trieToCommit and moves them to the db // assumes [db.lock] is held -func (db *merkleDB) moveChildViewsToDB(trieToCommit *trieView) { +func (db *merkleDB) moveChildViewsToDB(trieToCommit *view) { trieToCommit.validityTrackingLock.Lock() defer trieToCommit.validityTrackingLock.Unlock() @@ -1010,11 +995,11 @@ func (db *merkleDB) moveChildViewsToDB(trieToCommit *trieView) { childView.updateParent(db) db.childViews = append(db.childViews, childView) } - trieToCommit.childViews = make([]*trieView, 0, defaultPreallocationSize) + trieToCommit.childViews = make([]*view, 0, defaultPreallocationSize) } // CommitToDB is a no-op for db since it is already in sync with itself. -// This exists to satisfy the TrieView interface. +// This exists to satisfy the View interface. func (*merkleDB) CommitToDB(context.Context) error { return nil } @@ -1119,7 +1104,7 @@ func (db *merkleDB) VerifyChangeProof( } // Don't need to lock [view] because nobody else has a reference to it. - view, err := newTrieView(db, db, ViewChanges{BatchOps: ops, ConsumeBytes: true}) + view, err := newView(db, db, ViewChanges{BatchOps: ops, ConsumeBytes: true}) if err != nil { return err } @@ -1159,7 +1144,7 @@ func (db *merkleDB) VerifyChangeProof( // Invalidates and removes any child views that aren't [exception]. // Assumes [db.lock] is held. -func (db *merkleDB) invalidateChildrenExcept(exception *trieView) { +func (db *merkleDB) invalidateChildrenExcept(exception *view) { isTrackedView := false for _, childView := range db.childViews { @@ -1169,7 +1154,7 @@ func (db *merkleDB) invalidateChildrenExcept(exception *trieView) { isTrackedView = true } } - db.childViews = make([]*trieView, 0, defaultPreallocationSize) + db.childViews = make([]*view, 0, defaultPreallocationSize) if isTrackedView { db.childViews = append(db.childViews, exception) } @@ -1217,24 +1202,21 @@ func (db *merkleDB) initializeRoot() error { // If [start] is Nothing, there's no lower bound on the range. // If [end] is Nothing, there's no upper bound on the range. // Assumes [db.commitLock] is read locked. -func (db *merkleDB) getHistoricalViewForRange( +func (db *merkleDB) getTrieAtRootForRange( rootID ids.ID, start maybe.Maybe[[]byte], end maybe.Maybe[[]byte], -) (*trieView, error) { - currentRootID := db.getMerkleRoot() - +) (Trie, error) { // looking for the trie's current root id, so return the trie unmodified - if currentRootID == rootID { - // create an empty trie - return newTrieView(db, db, ViewChanges{}) + if rootID == db.getMerkleRoot() { + return db, nil } changeHistory, err := db.history.getChangesToGetToRoot(rootID, start, end) if err != nil { return nil, err } - return newHistoricalTrieView(db, changeHistory) + return newViewWithChanges(db, changeHistory) } // Returns all keys in range [start, end] that aren't in [keySet]. @@ -1294,6 +1276,7 @@ func (db *merkleDB) getNode(key Key, hasValue bool) (*node, error) { } } +// Assumes [db.lock] or [db.commitLock] is read locked. func (db *merkleDB) getRoot() maybe.Maybe[*node] { return db.root } @@ -1327,6 +1310,10 @@ func (db *merkleDB) Clear() error { return nil } +func (db *merkleDB) getTokenSize() int { + return db.tokenSize +} + // Returns [key] prefixed by [prefix]. // The returned []byte is taken from [bufferPool] and // should be returned to it when the caller is done with it. diff --git a/x/merkledb/db_test.go b/x/merkledb/db_test.go index e14149ae1471..06f42105e4f6 100644 --- a/x/merkledb/db_test.go +++ b/x/merkledb/db_test.go @@ -297,15 +297,15 @@ func Test_MerkleDB_Invalidate_Siblings_On_Commit(t *testing.T) { sibling2, err := dbTrie.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.False(sibling1.(*trieView).isInvalid()) - require.False(sibling2.(*trieView).isInvalid()) + require.False(sibling1.(*view).isInvalid()) + require.False(sibling2.(*view).isInvalid()) // Committing viewToCommit should invalidate siblings require.NoError(viewToCommit.CommitToDB(context.Background())) - require.True(sibling1.(*trieView).isInvalid()) - require.True(sibling2.(*trieView).isInvalid()) - require.False(viewToCommit.(*trieView).isInvalid()) + require.True(sibling1.(*view).isInvalid()) + require.True(sibling2.(*view).isInvalid()) + require.False(viewToCommit.(*view).isInvalid()) } func Test_MerkleDB_CommitRangeProof_DeletesValuesInRange(t *testing.T) { @@ -501,7 +501,7 @@ func TestDatabaseNewUntrackedView(t *testing.T) { require.NoError(err) // Create a new untracked view. - view, err := newTrieView( + view, err := newView( db, db, ViewChanges{ @@ -561,7 +561,7 @@ func TestDatabaseCommitChanges(t *testing.T) { // Committing an invalid view should fail. invalidView, err := db.NewView(context.Background(), ViewChanges{}) require.NoError(err) - invalidView.(*trieView).invalidate() + invalidView.(*view).invalidate() err = invalidView.CommitToDB(context.Background()) require.ErrorIs(err, ErrInvalid) @@ -582,22 +582,22 @@ func TestDatabaseCommitChanges(t *testing.T) { }, ) require.NoError(err) - require.IsType(&trieView{}, view1Intf) - view1 := view1Intf.(*trieView) + require.IsType(&view{}, view1Intf) + view1 := view1Intf.(*view) view1Root, err := view1.GetMerkleRoot(context.Background()) require.NoError(err) // Make a second view view2Intf, err := db.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view2Intf) - view2 := view2Intf.(*trieView) + require.IsType(&view{}, view2Intf) + view2 := view2Intf.(*view) // Make a view atop a view view3Intf, err := view1.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view3Intf) - view3 := view3Intf.(*trieView) + require.IsType(&view{}, view3Intf) + view3 := view3Intf.(*view) // view3 // | @@ -646,18 +646,18 @@ func TestDatabaseInvalidateChildrenExcept(t *testing.T) { // Create children view1Intf, err := db.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view1Intf) - view1 := view1Intf.(*trieView) + require.IsType(&view{}, view1Intf) + view1 := view1Intf.(*view) view2Intf, err := db.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view2Intf) - view2 := view2Intf.(*trieView) + require.IsType(&view{}, view2Intf) + view2 := view2Intf.(*view) view3Intf, err := db.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view3Intf) - view3 := view3Intf.(*trieView) + require.IsType(&view{}, view3Intf) + view3 := view3Intf.(*view) db.invalidateChildrenExcept(view1) @@ -1255,7 +1255,7 @@ func TestGetRangeProofAtRootEmptyRootID(t *testing.T) { db, err := getBasicDB() require.NoError(err) - _, err = db.getRangeProofAtRoot( + _, err = db.GetRangeProofAtRoot( context.Background(), ids.Empty, maybe.Nothing[[]byte](), diff --git a/x/merkledb/mock_db.go b/x/merkledb/mock_db.go index e07354e6b3e8..faca3d9c00cf 100644 --- a/x/merkledb/mock_db.go +++ b/x/merkledb/mock_db.go @@ -5,452 +5,495 @@ package merkledb import ( - reflect "reflect" - context "context" - database "github.com/ava-labs/avalanchego/database" - ids "github.com/ava-labs/avalanchego/ids" - maybe "github.com/ava-labs/avalanchego/utils/maybe" - gomock "go.uber.org/mock/gomock" + context "context" + database "github.com/ava-labs/avalanchego/database" + ids "github.com/ava-labs/avalanchego/ids" + maybe "github.com/ava-labs/avalanchego/utils/maybe" + gomock "go.uber.org/mock/gomock" + reflect "reflect" ) // MockMerkleDB is a mock of MerkleDB interface. type MockMerkleDB struct { - ctrl *gomock.Controller - recorder *MockMerkleDBMockRecorder + ctrl *gomock.Controller + recorder *MockMerkleDBMockRecorder } // MockMerkleDBMockRecorder is the mock recorder for MockMerkleDB. type MockMerkleDBMockRecorder struct { - mock *MockMerkleDB + mock *MockMerkleDB } // NewMockMerkleDB creates a new mock instance. func NewMockMerkleDB(ctrl *gomock.Controller) *MockMerkleDB { - mock := &MockMerkleDB{ctrl: ctrl} - mock.recorder = &MockMerkleDBMockRecorder{mock} - return mock + mock := &MockMerkleDB{ctrl: ctrl} + mock.recorder = &MockMerkleDBMockRecorder{mock} + return mock } // EXPECT returns an object that allows the caller to indicate expected use. func (m *MockMerkleDB) EXPECT() *MockMerkleDBMockRecorder { - return m.recorder + return m.recorder } // Clear mocks base method. func (m *MockMerkleDB) Clear() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Clear") - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Clear") + ret0, _ := ret[0].(error) + return ret0 } // Clear indicates an expected call of Clear. func (mr *MockMerkleDBMockRecorder) Clear() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clear", reflect.TypeOf((*MockMerkleDB)(nil).Clear)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Clear", reflect.TypeOf((*MockMerkleDB)(nil).Clear)) } // Close mocks base method. func (m *MockMerkleDB) Close() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 } // Close indicates an expected call of Close. func (mr *MockMerkleDBMockRecorder) Close() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockMerkleDB)(nil).Close)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockMerkleDB)(nil).Close)) } // CommitChangeProof mocks base method. func (m *MockMerkleDB) CommitChangeProof(arg0 context.Context, arg1 *ChangeProof) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CommitChangeProof", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CommitChangeProof", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // CommitChangeProof indicates an expected call of CommitChangeProof. func (mr *MockMerkleDBMockRecorder) CommitChangeProof(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitChangeProof), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitChangeProof), arg0, arg1) } // CommitRangeProof mocks base method. func (m *MockMerkleDB) CommitRangeProof(arg0 context.Context, arg1, arg2 maybe.Maybe[[]uint8], arg3 *RangeProof) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CommitRangeProof", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CommitRangeProof", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(error) + return ret0 } // CommitRangeProof indicates an expected call of CommitRangeProof. func (mr *MockMerkleDBMockRecorder) CommitRangeProof(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitRangeProof), arg0, arg1, arg2, arg3) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitRangeProof), arg0, arg1, arg2, arg3) } // Compact mocks base method. func (m *MockMerkleDB) Compact(arg0, arg1 []byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Compact", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Compact", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // Compact indicates an expected call of Compact. func (mr *MockMerkleDBMockRecorder) Compact(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Compact", reflect.TypeOf((*MockMerkleDB)(nil).Compact), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Compact", reflect.TypeOf((*MockMerkleDB)(nil).Compact), arg0, arg1) } // Delete mocks base method. func (m *MockMerkleDB) Delete(arg0 []byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(error) + return ret0 } // Delete indicates an expected call of Delete. func (mr *MockMerkleDBMockRecorder) Delete(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockMerkleDB)(nil).Delete), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockMerkleDB)(nil).Delete), arg0) } // Get mocks base method. func (m *MockMerkleDB) Get(arg0 []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 } // Get indicates an expected call of Get. func (mr *MockMerkleDBMockRecorder) Get(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMerkleDB)(nil).Get), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMerkleDB)(nil).Get), arg0) } // GetChangeProof mocks base method. func (m *MockMerkleDB) GetChangeProof(arg0 context.Context, arg1, arg2 ids.ID, arg3, arg4 maybe.Maybe[[]uint8], arg5 int) (*ChangeProof, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChangeProof", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].(*ChangeProof) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetChangeProof", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(*ChangeProof) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetChangeProof indicates an expected call of GetChangeProof. func (mr *MockMerkleDBMockRecorder) GetChangeProof(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetChangeProof), arg0, arg1, arg2, arg3, arg4, arg5) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetChangeProof), arg0, arg1, arg2, arg3, arg4, arg5) } // GetMerkleRoot mocks base method. func (m *MockMerkleDB) GetMerkleRoot(arg0 context.Context) (ids.ID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMerkleRoot", arg0) - ret0, _ := ret[0].(ids.ID) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMerkleRoot", arg0) + ret0, _ := ret[0].(ids.ID) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetMerkleRoot indicates an expected call of GetMerkleRoot. func (mr *MockMerkleDBMockRecorder) GetMerkleRoot(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMerkleRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetMerkleRoot), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMerkleRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetMerkleRoot), arg0) } // GetProof mocks base method. func (m *MockMerkleDB) GetProof(arg0 context.Context, arg1 []byte) (*Proof, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProof", arg0, arg1) - ret0, _ := ret[0].(*Proof) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetProof", arg0, arg1) + ret0, _ := ret[0].(*Proof) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetProof indicates an expected call of GetProof. func (mr *MockMerkleDBMockRecorder) GetProof(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProof", reflect.TypeOf((*MockMerkleDB)(nil).GetProof), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProof", reflect.TypeOf((*MockMerkleDB)(nil).GetProof), arg0, arg1) } // GetRangeProof mocks base method. func (m *MockMerkleDB) GetRangeProof(arg0 context.Context, arg1, arg2 maybe.Maybe[[]uint8], arg3 int) (*RangeProof, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRangeProof", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(*RangeProof) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRangeProof", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(*RangeProof) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetRangeProof indicates an expected call of GetRangeProof. func (mr *MockMerkleDBMockRecorder) GetRangeProof(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProof), arg0, arg1, arg2, arg3) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProof), arg0, arg1, arg2, arg3) } // GetRangeProofAtRoot mocks base method. func (m *MockMerkleDB) GetRangeProofAtRoot(arg0 context.Context, arg1 ids.ID, arg2, arg3 maybe.Maybe[[]uint8], arg4 int) (*RangeProof, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRangeProofAtRoot", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(*RangeProof) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRangeProofAtRoot", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(*RangeProof) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetRangeProofAtRoot indicates an expected call of GetRangeProofAtRoot. func (mr *MockMerkleDBMockRecorder) GetRangeProofAtRoot(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProofAtRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProofAtRoot), arg0, arg1, arg2, arg3, arg4) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProofAtRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProofAtRoot), arg0, arg1, arg2, arg3, arg4) } // GetValue mocks base method. func (m *MockMerkleDB) GetValue(arg0 context.Context, arg1 []byte) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValue", arg0, arg1) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValue", arg0, arg1) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetValue indicates an expected call of GetValue. func (mr *MockMerkleDBMockRecorder) GetValue(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValue", reflect.TypeOf((*MockMerkleDB)(nil).GetValue), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValue", reflect.TypeOf((*MockMerkleDB)(nil).GetValue), arg0, arg1) } // GetValues mocks base method. func (m *MockMerkleDB) GetValues(arg0 context.Context, arg1 [][]byte) ([][]byte, []error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValues", arg0, arg1) - ret0, _ := ret[0].([][]byte) - ret1, _ := ret[1].([]error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValues", arg0, arg1) + ret0, _ := ret[0].([][]byte) + ret1, _ := ret[1].([]error) + return ret0, ret1 } // GetValues indicates an expected call of GetValues. func (mr *MockMerkleDBMockRecorder) GetValues(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValues", reflect.TypeOf((*MockMerkleDB)(nil).GetValues), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValues", reflect.TypeOf((*MockMerkleDB)(nil).GetValues), arg0, arg1) } // Has mocks base method. func (m *MockMerkleDB) Has(arg0 []byte) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Has", arg0) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Has", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 } // Has indicates an expected call of Has. func (mr *MockMerkleDBMockRecorder) Has(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMerkleDB)(nil).Has), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMerkleDB)(nil).Has), arg0) } // HealthCheck mocks base method. func (m *MockMerkleDB) HealthCheck(arg0 context.Context) (interface{}, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HealthCheck", arg0) - ret0, _ := ret[0].(interface{}) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HealthCheck", arg0) + ret0, _ := ret[0].(interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 } // HealthCheck indicates an expected call of HealthCheck. func (mr *MockMerkleDBMockRecorder) HealthCheck(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockMerkleDB)(nil).HealthCheck), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockMerkleDB)(nil).HealthCheck), arg0) } // NewBatch mocks base method. func (m *MockMerkleDB) NewBatch() database.Batch { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewBatch") - ret0, _ := ret[0].(database.Batch) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewBatch") + ret0, _ := ret[0].(database.Batch) + return ret0 } // NewBatch indicates an expected call of NewBatch. func (mr *MockMerkleDBMockRecorder) NewBatch() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBatch", reflect.TypeOf((*MockMerkleDB)(nil).NewBatch)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBatch", reflect.TypeOf((*MockMerkleDB)(nil).NewBatch)) } // NewIterator mocks base method. func (m *MockMerkleDB) NewIterator() database.Iterator { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIterator") - ret0, _ := ret[0].(database.Iterator) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewIterator") + ret0, _ := ret[0].(database.Iterator) + return ret0 } // NewIterator indicates an expected call of NewIterator. func (mr *MockMerkleDBMockRecorder) NewIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIterator", reflect.TypeOf((*MockMerkleDB)(nil).NewIterator)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIterator", reflect.TypeOf((*MockMerkleDB)(nil).NewIterator)) } // NewIteratorWithPrefix mocks base method. func (m *MockMerkleDB) NewIteratorWithPrefix(arg0 []byte) database.Iterator { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithPrefix", arg0) - ret0, _ := ret[0].(database.Iterator) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewIteratorWithPrefix", arg0) + ret0, _ := ret[0].(database.Iterator) + return ret0 } // NewIteratorWithPrefix indicates an expected call of NewIteratorWithPrefix. func (mr *MockMerkleDBMockRecorder) NewIteratorWithPrefix(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithPrefix), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithPrefix), arg0) } // NewIteratorWithStart mocks base method. func (m *MockMerkleDB) NewIteratorWithStart(arg0 []byte) database.Iterator { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithStart", arg0) - ret0, _ := ret[0].(database.Iterator) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewIteratorWithStart", arg0) + ret0, _ := ret[0].(database.Iterator) + return ret0 } // NewIteratorWithStart indicates an expected call of NewIteratorWithStart. func (mr *MockMerkleDBMockRecorder) NewIteratorWithStart(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStart", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStart), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStart", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStart), arg0) } // NewIteratorWithStartAndPrefix mocks base method. func (m *MockMerkleDB) NewIteratorWithStartAndPrefix(arg0, arg1 []byte) database.Iterator { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithStartAndPrefix", arg0, arg1) - ret0, _ := ret[0].(database.Iterator) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewIteratorWithStartAndPrefix", arg0, arg1) + ret0, _ := ret[0].(database.Iterator) + return ret0 } // NewIteratorWithStartAndPrefix indicates an expected call of NewIteratorWithStartAndPrefix. func (mr *MockMerkleDBMockRecorder) NewIteratorWithStartAndPrefix(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStartAndPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStartAndPrefix), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStartAndPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStartAndPrefix), arg0, arg1) } // NewView mocks base method. -func (m *MockMerkleDB) NewView(arg0 context.Context, arg1 ViewChanges) (TrieView, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewView", arg0, arg1) - ret0, _ := ret[0].(TrieView) - ret1, _ := ret[1].(error) - return ret0, ret1 +func (m *MockMerkleDB) NewView(arg0 context.Context, arg1 ViewChanges) (View, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewView", arg0, arg1) + ret0, _ := ret[0].(View) + ret1, _ := ret[1].(error) + return ret0, ret1 } // NewView indicates an expected call of NewView. func (mr *MockMerkleDBMockRecorder) NewView(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewView", reflect.TypeOf((*MockMerkleDB)(nil).NewView), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewView", reflect.TypeOf((*MockMerkleDB)(nil).NewView), arg0, arg1) } // PrefetchPath mocks base method. func (m *MockMerkleDB) PrefetchPath(arg0 []byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PrefetchPath", arg0) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrefetchPath", arg0) + ret0, _ := ret[0].(error) + return ret0 } // PrefetchPath indicates an expected call of PrefetchPath. func (mr *MockMerkleDBMockRecorder) PrefetchPath(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPath", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPath), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPath", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPath), arg0) } // PrefetchPaths mocks base method. func (m *MockMerkleDB) PrefetchPaths(arg0 [][]byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PrefetchPaths", arg0) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrefetchPaths", arg0) + ret0, _ := ret[0].(error) + return ret0 } // PrefetchPaths indicates an expected call of PrefetchPaths. func (mr *MockMerkleDBMockRecorder) PrefetchPaths(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPaths", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPaths), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPaths", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPaths), arg0) } // Put mocks base method. func (m *MockMerkleDB) Put(arg0, arg1 []byte) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Put", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Put", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // Put indicates an expected call of Put. func (mr *MockMerkleDBMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockMerkleDB)(nil).Put), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockMerkleDB)(nil).Put), arg0, arg1) } // VerifyChangeProof mocks base method. func (m *MockMerkleDB) VerifyChangeProof(arg0 context.Context, arg1 *ChangeProof, arg2, arg3 maybe.Maybe[[]uint8], arg4 ids.ID) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VerifyChangeProof", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VerifyChangeProof", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(error) + return ret0 } // VerifyChangeProof indicates an expected call of VerifyChangeProof. func (mr *MockMerkleDBMockRecorder) VerifyChangeProof(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).VerifyChangeProof), arg0, arg1, arg2, arg3, arg4) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).VerifyChangeProof), arg0, arg1, arg2, arg3, arg4) } // getEditableNode mocks base method. func (m *MockMerkleDB) getEditableNode(arg0 Key, arg1 bool) (*node, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getEditableNode", arg0, arg1) - ret0, _ := ret[0].(*node) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getEditableNode", arg0, arg1) + ret0, _ := ret[0].(*node) + ret1, _ := ret[1].(error) + return ret0, ret1 } // getEditableNode indicates an expected call of getEditableNode. func (mr *MockMerkleDBMockRecorder) getEditableNode(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getEditableNode", reflect.TypeOf((*MockMerkleDB)(nil).getEditableNode), arg0, arg1) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getEditableNode", reflect.TypeOf((*MockMerkleDB)(nil).getEditableNode), arg0, arg1) } // getRoot mocks base method. func (m *MockMerkleDB) getRoot() maybe.Maybe[*node] { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getRoot") - ret0, _ := ret[0].(maybe.Maybe[*node]) - return ret0 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getRoot") + ret0, _ := ret[0].(maybe.Maybe[*node]) + return ret0 } // getRoot indicates an expected call of getRoot. func (mr *MockMerkleDBMockRecorder) getRoot() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getRoot", reflect.TypeOf((*MockMerkleDB)(nil).getRoot)) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getRoot", reflect.TypeOf((*MockMerkleDB)(nil).getRoot)) +} + +// getNode mocks base method. +func (m *MockMerkleDB) getNode(arg0 Key, arg1 bool) (*node, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getNode", arg0, arg1) + ret0, _ := ret[0].(*node) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// getNode indicates an expected call of getNode. +func (mr *MockMerkleDBMockRecorder) getNode(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getNode", reflect.TypeOf((*MockMerkleDB)(nil).getNode), arg0, arg1) +} + +// getSentinelNode mocks base method. +func (m *MockMerkleDB) getSentinelNode() *node { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getSentinelNode") + ret0, _ := ret[0].(*node) + return ret0 +} + +// getSentinelNode indicates an expected call of getSentinelNode. +func (mr *MockMerkleDBMockRecorder) getSentinelNode() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getSentinelNode", reflect.TypeOf((*MockMerkleDB)(nil).getSentinelNode)) +} + +// getTokenSize mocks base method. +func (m *MockMerkleDB) getTokenSize() int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getTokenSize") + ret0, _ := ret[0].(int) + return ret0 +} + +// getTokenSize indicates an expected call of getTokenSize. +func (mr *MockMerkleDBMockRecorder) getTokenSize() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getTokenSize", reflect.TypeOf((*MockMerkleDB)(nil).getTokenSize)) } // getValue mocks base method. func (m *MockMerkleDB) getValue(arg0 Key) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getValue", arg0) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "getValue", arg0) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 } // getValue indicates an expected call of getValue. func (mr *MockMerkleDBMockRecorder) getValue(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getValue", reflect.TypeOf((*MockMerkleDB)(nil).getValue), arg0) + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getValue", reflect.TypeOf((*MockMerkleDB)(nil).getValue), arg0) } diff --git a/x/merkledb/proof.go b/x/merkledb/proof.go index 940c172deecf..c49cd6bab679 100644 --- a/x/merkledb/proof.go +++ b/x/merkledb/proof.go @@ -169,7 +169,7 @@ func (proof *Proof) Verify(ctx context.Context, expectedRootID ids.ID, tokenSize } // Don't bother locking [view] -- nobody else has a reference to it. - view, err := getStandaloneTrieView(ctx, nil, tokenSize) + view, err := getStandaloneView(ctx, nil, tokenSize) if err != nil { return err } @@ -360,7 +360,7 @@ func (proof *RangeProof) Verify( } // Don't need to lock [view] because nobody else has a reference to it. - view, err := getStandaloneTrieView(ctx, ops, tokenSize) + view, err := getStandaloneView(ctx, ops, tokenSize) if err != nil { return err } @@ -794,9 +794,9 @@ func valueOrHashMatches(value maybe.Maybe[[]byte], valueOrHash maybe.Maybe[[]byt // < [insertChildrenLessThan] or > [insertChildrenGreaterThan]. // If [insertChildrenLessThan] is Nothing, no children are < [insertChildrenLessThan]. // If [insertChildrenGreaterThan] is Nothing, no children are > [insertChildrenGreaterThan]. -// Assumes [t.lock] is held. +// Assumes [v.lock] is held. func addPathInfo( - t *trieView, + v *view, proofPath []ProofNode, insertChildrenLessThan maybe.Maybe[Key], insertChildrenGreaterThan maybe.Maybe[Key], @@ -816,7 +816,7 @@ func addPathInfo( // load the node associated with the key or create a new one // pass nothing because we are going to overwrite the value digest below - n, err := t.insert(key, maybe.Nothing[[]byte]()) + n, err := v.insert(key, maybe.Nothing[[]byte]()) if err != nil { return err } @@ -837,7 +837,7 @@ func addPathInfo( if existingChild, ok := n.children[index]; ok { compressedKey = existingChild.compressedKey } - childKey := key.Extend(ToToken(index, t.tokenSize), compressedKey) + childKey := key.Extend(ToToken(index, v.tokenSize), compressedKey) if (shouldInsertLeftChildren && childKey.Less(insertChildrenLessThan.Value())) || (shouldInsertRightChildren && childKey.Greater(insertChildrenGreaterThan.Value())) { // We didn't set the other values on the child entry, but it doesn't matter. @@ -855,8 +855,8 @@ func addPathInfo( return nil } -// getStandaloneTrieView returns a new view that has nothing in it besides the changes due to [ops] -func getStandaloneTrieView(ctx context.Context, ops []database.BatchOp, size int) (*trieView, error) { +// getStandaloneView returns a new view that has nothing in it besides the changes due to [ops] +func getStandaloneView(ctx context.Context, ops []database.BatchOp, size int) (*view, error) { db, err := newDatabase( ctx, memdb.New(), @@ -873,5 +873,5 @@ func getStandaloneTrieView(ctx context.Context, ops []database.BatchOp, size int return nil, err } - return newTrieView(db, db, ViewChanges{BatchOps: ops, ConsumeBytes: true}) + return newView(db, db, ViewChanges{BatchOps: ops, ConsumeBytes: true}) } diff --git a/x/merkledb/trie.go b/x/merkledb/trie.go index 1e6870df27cb..0feeecdbfac2 100644 --- a/x/merkledb/trie.go +++ b/x/merkledb/trie.go @@ -4,13 +4,25 @@ package merkledb import ( + "bytes" "context" + "fmt" + + "golang.org/x/exp/slices" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/maybe" ) +type ViewChanges struct { + BatchOps []database.BatchOp + MapOps map[string]maybe.Maybe[[]byte] + // ConsumeBytes when set to true will skip copying of bytes and assume + // ownership of the provided bytes. + ConsumeBytes bool +} + type MerkleRootGetter interface { // GetMerkleRoot returns the merkle root of the trie. // Returns ids.Empty if the trie is empty. @@ -24,9 +36,31 @@ type ProofGetter interface { GetProof(ctx context.Context, keyBytes []byte) (*Proof, error) } -type ReadOnlyTrie interface { +type trieInternals interface { + // get the value associated with the key in path form + // database.ErrNotFound if the key is not present + getValue(key Key) ([]byte, error) + + // get an editable copy of the node with the given key path + // hasValue indicates which db to look in (value or intermediate) + getEditableNode(key Key, hasValue bool) (*node, error) + + // get the node associated with the key without locking + getNode(key Key, hasValue bool) (*node, error) + + // If this trie is non-empty, returns the root node. + // Must be copied before modification. + // Otherwise returns Nothing. + getRoot() maybe.Maybe[*node] + + getTokenSize() int +} + +type Trie interface { + trieInternals MerkleRootGetter ProofGetter + database.Iteratee // GetValue gets the value associated with the specified key // database.ErrNotFound if the key is not present @@ -36,19 +70,6 @@ type ReadOnlyTrie interface { // database.ErrNotFound if the key is not present GetValues(ctx context.Context, keys [][]byte) ([][]byte, []error) - // get the value associated with the key in path form - // database.ErrNotFound if the key is not present - getValue(key Key) ([]byte, error) - - // If this trie is non-empty, returns the root node. - // Must be copied before modification. - // Otherwise returns Nothing. - getRoot() maybe.Maybe[*node] - - // get an editable copy of the node with the given key path - // hasValue indicates which db to look in (value or intermediate) - getEditableNode(key Key, hasValue bool) (*node, error) - // GetRangeProof returns a proof of up to [maxLength] key-value pairs with // keys in range [start, end]. // If [start] is Nothing, there's no lower bound on the range. @@ -56,32 +77,195 @@ type ReadOnlyTrie interface { // Returns ErrEmptyProof if the trie is empty. GetRangeProof(ctx context.Context, start maybe.Maybe[[]byte], end maybe.Maybe[[]byte], maxLength int) (*RangeProof, error) - database.Iteratee -} - -type ViewChanges struct { - BatchOps []database.BatchOp - MapOps map[string]maybe.Maybe[[]byte] - // ConsumeBytes when set to true will skip copying of bytes and assume - // ownership of the provided bytes. - ConsumeBytes bool -} - -type Trie interface { - ReadOnlyTrie - // NewView returns a new view on top of this Trie where the passed changes // have been applied. NewView( ctx context.Context, changes ViewChanges, - ) (TrieView, error) + ) (View, error) } -type TrieView interface { +type View interface { Trie // CommitToDB writes the changes in this view to the database. // Takes the DB commit lock. CommitToDB(ctx context.Context) error } + +// Returns the nodes along the path to [key]. +// The first node is the root, and the last node is either the node with the +// given [key], if it's in the trie, or the node with the largest prefix of +// the [key] if it isn't in the trie. +// Always returns at least the root node. +// Assumes [t] doesn't change while this function is running. +func visitPathToKey(t Trie, key Key, visitNode func(*node) error) error { + maybeRoot := t.getRoot() + if maybeRoot.IsNothing() { + return nil + } + root := maybeRoot.Value() + if !key.HasPrefix(root.key) { + return nil + } + var ( + // all node paths start at the root + currentNode = root + tokenSize = t.getTokenSize() + err error + ) + if err := visitNode(currentNode); err != nil { + return err + } + // while the entire path hasn't been matched + for currentNode.key.length < key.length { + // confirm that a child exists and grab its ID before attempting to load it + nextChildEntry, hasChild := currentNode.children[key.Token(currentNode.key.length, tokenSize)] + + if !hasChild || !key.iteratedHasPrefix(nextChildEntry.compressedKey, currentNode.key.length+tokenSize, tokenSize) { + // there was no child along the path or the child that was there doesn't match the remaining path + return nil + } + // grab the next node along the path + currentNode, err = t.getNode(key.Take(currentNode.key.length+tokenSize+nextChildEntry.compressedKey.length), nextChildEntry.hasValue) + if err != nil { + return err + } + if err := visitNode(currentNode); err != nil { + return err + } + } + return nil +} + +// Returns a proof that [bytesPath] is in or not in trie [t]. +// Assumes [t] doesn't change while this function is running. +func getProof(t Trie, key []byte) (*Proof, error) { + root := t.getRoot() + if root.IsNothing() { + return nil, ErrEmptyProof + } + + proof := &Proof{ + Key: ToKey(key), + } + + var closestNode *node + if err := visitPathToKey(t, proof.Key, func(n *node) error { + closestNode = n + // From root --> node from left --> right. + proof.Path = append(proof.Path, n.asProofNode()) + return nil + }); err != nil { + return nil, err + } + + if len(proof.Path) == 0 { + // No key in [t] is a prefix of [key]. + // The root alone proves that [key] isn't in [t]. + proof.Path = append(proof.Path, root.Value().asProofNode()) + return proof, nil + } + + if closestNode.key == proof.Key { + // There is a node with the given [key]. + proof.Value = maybe.Bind(closestNode.value, slices.Clone[[]byte]) + return proof, nil + } + + // There is no node with the given [key]. + // If there is a child at the index where the node would be + // if it existed, include that child in the proof. + nextIndex := proof.Key.Token(closestNode.key.length, t.getTokenSize()) + child, ok := closestNode.children[nextIndex] + if !ok { + return proof, nil + } + + childNode, err := t.getNode( + closestNode.key.Extend(ToToken(nextIndex, t.getTokenSize()), child.compressedKey), + child.hasValue, + ) + if err != nil { + return nil, err + } + proof.Path = append(proof.Path, childNode.asProofNode()) + return proof, nil +} + +// GetRangeProof returns a range proof for (at least part of) the key range [start, end]. +// The returned proof's [KeyValues] has at most [maxLength] values. +// [maxLength] must be > 0. +// Assumes [t] doesn't change while this function is running. +func getRangeProof( + t Trie, + start maybe.Maybe[[]byte], + end maybe.Maybe[[]byte], + maxLength int, +) (*RangeProof, error) { + switch { + case start.HasValue() && end.HasValue() && bytes.Compare(start.Value(), end.Value()) == 1: + return nil, ErrStartAfterEnd + case maxLength <= 0: + return nil, fmt.Errorf("%w but was %d", ErrInvalidMaxLength, maxLength) + case t.getRoot().IsNothing(): + return nil, ErrEmptyProof + } + + result := RangeProof{ + KeyValues: make([]KeyValue, 0, initKeyValuesSize), + } + it := t.NewIteratorWithStart(start.Value()) + for it.Next() && len(result.KeyValues) < maxLength && (end.IsNothing() || bytes.Compare(it.Key(), end.Value()) <= 0) { + // clone the value to prevent editing of the values stored within the trie + result.KeyValues = append(result.KeyValues, KeyValue{ + Key: it.Key(), + Value: slices.Clone(it.Value()), + }) + } + it.Release() + if err := it.Error(); err != nil { + return nil, err + } + + // This proof may not contain all key-value pairs in [start, end] due to size limitations. + // The end proof we provide should be for the last key-value pair in the proof, not for + // the last key-value pair requested, which may not be in this proof. + var ( + endProof *Proof + err error + ) + if len(result.KeyValues) > 0 { + greatestKey := result.KeyValues[len(result.KeyValues)-1].Key + endProof, err = getProof(t, greatestKey) + if err != nil { + return nil, err + } + } else if end.HasValue() { + endProof, err = getProof(t, end.Value()) + if err != nil { + return nil, err + } + } + if endProof != nil { + result.EndProof = endProof.Path + } + + if start.HasValue() { + startProof, err := getProof(t, start.Value()) + if err != nil { + return nil, err + } + result.StartProof = startProof.Path + + // strip out any common nodes to reduce proof size + i := 0 + for ; i < len(result.StartProof) && + i < len(result.EndProof) && + result.StartProof[i].Key == result.EndProof[i].Key; i++ { + } + result.StartProof = result.StartProof[i:] + } + + return &result, nil +} diff --git a/x/merkledb/trie_test.go b/x/merkledb/trie_test.go index fec8a435d60a..223822aa611e 100644 --- a/x/merkledb/trie_test.go +++ b/x/merkledb/trie_test.go @@ -18,25 +18,17 @@ import ( "github.com/ava-labs/avalanchego/utils/hashing" ) -func getNodeValue(t ReadOnlyTrie, key string) ([]byte, error) { - var view *trieView - if asTrieView, ok := t.(*trieView); ok { - if err := asTrieView.calculateNodeIDs(context.Background()); err != nil { - return nil, err - } - view = asTrieView - } - if asDatabases, ok := t.(*merkleDB); ok { - dbView, err := asDatabases.NewView(context.Background(), ViewChanges{}) - if err != nil { +func getNodeValue(t Trie, key string) ([]byte, error) { + path := ToKey([]byte(key)) + if asView, ok := t.(*view); ok { + if err := asView.calculateNodeIDs(context.Background()); err != nil { return nil, err } - view = dbView.(*trieView) } - path := ToKey([]byte(key)) var result *node - err := view.visitPathToKey(path, func(n *node) error { + + err := visitPathToKey(t, path, func(n *node) error { result = n return nil }) @@ -56,7 +48,7 @@ func Test_GetValue_Safety(t *testing.T) { db, err := getBasicDB() require.NoError(err) - trieView, err := db.NewView( + view, err := db.NewView( context.Background(), ViewChanges{ BatchOps: []database.BatchOp{ @@ -66,13 +58,13 @@ func Test_GetValue_Safety(t *testing.T) { ) require.NoError(err) - trieVal, err := trieView.GetValue(context.Background(), []byte{0}) + trieVal, err := view.GetValue(context.Background(), []byte{0}) require.NoError(err) require.Equal([]byte{0}, trieVal) trieVal[0] = 1 // should still be []byte{0} after edit - trieVal, err = trieView.GetValue(context.Background(), []byte{0}) + trieVal, err = view.GetValue(context.Background(), []byte{0}) require.NoError(err) require.Equal([]byte{0}, trieVal) } @@ -83,7 +75,7 @@ func Test_GetValues_Safety(t *testing.T) { db, err := getBasicDB() require.NoError(err) - trieView, err := db.NewView( + view, err := db.NewView( context.Background(), ViewChanges{ BatchOps: []database.BatchOp{ @@ -93,7 +85,7 @@ func Test_GetValues_Safety(t *testing.T) { ) require.NoError(err) - trieVals, errs := trieView.GetValues(context.Background(), [][]byte{{0}}) + trieVals, errs := view.GetValues(context.Background(), [][]byte{{0}}) require.Len(errs, 1) require.NoError(errs[0]) require.Equal([]byte{0}, trieVals[0]) @@ -101,13 +93,13 @@ func Test_GetValues_Safety(t *testing.T) { require.Equal([]byte{1}, trieVals[0]) // should still be []byte{0} after edit - trieVals, errs = trieView.GetValues(context.Background(), [][]byte{{0}}) + trieVals, errs = view.GetValues(context.Background(), [][]byte{{0}}) require.Len(errs, 1) require.NoError(errs[0]) require.Equal([]byte{0}, trieVals[0]) } -func TestTrieViewVisitPathToKey(t *testing.T) { +func TestVisitPathToKey(t *testing.T) { require := require.New(t) db, err := getBasicDB() @@ -115,11 +107,11 @@ func TestTrieViewVisitPathToKey(t *testing.T) { trieIntf, err := db.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, trieIntf) - trie := trieIntf.(*trieView) + require.IsType(&view{}, trieIntf) + trie := trieIntf.(*view) var nodePath []*node - require.NoError(trie.visitPathToKey(ToKey(nil), func(n *node) error { + require.NoError(visitPathToKey(trie, ToKey(nil), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -137,12 +129,12 @@ func TestTrieViewVisitPathToKey(t *testing.T) { }, ) require.NoError(err) - require.IsType(&trieView{}, trieIntf) - trie = trieIntf.(*trieView) + require.IsType(&view{}, trieIntf) + trie = trieIntf.(*view) require.NoError(trie.calculateNodeIDs(context.Background())) nodePath = make([]*node, 0, 1) - require.NoError(trie.visitPathToKey(ToKey(key1), func(n *node) error { + require.NoError(visitPathToKey(trie, ToKey(key1), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -162,12 +154,12 @@ func TestTrieViewVisitPathToKey(t *testing.T) { }, ) require.NoError(err) - require.IsType(&trieView{}, trieIntf) - trie = trieIntf.(*trieView) + require.IsType(&view{}, trieIntf) + trie = trieIntf.(*view) require.NoError(trie.calculateNodeIDs(context.Background())) nodePath = make([]*node, 0, 2) - require.NoError(trie.visitPathToKey(ToKey(key2), func(n *node) error { + require.NoError(visitPathToKey(trie, ToKey(key2), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -191,8 +183,8 @@ func TestTrieViewVisitPathToKey(t *testing.T) { }, ) require.NoError(err) - require.IsType(&trieView{}, trieIntf) - trie = trieIntf.(*trieView) + require.IsType(&view{}, trieIntf) + trie = trieIntf.(*view) require.NoError(trie.calculateNodeIDs(context.Background())) // Trie is: @@ -202,7 +194,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { // | // [0,1] nodePath = make([]*node, 0, 2) - require.NoError(trie.visitPathToKey(ToKey(key3), func(n *node) error { + require.NoError(visitPathToKey(trie, ToKey(key3), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -214,7 +206,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { // Other key path not affected nodePath = make([]*node, 0, 3) - require.NoError(trie.visitPathToKey(ToKey(key2), func(n *node) error { + require.NoError(visitPathToKey(trie, ToKey(key2), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -226,7 +218,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { // Gets closest node when key doesn't exist key4 := []byte{0, 1, 2} nodePath = make([]*node, 0, 3) - require.NoError(trie.visitPathToKey(ToKey(key4), func(n *node) error { + require.NoError(visitPathToKey(trie, ToKey(key4), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -239,7 +231,7 @@ func TestTrieViewVisitPathToKey(t *testing.T) { // Gets just root when key doesn't exist and no key shares a prefix key5 := []byte{128} nodePath = make([]*node, 0, 1) - require.NoError(trie.visitPathToKey(ToKey(key5), func(n *node) error { + require.NoError(visitPathToKey(trie, ToKey(key5), func(n *node) error { nodePath = append(nodePath, n) return nil })) @@ -294,7 +286,7 @@ func Test_Trie_WriteToDB(t *testing.T) { trieIntf1, err := dbTrie.NewView(context.Background(), ViewChanges{}) require.NoError(err) - trie1 := trieIntf1.(*trieView) + trie1 := trieIntf1.(*view) // value hasn't been inserted so shouldn't exist value, err := trie1.GetValue(context.Background(), []byte("key")) @@ -310,7 +302,7 @@ func Test_Trie_WriteToDB(t *testing.T) { }, ) require.NoError(err) - trie2 := trieIntf2.(*trieView) + trie2 := trieIntf2.(*view) value, err = getNodeValue(trie2, "key") require.NoError(err) @@ -445,7 +437,7 @@ func Test_Trie_ExpandOnKeyPath(t *testing.T) { }, ) require.NoError(err) - trie := trieIntf.(*trieView) + trie := trieIntf.(*view) value, err := getNodeValue(trie, "key") require.NoError(err) @@ -460,7 +452,7 @@ func Test_Trie_ExpandOnKeyPath(t *testing.T) { }, ) require.NoError(err) - trie = trieIntf.(*trieView) + trie = trieIntf.(*view) value, err = getNodeValue(trie, "key") require.NoError(err) @@ -479,7 +471,7 @@ func Test_Trie_ExpandOnKeyPath(t *testing.T) { }, ) require.NoError(err) - trie = trieIntf.(*trieView) + trie = trieIntf.(*view) value, err = getNodeValue(trie, "key") require.NoError(err) @@ -509,7 +501,7 @@ func Test_Trie_CompressedKeys(t *testing.T) { }, ) require.NoError(err) - trie := trieIntf.(*trieView) + trie := trieIntf.(*view) value, err := getNodeValue(trie, "key12") require.NoError(err) @@ -524,7 +516,7 @@ func Test_Trie_CompressedKeys(t *testing.T) { }, ) require.NoError(err) - trie = trieIntf.(*trieView) + trie = trieIntf.(*view) value, err = getNodeValue(trie, "key12") require.NoError(err) @@ -543,7 +535,7 @@ func Test_Trie_CompressedKeys(t *testing.T) { }, ) require.NoError(err) - trie = trieIntf.(*trieView) + trie = trieIntf.(*view) value, err = getNodeValue(trie, "key12") require.NoError(err) @@ -783,7 +775,7 @@ func Test_Trie_ChainDeletion(t *testing.T) { ) require.NoError(err) - require.NoError(newTrie.(*trieView).calculateNodeIDs(context.Background())) + require.NoError(newTrie.(*view).calculateNodeIDs(context.Background())) maybeRoot := newTrie.getRoot() require.NoError(err) require.True(maybeRoot.HasValue()) @@ -802,7 +794,7 @@ func Test_Trie_ChainDeletion(t *testing.T) { }, ) require.NoError(err) - require.NoError(newTrie.(*trieView).calculateNodeIDs(context.Background())) + require.NoError(newTrie.(*view).calculateNodeIDs(context.Background())) // trie should be empty root := newTrie.getRoot() @@ -835,15 +827,15 @@ func Test_Trie_Invalidate_Siblings_On_Commit(t *testing.T) { sibling2, err := view1.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.False(sibling1.(*trieView).isInvalid()) - require.False(sibling2.(*trieView).isInvalid()) + require.False(sibling1.(*view).isInvalid()) + require.False(sibling2.(*view).isInvalid()) require.NoError(view1.CommitToDB(context.Background())) require.NoError(view2.CommitToDB(context.Background())) - require.True(sibling1.(*trieView).isInvalid()) - require.True(sibling2.(*trieView).isInvalid()) - require.False(view2.(*trieView).isInvalid()) + require.True(sibling1.(*view).isInvalid()) + require.True(sibling2.(*view).isInvalid()) + require.False(view2.(*view).isInvalid()) } func Test_Trie_NodeCollapse(t *testing.T) { @@ -869,7 +861,7 @@ func Test_Trie_NodeCollapse(t *testing.T) { ) require.NoError(err) - require.NoError(trie.(*trieView).calculateNodeIDs(context.Background())) + require.NoError(trie.(*view).calculateNodeIDs(context.Background())) for _, kv := range kvs { node, err := trie.getEditableNode(ToKey(kv.Key), true) @@ -896,7 +888,7 @@ func Test_Trie_NodeCollapse(t *testing.T) { ) require.NoError(err) - require.NoError(trie.(*trieView).calculateNodeIDs(context.Background())) + require.NoError(trie.(*view).calculateNodeIDs(context.Background())) for _, kv := range deletedKVs { _, err := trie.getEditableNode(ToKey(kv.Key), true) @@ -1029,8 +1021,8 @@ func TestNewViewOnCommittedView(t *testing.T) { // Create a view view1Intf, err := db.NewView(context.Background(), ViewChanges{BatchOps: []database.BatchOp{{Key: []byte{1}, Value: []byte{1}}}}) require.NoError(err) - require.IsType(&trieView{}, view1Intf) - view1 := view1Intf.(*trieView) + require.IsType(&view{}, view1Intf) + view1 := view1Intf.(*view) // view1 // | @@ -1054,8 +1046,8 @@ func TestNewViewOnCommittedView(t *testing.T) { // Create a new view on the committed view view2Intf, err := view1.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view2Intf) - view2 := view2Intf.(*trieView) + require.IsType(&view{}, view2Intf) + view2 := view2Intf.(*view) // view2 // | @@ -1076,8 +1068,8 @@ func TestNewViewOnCommittedView(t *testing.T) { // Make another view view3Intf, err := view2.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view3Intf) - view3 := view3Intf.(*trieView) + require.IsType(&view{}, view3Intf) + view3 := view3Intf.(*view) // view3 // | @@ -1122,7 +1114,7 @@ func TestNewViewOnCommittedView(t *testing.T) { require.Equal(db, view3.parentTrie) } -func Test_TrieView_NewView(t *testing.T) { +func Test_View_NewView(t *testing.T) { require := require.New(t) db, err := getBasicDB() @@ -1131,14 +1123,14 @@ func Test_TrieView_NewView(t *testing.T) { // Create a view view1Intf, err := db.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view1Intf) - view1 := view1Intf.(*trieView) + require.IsType(&view{}, view1Intf) + view1 := view1Intf.(*view) // Create a view atop view1 view2Intf, err := view1.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view2Intf) - view2 := view2Intf.(*trieView) + require.IsType(&view{}, view2Intf) + view2 := view2Intf.(*view) // view2 // | @@ -1157,8 +1149,8 @@ func Test_TrieView_NewView(t *testing.T) { // Make another view atop view1 view3Intf, err := view1.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view3Intf) - view3 := view3Intf.(*trieView) + require.IsType(&view{}, view3Intf) + view3 := view3Intf.(*view) // view3 // | @@ -1174,12 +1166,12 @@ func Test_TrieView_NewView(t *testing.T) { require.NotContains(view1.childViews, view3) // Assert that NewPreallocatedView on an invalid view fails - invalidView := &trieView{invalidated: true} + invalidView := &view{invalidated: true} _, err = invalidView.NewView(context.Background(), ViewChanges{}) require.ErrorIs(err, ErrInvalid) } -func TestTrieViewInvalidate(t *testing.T) { +func TestViewInvalidate(t *testing.T) { require := require.New(t) db, err := getBasicDB() @@ -1188,19 +1180,19 @@ func TestTrieViewInvalidate(t *testing.T) { // Create a view view1Intf, err := db.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view1Intf) - view1 := view1Intf.(*trieView) + require.IsType(&view{}, view1Intf) + view1 := view1Intf.(*view) // Create 2 views atop view1 view2Intf, err := view1.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view2Intf) - view2 := view2Intf.(*trieView) + require.IsType(&view{}, view2Intf) + view2 := view2Intf.(*view) view3Intf, err := view1.NewView(context.Background(), ViewChanges{}) require.NoError(err) - require.IsType(&trieView{}, view3Intf) - view3 := view3Intf.(*trieView) + require.IsType(&view{}, view3Intf) + view3 := view3Intf.(*view) // view2 view3 // | / @@ -1262,7 +1254,7 @@ func TestTrieCommitToDB(t *testing.T) { type test struct { name string - trieFunc func() TrieView + trieFunc func() View expectedErr error } @@ -1273,20 +1265,20 @@ func TestTrieCommitToDB(t *testing.T) { tests := []test{ { name: "invalid", - trieFunc: func() TrieView { - view, err := db.NewView(context.Background(), ViewChanges{}) + trieFunc: func() View { + nView, err := db.NewView(context.Background(), ViewChanges{}) r.NoError(err) // Invalidate the view - view.(*trieView).invalidate() + nView.(*view).invalidate() - return view + return nView }, expectedErr: ErrInvalid, }, { name: "committed", - trieFunc: func() TrieView { + trieFunc: func() View { view, err := db.NewView(context.Background(), ViewChanges{}) r.NoError(err) @@ -1299,14 +1291,14 @@ func TestTrieCommitToDB(t *testing.T) { }, { name: "parent not database", - trieFunc: func() TrieView { - view, err := db.NewView(context.Background(), ViewChanges{}) + trieFunc: func() View { + nView, err := db.NewView(context.Background(), ViewChanges{}) r.NoError(err) // Change the parent - view.(*trieView).parentTrie = &trieView{} + nView.(*view).parentTrie = &view{} - return view + return nView }, expectedErr: ErrParentNotDatabase, }, diff --git a/x/merkledb/trieview.go b/x/merkledb/view.go similarity index 54% rename from x/merkledb/trieview.go rename to x/merkledb/view.go index 12a17e7bbbac..301379d0a778 100644 --- a/x/merkledb/trieview.go +++ b/x/merkledb/view.go @@ -4,10 +4,8 @@ package merkledb import ( - "bytes" "context" "errors" - "fmt" "sync" "go.opentelemetry.io/otel/attribute" @@ -28,7 +26,7 @@ const ( ) var ( - _ TrieView = (*trieView)(nil) + _ View = (*view)(nil) ErrCommitted = errors.New("view has been committed") ErrInvalid = errors.New("the trie this view was based on has changed, rendering this view invalid") @@ -42,7 +40,7 @@ var ( ErrNodesAlreadyCalculated = errors.New("cannot modify the trie after the node changes have been calculated") ) -type trieView struct { +type view struct { // If true, this view has been committed. // [commitLock] must be held while accessing this field. committed bool @@ -54,9 +52,9 @@ type trieView struct { // calculateNodesOnce is a once to ensure that node calculation only occurs a single time calculateNodesOnce sync.Once - // Controls the trie's validity related fields. + // Controls the view's validity related fields. // Must be held while reading/writing [childViews], [invalidated], and [parentTrie]. - // Only use to lock current trieView or descendants of the current trieView + // Only use to lock current view or descendants of the current view // DO NOT grab the [validityTrackingLock] of any ancestor trie while this is held. validityTrackingLock sync.RWMutex @@ -70,7 +68,7 @@ type trieView struct { // // *Code Accessing Ancestor State* // - // if t.isInvalid() { + // if v.isInvalid() { // return ErrInvalid // } // return [result] @@ -83,11 +81,11 @@ type trieView struct { // the uncommitted parent trie of this view // [validityTrackingLock] must be held when reading/writing this field. - parentTrie TrieView + parentTrie View - // The valid children of this trie. + // The valid children of this view. // [validityTrackingLock] must be held when reading/writing this field. - childViews []*trieView + childViews []*view // Changes made to this view. // May include nodes that haven't been updated @@ -102,51 +100,51 @@ type trieView struct { tokenSize int } -// NewView returns a new view on top of this Trie where the passed changes +// NewView returns a new view on top of this view where the passed changes // have been applied. -// Adds the new view to [t.childViews]. -// Assumes [t.commitLock] isn't held. -func (t *trieView) NewView( +// Adds the new view to [v.childViews]. +// Assumes [v.commitLock] isn't held. +func (v *view) NewView( ctx context.Context, changes ViewChanges, -) (TrieView, error) { - if t.isInvalid() { +) (View, error) { + if v.isInvalid() { return nil, ErrInvalid } - t.commitLock.RLock() - defer t.commitLock.RUnlock() + v.commitLock.RLock() + defer v.commitLock.RUnlock() - if t.committed { - return t.getParentTrie().NewView(ctx, changes) + if v.committed { + return v.getParentTrie().NewView(ctx, changes) } - if err := t.calculateNodeIDs(ctx); err != nil { + if err := v.calculateNodeIDs(ctx); err != nil { return nil, err } - newView, err := newTrieView(t.db, t, changes) + newView, err := newView(v.db, v, changes) if err != nil { return nil, err } - t.validityTrackingLock.Lock() - defer t.validityTrackingLock.Unlock() + v.validityTrackingLock.Lock() + defer v.validityTrackingLock.Unlock() - if t.invalidated { + if v.invalidated { return nil, ErrInvalid } - t.childViews = append(t.childViews, newView) + v.childViews = append(v.childViews, newView) return newView, nil } // Creates a new view with the given [parentTrie]. -func newTrieView( +func newView( db *merkleDB, - parentTrie TrieView, + parentTrie View, changes ViewChanges, -) (*trieView, error) { - newView := &trieView{ +) (*view, error) { + newView := &view{ root: maybe.Bind(parentTrie.getRoot(), (*node).clone), db: db, parentTrie: parentTrie, @@ -184,15 +182,15 @@ func newTrieView( // Creates a view of the db at a historical root using the provided [changes]. // Returns ErrNoChanges if [changes] is empty. -func newHistoricalTrieView( +func newViewWithChanges( db *merkleDB, changes *changeSummary, -) (*trieView, error) { +) (*view, error) { if changes == nil { return nil, ErrNoChanges } - newView := &trieView{ + newView := &view{ root: changes.rootChange.after, db: db, parentTrie: db, @@ -206,57 +204,61 @@ func newHistoricalTrieView( return newView, nil } -func (t *trieView) getRoot() maybe.Maybe[*node] { - return t.root +func (v *view) getTokenSize() int { + return v.tokenSize +} + +func (v *view) getRoot() maybe.Maybe[*node] { + return v.root } // Recalculates the node IDs for all changed nodes in the trie. // Cancelling [ctx] doesn't cancel calculation. It's used only for tracing. -func (t *trieView) calculateNodeIDs(ctx context.Context) error { +func (v *view) calculateNodeIDs(ctx context.Context) error { var err error - t.calculateNodesOnce.Do(func() { - if t.isInvalid() { + v.calculateNodesOnce.Do(func() { + if v.isInvalid() { err = ErrInvalid return } - defer t.nodesAlreadyCalculated.Set(true) + defer v.nodesAlreadyCalculated.Set(true) - oldRoot := maybe.Bind(t.root, (*node).clone) + oldRoot := maybe.Bind(v.root, (*node).clone) // We wait to create the span until after checking that we need to actually // calculateNodeIDs to make traces more useful (otherwise there may be a span // per key modified even though IDs are not re-calculated). - _, span := t.db.infoTracer.Start(ctx, "MerkleDB.trieview.calculateNodeIDs") + _, span := v.db.infoTracer.Start(ctx, "MerkleDB.view.calculateNodeIDs") defer span.End() // add all the changed key/values to the nodes of the trie - for key, change := range t.changes.values { + for key, change := range v.changes.values { if change.after.IsNothing() { // Note we're setting [err] defined outside this function. - if err = t.remove(key); err != nil { + if err = v.remove(key); err != nil { return } // Note we're setting [err] defined outside this function. - } else if _, err = t.insert(key, change.after); err != nil { + } else if _, err = v.insert(key, change.after); err != nil { return } } - if !t.root.IsNothing() { - _ = t.db.calculateNodeIDsSema.Acquire(context.Background(), 1) - t.changes.rootID = t.calculateNodeIDsHelper(t.root.Value()) - t.db.calculateNodeIDsSema.Release(1) + if !v.root.IsNothing() { + _ = v.db.calculateNodeIDsSema.Acquire(context.Background(), 1) + v.changes.rootID = v.calculateNodeIDsHelper(v.root.Value()) + v.db.calculateNodeIDsSema.Release(1) } else { - t.changes.rootID = ids.Empty + v.changes.rootID = ids.Empty } - t.changes.rootChange = change[maybe.Maybe[*node]]{ + v.changes.rootChange = change[maybe.Maybe[*node]]{ before: oldRoot, - after: t.root, + after: v.root, } // ensure no ancestor changes occurred during execution - if t.isInvalid() { + if v.isInvalid() { err = ErrInvalid return } @@ -266,14 +268,14 @@ func (t *trieView) calculateNodeIDs(ctx context.Context) error { // Calculates the ID of all descendants of [n] which need to be recalculated, // and then calculates the ID of [n] itself. -func (t *trieView) calculateNodeIDsHelper(n *node) ids.ID { +func (v *view) calculateNodeIDsHelper(n *node) ids.ID { // We use [wg] to wait until all descendants of [n] have been updated. var wg sync.WaitGroup for childIndex := range n.children { childEntry := n.children[childIndex] - childKey := n.key.Extend(ToToken(childIndex, t.tokenSize), childEntry.compressedKey) - childNodeChange, ok := t.changes.nodes[childKey] + childKey := n.key.Extend(ToToken(childIndex, v.tokenSize), childEntry.compressedKey) + childNodeChange, ok := v.changes.nodes[childKey] if !ok { // This child wasn't changed. continue @@ -281,16 +283,16 @@ func (t *trieView) calculateNodeIDsHelper(n *node) ids.ID { childEntry.hasValue = childNodeChange.after.hasValue() // Try updating the child and its descendants in a goroutine. - if ok := t.db.calculateNodeIDsSema.TryAcquire(1); ok { + if ok := v.db.calculateNodeIDsSema.TryAcquire(1); ok { wg.Add(1) go func() { - childEntry.id = t.calculateNodeIDsHelper(childNodeChange.after) - t.db.calculateNodeIDsSema.Release(1) + childEntry.id = v.calculateNodeIDsHelper(childNodeChange.after) + v.db.calculateNodeIDsSema.Release(1) wg.Done() }() } else { // We're at the goroutine limit; do the work in this goroutine. - childEntry.id = t.calculateNodeIDsHelper(childNodeChange.after) + childEntry.id = v.calculateNodeIDsHelper(childNodeChange.after) } } @@ -298,248 +300,132 @@ func (t *trieView) calculateNodeIDsHelper(n *node) ids.ID { wg.Wait() // The IDs [n]'s descendants are up to date so we can calculate [n]'s ID. - return n.calculateID(t.db.metrics) + return n.calculateID(v.db.metrics) } // GetProof returns a proof that [bytesPath] is in or not in trie [t]. -func (t *trieView) GetProof(ctx context.Context, key []byte) (*Proof, error) { - _, span := t.db.infoTracer.Start(ctx, "MerkleDB.trieview.GetProof") +func (v *view) GetProof(ctx context.Context, key []byte) (*Proof, error) { + _, span := v.db.infoTracer.Start(ctx, "MerkleDB.view.GetProof") defer span.End() - if err := t.calculateNodeIDs(ctx); err != nil { + if err := v.calculateNodeIDs(ctx); err != nil { return nil, err } - return t.getProof(ctx, key) -} - -// Returns a proof that [key] is in or not in [t]. -func (t *trieView) getProof(ctx context.Context, key []byte) (*Proof, error) { - _, span := t.db.infoTracer.Start(ctx, "MerkleDB.trieview.getProof") - defer span.End() - - if t.root.IsNothing() { - return nil, ErrEmptyProof - } - - proof := &Proof{ - Key: ToKey(key), - } - - var closestNode *node - if err := t.visitPathToKey(proof.Key, func(n *node) error { - closestNode = n - // From root --> node from left --> right. - proof.Path = append(proof.Path, n.asProofNode()) - return nil - }); err != nil { - return nil, err - } - - if len(proof.Path) == 0 { - // No key in [t] is a prefix of [key]. - // The root alone proves that [key] isn't in [t]. - proof.Path = append(proof.Path, t.root.Value().asProofNode()) - return proof, nil - } - - if closestNode.key == proof.Key { - // There is a node with the given [key]. - proof.Value = maybe.Bind(closestNode.value, slices.Clone[[]byte]) - return proof, nil - } - - // There is no node with the given [key]. - // If there is a child at the index where the node would be - // if it existed, include that child in the proof. - nextIndex := proof.Key.Token(closestNode.key.length, t.tokenSize) - child, ok := closestNode.children[nextIndex] - if !ok { - return proof, nil - } - - childNode, err := t.getNode( - closestNode.key.Extend(ToToken(nextIndex, t.tokenSize), child.compressedKey), - child.hasValue, - ) + result, err := getProof(v, key) if err != nil { return nil, err } - proof.Path = append(proof.Path, childNode.asProofNode()) - if t.isInvalid() { + if v.isInvalid() { return nil, ErrInvalid } - return proof, nil + return result, nil } // GetRangeProof returns a range proof for (at least part of) the key range [start, end]. // The returned proof's [KeyValues] has at most [maxLength] values. // [maxLength] must be > 0. -func (t *trieView) GetRangeProof( +func (v *view) GetRangeProof( ctx context.Context, start maybe.Maybe[[]byte], end maybe.Maybe[[]byte], maxLength int, ) (*RangeProof, error) { - ctx, span := t.db.infoTracer.Start(ctx, "MerkleDB.trieview.GetRangeProof") + _, span := v.db.infoTracer.Start(ctx, "MerkleDB.view.GetRangeProof") defer span.End() - if start.HasValue() && end.HasValue() && bytes.Compare(start.Value(), end.Value()) == 1 { - return nil, ErrStartAfterEnd - } - - if maxLength <= 0 { - return nil, fmt.Errorf("%w but was %d", ErrInvalidMaxLength, maxLength) - } - - if err := t.calculateNodeIDs(ctx); err != nil { + if err := v.calculateNodeIDs(ctx); err != nil { return nil, err } - - if t.root.IsNothing() { - return nil, ErrEmptyProof - } - - var result RangeProof - - result.KeyValues = make([]KeyValue, 0, initKeyValuesSize) - it := t.NewIteratorWithStart(start.Value()) - for it.Next() && len(result.KeyValues) < maxLength && (end.IsNothing() || bytes.Compare(it.Key(), end.Value()) <= 0) { - // clone the value to prevent editing of the values stored within the trie - result.KeyValues = append(result.KeyValues, KeyValue{ - Key: it.Key(), - Value: slices.Clone(it.Value()), - }) - } - it.Release() - if err := it.Error(); err != nil { + result, err := getRangeProof(v, start, end, maxLength) + if err != nil { return nil, err } - - // This proof may not contain all key-value pairs in [start, end] due to size limitations. - // The end proof we provide should be for the last key-value pair in the proof, not for - // the last key-value pair requested, which may not be in this proof. - var ( - endProof *Proof - err error - ) - if len(result.KeyValues) > 0 { - greatestKey := result.KeyValues[len(result.KeyValues)-1].Key - endProof, err = t.getProof(ctx, greatestKey) - if err != nil { - return nil, err - } - } else if end.HasValue() { - endProof, err = t.getProof(ctx, end.Value()) - if err != nil { - return nil, err - } - } - if endProof != nil { - result.EndProof = endProof.Path - } - - if start.HasValue() { - startProof, err := t.getProof(ctx, start.Value()) - if err != nil { - return nil, err - } - result.StartProof = startProof.Path - - // strip out any common nodes to reduce proof size - i := 0 - for ; i < len(result.StartProof) && - i < len(result.EndProof) && - result.StartProof[i].Key == result.EndProof[i].Key; i++ { - } - result.StartProof = result.StartProof[i:] - } - - if t.isInvalid() { + if v.isInvalid() { return nil, ErrInvalid } - return &result, nil + return result, nil } -// CommitToDB commits changes from this trie to the underlying DB. -func (t *trieView) CommitToDB(ctx context.Context) error { - ctx, span := t.db.infoTracer.Start(ctx, "MerkleDB.trieview.CommitToDB") +// CommitToDB commits changes from this view to the underlying DB. +func (v *view) CommitToDB(ctx context.Context) error { + ctx, span := v.db.infoTracer.Start(ctx, "MerkleDB.view.CommitToDB") defer span.End() - t.db.commitLock.Lock() - defer t.db.commitLock.Unlock() + v.db.commitLock.Lock() + defer v.db.commitLock.Unlock() - return t.commitToDB(ctx) + return v.commitToDB(ctx) } // Commits the changes from [trieToCommit] to this view, // this view to its parent, and so on until committing to the db. -// Assumes [t.db.commitLock] is held. -func (t *trieView) commitToDB(ctx context.Context) error { - t.commitLock.Lock() - defer t.commitLock.Unlock() +// Assumes [v.db.commitLock] is held. +func (v *view) commitToDB(ctx context.Context) error { + v.commitLock.Lock() + defer v.commitLock.Unlock() - ctx, span := t.db.infoTracer.Start(ctx, "MerkleDB.trieview.commitToDB", oteltrace.WithAttributes( - attribute.Int("changeCount", len(t.changes.values)), + ctx, span := v.db.infoTracer.Start(ctx, "MerkleDB.view.commitToDB", oteltrace.WithAttributes( + attribute.Int("changeCount", len(v.changes.values)), )) defer span.End() - // Call this here instead of in [t.db.commitChanges] + // Call this here instead of in [v.db.commitChanges] // because doing so there would be a deadlock. - if err := t.calculateNodeIDs(ctx); err != nil { + if err := v.calculateNodeIDs(ctx); err != nil { return err } - if err := t.db.commitChanges(ctx, t); err != nil { + if err := v.db.commitChanges(ctx, v); err != nil { return err } - t.committed = true + v.committed = true return nil } -// Assumes [t.validityTrackingLock] isn't held. -func (t *trieView) isInvalid() bool { - t.validityTrackingLock.RLock() - defer t.validityTrackingLock.RUnlock() +// Assumes [v.validityTrackingLock] isn't held. +func (v *view) isInvalid() bool { + v.validityTrackingLock.RLock() + defer v.validityTrackingLock.RUnlock() - return t.invalidated + return v.invalidated } // Invalidates this view and all descendants. -// Assumes [t.validityTrackingLock] isn't held. -func (t *trieView) invalidate() { - t.validityTrackingLock.Lock() - defer t.validityTrackingLock.Unlock() +// Assumes [v.validityTrackingLock] isn't held. +func (v *view) invalidate() { + v.validityTrackingLock.Lock() + defer v.validityTrackingLock.Unlock() - t.invalidated = true + v.invalidated = true - for _, childView := range t.childViews { + for _, childView := range v.childViews { childView.invalidate() } // after invalidating the children, they no longer need to be tracked - t.childViews = make([]*trieView, 0, defaultPreallocationSize) + v.childViews = make([]*view, 0, defaultPreallocationSize) } -func (t *trieView) updateParent(newParent TrieView) { - t.validityTrackingLock.Lock() - defer t.validityTrackingLock.Unlock() +func (v *view) updateParent(newParent View) { + v.validityTrackingLock.Lock() + defer v.validityTrackingLock.Unlock() - t.parentTrie = newParent + v.parentTrie = newParent } -// GetMerkleRoot returns the ID of the root of this trie. -func (t *trieView) GetMerkleRoot(ctx context.Context) (ids.ID, error) { - if err := t.calculateNodeIDs(ctx); err != nil { +// GetMerkleRoot returns the ID of the root of this view. +func (v *view) GetMerkleRoot(ctx context.Context) (ids.ID, error) { + if err := v.calculateNodeIDs(ctx); err != nil { return ids.Empty, err } - return t.changes.rootID, nil + return v.changes.rootID, nil } -func (t *trieView) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []error) { - _, span := t.db.debugTracer.Start(ctx, "MerkleDB.trieview.GetValues", oteltrace.WithAttributes( +func (v *view) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []error) { + _, span := v.db.debugTracer.Start(ctx, "MerkleDB.view.GetValues", oteltrace.WithAttributes( attribute.Int("keyCount", len(keys)), )) defer span.End() @@ -548,52 +434,52 @@ func (t *trieView) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []er valueErrors := make([]error, len(keys)) for i, key := range keys { - results[i], valueErrors[i] = t.getValueCopy(ToKey(key)) + results[i], valueErrors[i] = v.getValueCopy(ToKey(key)) } return results, valueErrors } // GetValue returns the value for the given [key]. // Returns database.ErrNotFound if it doesn't exist. -func (t *trieView) GetValue(ctx context.Context, key []byte) ([]byte, error) { - _, span := t.db.debugTracer.Start(ctx, "MerkleDB.trieview.GetValue") +func (v *view) GetValue(ctx context.Context, key []byte) ([]byte, error) { + _, span := v.db.debugTracer.Start(ctx, "MerkleDB.view.GetValue") defer span.End() - return t.getValueCopy(ToKey(key)) + return v.getValueCopy(ToKey(key)) } // getValueCopy returns a copy of the value for the given [key]. // Returns database.ErrNotFound if it doesn't exist. -func (t *trieView) getValueCopy(key Key) ([]byte, error) { - val, err := t.getValue(key) +func (v *view) getValueCopy(key Key) ([]byte, error) { + val, err := v.getValue(key) if err != nil { return nil, err } return slices.Clone(val), nil } -func (t *trieView) getValue(key Key) ([]byte, error) { - if t.isInvalid() { +func (v *view) getValue(key Key) ([]byte, error) { + if v.isInvalid() { return nil, ErrInvalid } - if change, ok := t.changes.values[key]; ok { - t.db.metrics.ViewValueCacheHit() + if change, ok := v.changes.values[key]; ok { + v.db.metrics.ViewValueCacheHit() if change.after.IsNothing() { return nil, database.ErrNotFound } return change.after.Value(), nil } - t.db.metrics.ViewValueCacheMiss() + v.db.metrics.ViewValueCacheMiss() // if we don't have local copy of the key, then grab a copy from the parent trie - value, err := t.getParentTrie().getValue(key) + value, err := v.getParentTrie().getValue(key) if err != nil { return nil, err } // ensure no ancestor changes occurred during execution - if t.isInvalid() { + if v.isInvalid() { return nil, ErrInvalid } @@ -601,13 +487,13 @@ func (t *trieView) getValue(key Key) ([]byte, error) { } // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) remove(key Key) error { - if t.nodesAlreadyCalculated.Get() { +func (v *view) remove(key Key) error { + if v.nodesAlreadyCalculated.Get() { return ErrNodesAlreadyCalculated } // confirm a node exists with a value - keyNode, err := t.getNode(key, true) + keyNode, err := v.getNode(key, true) if err != nil { if errors.Is(err, database.ErrNotFound) { // [key] isn't in the trie. @@ -625,11 +511,11 @@ func (t *trieView) remove(key Key) error { // mark all ancestor for change // grab parent and grandparent nodes for path compression var grandParent, parent, nodeToDelete *node - if err := t.visitPathToKey(key, func(n *node) error { + if err := visitPathToKey(v, key, func(n *node) error { grandParent = parent parent = nodeToDelete nodeToDelete = n - return t.recordNodeChange(n) + return v.recordNodeChange(n) }); err != nil { return err } @@ -638,39 +524,39 @@ func (t *trieView) remove(key Key) error { // if the removed node has no children, the node can be removed from the trie if len(nodeToDelete.children) == 0 { - if err := t.recordNodeDeleted(nodeToDelete); err != nil { + if err := v.recordNodeDeleted(nodeToDelete); err != nil { return err } - if nodeToDelete.key == t.root.Value().key { + if nodeToDelete.key == v.root.Value().key { // We deleted the root. The trie is empty now. - t.root = maybe.Nothing[*node]() + v.root = maybe.Nothing[*node]() return nil } - // Note [parent] != nil since [nodeToDelete.key] != [t.root.key]. + // Note [parent] != nil since [nodeToDelete.key] != [v.root.key]. // i.e. There's the root and at least one more node. - parent.removeChild(nodeToDelete, t.tokenSize) + parent.removeChild(nodeToDelete, v.tokenSize) // merge the parent node and its child into a single node if possible - return t.compressNodePath(grandParent, parent) + return v.compressNodePath(grandParent, parent) } // merge this node and its descendants into a single node if possible - return t.compressNodePath(parent, nodeToDelete) + return v.compressNodePath(parent, nodeToDelete) } // Merges together nodes in the inclusive descendants of [n] that // have no value and a single child into one node with a compressed // path until a node that doesn't meet those criteria is reached. // [parent] is [n]'s parent. If [parent] is nil, [n] is the root -// node and [t.root] is updated to [n]. +// node and [v.root] is updated to [n]. // Assumes at least one of the following is true: // * [n] has a value. // * [n] has children. // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) compressNodePath(parent, n *node) error { - if t.nodesAlreadyCalculated.Get() { +func (v *view) compressNodePath(parent, n *node) error { + if v.nodesAlreadyCalculated.Get() { return ErrNodesAlreadyCalculated } @@ -678,7 +564,7 @@ func (t *trieView) compressNodePath(parent, n *node) error { return nil } - if err := t.recordNodeDeleted(n); err != nil { + if err := v.recordNodeDeleted(n); err != nil { return err } @@ -690,127 +576,86 @@ func (t *trieView) compressNodePath(parent, n *node) error { // "Cycle" over the key/values to find the only child. // Note this iteration once because len(node.children) == 1. for index, entry := range n.children { - childKey = n.key.Extend(ToToken(index, t.tokenSize), entry.compressedKey) + childKey = n.key.Extend(ToToken(index, v.tokenSize), entry.compressedKey) childEntry = entry } if parent == nil { - root, err := t.getNode(childKey, childEntry.hasValue) + root, err := v.getNode(childKey, childEntry.hasValue) if err != nil { return err } - t.root = maybe.Some(root) + v.root = maybe.Some(root) return nil } - parent.setChildEntry(childKey.Token(parent.key.length, t.tokenSize), + parent.setChildEntry(childKey.Token(parent.key.length, v.tokenSize), &child{ - compressedKey: childKey.Skip(parent.key.length + t.tokenSize), + compressedKey: childKey.Skip(parent.key.length + v.tokenSize), id: childEntry.id, hasValue: childEntry.hasValue, }) - return t.recordNodeChange(parent) -} - -// Calls [visitNode] on each node along the path to [key]. -// The first node (if any) is the root, and the last node is either the -// node with the given [key], if it's in [t], or the node with the -// largest prefix of [key] otherwise. -func (t *trieView) visitPathToKey(key Key, visitNode func(*node) error) error { - if t.root.IsNothing() { - return nil - } - root := t.root.Value() - if !key.HasPrefix(root.key) { - return nil - } - var ( - // all node paths start at the root - currentNode = root - err error - ) - if err := visitNode(currentNode); err != nil { - return err - } - // while the entire path hasn't been matched - for currentNode.key.length < key.length { - // confirm that a child exists and grab its ID before attempting to load it - nextChildEntry, hasChild := currentNode.children[key.Token(currentNode.key.length, t.tokenSize)] - - if !hasChild || !key.iteratedHasPrefix(nextChildEntry.compressedKey, currentNode.key.length+t.tokenSize, t.tokenSize) { - // there was no child along the path or the child that was there doesn't match the remaining path - return nil - } - // grab the next node along the path - currentNode, err = t.getNode(key.Take(currentNode.key.length+t.tokenSize+nextChildEntry.compressedKey.length), nextChildEntry.hasValue) - if err != nil { - return err - } - if err := visitNode(currentNode); err != nil { - return err - } - } - return nil + return v.recordNodeChange(parent) } -// Get a copy of the node matching the passed key from the trie. +// Get a copy of the node matching the passed key from the view. // Used by views to get nodes from their ancestors. -func (t *trieView) getEditableNode(key Key, hadValue bool) (*node, error) { - if t.isInvalid() { +func (v *view) getEditableNode(key Key, hadValue bool) (*node, error) { + if v.isInvalid() { return nil, ErrInvalid } // grab the node in question - n, err := t.getNode(key, hadValue) + n, err := v.getNode(key, hadValue) if err != nil { return nil, err } // ensure no ancestor changes occurred during execution - if t.isInvalid() { + if v.isInvalid() { return nil, ErrInvalid } - // return a clone of the node, so it can be edited without affecting this trie + // return a clone of the node, so it can be edited without affecting this view return n.clone(), nil } // insert a key/value pair into the correct node of the trie. // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) insert( +func (v *view) insert( key Key, value maybe.Maybe[[]byte], ) (*node, error) { - if t.nodesAlreadyCalculated.Get() { + if v.nodesAlreadyCalculated.Get() { return nil, ErrNodesAlreadyCalculated } - if t.root.IsNothing() { + if v.root.IsNothing() { // the trie is empty, so create a new root node. root := newNode(key) root.setValue(value) - t.root = maybe.Some(root) - return root, t.recordNewNode(root) + v.root = maybe.Some(root) + return root, v.recordNewNode(root) } // Find the node that most closely matches [key]. var closestNode *node - if err := t.visitPathToKey(key, func(n *node) error { + if err := visitPathToKey(v, key, func(n *node) error { closestNode = n // Need to recalculate ID for all nodes on path to [key]. - return t.recordNodeChange(n) + return v.recordNodeChange(n) }); err != nil { return nil, err } if closestNode == nil { - // [t.root.key] isn't a prefix of [key]. + // [v.root.key] isn't a prefix of [key]. var ( - oldRoot = t.root.Value() - commonPrefixLength = getLengthOfCommonPrefix(oldRoot.key, key, 0 /*offset*/, t.tokenSize) + oldRoot = v.root.Value() + commonPrefixLength = getLengthOfCommonPrefix(oldRoot.key, key, 0 /*offset*/, v.tokenSize) commonPrefix = oldRoot.key.Take(commonPrefixLength) newRoot = newNode(commonPrefix) - oldRootID = oldRoot.calculateID(t.db.metrics) + oldRootID = oldRoot.calculateID(v.db.metrics) ) // Call addChildWithID instead of addChild so the old root is added @@ -818,12 +663,12 @@ func (t *trieView) insert( // TODO: // [oldRootID] shouldn't need to be calculated here. // Either oldRootID should already be calculated or will be calculated at the end with the other nodes - // Initialize the t.changes.rootID during newTrieView and then use that here instead of oldRootID - newRoot.addChildWithID(oldRoot, t.tokenSize, oldRootID) - if err := t.recordNewNode(newRoot); err != nil { + // Initialize the v.changes.rootID during newView and then use that here instead of oldRootID + newRoot.addChildWithID(oldRoot, v.tokenSize, oldRootID) + if err := v.recordNewNode(newRoot); err != nil { return nil, err } - t.root = maybe.Some(newRoot) + v.root = maybe.Some(newRoot) closestNode = newRoot } @@ -839,13 +684,13 @@ func (t *trieView) insert( // key that hasn't been matched yet // Note that [key] has prefix [closestNode.key], so [key] must be longer // and the following index won't OOB. - existingChildEntry, hasChild := closestNode.children[key.Token(closestNode.key.length, t.tokenSize)] + existingChildEntry, hasChild := closestNode.children[key.Token(closestNode.key.length, v.tokenSize)] if !hasChild { // there are no existing nodes along the key [key], so create a new node to insert [value] newNode := newNode(key) newNode.setValue(value) - closestNode.addChild(newNode, t.tokenSize) - return newNode, t.recordNewNode(newNode) + closestNode.addChild(newNode, v.tokenSize) + return newNode, v.recordNewNode(newNode) } // if we have reached this point, then the [key] we are trying to insert and @@ -860,8 +705,8 @@ func (t *trieView) insert( commonPrefixLength := getLengthOfCommonPrefix( existingChildEntry.compressedKey, key, - closestNode.key.length+t.tokenSize, - t.tokenSize, + closestNode.key.length+v.tokenSize, + v.tokenSize, ) if existingChildEntry.compressedKey.length <= commonPrefixLength { @@ -870,8 +715,8 @@ func (t *trieView) insert( return nil, ErrVisitPathToKey } - branchNode := newNode(key.Take(closestNode.key.length + t.tokenSize + commonPrefixLength)) - closestNode.addChild(branchNode, t.tokenSize) + branchNode := newNode(key.Take(closestNode.key.length + v.tokenSize + commonPrefixLength)) + closestNode.addChild(branchNode, v.tokenSize) nodeWithValue := branchNode if key.length == branchNode.key.length { @@ -882,8 +727,8 @@ func (t *trieView) insert( // create a new node and add the value to it newNode := newNode(key) newNode.setValue(value) - branchNode.addChild(newNode, t.tokenSize) - if err := t.recordNewNode(newNode); err != nil { + branchNode.addChild(newNode, v.tokenSize) + if err := v.recordNewNode(newNode); err != nil { return nil, err } nodeWithValue = newNode @@ -891,14 +736,14 @@ func (t *trieView) insert( // add the existing child onto the branch node branchNode.setChildEntry( - existingChildEntry.compressedKey.Token(commonPrefixLength, t.tokenSize), + existingChildEntry.compressedKey.Token(commonPrefixLength, v.tokenSize), &child{ - compressedKey: existingChildEntry.compressedKey.Skip(commonPrefixLength + t.tokenSize), + compressedKey: existingChildEntry.compressedKey.Skip(commonPrefixLength + v.tokenSize), id: existingChildEntry.id, hasValue: existingChildEntry.hasValue, }) - return nodeWithValue, t.recordNewNode(branchNode) + return nodeWithValue, v.recordNewNode(branchNode) } func getLengthOfCommonPrefix(first, second Key, secondOffset int, tokenSize int) int { @@ -912,47 +757,47 @@ func getLengthOfCommonPrefix(first, second Key, secondOffset int, tokenSize int) // Records that a node has been created. // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) recordNewNode(after *node) error { - return t.recordKeyChange(after.key, after, after.hasValue(), true /* newNode */) +func (v *view) recordNewNode(after *node) error { + return v.recordKeyChange(after.key, after, after.hasValue(), true /* newNode */) } // Records that an existing node has been changed. // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) recordNodeChange(after *node) error { - return t.recordKeyChange(after.key, after, after.hasValue(), false /* newNode */) +func (v *view) recordNodeChange(after *node) error { + return v.recordKeyChange(after.key, after, after.hasValue(), false /* newNode */) } // Records that the node associated with the given key has been deleted. // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) recordNodeDeleted(after *node) error { - return t.recordKeyChange(after.key, nil, after.hasValue(), false /* newNode */) +func (v *view) recordNodeDeleted(after *node) error { + return v.recordKeyChange(after.key, nil, after.hasValue(), false /* newNode */) } // Records that the node associated with the given key has been changed. // If it is an existing node, record what its value was before it was changed. // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) recordKeyChange(key Key, after *node, hadValue bool, newNode bool) error { - if t.nodesAlreadyCalculated.Get() { +func (v *view) recordKeyChange(key Key, after *node, hadValue bool, newNode bool) error { + if v.nodesAlreadyCalculated.Get() { return ErrNodesAlreadyCalculated } - if existing, ok := t.changes.nodes[key]; ok { + if existing, ok := v.changes.nodes[key]; ok { existing.after = after return nil } if newNode { - t.changes.nodes[key] = &change[*node]{ + v.changes.nodes[key] = &change[*node]{ after: after, } return nil } - before, err := t.getParentTrie().getEditableNode(key, hadValue) + before, err := v.getParentTrie().getEditableNode(key, hadValue) if err != nil && !errors.Is(err, database.ErrNotFound) { return err } - t.changes.nodes[key] = &change[*node]{ + v.changes.nodes[key] = &change[*node]{ before: before, after: after, } @@ -963,20 +808,20 @@ func (t *trieView) recordKeyChange(key Key, after *node, hadValue bool, newNode // Doesn't actually change the trie data structure. // That's deferred until we call [calculateNodeIDs]. // Must not be called after [calculateNodeIDs] has returned. -func (t *trieView) recordValueChange(key Key, value maybe.Maybe[[]byte]) error { - if t.nodesAlreadyCalculated.Get() { +func (v *view) recordValueChange(key Key, value maybe.Maybe[[]byte]) error { + if v.nodesAlreadyCalculated.Get() { return ErrNodesAlreadyCalculated } // update the existing change if it exists - if existing, ok := t.changes.values[key]; ok { + if existing, ok := v.changes.values[key]; ok { existing.after = value return nil } // grab the before value var beforeMaybe maybe.Maybe[[]byte] - before, err := t.getParentTrie().getValue(key) + before, err := v.getParentTrie().getValue(key) switch err { case nil: beforeMaybe = maybe.Some(before) @@ -986,7 +831,7 @@ func (t *trieView) recordValueChange(key Key, value maybe.Maybe[[]byte]) error { return err } - t.changes.values[key] = &change[maybe.Maybe[[]byte]]{ + v.changes.values[key] = &change[maybe.Maybe[[]byte]]{ before: beforeMaybe, after: value, } @@ -994,14 +839,14 @@ func (t *trieView) recordValueChange(key Key, value maybe.Maybe[[]byte]) error { } // Retrieves a node with the given [key]. -// If the node is fetched from [t.parentTrie] and [id] isn't empty, +// If the node is fetched from [v.parentTrie] and [id] isn't empty, // sets the node's ID to [id]. // If the node is loaded from the baseDB, [hasValue] determines which database the node is stored in. // Returns database.ErrNotFound if the node doesn't exist. -func (t *trieView) getNode(key Key, hasValue bool) (*node, error) { +func (v *view) getNode(key Key, hasValue bool) (*node, error) { // check for the key within the changed nodes - if nodeChange, isChanged := t.changes.nodes[key]; isChanged { - t.db.metrics.ViewNodeCacheHit() + if nodeChange, isChanged := v.changes.nodes[key]; isChanged { + v.db.metrics.ViewNodeCacheHit() if nodeChange.after == nil { return nil, database.ErrNotFound } @@ -1009,12 +854,12 @@ func (t *trieView) getNode(key Key, hasValue bool) (*node, error) { } // get the node from the parent trie and store a local copy - return t.getParentTrie().getEditableNode(key, hasValue) + return v.getParentTrie().getEditableNode(key, hasValue) } // Get the parent trie of the view -func (t *trieView) getParentTrie() TrieView { - t.validityTrackingLock.RLock() - defer t.validityTrackingLock.RUnlock() - return t.parentTrie +func (v *view) getParentTrie() View { + v.validityTrackingLock.RLock() + defer v.validityTrackingLock.RUnlock() + return v.parentTrie } diff --git a/x/merkledb/view_iterator.go b/x/merkledb/view_iterator.go index 0216bcc45199..2995cb6e8449 100644 --- a/x/merkledb/view_iterator.go +++ b/x/merkledb/view_iterator.go @@ -11,26 +11,26 @@ import ( "golang.org/x/exp/slices" ) -func (t *trieView) NewIterator() database.Iterator { - return t.NewIteratorWithStartAndPrefix(nil, nil) +func (v *view) NewIterator() database.Iterator { + return v.NewIteratorWithStartAndPrefix(nil, nil) } -func (t *trieView) NewIteratorWithStart(start []byte) database.Iterator { - return t.NewIteratorWithStartAndPrefix(start, nil) +func (v *view) NewIteratorWithStart(start []byte) database.Iterator { + return v.NewIteratorWithStartAndPrefix(start, nil) } -func (t *trieView) NewIteratorWithPrefix(prefix []byte) database.Iterator { - return t.NewIteratorWithStartAndPrefix(nil, prefix) +func (v *view) NewIteratorWithPrefix(prefix []byte) database.Iterator { + return v.NewIteratorWithStartAndPrefix(nil, prefix) } -func (t *trieView) NewIteratorWithStartAndPrefix(start, prefix []byte) database.Iterator { +func (v *view) NewIteratorWithStartAndPrefix(start, prefix []byte) database.Iterator { var ( - changes = make([]KeyChange, 0, len(t.changes.values)) + changes = make([]KeyChange, 0, len(v.changes.values)) startKey = ToKey(start) prefixKey = ToKey(prefix) ) - for key, change := range t.changes.values { + for key, change := range v.changes.values { if len(start) > 0 && startKey.Greater(key) || !key.HasPrefix(prefixKey) { continue } @@ -46,8 +46,8 @@ func (t *trieView) NewIteratorWithStartAndPrefix(start, prefix []byte) database. }) return &viewIterator{ - view: t, - parentIter: t.parentTrie.NewIteratorWithStartAndPrefix(start, prefix), + view: v, + parentIter: v.parentTrie.NewIteratorWithStartAndPrefix(start, prefix), sortedChanges: changes, } } @@ -55,7 +55,7 @@ func (t *trieView) NewIteratorWithStartAndPrefix(start, prefix []byte) database. // viewIterator walks over both the in memory database and the underlying database // at the same time. type viewIterator struct { - view *trieView + view *view parentIter database.Iterator key, value []byte diff --git a/x/merkledb/view_iterator_test.go b/x/merkledb/view_iterator_test.go index 8b439b3a90df..97d4e47ca11a 100644 --- a/x/merkledb/view_iterator_test.go +++ b/x/merkledb/view_iterator_test.go @@ -19,7 +19,7 @@ import ( "github.com/ava-labs/avalanchego/utils/maybe" ) -func Test_TrieView_Iterator(t *testing.T) { +func Test_View_Iterator(t *testing.T) { require := require.New(t) key1 := []byte("hello1") @@ -55,7 +55,7 @@ func Test_TrieView_Iterator(t *testing.T) { require.NoError(iterator.Error()) } -func Test_TrieView_Iterator_DBClosed(t *testing.T) { +func Test_View_Iterator_DBClosed(t *testing.T) { require := require.New(t) key1 := []byte("hello1") @@ -82,9 +82,9 @@ func Test_TrieView_Iterator_DBClosed(t *testing.T) { require.ErrorIs(err, ErrInvalid) } -// Test_TrieView_IteratorStart tests to make sure the iterator can be configured to +// Test_View_IteratorStart tests to make sure the iterator can be configured to // start midway through the database. -func Test_TrieView_IteratorStart(t *testing.T) { +func Test_View_IteratorStart(t *testing.T) { require := require.New(t) db, err := getBasicDB() require.NoError(err) @@ -115,9 +115,9 @@ func Test_TrieView_IteratorStart(t *testing.T) { require.NoError(iterator.Error()) } -// Test_TrieView_IteratorPrefix tests to make sure the iterator can be configured to skip +// Test_View_IteratorPrefix tests to make sure the iterator can be configured to skip // keys missing the provided prefix. -func Test_TrieView_IteratorPrefix(t *testing.T) { +func Test_View_IteratorPrefix(t *testing.T) { require := require.New(t) db, err := getBasicDB() require.NoError(err) @@ -152,9 +152,9 @@ func Test_TrieView_IteratorPrefix(t *testing.T) { require.NoError(iterator.Error()) } -// Test_TrieView_IteratorStartPrefix tests to make sure that the iterator can start +// Test_View_IteratorStartPrefix tests to make sure that the iterator can start // midway through the database while skipping a prefix. -func Test_TrieView_IteratorStartPrefix(t *testing.T) { +func Test_View_IteratorStartPrefix(t *testing.T) { require := require.New(t) db, err := getBasicDB() require.NoError(err) @@ -196,7 +196,7 @@ func Test_TrieView_IteratorStartPrefix(t *testing.T) { // Test view iteration by creating a stack of views, // inserting random key/value pairs into them, and // iterating over the last view. -func Test_TrieView_Iterator_Random(t *testing.T) { +func Test_View_Iterator_Random(t *testing.T) { require := require.New(t) now := time.Now().UnixNano() t.Logf("seed: %d", now) From 040bcd84ecb234f601dc935eb90ecd7ead68ef50 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 28 Dec 2023 16:10:14 -0500 Subject: [PATCH 209/267] Do not mark txs as dropped when mempool is full (#2557) --- vms/avm/txs/mempool/mempool.go | 4 ++++ vms/avm/txs/mempool/mempool_test.go | 15 +++++++++++++++ vms/platformvm/txs/mempool/mempool.go | 4 ++++ vms/platformvm/txs/mempool/mempool_test.go | 5 +++++ 4 files changed, 28 insertions(+) diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index b4b05a72d2a3..f7d9bc37262d 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -208,6 +208,10 @@ func (m *mempool) RequestBuildBlock() { } func (m *mempool) MarkDropped(txID ids.ID, reason error) { + if errors.Is(reason, ErrMempoolFull) { + return + } + m.lock.RLock() defer m.lock.RUnlock() diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index ae1a75dbba17..5691662cbaa0 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -26,36 +26,42 @@ func TestAdd(t *testing.T) { initialTxs []*txs.Tx tx *txs.Tx err error + dropReason error }{ { name: "successfully add tx", initialTxs: nil, tx: tx0, err: nil, + dropReason: nil, }, { name: "attempt adding duplicate tx", initialTxs: []*txs.Tx{tx0}, tx: tx0, err: ErrDuplicateTx, + dropReason: nil, }, { name: "attempt adding too large tx", initialTxs: nil, tx: newTx(0, MaxTxSize+1), err: ErrTxTooLarge, + dropReason: ErrTxTooLarge, }, { name: "attempt adding tx when full", initialTxs: newTxs(maxMempoolSize/MaxTxSize, MaxTxSize), tx: newTx(maxMempoolSize/MaxTxSize, MaxTxSize), err: ErrMempoolFull, + dropReason: nil, }, { name: "attempt adding conflicting tx", initialTxs: []*txs.Tx{tx0}, tx: newTx(0, 32), err: ErrConflictsWithOtherTx, + dropReason: ErrConflictsWithOtherTx, }, } for _, test := range tests { @@ -75,6 +81,15 @@ func TestAdd(t *testing.T) { err = mempool.Add(test.tx) require.ErrorIs(err, test.err) + + txID := test.tx.ID() + + if err != nil { + mempool.MarkDropped(txID, err) + } + + err = mempool.GetDropReason(txID) + require.ErrorIs(err, test.dropReason) }) } } diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 37355b017d3f..148a804f9df6 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -212,6 +212,10 @@ func (m *mempool) Iterate(f func(tx *txs.Tx) bool) { } func (m *mempool) MarkDropped(txID ids.ID, reason error) { + if errors.Is(reason, ErrMempoolFull) { + return + } + m.lock.RLock() defer m.lock.RUnlock() diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index ffbb00359fc5..31420e94ecbb 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -40,6 +40,11 @@ func TestBlockBuilderMaxMempoolSizeHandling(t *testing.T) { err = mpool.Add(tx) require.ErrorIs(err, ErrMempoolFull) + // tx should not be marked as dropped if the mempool is full + txID := tx.ID() + mpool.MarkDropped(txID, err) + require.NoError(mpool.GetDropReason(txID)) + // shortcut to simulated almost filled mempool mpool.(*mempool).bytesAvailable = len(tx.Bytes()) From 7ca56e86742104b5d182eaa14de75ef000d5727d Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 28 Dec 2023 20:16:02 -0500 Subject: [PATCH 210/267] Update bug bounty program to immunefi (#2558) --- SECURITY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 26e938c8df29..9a04ba2528f5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,13 +4,13 @@ Avalanche takes the security of the platform and of its users very seriously. We ## Reporting a Vulnerability -**Please do not file a public ticket** mentioning the vulnerability. To disclose a vulnerability submit it through our [Bug Bounty Program](https://hackenproof.com/avalanche). +**Please do not file a public ticket** mentioning the vulnerability. To disclose a vulnerability submit it through our [Bug Bounty Program](https://immunefi.com/bounty/avalanche/). Vulnerabilities must be disclosed to us privately with reasonable time to respond, and avoid compromise of other users and accounts, or loss of funds that are not your own. We do not reward spam or social engineering vulnerabilities. Do not test for or validate any security issues in the live Avalanche networks (Mainnet and Fuji testnet), confirm all exploits in a local private testnet. -Please refer to the [Bug Bounty Page](https://hackenproof.com/avalanche) for the most up-to-date program rules and scope. +Please refer to the [Bug Bounty Page](https://immunefi.com/bounty/avalanche/) for the most up-to-date program rules and scope. ## Supported Versions From 4bcf7eecabcd3e7382369fb43e60f65c483c9283 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 29 Dec 2023 02:19:51 -0500 Subject: [PATCH 211/267] Fix p2p sdk metric labels (#2561) --- network/p2p/gossip/gossip.go | 25 +++++++++++-------------- network/p2p/gossip/handler.go | 16 ++++------------ 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index c35d169c4259..17795759e063 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -40,6 +40,12 @@ var ( _ Accumulator[*testTx] = (*TestAccumulator[*testTx])(nil) metricLabels = []string{typeLabel} + pushLabels = prometheus.Labels{ + typeLabel: pushType, + } + pullLabels = prometheus.Labels{ + typeLabel: pullType, + } ) // Gossiper gossips Gossipables to other nodes @@ -131,9 +137,6 @@ func NewPullGossiper[T Gossipable]( client: client, metrics: metrics, pollSize: pollSize, - labels: prometheus.Labels{ - typeLabel: pullType, - }, } } @@ -144,7 +147,6 @@ type PullGossiper[T Gossipable] struct { client *p2p.Client metrics Metrics pollSize int - labels prometheus.Labels } func (p *PullGossiper[_]) Gossip(ctx context.Context) error { @@ -223,13 +225,13 @@ func (p *PullGossiper[_]) handleResponse( } } - receivedCountMetric, err := p.metrics.receivedCount.GetMetricWith(p.labels) + receivedCountMetric, err := p.metrics.receivedCount.GetMetricWith(pullLabels) if err != nil { p.log.Error("failed to get received count metric", zap.Error(err)) return } - receivedBytesMetric, err := p.metrics.receivedBytes.GetMetricWith(p.labels) + receivedBytesMetric, err := p.metrics.receivedBytes.GetMetricWith(pullLabels) if err != nil { p.log.Error("failed to get received bytes metric", zap.Error(err)) return @@ -246,10 +248,7 @@ func NewPushGossiper[T Gossipable](marshaller Marshaller[T], client *p2p.Client, client: client, metrics: metrics, targetGossipSize: targetGossipSize, - labels: prometheus.Labels{ - typeLabel: pushType, - }, - pending: buffer.NewUnboundedDeque[T](0), + pending: buffer.NewUnboundedDeque[T](0), } } @@ -260,8 +259,6 @@ type PushGossiper[T Gossipable] struct { metrics Metrics targetGossipSize int - labels prometheus.Labels - lock sync.Mutex pending buffer.Deque[T] } @@ -303,12 +300,12 @@ func (p *PushGossiper[T]) Gossip(ctx context.Context) error { return err } - sentCountMetric, err := p.metrics.sentCount.GetMetricWith(p.labels) + sentCountMetric, err := p.metrics.sentCount.GetMetricWith(pushLabels) if err != nil { return fmt.Errorf("failed to get sent count metric: %w", err) } - sentBytesMetric, err := p.metrics.sentBytes.GetMetricWith(p.labels) + sentBytesMetric, err := p.metrics.sentBytes.GetMetricWith(pushLabels) if err != nil { return fmt.Errorf("failed to get sent bytes metric: %w", err) } diff --git a/network/p2p/gossip/handler.go b/network/p2p/gossip/handler.go index 0cea0c98ab71..85d2d1413544 100644 --- a/network/p2p/gossip/handler.go +++ b/network/p2p/gossip/handler.go @@ -10,8 +10,6 @@ import ( bloomfilter "github.com/holiman/bloomfilter/v2" - "github.com/prometheus/client_golang/prometheus" - "go.uber.org/zap" "google.golang.org/protobuf/proto" @@ -40,9 +38,6 @@ func NewHandler[T Gossipable]( set: set, metrics: metrics, targetResponseSize: targetResponseSize, - pullLabels: prometheus.Labels{ - typeLabel: pullType, - }, } } @@ -54,9 +49,6 @@ type Handler[T Gossipable] struct { set Set[T] metrics Metrics targetResponseSize int - - pullLabels prometheus.Labels - pushLabels prometheus.Labels } func (h Handler[T]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, requestBytes []byte) ([]byte, error) { @@ -108,12 +100,12 @@ func (h Handler[T]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, req Gossip: gossipBytes, } - sentCountMetric, err := h.metrics.sentCount.GetMetricWith(h.pullLabels) + sentCountMetric, err := h.metrics.sentCount.GetMetricWith(pullLabels) if err != nil { return nil, fmt.Errorf("failed to get sent count metric: %w", err) } - sentBytesMetric, err := h.metrics.sentBytes.GetMetricWith(h.pullLabels) + sentBytesMetric, err := h.metrics.sentBytes.GetMetricWith(pullLabels) if err != nil { return nil, fmt.Errorf("failed to get sent bytes metric: %w", err) } @@ -162,13 +154,13 @@ func (h Handler[_]) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipByte return } - receivedCountMetric, err := h.metrics.receivedCount.GetMetricWith(h.pushLabels) + receivedCountMetric, err := h.metrics.receivedCount.GetMetricWith(pushLabels) if err != nil { h.log.Error("failed to get received count metric", zap.Error(err)) return } - receivedBytesMetric, err := h.metrics.receivedBytes.GetMetricWith(h.pushLabels) + receivedBytesMetric, err := h.metrics.receivedBytes.GetMetricWith(pushLabels) if err != nil { h.log.Error("failed to get received bytes metric", zap.Error(err)) return From bbcc5f09b25611b59b244fabca739249ab089450 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 29 Dec 2023 02:21:53 -0500 Subject: [PATCH 212/267] Suppress gossip warnings due to no sampled peers (#2562) --- network/p2p/gossip/gossip.go | 4 +++- network/p2p/validators.go | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index 17795759e063..60eb5560babf 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -5,6 +5,7 @@ package gossip import ( "context" + "errors" "fmt" "sync" "time" @@ -165,7 +166,8 @@ func (p *PullGossiper[_]) Gossip(ctx context.Context) error { } for i := 0; i < p.pollSize; i++ { - if err := p.client.AppRequestAny(ctx, msgBytes, p.handleResponse); err != nil { + err := p.client.AppRequestAny(ctx, msgBytes, p.handleResponse) + if err != nil && !errors.Is(err, p2p.ErrNoPeers) { return err } } diff --git a/network/p2p/validators.go b/network/p2p/validators.go index a780c87f0d8c..06a1e913bd0f 100644 --- a/network/p2p/validators.go +++ b/network/p2p/validators.go @@ -86,6 +86,8 @@ func (v *Validators) Sample(ctx context.Context, limit int) []ids.NodeID { v.refresh(ctx) + // TODO: Account for peer connectivity during the sampling of validators + // rather than filtering sampled validators. validatorIDs := v.validatorIDs.Sample(limit) sampled := validatorIDs[:0] From 029867f92a5fc66e2990b2737cf36ba38e6a3a74 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 29 Dec 2023 10:57:19 -0500 Subject: [PATCH 213/267] Remove dead code and unnecessary lock from reflect codec (#2560) --- codec/reflectcodec/struct_fielder.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/codec/reflectcodec/struct_fielder.go b/codec/reflectcodec/struct_fielder.go index 2fa9133b7d02..8aff2ea33139 100644 --- a/codec/reflectcodec/struct_fielder.go +++ b/codec/reflectcodec/struct_fielder.go @@ -48,7 +48,7 @@ func NewStructFielder(tagNames []string, maxSliceLen uint32) StructFielder { } type structFielder struct { - lock sync.Mutex + lock sync.RWMutex // multiple tags per field can be specified. A field is serialized/deserialized // if it has at least one of the specified tags. @@ -65,15 +65,13 @@ type structFielder struct { } func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error) { + if serializedFields, ok := s.getCachedSerializedFields(t); ok { // use pre-computed result + return serializedFields, nil + } + s.lock.Lock() defer s.lock.Unlock() - if s.serializedFieldIndices == nil { - s.serializedFieldIndices = make(map[reflect.Type][]FieldDesc) - } - if serializedFields, ok := s.serializedFieldIndices[t]; ok { // use pre-computed result - return serializedFields, nil - } numFields := t.NumField() serializedFields := make([]FieldDesc, 0, numFields) for i := 0; i < numFields; i++ { // Go through all fields of this struct @@ -82,9 +80,7 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error) // Multiple tags per fields can be specified. // Serialize/Deserialize field if it has // any tag with the right value - var ( - captureField bool - ) + var captureField bool for _, tag := range s.tags { if field.Tag.Get(tag) == TagValue { captureField = true @@ -114,3 +110,11 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error) s.serializedFieldIndices[t] = serializedFields // cache result return serializedFields, nil } + +func (s *structFielder) getCachedSerializedFields(t reflect.Type) ([]FieldDesc, bool) { + s.lock.RLock() + defer s.lock.RUnlock() + + cachedFields, ok := s.serializedFieldIndices[t] + return cachedFields, ok +} From cb840e9be7b28b52408d6cbb72b2693ae9f4f931 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 29 Dec 2023 14:25:13 -0500 Subject: [PATCH 214/267] Remove unused index interface (#2564) --- indexer/index.go | 30 ++++++++++-------------------- indexer/index_test.go | 9 +++------ indexer/indexer.go | 16 ++++++++-------- indexer/service.go | 22 +++++++++++----------- 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/indexer/index.go b/indexer/index.go index 5361754bf73d..19ec2b38aa5f 100644 --- a/indexer/index.go +++ b/indexer/index.go @@ -6,7 +6,6 @@ package indexer import ( "errors" "fmt" - "io" "sync" "go.uber.org/zap" @@ -36,24 +35,14 @@ var ( errNumToFetchInvalid = fmt.Errorf("numToFetch must be in [1,%d]", MaxFetchedByRange) errNoContainerAtIndex = errors.New("no container at index") - _ Index = (*index)(nil) + _ snow.Acceptor = (*index)(nil) ) -// Index indexes containers in their order of acceptance -// Index is thread-safe. -// Index assumes that Accept is called before the container is committed to the -// database of the VM that the container exists in. -type Index interface { - snow.Acceptor - GetContainerByIndex(index uint64) (Container, error) - GetContainerRange(startIndex uint64, numToFetch uint64) ([]Container, error) - GetLastAccepted() (Container, error) - GetIndex(id ids.ID) (uint64, error) - GetContainerByID(id ids.ID) (Container, error) - io.Closer -} - -// indexer indexes all accepted transactions by the order in which they were accepted +// index indexes containers in their order of acceptance +// +// Invariant: index is thread-safe. +// Invariant: index assumes that Accept is called, before the container is +// committed to the database of the VM, in the order they were accepted. type index struct { codec codec.Manager clock mockable.Clock @@ -71,14 +60,15 @@ type index struct { log logging.Logger } -// Returns a new, thread-safe Index. -// Closes [baseDB] on close. +// Create a new thread-safe index. +// +// Invariant: Closes [baseDB] on close. func newIndex( baseDB database.Database, log logging.Logger, codec codec.Manager, clock mockable.Clock, -) (Index, error) { +) (*index, error) { vDB := versiondb.New(baseDB) indexToContainer := prefixdb.New(indexToContainerPrefix, vDB) containerToIndex := prefixdb.New(containerToIDPrefix, vDB) diff --git a/indexer/index_test.go b/indexer/index_test.go index dbac03430a3f..5c4c2f196a61 100644 --- a/indexer/index_test.go +++ b/indexer/index_test.go @@ -31,9 +31,8 @@ func TestIndex(t *testing.T) { snowCtx := snowtest.Context(t, snowtest.CChainID) ctx := snowtest.ConsensusContext(snowCtx) - indexIntf, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) + idx, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) - idx := indexIntf.(*index) // Populate "containers" with random IDs/bytes containers := map[ids.ID][]byte{} @@ -84,9 +83,8 @@ func TestIndex(t *testing.T) { require.NoError(db.Commit()) require.NoError(idx.Close()) db = versiondb.New(baseDB) - indexIntf, err = newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) + idx, err = newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) - idx = indexIntf.(*index) // Get all of the containers containersList, err := idx.GetContainerRange(0, pageSize) @@ -119,9 +117,8 @@ func TestIndexGetContainerByRangeMaxPageSize(t *testing.T) { db := memdb.New() snowCtx := snowtest.Context(t, snowtest.CChainID) ctx := snowtest.ConsensusContext(snowCtx) - indexIntf, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) + idx, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) require.NoError(err) - idx := indexIntf.(*index) // Insert [MaxFetchedByRange] + 1 containers for i := uint64(0); i < MaxFetchedByRange+1; i++ { diff --git a/indexer/indexer.go b/indexer/indexer.go index e6080c104c2a..8823c184fe14 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -88,9 +88,9 @@ func NewIndexer(config Config) (Indexer, error) { blockAcceptorGroup: config.BlockAcceptorGroup, txAcceptorGroup: config.TxAcceptorGroup, vertexAcceptorGroup: config.VertexAcceptorGroup, - txIndices: map[ids.ID]Index{}, - vtxIndices: map[ids.ID]Index{}, - blockIndices: map[ids.ID]Index{}, + txIndices: map[ids.ID]*index{}, + vtxIndices: map[ids.ID]*index{}, + blockIndices: map[ids.ID]*index{}, pathAdder: config.APIServer, shutdownF: config.ShutdownF, } @@ -134,11 +134,11 @@ type indexer struct { indexingEnabled bool // Chain ID --> index of blocks of that chain (if applicable) - blockIndices map[ids.ID]Index + blockIndices map[ids.ID]*index // Chain ID --> index of vertices of that chain (if applicable) - vtxIndices map[ids.ID]Index + vtxIndices map[ids.ID]*index // Chain ID --> index of txs of that chain (if applicable) - txIndices map[ids.ID]Index + txIndices map[ids.ID]*index // Notifies of newly accepted blocks blockAcceptorGroup snow.AcceptorGroup @@ -331,7 +331,7 @@ func (i *indexer) registerChainHelper( prefixEnd byte, name, endpoint string, acceptorGroup snow.AcceptorGroup, -) (Index, error) { +) (*index, error) { prefix := make([]byte, ids.IDLen+wrappers.ByteLen) copy(prefix, chainID[:]) prefix[ids.IDLen] = prefixEnd @@ -353,7 +353,7 @@ func (i *indexer) registerChainHelper( codec := json.NewCodec() apiServer.RegisterCodec(codec, "application/json") apiServer.RegisterCodec(codec, "application/json;charset=UTF-8") - if err := apiServer.RegisterService(&service{Index: index}, "index"); err != nil { + if err := apiServer.RegisterService(&service{index: index}, "index"); err != nil { _ = index.Close() return nil, err } diff --git a/indexer/service.go b/indexer/service.go index 98bc91e90787..5fae26bd3ee2 100644 --- a/indexer/service.go +++ b/indexer/service.go @@ -15,7 +15,7 @@ import ( ) type service struct { - Index + index *index } type FormattedContainer struct { @@ -46,11 +46,11 @@ type GetLastAcceptedArgs struct { } func (s *service) GetLastAccepted(_ *http.Request, args *GetLastAcceptedArgs, reply *FormattedContainer) error { - container, err := s.Index.GetLastAccepted() + container, err := s.index.GetLastAccepted() if err != nil { return err } - index, err := s.Index.GetIndex(container.ID) + index, err := s.index.GetIndex(container.ID) if err != nil { return fmt.Errorf("couldn't get index: %w", err) } @@ -64,11 +64,11 @@ type GetContainerByIndexArgs struct { } func (s *service) GetContainerByIndex(_ *http.Request, args *GetContainerByIndexArgs, reply *FormattedContainer) error { - container, err := s.Index.GetContainerByIndex(uint64(args.Index)) + container, err := s.index.GetContainerByIndex(uint64(args.Index)) if err != nil { return err } - index, err := s.Index.GetIndex(container.ID) + index, err := s.index.GetIndex(container.ID) if err != nil { return fmt.Errorf("couldn't get index: %w", err) } @@ -92,14 +92,14 @@ type GetContainerRangeResponse struct { // If [n] > [MaxFetchedByRange], returns an error. // If we run out of transactions, returns the ones fetched before running out. func (s *service) GetContainerRange(_ *http.Request, args *GetContainerRangeArgs, reply *GetContainerRangeResponse) error { - containers, err := s.Index.GetContainerRange(uint64(args.StartIndex), uint64(args.NumToFetch)) + containers, err := s.index.GetContainerRange(uint64(args.StartIndex), uint64(args.NumToFetch)) if err != nil { return err } reply.Containers = make([]FormattedContainer, len(containers)) for i, container := range containers { - index, err := s.Index.GetIndex(container.ID) + index, err := s.index.GetIndex(container.ID) if err != nil { return fmt.Errorf("couldn't get index: %w", err) } @@ -120,7 +120,7 @@ type GetIndexResponse struct { } func (s *service) GetIndex(_ *http.Request, args *GetIndexArgs, reply *GetIndexResponse) error { - index, err := s.Index.GetIndex(args.ID) + index, err := s.index.GetIndex(args.ID) reply.Index = json.Uint64(index) return err } @@ -134,7 +134,7 @@ type IsAcceptedResponse struct { } func (s *service) IsAccepted(_ *http.Request, args *IsAcceptedArgs, reply *IsAcceptedResponse) error { - _, err := s.Index.GetIndex(args.ID) + _, err := s.index.GetIndex(args.ID) if err == nil { reply.IsAccepted = true return nil @@ -152,11 +152,11 @@ type GetContainerByIDArgs struct { } func (s *service) GetContainerByID(_ *http.Request, args *GetContainerByIDArgs, reply *FormattedContainer) error { - container, err := s.Index.GetContainerByID(args.ID) + container, err := s.index.GetContainerByID(args.ID) if err != nil { return err } - index, err := s.Index.GetIndex(container.ID) + index, err := s.index.GetIndex(container.ID) if err != nil { return fmt.Errorf("couldn't get index: %w", err) } From 60a8158eb1848b2a4d1c837638ace879ff4b4fa0 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 29 Dec 2023 15:36:35 -0500 Subject: [PATCH 215/267] Implement SetMap and use it in XP-chain mempools (#2555) Co-authored-by: Dan Laine --- utils/setmap/setmap.go | 138 +++++++ utils/setmap/setmap_test.go | 450 +++++++++++++++++++++ vms/avm/txs/mempool/mempool.go | 29 +- vms/avm/txs/mempool/mempool_test.go | 25 ++ vms/platformvm/txs/mempool/mempool.go | 33 +- vms/platformvm/txs/mempool/mempool_test.go | 25 ++ 6 files changed, 675 insertions(+), 25 deletions(-) create mode 100644 utils/setmap/setmap.go create mode 100644 utils/setmap/setmap_test.go diff --git a/utils/setmap/setmap.go b/utils/setmap/setmap.go new file mode 100644 index 000000000000..b5d694a967c6 --- /dev/null +++ b/utils/setmap/setmap.go @@ -0,0 +1,138 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package setmap + +import ( + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/set" +) + +type Entry[K any, V comparable] struct { + Key K + Set set.Set[V] +} + +// SetMap is a map to a set where all sets are non-overlapping. +type SetMap[K, V comparable] struct { + keyToSet map[K]set.Set[V] + valueToKey map[V]K +} + +// New creates a new empty setmap. +func New[K, V comparable]() *SetMap[K, V] { + return &SetMap[K, V]{ + keyToSet: make(map[K]set.Set[V]), + valueToKey: make(map[V]K), + } +} + +// Put the new entry into the map. Removes and returns: +// * The existing entry for [key]. +// * Existing entries where the set overlaps with the [set]. +func (m *SetMap[K, V]) Put(key K, set set.Set[V]) []Entry[K, V] { + removed := m.DeleteOverlapping(set) + if removedSet, ok := m.DeleteKey(key); ok { + removed = append(removed, Entry[K, V]{ + Key: key, + Set: removedSet, + }) + } + + m.keyToSet[key] = set + for val := range set { + m.valueToKey[val] = key + } + return removed +} + +// GetKey that maps to the provided value. +func (m *SetMap[K, V]) GetKey(val V) (K, bool) { + key, ok := m.valueToKey[val] + return key, ok +} + +// GetSet that is mapped to by the provided key. +func (m *SetMap[K, V]) GetSet(key K) (set.Set[V], bool) { + val, ok := m.keyToSet[key] + return val, ok +} + +// HasKey returns true if [key] is in the map. +func (m *SetMap[K, _]) HasKey(key K) bool { + _, ok := m.keyToSet[key] + return ok +} + +// HasValue returns true if [val] is in a set in the map. +func (m *SetMap[_, V]) HasValue(val V) bool { + _, ok := m.valueToKey[val] + return ok +} + +// HasOverlap returns true if [set] overlaps with any of the sets in the map. +func (m *SetMap[_, V]) HasOverlap(set set.Set[V]) bool { + if set.Len() < len(m.valueToKey) { + for val := range set { + if _, ok := m.valueToKey[val]; ok { + return true + } + } + } else { + for val := range m.valueToKey { + if set.Contains(val) { + return true + } + } + } + return false +} + +// DeleteKey removes [key] from the map and returns the set it mapped to. +func (m *SetMap[K, V]) DeleteKey(key K) (set.Set[V], bool) { + set, ok := m.keyToSet[key] + if !ok { + return nil, false + } + + delete(m.keyToSet, key) + for val := range set { + delete(m.valueToKey, val) + } + return set, true +} + +// DeleteValue removes and returns the entry that contained [val]. +func (m *SetMap[K, V]) DeleteValue(val V) (K, set.Set[V], bool) { + key, ok := m.valueToKey[val] + if !ok { + return utils.Zero[K](), nil, false + } + set, _ := m.DeleteKey(key) + return key, set, true +} + +// DeleteOverlapping removes and returns all the entries where the set overlaps +// with [set]. +func (m *SetMap[K, V]) DeleteOverlapping(set set.Set[V]) []Entry[K, V] { + var removed []Entry[K, V] + for val := range set { + if k, removedSet, ok := m.DeleteValue(val); ok { + removed = append(removed, Entry[K, V]{ + Key: k, + Set: removedSet, + }) + } + } + return removed +} + +// Len return the number of sets in the map. +func (m *SetMap[K, V]) Len() int { + return len(m.keyToSet) +} + +// LenValues return the total number of values across all sets in the map. +func (m *SetMap[K, V]) LenValues() int { + return len(m.valueToKey) +} diff --git a/utils/setmap/setmap_test.go b/utils/setmap/setmap_test.go new file mode 100644 index 000000000000..7d140f5c69e2 --- /dev/null +++ b/utils/setmap/setmap_test.go @@ -0,0 +1,450 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package setmap + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/utils/set" +) + +func TestSetMapPut(t *testing.T) { + tests := []struct { + name string + state *SetMap[int, int] + key int + value set.Set[int] + expectedRemoved []Entry[int, int] + expectedState *SetMap[int, int] + }{ + { + name: "none removed", + state: New[int, int](), + key: 1, + value: set.Of(2), + expectedRemoved: nil, + expectedState: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(2), + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + }, + { + name: "key removed", + state: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(2), + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + key: 1, + value: set.Of(3), + expectedRemoved: []Entry[int, int]{ + { + Key: 1, + Set: set.Of(2), + }, + }, + expectedState: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(3), + }, + valueToKey: map[int]int{ + 3: 1, + }, + }, + }, + { + name: "value removed", + state: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(2), + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + key: 3, + value: set.Of(2), + expectedRemoved: []Entry[int, int]{ + { + Key: 1, + Set: set.Of(2), + }, + }, + expectedState: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 3: set.Of(2), + }, + valueToKey: map[int]int{ + 2: 3, + }, + }, + }, + { + name: "key and value removed", + state: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(2), + 3: set.Of(4), + }, + valueToKey: map[int]int{ + 2: 1, + 4: 3, + }, + }, + key: 1, + value: set.Of(4), + expectedRemoved: []Entry[int, int]{ + { + Key: 1, + Set: set.Of(2), + }, + { + Key: 3, + Set: set.Of(4), + }, + }, + expectedState: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(4), + }, + valueToKey: map[int]int{ + 4: 1, + }, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + removed := test.state.Put(test.key, test.value) + require.ElementsMatch(test.expectedRemoved, removed) + require.Equal(test.expectedState, test.state) + }) + } +} + +func TestSetMapHasValueAndGetKeyAndSetOverlaps(t *testing.T) { + m := New[int, int]() + require.Empty(t, m.Put(1, set.Of(2))) + + tests := []struct { + name string + value int + expectedKey int + expectedExists bool + }{ + { + name: "fetch unknown", + value: 3, + expectedKey: 0, + expectedExists: false, + }, + { + name: "fetch known value", + value: 2, + expectedKey: 1, + expectedExists: true, + }, + { + name: "fetch known key", + value: 1, + expectedKey: 0, + expectedExists: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + exists := m.HasValue(test.value) + require.Equal(test.expectedExists, exists) + + key, exists := m.GetKey(test.value) + require.Equal(test.expectedKey, key) + require.Equal(test.expectedExists, exists) + }) + } +} + +func TestSetMapHasOverlap(t *testing.T) { + m := New[int, int]() + require.Empty(t, m.Put(1, set.Of(2))) + require.Empty(t, m.Put(2, set.Of(3, 4))) + + tests := []struct { + name string + set set.Set[int] + expectedOverlaps bool + }{ + { + name: "small fetch unknown", + set: set.Of(5), + expectedOverlaps: false, + }, + { + name: "large fetch unknown", + set: set.Of(5, 6, 7, 8), + expectedOverlaps: false, + }, + { + name: "small fetch known", + set: set.Of(3), + expectedOverlaps: true, + }, + { + name: "large fetch known", + set: set.Of(3, 5, 6, 7, 8), + expectedOverlaps: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + overlaps := m.HasOverlap(test.set) + require.Equal(t, test.expectedOverlaps, overlaps) + }) + } +} + +func TestSetMapHasKeyAndGetSet(t *testing.T) { + m := New[int, int]() + require.Empty(t, m.Put(1, set.Of(2))) + + tests := []struct { + name string + key int + expectedValue set.Set[int] + expectedExists bool + }{ + { + name: "fetch unknown", + key: 3, + expectedValue: nil, + expectedExists: false, + }, + { + name: "fetch known key", + key: 1, + expectedValue: set.Of(2), + expectedExists: true, + }, + { + name: "fetch known value", + key: 2, + expectedValue: nil, + expectedExists: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + exists := m.HasKey(test.key) + require.Equal(test.expectedExists, exists) + + value, exists := m.GetSet(test.key) + require.Equal(test.expectedValue, value) + require.Equal(test.expectedExists, exists) + }) + } +} + +func TestSetMapDeleteKey(t *testing.T) { + tests := []struct { + name string + state *SetMap[int, int] + key int + expectedValue set.Set[int] + expectedRemoved bool + expectedState *SetMap[int, int] + }{ + { + name: "none removed", + state: New[int, int](), + key: 1, + expectedValue: nil, + expectedRemoved: false, + expectedState: New[int, int](), + }, + { + name: "key removed", + state: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(2), + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + key: 1, + expectedValue: set.Of(2), + expectedRemoved: true, + expectedState: New[int, int](), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + value, removed := test.state.DeleteKey(test.key) + require.Equal(test.expectedValue, value) + require.Equal(test.expectedRemoved, removed) + require.Equal(test.expectedState, test.state) + }) + } +} + +func TestSetMapDeleteValue(t *testing.T) { + tests := []struct { + name string + state *SetMap[int, int] + value int + expectedKey int + expectedSet set.Set[int] + expectedRemoved bool + expectedState *SetMap[int, int] + }{ + { + name: "none removed", + state: New[int, int](), + value: 1, + expectedKey: 0, + expectedSet: nil, + expectedRemoved: false, + expectedState: New[int, int](), + }, + { + name: "key removed", + state: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(2), + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + value: 2, + expectedKey: 1, + expectedSet: set.Of(2), + expectedRemoved: true, + expectedState: New[int, int](), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + key, set, removed := test.state.DeleteValue(test.value) + require.Equal(test.expectedKey, key) + require.Equal(test.expectedSet, set) + require.Equal(test.expectedRemoved, removed) + require.Equal(test.expectedState, test.state) + }) + } +} + +func TestSetMapDeleteOverlapping(t *testing.T) { + tests := []struct { + name string + state *SetMap[int, int] + set set.Set[int] + expectedRemoved []Entry[int, int] + expectedState *SetMap[int, int] + }{ + { + name: "none removed", + state: New[int, int](), + set: set.Of(1), + expectedRemoved: nil, + expectedState: New[int, int](), + }, + { + name: "key removed", + state: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(2), + }, + valueToKey: map[int]int{ + 2: 1, + }, + }, + set: set.Of(2), + expectedRemoved: []Entry[int, int]{ + { + Key: 1, + Set: set.Of(2), + }, + }, + expectedState: New[int, int](), + }, + { + name: "multiple keys removed", + state: &SetMap[int, int]{ + keyToSet: map[int]set.Set[int]{ + 1: set.Of(2, 3), + 2: set.Of(4), + }, + valueToKey: map[int]int{ + 2: 1, + 3: 1, + 4: 2, + }, + }, + set: set.Of(2, 4), + expectedRemoved: []Entry[int, int]{ + { + Key: 1, + Set: set.Of(2, 3), + }, + { + Key: 2, + Set: set.Of(4), + }, + }, + expectedState: New[int, int](), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require := require.New(t) + + removed := test.state.DeleteOverlapping(test.set) + require.ElementsMatch(test.expectedRemoved, removed) + require.Equal(test.expectedState, test.state) + }) + } +} + +func TestSetMapLen(t *testing.T) { + require := require.New(t) + + m := New[int, int]() + require.Zero(m.Len()) + require.Zero(m.LenValues()) + + m.Put(1, set.Of(2)) + require.Equal(1, m.Len()) + require.Equal(1, m.LenValues()) + + m.Put(2, set.Of(3, 4)) + require.Equal(2, m.Len()) + require.Equal(3, m.LenValues()) + + m.Put(1, set.Of(4, 5)) + require.Equal(1, m.Len()) + require.Equal(2, m.LenValues()) + + m.DeleteKey(1) + require.Zero(m.Len()) + require.Zero(m.LenValues()) +} diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index f7d9bc37262d..3e0dd3793560 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/linkedhashmap" - "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/setmap" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/avm/txs" ) @@ -45,6 +45,7 @@ var ( type Mempool interface { Add(tx *txs.Tx) error Get(txID ids.ID) (*txs.Tx, bool) + // Remove [txs] and any conflicts of [txs] from the mempool. Remove(txs ...*txs.Tx) // Peek returns the oldest tx in the mempool. @@ -67,7 +68,7 @@ type Mempool interface { type mempool struct { lock sync.RWMutex unissuedTxs linkedhashmap.LinkedHashmap[ids.ID, *txs.Tx] - consumedUTXOs set.Set[ids.ID] + consumedUTXOs *setmap.SetMap[ids.ID, ids.ID] // TxID -> Consumed UTXOs bytesAvailable int droppedTxIDs *cache.LRU[ids.ID, error] // TxID -> Verification error @@ -84,6 +85,7 @@ func New( ) (Mempool, error) { m := &mempool{ unissuedTxs: linkedhashmap.New[ids.ID, *txs.Tx](), + consumedUTXOs: setmap.New[ids.ID, ids.ID](), bytesAvailable: maxMempoolSize, droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, toEngine: toEngine, @@ -136,7 +138,7 @@ func (m *mempool) Add(tx *txs.Tx) error { } inputs := tx.Unsigned.InputIDs() - if m.consumedUTXOs.Overlaps(inputs) { + if m.consumedUTXOs.HasOverlap(inputs) { return fmt.Errorf("%w: %s", ErrConflictsWithOtherTx, txID) } @@ -147,7 +149,7 @@ func (m *mempool) Add(tx *txs.Tx) error { m.numTxs.Inc() // Mark these UTXOs as consumed in the mempool - m.consumedUTXOs.Union(inputs) + m.consumedUTXOs.Put(txID, inputs) // An added tx must not be marked as dropped. m.droppedTxIDs.Evict(txID) @@ -165,18 +167,23 @@ func (m *mempool) Remove(txs ...*txs.Tx) { for _, tx := range txs { txID := tx.ID() - if !m.unissuedTxs.Delete(txID) { + // If the transaction is in the mempool, remove it. + if _, ok := m.consumedUTXOs.DeleteKey(txID); ok { + m.unissuedTxs.Delete(txID) + m.bytesAvailable += len(tx.Bytes()) continue } - m.bytesAvailable += len(tx.Bytes()) - m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) - - m.numTxs.Dec() - + // If the transaction isn't in the mempool, remove any conflicts it has. inputs := tx.Unsigned.InputIDs() - m.consumedUTXOs.Difference(inputs) + for _, removed := range m.consumedUTXOs.DeleteOverlapping(inputs) { + tx, _ := m.unissuedTxs.Get(removed.Key) + m.unissuedTxs.Delete(removed.Key) + m.bytesAvailable += len(tx.Bytes()) + } } + m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) + m.numTxs.Set(float64(m.unissuedTxs.Len())) } func (m *mempool) Peek() (*txs.Tx, bool) { diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index 5691662cbaa0..d76caebbb2af 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -163,6 +163,31 @@ func TestPeek(t *testing.T) { require.False(exists) } +func TestRemoveConflict(t *testing.T) { + require := require.New(t) + + mempool, err := New( + "mempool", + prometheus.NewRegistry(), + nil, + ) + require.NoError(err) + + tx := newTx(0, 32) + txConflict := newTx(0, 32) + + require.NoError(mempool.Add(tx)) + + returnedTx, exists := mempool.Peek() + require.True(exists) + require.Equal(returnedTx, tx) + + mempool.Remove(txConflict) + + _, exists = mempool.Peek() + require.False(exists) +} + func TestIterate(t *testing.T) { require := require.New(t) diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 148a804f9df6..63315d99c5fc 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/linkedhashmap" - "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/setmap" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) @@ -28,8 +28,6 @@ const ( // droppedTxIDsCacheSize is the maximum number of dropped txIDs to cache droppedTxIDsCacheSize = 64 - initialConsumedUTXOsSize = 512 - // maxMempoolSize is the maximum number of bytes allowed in the mempool maxMempoolSize = 64 * units.MiB ) @@ -48,6 +46,7 @@ var ( type Mempool interface { Add(tx *txs.Tx) error Get(txID ids.ID) (*txs.Tx, bool) + // Remove [txs] and any conflicts of [txs] from the mempool. Remove(txs ...*txs.Tx) // Peek returns the oldest tx in the mempool. @@ -75,7 +74,7 @@ type Mempool interface { type mempool struct { lock sync.RWMutex unissuedTxs linkedhashmap.LinkedHashmap[ids.ID, *txs.Tx] - consumedUTXOs set.Set[ids.ID] + consumedUTXOs *setmap.SetMap[ids.ID, ids.ID] // TxID -> Consumed UTXOs bytesAvailable int droppedTxIDs *cache.LRU[ids.ID, error] // TxID -> verification error @@ -92,7 +91,7 @@ func New( ) (Mempool, error) { m := &mempool{ unissuedTxs: linkedhashmap.New[ids.ID, *txs.Tx](), - consumedUTXOs: set.NewSet[ids.ID](initialConsumedUTXOsSize), + consumedUTXOs: setmap.New[ids.ID, ids.ID](), bytesAvailable: maxMempoolSize, droppedTxIDs: &cache.LRU[ids.ID, error]{Size: droppedTxIDsCacheSize}, toEngine: toEngine, @@ -153,17 +152,17 @@ func (m *mempool) Add(tx *txs.Tx) error { } inputs := tx.Unsigned.InputIDs() - if m.consumedUTXOs.Overlaps(inputs) { + if m.consumedUTXOs.HasOverlap(inputs) { return fmt.Errorf("%w: %s", ErrConflictsWithOtherTx, txID) } - m.unissuedTxs.Put(tx.ID(), tx) + m.unissuedTxs.Put(txID, tx) m.numTxs.Inc() m.bytesAvailable -= txSize m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) // Mark these UTXOs as consumed in the mempool - m.consumedUTXOs.Union(inputs) + m.consumedUTXOs.Put(txID, inputs) // An explicitly added tx must not be marked as dropped. m.droppedTxIDs.Evict(txID) @@ -181,17 +180,23 @@ func (m *mempool) Remove(txs ...*txs.Tx) { for _, tx := range txs { txID := tx.ID() - if !m.unissuedTxs.Delete(txID) { + // If the transaction is in the mempool, remove it. + if _, ok := m.consumedUTXOs.DeleteKey(txID); ok { + m.unissuedTxs.Delete(txID) + m.bytesAvailable += len(tx.Bytes()) continue } - m.numTxs.Dec() - - m.bytesAvailable += len(tx.Bytes()) - m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) + // If the transaction isn't in the mempool, remove any conflicts it has. inputs := tx.Unsigned.InputIDs() - m.consumedUTXOs.Difference(inputs) + for _, removed := range m.consumedUTXOs.DeleteOverlapping(inputs) { + tx, _ := m.unissuedTxs.Get(removed.Key) + m.unissuedTxs.Delete(removed.Key) + m.bytesAvailable += len(tx.Bytes()) + } } + m.bytesAvailableMetric.Set(float64(m.bytesAvailable)) + m.numTxs.Set(float64(m.unissuedTxs.Len())) } func (m *mempool) Peek() (*txs.Tx, bool) { diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index 31420e94ecbb..280dc5487ba6 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -239,3 +239,28 @@ func TestPeekTxs(t *testing.T) { require.False(exists) require.Nil(tx) } + +func TestRemoveConflicts(t *testing.T) { + require := require.New(t) + + registerer := prometheus.NewRegistry() + toEngine := make(chan common.Message, 100) + mempool, err := New("mempool", registerer, toEngine) + require.NoError(err) + + txs, err := createTestDecisionTxs(1) + require.NoError(err) + conflictTxs, err := createTestDecisionTxs(1) + require.NoError(err) + + require.NoError(mempool.Add(txs[0])) + + tx, exists := mempool.Peek() + require.True(exists) + require.Equal(tx, txs[0]) + + mempool.Remove(conflictTxs[0]) + + _, exists = mempool.Peek() + require.False(exists) +} From 6d28ae0fc0e1d22859ba2f4e6c7ae268c4ab4ecb Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Fri, 29 Dec 2023 16:06:30 -0500 Subject: [PATCH 216/267] `vms/platformvm`: Add `TestIterate` (#2565) --- vms/platformvm/txs/mempool/mempool_test.go | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index 280dc5487ba6..c4af0fc1c6db 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" @@ -264,3 +265,36 @@ func TestRemoveConflicts(t *testing.T) { _, exists = mempool.Peek() require.False(exists) } + +func TestIterate(t *testing.T) { + require := require.New(t) + + registerer := prometheus.NewRegistry() + toEngine := make(chan common.Message, 100) + mempool, err := New("mempool", registerer, toEngine) + require.NoError(err) + + testDecisionTxs, err := createTestDecisionTxs(1) + require.NoError(err) + decisionTx := testDecisionTxs[0] + + testProposalTxs, err := createTestProposalTxs(1) + require.NoError(err) + proposalTx := testProposalTxs[0] + + require.NoError(mempool.Add(decisionTx)) + require.NoError(mempool.Add(proposalTx)) + + expectedSet := set.Of( + decisionTx.ID(), + proposalTx.ID(), + ) + + set := set.NewSet[ids.ID](2) + mempool.Iterate(func(tx *txs.Tx) bool { + set.Add(tx.ID()) + return true + }) + + require.Equal(expectedSet, set) +} From e89d9728b0cb62a5ec2a621f4aa8752de6debcb5 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 29 Dec 2023 16:18:14 -0500 Subject: [PATCH 217/267] Cleanup codec usage (#2563) --- api/keystore/codec.go | 10 ++--- api/keystore/keystore.go | 10 ++--- chains/atomic/codec.go | 12 +++--- chains/atomic/memory.go | 2 +- chains/atomic/state.go | 6 +-- database/encdb/codec.go | 22 +++++++++++ database/encdb/db.go | 19 ++-------- database/linkeddb/codec.go | 13 ++----- database/linkeddb/linkeddb.go | 4 +- indexer/codec.go | 24 ++++++++++++ indexer/index.go | 8 +--- indexer/index_test.go | 16 ++------ indexer/indexer.go | 37 +++++-------------- indexer/indexer_test.go | 1 - snow/engine/avalanche/vertex/builder.go | 6 +-- snow/engine/avalanche/vertex/codec.go | 25 +++++++------ snow/engine/avalanche/vertex/parser.go | 2 +- .../avalanche/vertex/stateless_vertex.go | 8 ++-- vms/components/keystore/codec.go | 6 +-- vms/components/message/codec.go | 10 ++--- vms/components/message/message.go | 6 +-- vms/example/xsvm/api/client.go | 2 +- vms/example/xsvm/block/block.go | 2 +- vms/example/xsvm/block/codec.go | 3 +- vms/example/xsvm/chain/chain.go | 2 +- vms/example/xsvm/cmd/chain/create/cmd.go | 2 +- vms/example/xsvm/cmd/chain/genesis/cmd.go | 2 +- vms/example/xsvm/execute/block.go | 2 +- vms/example/xsvm/execute/genesis.go | 2 +- vms/example/xsvm/genesis/codec.go | 3 +- vms/example/xsvm/genesis/genesis.go | 2 +- vms/example/xsvm/genesis/genesis_test.go | 2 +- vms/example/xsvm/tx/codec.go | 5 +-- vms/example/xsvm/tx/payload.go | 2 +- vms/example/xsvm/tx/tx.go | 6 +-- vms/platformvm/api/static_service.go | 2 +- vms/platformvm/block/block.go | 2 +- .../block/builder/standard_block_test.go | 2 +- vms/platformvm/block/codec.go | 7 ++-- vms/platformvm/block/serialization_test.go | 2 +- vms/platformvm/genesis/codec.go | 2 +- vms/platformvm/service.go | 6 +-- vms/platformvm/service_test.go | 2 +- vms/platformvm/state/metadata_codec.go | 20 +++++----- vms/platformvm/state/metadata_delegator.go | 4 +- .../state/metadata_delegator_test.go | 8 ++-- vms/platformvm/state/metadata_validator.go | 6 +-- .../state/metadata_validator_test.go | 7 ++-- vms/platformvm/state/state.go | 20 +++++----- vms/platformvm/state/state_test.go | 2 +- .../add_permissionless_delegator_tx_test.go | 8 ++-- .../add_permissionless_validator_tx_test.go | 8 ++-- .../txs/add_subnet_validator_test.go | 2 +- vms/platformvm/txs/base_tx_test.go | 4 +- vms/platformvm/txs/codec.go | 7 ++-- .../txs/executor/advance_time_test.go | 2 +- vms/platformvm/txs/executor/import_test.go | 2 +- .../txs/executor/standard_tx_executor.go | 2 +- .../txs/remove_subnet_validator_tx_test.go | 4 +- .../txs/transfer_subnet_ownership_tx_test.go | 4 +- .../txs/transform_subnet_tx_test.go | 4 +- vms/platformvm/txs/tx.go | 10 ++--- vms/platformvm/utxo/handler.go | 4 +- vms/platformvm/vm_regression_test.go | 4 +- vms/platformvm/vm_test.go | 2 +- vms/platformvm/warp/codec.go | 9 ++--- vms/platformvm/warp/message.go | 4 +- vms/platformvm/warp/payload/codec.go | 9 ++--- vms/platformvm/warp/payload/payload.go | 4 +- vms/platformvm/warp/unsigned_message.go | 4 +- vms/proposervm/block/build.go | 10 ++--- vms/proposervm/block/codec.go | 21 +++++------ vms/proposervm/block/parse.go | 12 +++--- vms/proposervm/state/block_state.go | 6 +-- vms/proposervm/state/codec.go | 8 ++-- vms/proposervm/summary/build.go | 2 +- vms/proposervm/summary/codec.go | 8 ++-- vms/proposervm/summary/parse.go | 4 +- wallet/chain/p/signer_visitor.go | 4 +- 79 files changed, 265 insertions(+), 283 deletions(-) create mode 100644 database/encdb/codec.go create mode 100644 indexer/codec.go diff --git a/api/keystore/codec.go b/api/keystore/codec.go index ebb196ccbfff..68025c140564 100644 --- a/api/keystore/codec.go +++ b/api/keystore/codec.go @@ -10,18 +10,18 @@ import ( ) const ( + CodecVersion = 0 + maxPackerSize = 1 * units.GiB // max size, in bytes, of something being marshalled by Marshal() maxSliceLength = linearcodec.DefaultMaxSliceLength - - codecVersion = 0 ) -var c codec.Manager +var Codec codec.Manager func init() { lc := linearcodec.NewCustomMaxLength(maxSliceLength) - c = codec.NewManager(maxPackerSize) - if err := c.RegisterCodec(codecVersion, lc); err != nil { + Codec = codec.NewManager(maxPackerSize) + if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { panic(err) } } diff --git a/api/keystore/keystore.go b/api/keystore/keystore.go index cd7f0b8a8f21..02d5f5dc6238 100644 --- a/api/keystore/keystore.go +++ b/api/keystore/keystore.go @@ -188,7 +188,7 @@ func (ks *keystore) CreateUser(username, pw string) error { return err } - passwordBytes, err := c.Marshal(codecVersion, passwordHash) + passwordBytes, err := Codec.Marshal(CodecVersion, passwordHash) if err != nil { return err } @@ -288,14 +288,14 @@ func (ks *keystore) ImportUser(username, pw string, userBytes []byte) error { } userData := user{} - if _, err := c.Unmarshal(userBytes, &userData); err != nil { + if _, err := Codec.Unmarshal(userBytes, &userData); err != nil { return err } if !userData.Hash.Check(pw) { return fmt.Errorf("%w: user %q", errIncorrectPassword, username) } - usrBytes, err := c.Marshal(codecVersion, &userData.Hash) + usrBytes, err := Codec.Marshal(CodecVersion, &userData.Hash) if err != nil { return err } @@ -355,7 +355,7 @@ func (ks *keystore) ExportUser(username, pw string) ([]byte, error) { } // Return the byte representation of the user - return c.Marshal(codecVersion, &userData) + return Codec.Marshal(CodecVersion, &userData) } func (ks *keystore) getPassword(username string) (*password.Hash, error) { @@ -377,6 +377,6 @@ func (ks *keystore) getPassword(username string) (*password.Hash, error) { } passwordHash = &password.Hash{} - _, err = c.Unmarshal(userBytes, passwordHash) + _, err = Codec.Unmarshal(userBytes, passwordHash) return passwordHash, err } diff --git a/chains/atomic/codec.go b/chains/atomic/codec.go index bc2e93c27213..49bfd4bf9323 100644 --- a/chains/atomic/codec.go +++ b/chains/atomic/codec.go @@ -8,15 +8,15 @@ import ( "github.com/ava-labs/avalanchego/codec/linearcodec" ) -const codecVersion = 0 +const CodecVersion = 0 -// codecManager is used to marshal and unmarshal dbElements and chain IDs. -var codecManager codec.Manager +// Codec is used to marshal and unmarshal dbElements and chain IDs. +var Codec codec.Manager func init() { - linearCodec := linearcodec.NewDefault() - codecManager = codec.NewDefaultManager() - if err := codecManager.RegisterCodec(codecVersion, linearCodec); err != nil { + lc := linearcodec.NewDefault() + Codec = codec.NewDefaultManager() + if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { panic(err) } } diff --git a/chains/atomic/memory.go b/chains/atomic/memory.go index a8aa703fe217..77c1bb78cec6 100644 --- a/chains/atomic/memory.go +++ b/chains/atomic/memory.go @@ -107,7 +107,7 @@ func sharedID(id1, id2 ids.ID) ids.ID { id1, id2 = id2, id1 } - combinedBytes, err := codecManager.Marshal(codecVersion, [2]ids.ID{id1, id2}) + combinedBytes, err := Codec.Marshal(CodecVersion, [2]ids.ID{id1, id2}) if err != nil { panic(err) } diff --git a/chains/atomic/state.go b/chains/atomic/state.go index 402477299c21..7751d452b510 100644 --- a/chains/atomic/state.go +++ b/chains/atomic/state.go @@ -112,7 +112,7 @@ func (s *state) SetValue(e *Element) error { Traits: e.Traits, } - valueBytes, err := codecManager.Marshal(codecVersion, &dbElem) + valueBytes, err := Codec.Marshal(CodecVersion, &dbElem) if err != nil { return err } @@ -156,7 +156,7 @@ func (s *state) RemoveValue(key []byte) error { // The value doesn't exist, so we should optimistically delete it dbElem := dbElement{Present: false} - valueBytes, err := codecManager.Marshal(codecVersion, &dbElem) + valueBytes, err := Codec.Marshal(CodecVersion, &dbElem) if err != nil { return err } @@ -189,7 +189,7 @@ func (s *state) loadValue(key []byte) (*dbElement, error) { // The key was in the database value := &dbElement{} - _, err = codecManager.Unmarshal(valueBytes, value) + _, err = Codec.Unmarshal(valueBytes, value) return value, err } diff --git a/database/encdb/codec.go b/database/encdb/codec.go new file mode 100644 index 000000000000..ab9977945f6d --- /dev/null +++ b/database/encdb/codec.go @@ -0,0 +1,22 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package encdb + +import ( + "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/codec/linearcodec" +) + +const CodecVersion = 0 + +var Codec codec.Manager + +func init() { + lc := linearcodec.NewDefault() + Codec = codec.NewDefaultManager() + + if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { + panic(err) + } +} diff --git a/database/encdb/db.go b/database/encdb/db.go index 42518bef9fc9..27565c87f99b 100644 --- a/database/encdb/db.go +++ b/database/encdb/db.go @@ -13,16 +13,10 @@ import ( "golang.org/x/exp/slices" - "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/utils/hashing" ) -const ( - codecVersion = 0 -) - var ( _ database.Database = (*Database)(nil) _ database.Batch = (*batch)(nil) @@ -32,7 +26,6 @@ var ( // Database encrypts all values that are provided type Database struct { lock sync.RWMutex - codec codec.Manager cipher cipher.AEAD db database.Database closed bool @@ -42,16 +35,10 @@ type Database struct { func New(password []byte, db database.Database) (*Database, error) { h := hashing.ComputeHash256(password) aead, err := chacha20poly1305.NewX(h) - if err != nil { - return nil, err - } - c := linearcodec.NewDefault() - manager := codec.NewDefaultManager() return &Database{ - codec: manager, cipher: aead, db: db, - }, manager.RegisterCodec(codecVersion, c) + }, err } func (db *Database) Has(key []byte) (bool, error) { @@ -297,7 +284,7 @@ func (db *Database) encrypt(plaintext []byte) ([]byte, error) { return nil, err } ciphertext := db.cipher.Seal(nil, nonce, plaintext, nil) - return db.codec.Marshal(codecVersion, &encryptedValue{ + return Codec.Marshal(CodecVersion, &encryptedValue{ Ciphertext: ciphertext, Nonce: nonce, }) @@ -305,7 +292,7 @@ func (db *Database) encrypt(plaintext []byte) ([]byte, error) { func (db *Database) decrypt(ciphertext []byte) ([]byte, error) { val := encryptedValue{} - if _, err := db.codec.Unmarshal(ciphertext, &val); err != nil { + if _, err := Codec.Unmarshal(ciphertext, &val); err != nil { return nil, err } return db.cipher.Open(nil, val.Nonce, val.Ciphertext, nil) diff --git a/database/linkeddb/codec.go b/database/linkeddb/codec.go index 7780690b2e92..b2607dfbb045 100644 --- a/database/linkeddb/codec.go +++ b/database/linkeddb/codec.go @@ -10,20 +10,15 @@ import ( "github.com/ava-labs/avalanchego/codec/linearcodec" ) -const ( - codecVersion = 0 -) +const CodecVersion = 0 -// c does serialization and deserialization -var ( - c codec.Manager -) +var Codec codec.Manager func init() { lc := linearcodec.NewCustomMaxLength(math.MaxUint32) - c = codec.NewManager(math.MaxInt32) + Codec = codec.NewManager(math.MaxInt32) - if err := c.RegisterCodec(codecVersion, lc); err != nil { + if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { panic(err) } } diff --git a/database/linkeddb/linkeddb.go b/database/linkeddb/linkeddb.go index 597e1258367e..6120d182fbc2 100644 --- a/database/linkeddb/linkeddb.go +++ b/database/linkeddb/linkeddb.go @@ -316,7 +316,7 @@ func (ldb *linkedDB) getNode(key []byte) (node, error) { return node{}, err } n := node{} - _, err = c.Unmarshal(nodeBytes, &n) + _, err = Codec.Unmarshal(nodeBytes, &n) if err == nil { ldb.nodeCache.Put(keyStr, &n) } @@ -325,7 +325,7 @@ func (ldb *linkedDB) getNode(key []byte) (node, error) { func (ldb *linkedDB) putNode(key []byte, n node) error { ldb.updatedNodes[string(key)] = &n - nodeBytes, err := c.Marshal(codecVersion, n) + nodeBytes, err := Codec.Marshal(CodecVersion, n) if err != nil { return err } diff --git a/indexer/codec.go b/indexer/codec.go new file mode 100644 index 000000000000..f41cb8fa80f1 --- /dev/null +++ b/indexer/codec.go @@ -0,0 +1,24 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package indexer + +import ( + "math" + + "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/codec/linearcodec" +) + +const CodecVersion = 0 + +var Codec codec.Manager + +func init() { + lc := linearcodec.NewCustomMaxLength(math.MaxUint32) + Codec = codec.NewManager(math.MaxInt) + + if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { + panic(err) + } +} diff --git a/indexer/index.go b/indexer/index.go index 19ec2b38aa5f..d182c6938d8e 100644 --- a/indexer/index.go +++ b/indexer/index.go @@ -10,7 +10,6 @@ import ( "go.uber.org/zap" - "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/database/versiondb" @@ -44,7 +43,6 @@ var ( // Invariant: index assumes that Accept is called, before the container is // committed to the database of the VM, in the order they were accepted. type index struct { - codec codec.Manager clock mockable.Clock lock sync.RWMutex // The index of the next accepted transaction @@ -66,7 +64,6 @@ type index struct { func newIndex( baseDB database.Database, log logging.Logger, - codec codec.Manager, clock mockable.Clock, ) (*index, error) { vDB := versiondb.New(baseDB) @@ -75,7 +72,6 @@ func newIndex( i := &index{ clock: clock, - codec: codec, baseDB: baseDB, vDB: vDB, indexToContainer: indexToContainer, @@ -140,7 +136,7 @@ func (i *index) Accept(ctx *snow.ConsensusContext, containerID ids.ID, container ) // Persist index --> Container nextAcceptedIndexBytes := database.PackUInt64(i.nextAcceptedIndex) - bytes, err := i.codec.Marshal(codecVersion, Container{ + bytes, err := Codec.Marshal(CodecVersion, Container{ ID: containerID, Bytes: containerBytes, Timestamp: i.clock.Time().UnixNano(), @@ -199,7 +195,7 @@ func (i *index) getContainerByIndexBytes(indexBytes []byte) (Container, error) { return Container{}, fmt.Errorf("couldn't read from database: %w", err) } var container Container - if _, err := i.codec.Unmarshal(containerBytes, &container); err != nil { + if _, err := Codec.Unmarshal(containerBytes, &container); err != nil { return Container{}, fmt.Errorf("couldn't unmarshal container: %w", err) } return container, nil diff --git a/indexer/index_test.go b/indexer/index_test.go index 5c4c2f196a61..0007c8ae4e12 100644 --- a/indexer/index_test.go +++ b/indexer/index_test.go @@ -8,8 +8,6 @@ import ( "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/ids" @@ -24,14 +22,12 @@ func TestIndex(t *testing.T) { // Setup pageSize := uint64(64) require := require.New(t) - codec := codec.NewDefaultManager() - require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) baseDB := memdb.New() db := versiondb.New(baseDB) snowCtx := snowtest.Context(t, snowtest.CChainID) ctx := snowtest.ConsensusContext(snowCtx) - idx, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) + idx, err := newIndex(db, logging.NoLog{}, mockable.Clock{}) require.NoError(err) // Populate "containers" with random IDs/bytes @@ -83,7 +79,7 @@ func TestIndex(t *testing.T) { require.NoError(db.Commit()) require.NoError(idx.Close()) db = versiondb.New(baseDB) - idx, err = newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) + idx, err = newIndex(db, logging.NoLog{}, mockable.Clock{}) require.NoError(err) // Get all of the containers @@ -112,12 +108,10 @@ func TestIndex(t *testing.T) { func TestIndexGetContainerByRangeMaxPageSize(t *testing.T) { // Setup require := require.New(t) - codec := codec.NewDefaultManager() - require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) db := memdb.New() snowCtx := snowtest.Context(t, snowtest.CChainID) ctx := snowtest.ConsensusContext(snowCtx) - idx, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) + idx, err := newIndex(db, logging.NoLog{}, mockable.Clock{}) require.NoError(err) // Insert [MaxFetchedByRange] + 1 containers @@ -152,12 +146,10 @@ func TestIndexGetContainerByRangeMaxPageSize(t *testing.T) { func TestDontIndexSameContainerTwice(t *testing.T) { // Setup require := require.New(t) - codec := codec.NewDefaultManager() - require.NoError(codec.RegisterCodec(codecVersion, linearcodec.NewDefault())) db := memdb.New() snowCtx := snowtest.Context(t, snowtest.CChainID) ctx := snowtest.ConsensusContext(snowCtx) - idx, err := newIndex(db, logging.NoLog{}, codec, mockable.Clock{}) + idx, err := newIndex(db, logging.NoLog{}, mockable.Clock{}) require.NoError(err) // Accept the same container twice diff --git a/indexer/indexer.go b/indexer/indexer.go index 8823c184fe14..99f475892562 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -6,7 +6,6 @@ package indexer import ( "fmt" "io" - "math" "sync" "github.com/gorilla/rpc/v2" @@ -15,8 +14,6 @@ import ( "github.com/ava-labs/avalanchego/api/server" "github.com/ava-labs/avalanchego/chains" - "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/ids" @@ -32,26 +29,18 @@ import ( ) const ( - indexNamePrefix = "index-" - codecVersion = uint16(0) - // Max size, in bytes, of something serialized by this indexer - // Assumes no containers are larger than math.MaxUint32 - // wrappers.IntLen accounts for the size of the container bytes - // wrappers.LongLen accounts for the timestamp of the container - // ids.IDLen accounts for the container ID - // wrappers.ShortLen accounts for the codec version - codecMaxSize = int(constants.DefaultMaxMessageSize) + wrappers.IntLen + wrappers.LongLen + ids.IDLen + wrappers.ShortLen + indexNamePrefix = "index-" + txPrefix = 0x01 + vtxPrefix = 0x02 + blockPrefix = 0x03 + isIncompletePrefix = 0x04 + previouslyIndexedPrefix = 0x05 ) var ( - txPrefix = byte(0x01) - vtxPrefix = byte(0x02) - blockPrefix = byte(0x03) - isIncompletePrefix = byte(0x04) - previouslyIndexedPrefix = byte(0x05) - hasRunKey = []byte{0x07} - _ Indexer = (*indexer)(nil) + + hasRunKey = []byte{0x07} ) // Config for an indexer @@ -80,7 +69,6 @@ type Indexer interface { // NewIndexer returns a new Indexer and registers a new endpoint on the given API server. func NewIndexer(config Config) (Indexer, error) { indexer := &indexer{ - codec: codec.NewManager(codecMaxSize), log: config.Log, db: config.DB, allowIncompleteIndex: config.AllowIncompleteIndex, @@ -95,12 +83,6 @@ func NewIndexer(config Config) (Indexer, error) { shutdownF: config.ShutdownF, } - if err := indexer.codec.RegisterCodec( - codecVersion, - linearcodec.NewCustomMaxLength(math.MaxUint32), - ); err != nil { - return nil, fmt.Errorf("couldn't register codec: %w", err) - } hasRun, err := indexer.hasRun() if err != nil { return nil, err @@ -110,7 +92,6 @@ func NewIndexer(config Config) (Indexer, error) { } type indexer struct { - codec codec.Manager clock mockable.Clock lock sync.RWMutex log logging.Logger @@ -336,7 +317,7 @@ func (i *indexer) registerChainHelper( copy(prefix, chainID[:]) prefix[ids.IDLen] = prefixEnd indexDB := prefixdb.New(prefix, i.db) - index, err := newIndex(indexDB, i.log, i.codec, i.clock) + index, err := newIndex(indexDB, i.log, i.clock) if err != nil { _ = indexDB.Close() return nil, err diff --git a/indexer/indexer_test.go b/indexer/indexer_test.go index fd5abe1ddc6b..df9bce500eff 100644 --- a/indexer/indexer_test.go +++ b/indexer/indexer_test.go @@ -68,7 +68,6 @@ func TestNewIndexer(t *testing.T) { require.NoError(err) require.IsType(&indexer{}, idxrIntf) idxr := idxrIntf.(*indexer) - require.NotNil(idxr.codec) require.NotNil(idxr.log) require.NotNil(idxr.db) require.False(idxr.closed) diff --git a/snow/engine/avalanche/vertex/builder.go b/snow/engine/avalanche/vertex/builder.go index 34ee26763849..dd83016d7ee6 100644 --- a/snow/engine/avalanche/vertex/builder.go +++ b/snow/engine/avalanche/vertex/builder.go @@ -62,10 +62,10 @@ func buildVtx( utils.Sort(parentIDs) utils.SortByHash(txs) - codecVer := codecVersion + codecVer := CodecVersion if stopVertex { // use new codec version for the "StopVertex" - codecVer = codecVersionWithStopVtx + codecVer = CodecVersionWithStopVtx } innerVtx := innerStatelessVertex{ @@ -80,7 +80,7 @@ func buildVtx( return nil, err } - vtxBytes, err := c.Marshal(innerVtx.Version, innerVtx) + vtxBytes, err := Codec.Marshal(innerVtx.Version, innerVtx) vtx := statelessVertex{ innerStatelessVertex: innerVtx, id: hashing.ComputeHash256Array(vtxBytes), diff --git a/snow/engine/avalanche/vertex/codec.go b/snow/engine/avalanche/vertex/codec.go index 564d699a25e9..65c0ff84cdc2 100644 --- a/snow/engine/avalanche/vertex/codec.go +++ b/snow/engine/avalanche/vertex/codec.go @@ -7,29 +7,30 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/codec/reflectcodec" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/units" ) const ( + CodecVersion uint16 = 0 + CodecVersionWithStopVtx uint16 = 1 + // maxSize is the maximum allowed vertex size. It is necessary to deter DoS maxSize = units.MiB - - codecVersion uint16 = 0 - codecVersionWithStopVtx uint16 = 1 ) -var c codec.Manager +var Codec codec.Manager func init() { - lc := linearcodec.New([]string{reflectcodec.DefaultTagName + "V0"}, maxSize) - lc2 := linearcodec.New([]string{reflectcodec.DefaultTagName + "V1"}, maxSize) + lc0 := linearcodec.New([]string{reflectcodec.DefaultTagName + "V0"}, maxSize) + lc1 := linearcodec.New([]string{reflectcodec.DefaultTagName + "V1"}, maxSize) - c = codec.NewManager(maxSize) - // for backward compatibility, still register the initial codec version - if err := c.RegisterCodec(codecVersion, lc); err != nil { - panic(err) - } - if err := c.RegisterCodec(codecVersionWithStopVtx, lc2); err != nil { + Codec = codec.NewManager(maxSize) + err := utils.Err( + Codec.RegisterCodec(CodecVersion, lc0), + Codec.RegisterCodec(CodecVersionWithStopVtx, lc1), + ) + if err != nil { panic(err) } } diff --git a/snow/engine/avalanche/vertex/parser.go b/snow/engine/avalanche/vertex/parser.go index cd409c7edc65..f0b7a8aa5571 100644 --- a/snow/engine/avalanche/vertex/parser.go +++ b/snow/engine/avalanche/vertex/parser.go @@ -19,7 +19,7 @@ type Parser interface { // Parse parses the provided vertex bytes into a stateless vertex func Parse(bytes []byte) (StatelessVertex, error) { vtx := innerStatelessVertex{} - version, err := c.Unmarshal(bytes, &vtx) + version, err := Codec.Unmarshal(bytes, &vtx) if err != nil { return nil, err } diff --git a/snow/engine/avalanche/vertex/stateless_vertex.go b/snow/engine/avalanche/vertex/stateless_vertex.go index cef298c9b90f..ca772ed8670a 100644 --- a/snow/engine/avalanche/vertex/stateless_vertex.go +++ b/snow/engine/avalanche/vertex/stateless_vertex.go @@ -73,7 +73,7 @@ func (v statelessVertex) ChainID() ids.ID { } func (v statelessVertex) StopVertex() bool { - return v.innerStatelessVertex.Version == codecVersionWithStopVtx + return v.innerStatelessVertex.Version == CodecVersionWithStopVtx } func (v statelessVertex) Height() uint64 { @@ -102,7 +102,7 @@ type innerStatelessVertex struct { } func (v innerStatelessVertex) Verify() error { - if v.Version == codecVersionWithStopVtx { + if v.Version == CodecVersionWithStopVtx { return v.verifyStopVertex() } return v.verify() @@ -110,7 +110,7 @@ func (v innerStatelessVertex) Verify() error { func (v innerStatelessVertex) verify() error { switch { - case v.Version != codecVersion: + case v.Version != CodecVersion: return errBadVersion case v.Epoch != 0: return errBadEpoch @@ -131,7 +131,7 @@ func (v innerStatelessVertex) verify() error { func (v innerStatelessVertex) verifyStopVertex() error { switch { - case v.Version != codecVersionWithStopVtx: + case v.Version != CodecVersionWithStopVtx: return errBadVersion case v.Epoch != 0: return errBadEpoch diff --git a/vms/components/keystore/codec.go b/vms/components/keystore/codec.go index 5acb1725aa6e..9739dc4328a4 100644 --- a/vms/components/keystore/codec.go +++ b/vms/components/keystore/codec.go @@ -11,12 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils" ) -const ( - // CodecVersion is the current default codec version - CodecVersion = 0 -) +const CodecVersion = 0 -// Codecs do serialization and deserialization var ( Codec codec.Manager LegacyCodec codec.Manager diff --git a/vms/components/message/codec.go b/vms/components/message/codec.go index 3a5eee5416ca..db47a18fc9a5 100644 --- a/vms/components/message/codec.go +++ b/vms/components/message/codec.go @@ -11,21 +11,21 @@ import ( ) const ( - codecVersion = 0 + CodecVersion = 0 + maxMessageSize = 512 * units.KiB maxSliceLen = maxMessageSize ) -// Codec does serialization and deserialization -var c codec.Manager +var Codec codec.Manager func init() { - c = codec.NewManager(maxMessageSize) + Codec = codec.NewManager(maxMessageSize) lc := linearcodec.NewCustomMaxLength(maxSliceLen) err := utils.Err( lc.RegisterType(&Tx{}), - c.RegisterCodec(codecVersion, lc), + Codec.RegisterCodec(CodecVersion, lc), ) if err != nil { panic(err) diff --git a/vms/components/message/message.go b/vms/components/message/message.go index 009cf67f4884..f0e13aab3d10 100644 --- a/vms/components/message/message.go +++ b/vms/components/message/message.go @@ -65,11 +65,11 @@ func Parse(bytes []byte) (Message, error) { // It must have been encoded with avalanchego's codec. // TODO remove else statement remove once all nodes support proto encoding. // i.e. when all nodes are on v1.11.0 or later. - version, err := c.Unmarshal(bytes, &msg) + version, err := Codec.Unmarshal(bytes, &msg) if err != nil { return nil, err } - if version != codecVersion { + if version != CodecVersion { return nil, ErrUnexpectedCodecVersion } } @@ -78,7 +78,7 @@ func Parse(bytes []byte) (Message, error) { } func Build(msg Message) ([]byte, error) { - bytes, err := c.Marshal(codecVersion, &msg) + bytes, err := Codec.Marshal(CodecVersion, &msg) msg.initialize(bytes) return bytes, err } diff --git a/vms/example/xsvm/api/client.go b/vms/example/xsvm/api/client.go index 785b092faed1..d8d6a94f1b4b 100644 --- a/vms/example/xsvm/api/client.go +++ b/vms/example/xsvm/api/client.go @@ -170,7 +170,7 @@ func (c *client) IssueTx( newTx *tx.Tx, options ...rpc.Option, ) (ids.ID, error) { - txBytes, err := tx.Codec.Marshal(tx.Version, newTx) + txBytes, err := tx.Codec.Marshal(tx.CodecVersion, newTx) if err != nil { return ids.Empty, err } diff --git a/vms/example/xsvm/block/block.go b/vms/example/xsvm/block/block.go index 2db314ea1a5a..fee3c801de2f 100644 --- a/vms/example/xsvm/block/block.go +++ b/vms/example/xsvm/block/block.go @@ -26,7 +26,7 @@ func (b *Stateless) Time() time.Time { } func (b *Stateless) ID() (ids.ID, error) { - bytes, err := Codec.Marshal(Version, b) + bytes, err := Codec.Marshal(CodecVersion, b) return hashing.ComputeHash256Array(bytes), err } diff --git a/vms/example/xsvm/block/codec.go b/vms/example/xsvm/block/codec.go index 0ffbc98d58e7..0edbcaee5302 100644 --- a/vms/example/xsvm/block/codec.go +++ b/vms/example/xsvm/block/codec.go @@ -5,7 +5,6 @@ package block import "github.com/ava-labs/avalanchego/vms/example/xsvm/tx" -// Version is the current default codec version -const Version = tx.Version +const CodecVersion = tx.CodecVersion var Codec = tx.Codec diff --git a/vms/example/xsvm/chain/chain.go b/vms/example/xsvm/chain/chain.go index ef6a59de2dbb..954cd3729291 100644 --- a/vms/example/xsvm/chain/chain.go +++ b/vms/example/xsvm/chain/chain.go @@ -80,7 +80,7 @@ func (c *chain) NewBlock(blk *xsblock.Stateless) (Block, error) { return blk, nil } - blkBytes, err := xsblock.Codec.Marshal(xsblock.Version, blk) + blkBytes, err := xsblock.Codec.Marshal(xsblock.CodecVersion, blk) if err != nil { return nil, err } diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 1f00491a4ce6..e562c8567b06 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -55,7 +55,7 @@ func createFunc(c *cobra.Command, args []string) error { // Get the P-chain wallet pWallet := wallet.P() - genesisBytes, err := genesis.Codec.Marshal(genesis.Version, &genesis.Genesis{ + genesisBytes, err := genesis.Codec.Marshal(genesis.CodecVersion, &genesis.Genesis{ Timestamp: 0, Allocations: []genesis.Allocation{ { diff --git a/vms/example/xsvm/cmd/chain/genesis/cmd.go b/vms/example/xsvm/cmd/chain/genesis/cmd.go index ae18e1db85e3..8ef49baa77ab 100644 --- a/vms/example/xsvm/cmd/chain/genesis/cmd.go +++ b/vms/example/xsvm/cmd/chain/genesis/cmd.go @@ -34,7 +34,7 @@ func genesisFunc(c *cobra.Command, args []string) error { return err } - genesisBytes, err := genesis.Codec.Marshal(genesis.Version, config.Genesis) + genesisBytes, err := genesis.Codec.Marshal(genesis.CodecVersion, config.Genesis) if err != nil { return err } diff --git a/vms/example/xsvm/execute/block.go b/vms/example/xsvm/execute/block.go index dc9de45af19e..3d51c64abaa2 100644 --- a/vms/example/xsvm/execute/block.go +++ b/vms/example/xsvm/execute/block.go @@ -62,7 +62,7 @@ func Block( return err } - blkBytes, err := xsblock.Codec.Marshal(xsblock.Version, blk) + blkBytes, err := xsblock.Codec.Marshal(xsblock.CodecVersion, blk) if err != nil { return err } diff --git a/vms/example/xsvm/execute/genesis.go b/vms/example/xsvm/execute/genesis.go index 312a7bd0b73c..c0a44e2ef6bb 100644 --- a/vms/example/xsvm/execute/genesis.go +++ b/vms/example/xsvm/execute/genesis.go @@ -36,7 +36,7 @@ func Genesis(db database.KeyValueReaderWriterDeleter, chainID ids.ID, g *genesis return err } - blkBytes, err := block.Codec.Marshal(block.Version, blk) + blkBytes, err := block.Codec.Marshal(block.CodecVersion, blk) if err != nil { return err } diff --git a/vms/example/xsvm/genesis/codec.go b/vms/example/xsvm/genesis/codec.go index 6ef652864574..3533e29a0188 100644 --- a/vms/example/xsvm/genesis/codec.go +++ b/vms/example/xsvm/genesis/codec.go @@ -5,7 +5,6 @@ package genesis import "github.com/ava-labs/avalanchego/vms/example/xsvm/block" -// Version is the current default codec version -const Version = block.Version +const CodecVersion = block.CodecVersion var Codec = block.Codec diff --git a/vms/example/xsvm/genesis/genesis.go b/vms/example/xsvm/genesis/genesis.go index e8580ffef7f6..fddc96716bd6 100644 --- a/vms/example/xsvm/genesis/genesis.go +++ b/vms/example/xsvm/genesis/genesis.go @@ -26,7 +26,7 @@ func Parse(bytes []byte) (*Genesis, error) { } func Block(genesis *Genesis) (*block.Stateless, error) { - bytes, err := Codec.Marshal(Version, genesis) + bytes, err := Codec.Marshal(CodecVersion, genesis) if err != nil { return nil, err } diff --git a/vms/example/xsvm/genesis/genesis_test.go b/vms/example/xsvm/genesis/genesis_test.go index 511c5c9b0b8b..f15e72ecc743 100644 --- a/vms/example/xsvm/genesis/genesis_test.go +++ b/vms/example/xsvm/genesis/genesis_test.go @@ -26,7 +26,7 @@ func TestGenesis(t *testing.T) { {Address: id2, Balance: 3000000000}, }, } - bytes, err := Codec.Marshal(Version, genesis) + bytes, err := Codec.Marshal(CodecVersion, genesis) require.NoError(err) parsed, err := Parse(bytes) diff --git a/vms/example/xsvm/tx/codec.go b/vms/example/xsvm/tx/codec.go index c91a2165f1f6..1f8b8fc9dd0e 100644 --- a/vms/example/xsvm/tx/codec.go +++ b/vms/example/xsvm/tx/codec.go @@ -11,8 +11,7 @@ import ( "github.com/ava-labs/avalanchego/utils" ) -// Version is the current default codec version -const Version = 0 +const CodecVersion = 0 var Codec codec.Manager @@ -24,7 +23,7 @@ func init() { c.RegisterType(&Transfer{}), c.RegisterType(&Export{}), c.RegisterType(&Import{}), - Codec.RegisterCodec(Version, c), + Codec.RegisterCodec(CodecVersion, c), ) if err != nil { panic(err) diff --git a/vms/example/xsvm/tx/payload.go b/vms/example/xsvm/tx/payload.go index e93e5f560ac5..0d1671535c9d 100644 --- a/vms/example/xsvm/tx/payload.go +++ b/vms/example/xsvm/tx/payload.go @@ -34,7 +34,7 @@ func NewPayload( Amount: amount, To: to, } - bytes, err := Codec.Marshal(Version, p) + bytes, err := Codec.Marshal(CodecVersion, p) p.bytes = bytes return p, err } diff --git a/vms/example/xsvm/tx/tx.go b/vms/example/xsvm/tx/tx.go index fae58bae0806..05beec274cb4 100644 --- a/vms/example/xsvm/tx/tx.go +++ b/vms/example/xsvm/tx/tx.go @@ -28,7 +28,7 @@ func Parse(bytes []byte) (*Tx, error) { } func Sign(utx Unsigned, key *secp256k1.PrivateKey) (*Tx, error) { - unsignedBytes, err := Codec.Marshal(Version, &utx) + unsignedBytes, err := Codec.Marshal(CodecVersion, &utx) if err != nil { return nil, err } @@ -46,12 +46,12 @@ func Sign(utx Unsigned, key *secp256k1.PrivateKey) (*Tx, error) { } func (tx *Tx) ID() (ids.ID, error) { - bytes, err := Codec.Marshal(Version, tx) + bytes, err := Codec.Marshal(CodecVersion, tx) return hashing.ComputeHash256Array(bytes), err } func (tx *Tx) SenderID() (ids.ShortID, error) { - unsignedBytes, err := Codec.Marshal(Version, &tx.Unsigned) + unsignedBytes, err := Codec.Marshal(CodecVersion, &tx.Unsigned) if err != nil { return ids.ShortEmpty, err } diff --git a/vms/platformvm/api/static_service.go b/vms/platformvm/api/static_service.go index 7f37b247b34b..dea7ce656aa9 100644 --- a/vms/platformvm/api/static_service.go +++ b/vms/platformvm/api/static_service.go @@ -390,7 +390,7 @@ func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, repl } // Marshal genesis to bytes - bytes, err := genesis.Codec.Marshal(genesis.Version, g) + bytes, err := genesis.Codec.Marshal(genesis.CodecVersion, g) if err != nil { return fmt.Errorf("couldn't marshal genesis: %w", err) } diff --git a/vms/platformvm/block/block.go b/vms/platformvm/block/block.go index 5cdc3a90dbc0..dd9c61e4ce9c 100644 --- a/vms/platformvm/block/block.go +++ b/vms/platformvm/block/block.go @@ -39,7 +39,7 @@ type BanffBlock interface { func initialize(blk Block, commonBlk *CommonBlock) error { // We serialize this block as a pointer so that it can be deserialized into // a Block - bytes, err := Codec.Marshal(Version, &blk) + bytes, err := Codec.Marshal(CodecVersion, &blk) if err != nil { return fmt.Errorf("couldn't marshal block: %w", err) } diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index cdfe27d662ad..8e94a0791fbd 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -51,7 +51,7 @@ func TestAtomicTxImports(t *testing.T) { }, }, } - utxoBytes, err := txs.Codec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) require.NoError(err) inputID := utxo.InputID() diff --git a/vms/platformvm/block/codec.go b/vms/platformvm/block/codec.go index 1034ee9f759a..7a730e2720de 100644 --- a/vms/platformvm/block/codec.go +++ b/vms/platformvm/block/codec.go @@ -13,8 +13,7 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs" ) -// Version is the current default codec version -const Version = txs.Version +const CodecVersion = txs.CodecVersion // GenesisCode allows blocks of larger than usual size to be parsed. // While this gives flexibility in accommodating large genesis blocks @@ -41,8 +40,8 @@ func init() { ) } errs.Add( - Codec.RegisterCodec(Version, c), - GenesisCodec.RegisterCodec(Version, gc), + Codec.RegisterCodec(CodecVersion, c), + GenesisCodec.RegisterCodec(CodecVersion, gc), ) if errs.Errored() { panic(errs.Err) diff --git a/vms/platformvm/block/serialization_test.go b/vms/platformvm/block/serialization_test.go index bfa08684e6f0..2d936d35e00e 100644 --- a/vms/platformvm/block/serialization_test.go +++ b/vms/platformvm/block/serialization_test.go @@ -113,7 +113,7 @@ func TestBanffBlockSerialization(t *testing.T) { t.Run(testName, func(t *testing.T) { require := require.New(t) - got, err := Codec.Marshal(Version, &block) + got, err := Codec.Marshal(CodecVersion, &block) require.NoError(err) require.Equal(test.bytes, got) }) diff --git a/vms/platformvm/genesis/codec.go b/vms/platformvm/genesis/codec.go index 7b68ac58d634..f8cbe110bf07 100644 --- a/vms/platformvm/genesis/codec.go +++ b/vms/platformvm/genesis/codec.go @@ -5,6 +5,6 @@ package genesis import "github.com/ava-labs/avalanchego/vms/platformvm/block" -const Version = block.Version +const CodecVersion = block.CodecVersion var Codec = block.GenesisCodec diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 6331e72a2acc..8326f0fbff8b 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -489,7 +489,7 @@ func (s *Service) GetUTXOs(_ *http.Request, args *api.GetUTXOsArgs, response *ap response.UTXOs = make([]string, len(utxos)) for i, utxo := range utxos { - bytes, err := txs.Codec.Marshal(txs.Version, utxo) + bytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) if err != nil { return fmt.Errorf("couldn't serialize UTXO %q: %w", utxo.InputID(), err) } @@ -2426,7 +2426,7 @@ func (s *Service) GetStake(_ *http.Request, args *GetStakeArgs, response *GetSta response.Staked = response.Stakeds[s.vm.ctx.AVAXAssetID] response.Outputs = make([]string, len(stakedOuts)) for i, output := range stakedOuts { - bytes, err := txs.Codec.Marshal(txs.Version, output) + bytes, err := txs.Codec.Marshal(txs.CodecVersion, output) if err != nil { return fmt.Errorf("couldn't serialize output %s: %w", output.ID, err) } @@ -2608,7 +2608,7 @@ func (s *Service) GetRewardUTXOs(_ *http.Request, args *api.GetTxArgs, reply *Ge reply.NumFetched = json.Uint64(len(utxos)) reply.UTXOs = make([]string, len(utxos)) for i, utxo := range utxos { - utxoBytes, err := txs.GenesisCodec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.GenesisCodec.Marshal(txs.CodecVersion, utxo) if err != nil { return fmt.Errorf("couldn't encode UTXO to bytes: %w", err) } diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index de0c16718b9a..d80aeb5726b2 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -199,7 +199,7 @@ func TestGetTxStatus(t *testing.T) { }, }, } - utxoBytes, err := txs.Codec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) require.NoError(err) inputID := utxo.InputID() diff --git a/vms/platformvm/state/metadata_codec.go b/vms/platformvm/state/metadata_codec.go index 50b3988c7d75..291d425c67bb 100644 --- a/vms/platformvm/state/metadata_codec.go +++ b/vms/platformvm/state/metadata_codec.go @@ -12,23 +12,23 @@ import ( ) const ( - v0tag = "v0" - v0 = uint16(0) + CodecVersion0Tag = "v0" + CodecVersion0 uint16 = 0 - v1tag = "v1" - v1 = uint16(1) + CodecVersion1Tag = "v1" + CodecVersion1 uint16 = 1 ) -var metadataCodec codec.Manager +var MetadataCodec codec.Manager func init() { - c0 := linearcodec.New([]string{v0tag}, math.MaxInt32) - c1 := linearcodec.New([]string{v0tag, v1tag}, math.MaxInt32) - metadataCodec = codec.NewManager(math.MaxInt32) + c0 := linearcodec.New([]string{CodecVersion0Tag}, math.MaxInt32) + c1 := linearcodec.New([]string{CodecVersion0Tag, CodecVersion1Tag}, math.MaxInt32) + MetadataCodec = codec.NewManager(math.MaxInt32) err := utils.Err( - metadataCodec.RegisterCodec(v0, c0), - metadataCodec.RegisterCodec(v1, c1), + MetadataCodec.RegisterCodec(CodecVersion0, c0), + MetadataCodec.RegisterCodec(CodecVersion1, c1), ) if err != nil { panic(err) diff --git a/vms/platformvm/state/metadata_delegator.go b/vms/platformvm/state/metadata_delegator.go index 852cbe607408..9e9ed42d2108 100644 --- a/vms/platformvm/state/metadata_delegator.go +++ b/vms/platformvm/state/metadata_delegator.go @@ -22,7 +22,7 @@ func parseDelegatorMetadata(bytes []byte, metadata *delegatorMetadata) error { // only potential reward was stored metadata.PotentialReward, err = database.ParseUInt64(bytes) default: - _, err = metadataCodec.Unmarshal(bytes, metadata) + _, err = MetadataCodec.Unmarshal(bytes, metadata) } return err } @@ -36,7 +36,7 @@ func writeDelegatorMetadata(db database.KeyValueWriter, metadata *delegatorMetad if codecVersion == 0 { return database.PutUInt64(db, metadata.txID[:], metadata.PotentialReward) } - metadataBytes, err := metadataCodec.Marshal(codecVersion, metadata) + metadataBytes, err := MetadataCodec.Marshal(codecVersion, metadata) if err != nil { return err } diff --git a/vms/platformvm/state/metadata_delegator_test.go b/vms/platformvm/state/metadata_delegator_test.go index 889854d313a2..67eceb62ad10 100644 --- a/vms/platformvm/state/metadata_delegator_test.go +++ b/vms/platformvm/state/metadata_delegator_test.go @@ -99,8 +99,8 @@ func TestWriteDelegatorMetadata(t *testing.T) { } tests := []test{ { - name: "v0", - version: v0, + name: CodecVersion0Tag, + version: CodecVersion0, metadata: &delegatorMetadata{ PotentialReward: 123, StakerStartTime: 456, @@ -111,8 +111,8 @@ func TestWriteDelegatorMetadata(t *testing.T) { }, }, { - name: "v1", - version: v1, + name: CodecVersion1Tag, + version: CodecVersion1, metadata: &delegatorMetadata{ PotentialReward: 123, StakerStartTime: 456, diff --git a/vms/platformvm/state/metadata_validator.go b/vms/platformvm/state/metadata_validator.go index ed62b723eeac..84704cb7a5b7 100644 --- a/vms/platformvm/state/metadata_validator.go +++ b/vms/platformvm/state/metadata_validator.go @@ -59,7 +59,7 @@ func parseValidatorMetadata(bytes []byte, metadata *validatorMetadata) error { // potential reward and uptime was stored but potential delegatee reward // was not tmp := preDelegateeRewardMetadata{} - if _, err := metadataCodec.Unmarshal(bytes, &tmp); err != nil { + if _, err := MetadataCodec.Unmarshal(bytes, &tmp); err != nil { return err } @@ -68,7 +68,7 @@ func parseValidatorMetadata(bytes []byte, metadata *validatorMetadata) error { metadata.PotentialReward = tmp.PotentialReward default: // everything was stored - if _, err := metadataCodec.Unmarshal(bytes, metadata); err != nil { + if _, err := MetadataCodec.Unmarshal(bytes, metadata); err != nil { return err } } @@ -239,7 +239,7 @@ func (m *metadata) WriteValidatorMetadata( metadata := m.metadata[vdrID][subnetID] metadata.LastUpdated = uint64(metadata.lastUpdated.Unix()) - metadataBytes, err := metadataCodec.Marshal(codecVersion, metadata) + metadataBytes, err := MetadataCodec.Marshal(codecVersion, metadata) if err != nil { return err } diff --git a/vms/platformvm/state/metadata_validator_test.go b/vms/platformvm/state/metadata_validator_test.go index 67ba494a88f7..bb5cf6a5bd08 100644 --- a/vms/platformvm/state/metadata_validator_test.go +++ b/vms/platformvm/state/metadata_validator_test.go @@ -82,9 +82,8 @@ func TestWriteValidatorMetadata(t *testing.T) { primaryDB := memdb.New() subnetDB := memdb.New() - codecVersion := v1 // write empty uptimes - require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, codecVersion)) + require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, CodecVersion1)) // load uptime nodeID := ids.GenerateTestNodeID() @@ -98,7 +97,7 @@ func TestWriteValidatorMetadata(t *testing.T) { state.LoadValidatorMetadata(nodeID, subnetID, testUptimeReward) // write state, should not reflect to DB yet - require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, codecVersion)) + require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, CodecVersion1)) require.False(primaryDB.Has(testUptimeReward.txID[:])) require.False(subnetDB.Has(testUptimeReward.txID[:])) @@ -114,7 +113,7 @@ func TestWriteValidatorMetadata(t *testing.T) { require.NoError(state.SetUptime(nodeID, subnetID, newUpDuration, newLastUpdated)) // write uptimes, should reflect to subnet DB - require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, codecVersion)) + require.NoError(state.WriteValidatorMetadata(primaryDB, subnetDB, CodecVersion1)) require.False(primaryDB.Has(testUptimeReward.txID[:])) require.True(subnetDB.Has(testUptimeReward.txID[:])) } diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index b6f0218128ce..2c7785e8d5c7 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1190,7 +1190,7 @@ func (s *state) ApplyValidatorWeightDiffs( Height: height, SubnetID: subnetID, } - prefixBytes, err := block.GenesisCodec.Marshal(block.Version, prefixStruct) + prefixBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, prefixStruct) if err != nil { return err } @@ -1735,9 +1735,9 @@ func (s *state) initValidatorSets() error { } func (s *state) write(updateValidators bool, height uint64) error { - codecVersion := v1 + codecVersion := CodecVersion1 if !s.cfg.IsDurangoActivated(s.GetTimestamp()) { - codecVersion = v0 + codecVersion = CodecVersion0 } return utils.Err( @@ -1990,7 +1990,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecV Height: height, SubnetID: subnetID, } - prefixBytes, err := block.GenesisCodec.Marshal(block.Version, prefixStruct) + prefixBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, prefixStruct) if err != nil { return fmt.Errorf("failed to create prefix bytes: %w", err) } @@ -2041,7 +2041,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecV PotentialDelegateeReward: 0, } - metadataBytes, err := metadataCodec.Marshal(codecVersion, metadata) + metadataBytes, err := MetadataCodec.Marshal(codecVersion, metadata) if err != nil { return fmt.Errorf("failed to serialize current validator: %w", err) } @@ -2114,7 +2114,7 @@ func (s *state) writeCurrentStakers(updateValidators bool, height uint64, codecV } // TODO: Remove this once we no longer support version rollbacks. - weightDiffBytes, err := block.GenesisCodec.Marshal(block.Version, weightDiff) + weightDiffBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, weightDiff) if err != nil { return fmt.Errorf("failed to serialize validator weight diff: %w", err) } @@ -2275,7 +2275,7 @@ func (s *state) writeTXs() error { // Note that we're serializing a [txBytesAndStatus] here, not a // *txs.Tx, so we don't use [txs.Codec]. - txBytes, err := txs.GenesisCodec.Marshal(txs.Version, &stx) + txBytes, err := txs.GenesisCodec.Marshal(txs.CodecVersion, &stx) if err != nil { return fmt.Errorf("failed to serialize tx: %w", err) } @@ -2300,7 +2300,7 @@ func (s *state) writeRewardUTXOs() error { txDB := linkeddb.NewDefault(rawTxDB) for _, utxo := range utxos { - utxoBytes, err := txs.GenesisCodec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.GenesisCodec.Marshal(txs.CodecVersion, utxo) if err != nil { return fmt.Errorf("failed to serialize reward UTXO: %w", err) } @@ -2348,7 +2348,7 @@ func (s *state) writeSubnetOwners() error { owner := owner delete(s.subnetOwners, subnetID) - ownerBytes, err := block.GenesisCodec.Marshal(block.Version, &owner) + ownerBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, &owner) if err != nil { return fmt.Errorf("failed to marshal subnet owner: %w", err) } @@ -2429,7 +2429,7 @@ func (s *state) writeMetadata() error { } if s.indexedHeights != nil { - indexedHeightsBytes, err := block.GenesisCodec.Marshal(block.Version, s.indexedHeights) + indexedHeightsBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, s.indexedHeights) if err != nil { return err } diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index 0f87a6f90b00..8adcbba07a4b 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -649,7 +649,7 @@ func TestParsedStateBlock(t *testing.T) { Status: choices.Accepted, } - stBlkBytes, err := block.GenesisCodec.Marshal(block.Version, &stBlk) + stBlkBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, &stBlk) require.NoError(err) gotBlk, _, isStateBlk, err := parseStoredBlock(stBlkBytes) diff --git a/vms/platformvm/txs/add_permissionless_delegator_tx_test.go b/vms/platformvm/txs/add_permissionless_delegator_tx_test.go index c70bf720bfe3..79a91c16e485 100644 --- a/vms/platformvm/txs/add_permissionless_delegator_tx_test.go +++ b/vms/platformvm/txs/add_permissionless_delegator_tx_test.go @@ -216,7 +216,7 @@ func TestAddPermissionlessPrimaryDelegatorSerialization(t *testing.T) { 0x44, 0x55, 0x66, 0x77, } var unsignedSimpleAddPrimaryTx UnsignedTx = simpleAddPrimaryTx - unsignedSimpleAddPrimaryTxBytes, err := Codec.Marshal(Version, &unsignedSimpleAddPrimaryTx) + unsignedSimpleAddPrimaryTxBytes, err := Codec.Marshal(CodecVersion, &unsignedSimpleAddPrimaryTx) require.NoError(err) require.Equal(expectedUnsignedSimpleAddPrimaryTxBytes, unsignedSimpleAddPrimaryTxBytes) @@ -599,7 +599,7 @@ func TestAddPermissionlessPrimaryDelegatorSerialization(t *testing.T) { 0x00, 0x00, 0x00, 0x00, } var unsignedComplexAddPrimaryTx UnsignedTx = complexAddPrimaryTx - unsignedComplexAddPrimaryTxBytes, err := Codec.Marshal(Version, &unsignedComplexAddPrimaryTx) + unsignedComplexAddPrimaryTxBytes, err := Codec.Marshal(CodecVersion, &unsignedComplexAddPrimaryTx) require.NoError(err) require.Equal(expectedUnsignedComplexAddPrimaryTxBytes, unsignedComplexAddPrimaryTxBytes) @@ -972,7 +972,7 @@ func TestAddPermissionlessSubnetDelegatorSerialization(t *testing.T) { 0x44, 0x55, 0x66, 0x77, } var unsignedSimpleAddSubnetTx UnsignedTx = simpleAddSubnetTx - unsignedSimpleAddSubnetTxBytes, err := Codec.Marshal(Version, &unsignedSimpleAddSubnetTx) + unsignedSimpleAddSubnetTxBytes, err := Codec.Marshal(CodecVersion, &unsignedSimpleAddSubnetTx) require.NoError(err) require.Equal(expectedUnsignedSimpleAddSubnetTxBytes, unsignedSimpleAddSubnetTxBytes) @@ -1355,7 +1355,7 @@ func TestAddPermissionlessSubnetDelegatorSerialization(t *testing.T) { 0x00, 0x00, 0x00, 0x00, } var unsignedComplexAddSubnetTx UnsignedTx = complexAddSubnetTx - unsignedComplexAddSubnetTxBytes, err := Codec.Marshal(Version, &unsignedComplexAddSubnetTx) + unsignedComplexAddSubnetTxBytes, err := Codec.Marshal(CodecVersion, &unsignedComplexAddSubnetTx) require.NoError(err) require.Equal(expectedUnsignedComplexAddSubnetTxBytes, unsignedComplexAddSubnetTxBytes) diff --git a/vms/platformvm/txs/add_permissionless_validator_tx_test.go b/vms/platformvm/txs/add_permissionless_validator_tx_test.go index 80e4d3b6ae93..aed095b16af9 100644 --- a/vms/platformvm/txs/add_permissionless_validator_tx_test.go +++ b/vms/platformvm/txs/add_permissionless_validator_tx_test.go @@ -267,7 +267,7 @@ func TestAddPermissionlessPrimaryValidator(t *testing.T) { 0x00, 0x0f, 0x42, 0x40, } var unsignedSimpleAddPrimaryTx UnsignedTx = simpleAddPrimaryTx - unsignedSimpleAddPrimaryTxBytes, err := Codec.Marshal(Version, &unsignedSimpleAddPrimaryTx) + unsignedSimpleAddPrimaryTxBytes, err := Codec.Marshal(CodecVersion, &unsignedSimpleAddPrimaryTx) require.NoError(err) require.Equal(expectedUnsignedSimpleAddPrimaryTxBytes, unsignedSimpleAddPrimaryTxBytes) @@ -695,7 +695,7 @@ func TestAddPermissionlessPrimaryValidator(t *testing.T) { 0x00, 0x0f, 0x42, 0x40, } var unsignedComplexAddPrimaryTx UnsignedTx = complexAddPrimaryTx - unsignedComplexAddPrimaryTxBytes, err := Codec.Marshal(Version, &unsignedComplexAddPrimaryTx) + unsignedComplexAddPrimaryTxBytes, err := Codec.Marshal(CodecVersion, &unsignedComplexAddPrimaryTx) require.NoError(err) require.Equal(expectedUnsignedComplexAddPrimaryTxBytes, unsignedComplexAddPrimaryTxBytes) } @@ -954,7 +954,7 @@ func TestAddPermissionlessSubnetValidator(t *testing.T) { 0x00, 0x0f, 0x42, 0x40, } var unsignedSimpleAddSubnetTx UnsignedTx = simpleAddSubnetTx - unsignedSimpleAddSubnetTxBytes, err := Codec.Marshal(Version, &unsignedSimpleAddSubnetTx) + unsignedSimpleAddSubnetTxBytes, err := Codec.Marshal(CodecVersion, &unsignedSimpleAddSubnetTx) require.NoError(err) require.Equal(expectedUnsignedSimpleAddSubnetTxBytes, unsignedSimpleAddSubnetTxBytes) @@ -1362,7 +1362,7 @@ func TestAddPermissionlessSubnetValidator(t *testing.T) { 0x00, 0x0f, 0x42, 0x40, } var unsignedComplexAddSubnetTx UnsignedTx = complexAddSubnetTx - unsignedComplexAddSubnetTxBytes, err := Codec.Marshal(Version, &unsignedComplexAddSubnetTx) + unsignedComplexAddSubnetTxBytes, err := Codec.Marshal(CodecVersion, &unsignedComplexAddSubnetTx) require.NoError(err) require.Equal(expectedUnsignedComplexAddSubnetTxBytes, unsignedComplexAddSubnetTxBytes) } diff --git a/vms/platformvm/txs/add_subnet_validator_test.go b/vms/platformvm/txs/add_subnet_validator_test.go index e5f0684b25d7..c1f68cb664c1 100644 --- a/vms/platformvm/txs/add_subnet_validator_test.go +++ b/vms/platformvm/txs/add_subnet_validator_test.go @@ -201,7 +201,7 @@ func TestAddSubnetValidatorMarshal(t *testing.T) { require.NoError(err) require.NoError(stx.SyntacticVerify(ctx)) - txBytes, err := Codec.Marshal(Version, stx) + txBytes, err := Codec.Marshal(CodecVersion, stx) require.NoError(err) parsedTx, err := Parse(Codec, txBytes) diff --git a/vms/platformvm/txs/base_tx_test.go b/vms/platformvm/txs/base_tx_test.go index c6cba1570312..7c2dc3ad5208 100644 --- a/vms/platformvm/txs/base_tx_test.go +++ b/vms/platformvm/txs/base_tx_test.go @@ -118,7 +118,7 @@ func TestBaseTxSerialization(t *testing.T) { 0x00, 0x00, 0x00, 0x00, } var unsignedSimpleBaseTx UnsignedTx = simpleBaseTx - unsignedSimpleBaseTxBytes, err := Codec.Marshal(Version, &unsignedSimpleBaseTx) + unsignedSimpleBaseTxBytes, err := Codec.Marshal(CodecVersion, &unsignedSimpleBaseTx) require.NoError(err) require.Equal(expectedUnsignedSimpleBaseTxBytes, unsignedSimpleBaseTxBytes) @@ -358,7 +358,7 @@ func TestBaseTxSerialization(t *testing.T) { 0x01, 0x23, 0x45, 0x21, } var unsignedComplexBaseTx UnsignedTx = complexBaseTx - unsignedComplexBaseTxBytes, err := Codec.Marshal(Version, &unsignedComplexBaseTx) + unsignedComplexBaseTxBytes, err := Codec.Marshal(CodecVersion, &unsignedComplexBaseTx) require.NoError(err) require.Equal(expectedUnsignedComplexBaseTxBytes, unsignedComplexBaseTxBytes) diff --git a/vms/platformvm/txs/codec.go b/vms/platformvm/txs/codec.go index d743376d1acb..0d011f246546 100644 --- a/vms/platformvm/txs/codec.go +++ b/vms/platformvm/txs/codec.go @@ -15,8 +15,7 @@ import ( "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) -// Version is the current default codec version -const Version = 0 +const CodecVersion = 0 var ( Codec codec.Manager @@ -48,8 +47,8 @@ func init() { errs.Add(RegisterDUnsignedTxsTypes(c)) } errs.Add( - Codec.RegisterCodec(Version, c), - GenesisCodec.RegisterCodec(Version, gc), + Codec.RegisterCodec(CodecVersion, c), + GenesisCodec.RegisterCodec(CodecVersion, gc), ) if errs.Errored() { panic(errs.Err) diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 55cc49e4350b..9db644f4c1be 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -909,7 +909,7 @@ func TestAdvanceTimeTxUnmarshal(t *testing.T) { tx, err := env.txBuilder.NewAdvanceTimeTx(chainTime.Add(time.Second)) require.NoError(err) - bytes, err := txs.Codec.Marshal(txs.Version, tx) + bytes, err := txs.Codec.Marshal(txs.CodecVersion, tx) require.NoError(err) var unmarshaledTx txs.Tx diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 4ce779a9165e..9144a92873b1 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -67,7 +67,7 @@ func TestNewImportTx(t *testing.T) { }, }, } - utxoBytes, err := txs.Codec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) require.NoError(t, err) inputID := utxo.InputID() diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 53269520d88e..9bd5b140b314 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -254,7 +254,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { Out: out.Out, } - utxoBytes, err := txs.Codec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) if err != nil { return fmt.Errorf("failed to marshal UTXO: %w", err) } diff --git a/vms/platformvm/txs/remove_subnet_validator_tx_test.go b/vms/platformvm/txs/remove_subnet_validator_tx_test.go index 4b1f381c039b..45bf7483cf47 100644 --- a/vms/platformvm/txs/remove_subnet_validator_tx_test.go +++ b/vms/platformvm/txs/remove_subnet_validator_tx_test.go @@ -157,7 +157,7 @@ func TestRemoveSubnetValidatorTxSerialization(t *testing.T) { 0x00, 0x00, 0x00, 0x03, } var unsignedSimpleRemoveValidatorTx UnsignedTx = simpleRemoveValidatorTx - unsignedSimpleRemoveValidatorTxBytes, err := Codec.Marshal(Version, &unsignedSimpleRemoveValidatorTx) + unsignedSimpleRemoveValidatorTxBytes, err := Codec.Marshal(CodecVersion, &unsignedSimpleRemoveValidatorTx) require.NoError(err) require.Equal(expectedUnsignedSimpleRemoveValidatorTxBytes, unsignedSimpleRemoveValidatorTxBytes) @@ -417,7 +417,7 @@ func TestRemoveSubnetValidatorTxSerialization(t *testing.T) { 0x00, 0x00, 0x00, 0x00, } var unsignedComplexRemoveValidatorTx UnsignedTx = complexRemoveValidatorTx - unsignedComplexRemoveValidatorTxBytes, err := Codec.Marshal(Version, &unsignedComplexRemoveValidatorTx) + unsignedComplexRemoveValidatorTxBytes, err := Codec.Marshal(CodecVersion, &unsignedComplexRemoveValidatorTx) require.NoError(err) require.Equal(expectedUnsignedComplexRemoveValidatorTxBytes, unsignedComplexRemoveValidatorTxBytes) diff --git a/vms/platformvm/txs/transfer_subnet_ownership_tx_test.go b/vms/platformvm/txs/transfer_subnet_ownership_tx_test.go index e8cddeb3e1d0..e1b57a589461 100644 --- a/vms/platformvm/txs/transfer_subnet_ownership_tx_test.go +++ b/vms/platformvm/txs/transfer_subnet_ownership_tx_test.go @@ -164,7 +164,7 @@ func TestTransferSubnetOwnershipTxSerialization(t *testing.T) { 0x44, 0x55, 0x66, 0x77, } var unsignedSimpleTransferSubnetOwnershipTx UnsignedTx = simpleTransferSubnetOwnershipTx - unsignedSimpleTransferSubnetOwnershipTxBytes, err := Codec.Marshal(Version, &unsignedSimpleTransferSubnetOwnershipTx) + unsignedSimpleTransferSubnetOwnershipTxBytes, err := Codec.Marshal(CodecVersion, &unsignedSimpleTransferSubnetOwnershipTx) require.NoError(err) require.Equal(expectedUnsignedSimpleTransferSubnetOwnershipTxBytes, unsignedSimpleTransferSubnetOwnershipTxBytes) @@ -438,7 +438,7 @@ func TestTransferSubnetOwnershipTxSerialization(t *testing.T) { 0x44, 0x55, 0x66, 0x77, } var unsignedComplexTransferSubnetOwnershipTx UnsignedTx = complexTransferSubnetOwnershipTx - unsignedComplexTransferSubnetOwnershipTxBytes, err := Codec.Marshal(Version, &unsignedComplexTransferSubnetOwnershipTx) + unsignedComplexTransferSubnetOwnershipTxBytes, err := Codec.Marshal(CodecVersion, &unsignedComplexTransferSubnetOwnershipTx) require.NoError(err) require.Equal(expectedUnsignedComplexTransferSubnetOwnershipTxBytes, unsignedComplexTransferSubnetOwnershipTxBytes) diff --git a/vms/platformvm/txs/transform_subnet_tx_test.go b/vms/platformvm/txs/transform_subnet_tx_test.go index 4b88fd60ef3a..7a9b0b6981be 100644 --- a/vms/platformvm/txs/transform_subnet_tx_test.go +++ b/vms/platformvm/txs/transform_subnet_tx_test.go @@ -223,7 +223,7 @@ func TestTransformSubnetTxSerialization(t *testing.T) { 0x00, 0x00, 0x00, 0x03, } var unsignedSimpleTransformTx UnsignedTx = simpleTransformTx - unsignedSimpleTransformTxBytes, err := Codec.Marshal(Version, &unsignedSimpleTransformTx) + unsignedSimpleTransformTxBytes, err := Codec.Marshal(CodecVersion, &unsignedSimpleTransformTx) require.NoError(err) require.Equal(expectedUnsignedSimpleTransformTxBytes, unsignedSimpleTransformTxBytes) @@ -520,7 +520,7 @@ func TestTransformSubnetTxSerialization(t *testing.T) { 0x00, 0x00, 0x00, 0x00, } var unsignedComplexTransformTx UnsignedTx = complexTransformTx - unsignedComplexTransformTxBytes, err := Codec.Marshal(Version, &unsignedComplexTransformTx) + unsignedComplexTransformTxBytes, err := Codec.Marshal(CodecVersion, &unsignedComplexTransformTx) require.NoError(err) require.Equal(expectedUnsignedComplexTransformTxBytes, unsignedComplexTransformTxBytes) diff --git a/vms/platformvm/txs/tx.go b/vms/platformvm/txs/tx.go index c9713ffe09c3..52ee3f80b29c 100644 --- a/vms/platformvm/txs/tx.go +++ b/vms/platformvm/txs/tx.go @@ -48,12 +48,12 @@ func NewSigned( } func (tx *Tx) Initialize(c codec.Manager) error { - signedBytes, err := c.Marshal(Version, tx) + signedBytes, err := c.Marshal(CodecVersion, tx) if err != nil { return fmt.Errorf("couldn't marshal ProposalTx: %w", err) } - unsignedBytesLen, err := c.Size(Version, &tx.Unsigned) + unsignedBytesLen, err := c.Size(CodecVersion, &tx.Unsigned) if err != nil { return fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) } @@ -78,7 +78,7 @@ func Parse(c codec.Manager, signedBytes []byte) (*Tx, error) { return nil, fmt.Errorf("couldn't parse tx: %w", err) } - unsignedBytesLen, err := c.Size(Version, &tx.Unsigned) + unsignedBytesLen, err := c.Size(CodecVersion, &tx.Unsigned) if err != nil { return nil, fmt.Errorf("couldn't calculate UnsignedTx marshal length: %w", err) } @@ -132,7 +132,7 @@ func (tx *Tx) SyntacticVerify(ctx *snow.Context) error { // Note: We explicitly pass the codec in Sign since we may need to sign P-Chain // genesis txs whose length exceed the max length of txs.Codec. func (tx *Tx) Sign(c codec.Manager, signers [][]*secp256k1.PrivateKey) error { - unsignedBytes, err := c.Marshal(Version, &tx.Unsigned) + unsignedBytes, err := c.Marshal(CodecVersion, &tx.Unsigned) if err != nil { return fmt.Errorf("couldn't marshal UnsignedTx: %w", err) } @@ -153,7 +153,7 @@ func (tx *Tx) Sign(c codec.Manager, signers [][]*secp256k1.PrivateKey) error { tx.Creds = append(tx.Creds, cred) // Attach credential } - signedBytes, err := c.Marshal(Version, tx) + signedBytes, err := c.Marshal(CodecVersion, tx) if err != nil { return fmt.Errorf("couldn't marshal ProposalTx: %w", err) } diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 2d652103fee2..37f53238e4cb 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -557,7 +557,7 @@ func (h *handler) VerifySpendUTXOs( return fmt.Errorf("expected fx.Owned but got %T", out) } owner := owned.Owners() - ownerBytes, err := txs.Codec.Marshal(txs.Version, owner) + ownerBytes, err := txs.Codec.Marshal(txs.CodecVersion, owner) if err != nil { return fmt.Errorf("couldn't marshal owner: %w", err) } @@ -606,7 +606,7 @@ func (h *handler) VerifySpendUTXOs( return fmt.Errorf("expected fx.Owned but got %T", out) } owner := owned.Owners() - ownerBytes, err := txs.Codec.Marshal(txs.Version, owner) + ownerBytes, err := txs.Codec.Marshal(txs.CodecVersion, owner) if err != nil { return fmt.Errorf("couldn't marshal owner: %w", err) } diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 4b820f615913..8dbf16cab605 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -604,7 +604,7 @@ func TestRejectedStateRegressionInvalidValidatorTimestamp(t *testing.T) { mutableSharedMemory.SharedMemory = m.NewSharedMemory(vm.ctx.ChainID) peerSharedMemory := m.NewSharedMemory(vm.ctx.XChainID) - utxoBytes, err := txs.Codec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) require.NoError(err) inputID := utxo.InputID() @@ -849,7 +849,7 @@ func TestRejectedStateRegressionInvalidValidatorReward(t *testing.T) { mutableSharedMemory.SharedMemory = m.NewSharedMemory(vm.ctx.ChainID) peerSharedMemory := m.NewSharedMemory(vm.ctx.XChainID) - utxoBytes, err := txs.Codec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) require.NoError(err) inputID := utxo.InputID() diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 746d9e105968..ce074150c1c8 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1013,7 +1013,7 @@ func TestAtomicImport(t *testing.T) { }, }, } - utxoBytes, err := txs.Codec.Marshal(txs.Version, utxo) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, utxo) require.NoError(err) inputID := utxo.InputID() diff --git a/vms/platformvm/warp/codec.go b/vms/platformvm/warp/codec.go index cf4587224751..937cca628ad9 100644 --- a/vms/platformvm/warp/codec.go +++ b/vms/platformvm/warp/codec.go @@ -11,18 +11,17 @@ import ( "github.com/ava-labs/avalanchego/utils" ) -const codecVersion = 0 +const CodecVersion = 0 -// Codec does serialization and deserialization for Warp messages. -var c codec.Manager +var Codec codec.Manager func init() { - c = codec.NewManager(math.MaxInt) + Codec = codec.NewManager(math.MaxInt) lc := linearcodec.NewCustomMaxLength(math.MaxInt32) err := utils.Err( lc.RegisterType(&BitSetSignature{}), - c.RegisterCodec(codecVersion, lc), + Codec.RegisterCodec(CodecVersion, lc), ) if err != nil { panic(err) diff --git a/vms/platformvm/warp/message.go b/vms/platformvm/warp/message.go index 34850aed98ad..454ab9482d17 100644 --- a/vms/platformvm/warp/message.go +++ b/vms/platformvm/warp/message.go @@ -28,7 +28,7 @@ func ParseMessage(b []byte) (*Message, error) { msg := &Message{ bytes: b, } - _, err := c.Unmarshal(b, msg) + _, err := Codec.Unmarshal(b, msg) if err != nil { return nil, err } @@ -38,7 +38,7 @@ func ParseMessage(b []byte) (*Message, error) { // Initialize recalculates the result of Bytes(). It does not call Initialize() // on the UnsignedMessage. func (m *Message) Initialize() error { - bytes, err := c.Marshal(codecVersion, m) + bytes, err := Codec.Marshal(CodecVersion, m) m.bytes = bytes return err } diff --git a/vms/platformvm/warp/payload/codec.go b/vms/platformvm/warp/payload/codec.go index e2e8ddd7a7f5..57642968e9e5 100644 --- a/vms/platformvm/warp/payload/codec.go +++ b/vms/platformvm/warp/payload/codec.go @@ -11,7 +11,7 @@ import ( ) const ( - codecVersion = 0 + CodecVersion = 0 MaxMessageSize = 24 * units.KiB @@ -20,17 +20,16 @@ const ( MaxSliceLen = 24 * 1024 ) -// Codec does serialization and deserialization for Warp messages. -var c codec.Manager +var Codec codec.Manager func init() { - c = codec.NewManager(MaxMessageSize) + Codec = codec.NewManager(MaxMessageSize) lc := linearcodec.NewCustomMaxLength(MaxSliceLen) err := utils.Err( lc.RegisterType(&Hash{}), lc.RegisterType(&AddressedCall{}), - c.RegisterCodec(codecVersion, lc), + Codec.RegisterCodec(CodecVersion, lc), ) if err != nil { panic(err) diff --git a/vms/platformvm/warp/payload/payload.go b/vms/platformvm/warp/payload/payload.go index e4601945be98..dbed48ae9c29 100644 --- a/vms/platformvm/warp/payload/payload.go +++ b/vms/platformvm/warp/payload/payload.go @@ -22,7 +22,7 @@ type Payload interface { func Parse(bytes []byte) (Payload, error) { var payload Payload - if _, err := c.Unmarshal(bytes, &payload); err != nil { + if _, err := Codec.Unmarshal(bytes, &payload); err != nil { return nil, err } payload.initialize(bytes) @@ -30,7 +30,7 @@ func Parse(bytes []byte) (Payload, error) { } func initialize(p Payload) error { - bytes, err := c.Marshal(codecVersion, &p) + bytes, err := Codec.Marshal(CodecVersion, &p) if err != nil { return fmt.Errorf("couldn't marshal %T payload: %w", p, err) } diff --git a/vms/platformvm/warp/unsigned_message.go b/vms/platformvm/warp/unsigned_message.go index 95ef0d2d07f0..873f6995357d 100644 --- a/vms/platformvm/warp/unsigned_message.go +++ b/vms/platformvm/warp/unsigned_message.go @@ -41,13 +41,13 @@ func ParseUnsignedMessage(b []byte) (*UnsignedMessage, error) { bytes: b, id: hashing.ComputeHash256Array(b), } - _, err := c.Unmarshal(b, msg) + _, err := Codec.Unmarshal(b, msg) return msg, err } // Initialize recalculates the result of Bytes(). func (m *UnsignedMessage) Initialize() error { - bytes, err := c.Marshal(codecVersion, m) + bytes, err := Codec.Marshal(CodecVersion, m) if err != nil { return fmt.Errorf("couldn't marshal warp unsigned message: %w", err) } diff --git a/vms/proposervm/block/build.go b/vms/proposervm/block/build.go index cdf943318fcc..c6f18020507f 100644 --- a/vms/proposervm/block/build.go +++ b/vms/proposervm/block/build.go @@ -31,7 +31,7 @@ func BuildUnsigned( timestamp: timestamp, } - bytes, err := c.Marshal(codecVersion, &block) + bytes, err := Codec.Marshal(CodecVersion, &block) if err != nil { return nil, err } @@ -61,7 +61,7 @@ func Build( } var blockIntf SignedBlock = block - unsignedBytesWithEmptySignature, err := c.Marshal(codecVersion, &blockIntf) + unsignedBytesWithEmptySignature, err := Codec.Marshal(CodecVersion, &blockIntf) if err != nil { return nil, err } @@ -85,7 +85,7 @@ func Build( return nil, err } - block.bytes, err = c.Marshal(codecVersion, &blockIntf) + block.bytes, err = Codec.Marshal(CodecVersion, &blockIntf) return block, err } @@ -100,7 +100,7 @@ func BuildHeader( Body: bodyID, } - bytes, err := c.Marshal(codecVersion, &header) + bytes, err := Codec.Marshal(CodecVersion, &header) header.bytes = bytes return &header, err } @@ -117,7 +117,7 @@ func BuildOption( InnerBytes: innerBytes, } - bytes, err := c.Marshal(codecVersion, &block) + bytes, err := Codec.Marshal(CodecVersion, &block) if err != nil { return nil, err } diff --git a/vms/proposervm/block/codec.go b/vms/proposervm/block/codec.go index 6d68a4cc2fe7..fc6910377d47 100644 --- a/vms/proposervm/block/codec.go +++ b/vms/proposervm/block/codec.go @@ -11,23 +11,20 @@ import ( "github.com/ava-labs/avalanchego/utils" ) -const codecVersion = 0 +const CodecVersion = 0 -// The maximum block size is enforced by the p2p message size limit. -// See: [constants.DefaultMaxMessageSize] -// -// Invariant: This codec must never be used to unmarshal a slice unless it is a -// `[]byte`. Otherwise a malicious payload could cause an OOM. -var c codec.Manager +var Codec codec.Manager func init() { - linearCodec := linearcodec.NewCustomMaxLength(math.MaxUint32) - c = codec.NewManager(math.MaxInt) + lc := linearcodec.NewCustomMaxLength(math.MaxUint32) + // The maximum block size is enforced by the p2p message size limit. + // See: [constants.DefaultMaxMessageSize] + Codec = codec.NewManager(math.MaxInt) err := utils.Err( - linearCodec.RegisterType(&statelessBlock{}), - linearCodec.RegisterType(&option{}), - c.RegisterCodec(codecVersion, linearCodec), + lc.RegisterType(&statelessBlock{}), + lc.RegisterType(&option{}), + Codec.RegisterCodec(CodecVersion, lc), ) if err != nil { panic(err) diff --git a/vms/proposervm/block/parse.go b/vms/proposervm/block/parse.go index aff15bde9d2b..1a55e5045981 100644 --- a/vms/proposervm/block/parse.go +++ b/vms/proposervm/block/parse.go @@ -7,24 +7,24 @@ import "fmt" func Parse(bytes []byte) (Block, error) { var block Block - parsedVersion, err := c.Unmarshal(bytes, &block) + parsedVersion, err := Codec.Unmarshal(bytes, &block) if err != nil { return nil, err } - if parsedVersion != codecVersion { - return nil, fmt.Errorf("expected codec version %d but got %d", codecVersion, parsedVersion) + if parsedVersion != CodecVersion { + return nil, fmt.Errorf("expected codec version %d but got %d", CodecVersion, parsedVersion) } return block, block.initialize(bytes) } func ParseHeader(bytes []byte) (Header, error) { header := statelessHeader{} - parsedVersion, err := c.Unmarshal(bytes, &header) + parsedVersion, err := Codec.Unmarshal(bytes, &header) if err != nil { return nil, err } - if parsedVersion != codecVersion { - return nil, fmt.Errorf("expected codec version %d but got %d", codecVersion, parsedVersion) + if parsedVersion != CodecVersion { + return nil, fmt.Errorf("expected codec version %d but got %d", CodecVersion, parsedVersion) } header.bytes = bytes return &header, nil diff --git a/vms/proposervm/state/block_state.go b/vms/proposervm/state/block_state.go index fa4c67e1ecf5..b0d6d6547c9a 100644 --- a/vms/proposervm/state/block_state.go +++ b/vms/proposervm/state/block_state.go @@ -100,11 +100,11 @@ func (s *blockState) GetBlock(blkID ids.ID) (block.Block, choices.Status, error) } blkWrapper := blockWrapper{} - parsedVersion, err := c.Unmarshal(blkWrapperBytes, &blkWrapper) + parsedVersion, err := Codec.Unmarshal(blkWrapperBytes, &blkWrapper) if err != nil { return nil, choices.Unknown, err } - if parsedVersion != version { + if parsedVersion != CodecVersion { return nil, choices.Unknown, errBlockWrongVersion } @@ -126,7 +126,7 @@ func (s *blockState) PutBlock(blk block.Block, status choices.Status) error { block: blk, } - bytes, err := c.Marshal(version, &blkWrapper) + bytes, err := Codec.Marshal(CodecVersion, &blkWrapper) if err != nil { return err } diff --git a/vms/proposervm/state/codec.go b/vms/proposervm/state/codec.go index f73523806e53..6c1ecabd919c 100644 --- a/vms/proposervm/state/codec.go +++ b/vms/proposervm/state/codec.go @@ -10,15 +10,15 @@ import ( "github.com/ava-labs/avalanchego/codec/linearcodec" ) -const version = 0 +const CodecVersion = 0 -var c codec.Manager +var Codec codec.Manager func init() { lc := linearcodec.NewCustomMaxLength(math.MaxUint32) - c = codec.NewManager(math.MaxInt32) + Codec = codec.NewManager(math.MaxInt32) - err := c.RegisterCodec(version, lc) + err := Codec.RegisterCodec(CodecVersion, lc) if err != nil { panic(err) } diff --git a/vms/proposervm/summary/build.go b/vms/proposervm/summary/build.go index 35e2e179f0e3..a166d3c6c33c 100644 --- a/vms/proposervm/summary/build.go +++ b/vms/proposervm/summary/build.go @@ -20,7 +20,7 @@ func Build( InnerSummary: coreSummary, } - bytes, err := c.Marshal(codecVersion, &summary) + bytes, err := Codec.Marshal(CodecVersion, &summary) if err != nil { return nil, fmt.Errorf("cannot marshal proposer summary due to: %w", err) } diff --git a/vms/proposervm/summary/codec.go b/vms/proposervm/summary/codec.go index a71350f37d0f..188e6470f80f 100644 --- a/vms/proposervm/summary/codec.go +++ b/vms/proposervm/summary/codec.go @@ -11,18 +11,18 @@ import ( "github.com/ava-labs/avalanchego/codec/linearcodec" ) -const codecVersion = 0 +const CodecVersion = 0 var ( - c codec.Manager + Codec codec.Manager errWrongCodecVersion = errors.New("wrong codec version") ) func init() { lc := linearcodec.NewCustomMaxLength(math.MaxUint32) - c = codec.NewManager(math.MaxInt32) - if err := c.RegisterCodec(codecVersion, lc); err != nil { + Codec = codec.NewManager(math.MaxInt32) + if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { panic(err) } } diff --git a/vms/proposervm/summary/parse.go b/vms/proposervm/summary/parse.go index 3d9295444782..e4dd8733c091 100644 --- a/vms/proposervm/summary/parse.go +++ b/vms/proposervm/summary/parse.go @@ -14,11 +14,11 @@ func Parse(bytes []byte) (StateSummary, error) { id: hashing.ComputeHash256Array(bytes), bytes: bytes, } - version, err := c.Unmarshal(bytes, &summary) + version, err := Codec.Unmarshal(bytes, &summary) if err != nil { return nil, fmt.Errorf("could not unmarshal summary due to: %w", err) } - if version != codecVersion { + if version != CodecVersion { return nil, errWrongCodecVersion } return &summary, nil diff --git a/wallet/chain/p/signer_visitor.go b/wallet/chain/p/signer_visitor.go index 9dd6018ea2e3..25429b47e50f 100644 --- a/wallet/chain/p/signer_visitor.go +++ b/wallet/chain/p/signer_visitor.go @@ -284,7 +284,7 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri // TODO: remove [signHash] after the ledger supports signing all transactions. func sign(tx *txs.Tx, signHash bool, txSigners [][]keychain.Signer) error { - unsignedBytes, err := txs.Codec.Marshal(txs.Version, &tx.Unsigned) + unsignedBytes, err := txs.Codec.Marshal(txs.CodecVersion, &tx.Unsigned) if err != nil { return fmt.Errorf("couldn't marshal unsigned tx: %w", err) } @@ -345,7 +345,7 @@ func sign(tx *txs.Tx, signHash bool, txSigners [][]keychain.Signer) error { } } - signedBytes, err := txs.Codec.Marshal(txs.Version, tx) + signedBytes, err := txs.Codec.Marshal(txs.CodecVersion, tx) if err != nil { return fmt.Errorf("couldn't marshal tx: %w", err) } From 8618c308242003f69042589fe202b05cdc4e67a8 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 29 Dec 2023 17:03:14 -0500 Subject: [PATCH 218/267] Remove `len` tag parsing from the reflect codec (#2559) --- codec/reflectcodec/struct_fielder.go | 46 ++++----------- codec/reflectcodec/type_codec.go | 56 +++++++++---------- codec/test_codec.go | 26 +-------- .../avalanche/vertex/stateless_vertex.go | 10 ++-- 4 files changed, 45 insertions(+), 93 deletions(-) diff --git a/codec/reflectcodec/struct_fielder.go b/codec/reflectcodec/struct_fielder.go index 8aff2ea33139..a16212a62103 100644 --- a/codec/reflectcodec/struct_fielder.go +++ b/codec/reflectcodec/struct_fielder.go @@ -6,44 +6,31 @@ package reflectcodec import ( "fmt" "reflect" - "strconv" "sync" "github.com/ava-labs/avalanchego/codec" ) -const ( - // SliceLenTagName that specifies the length of a slice. - SliceLenTagName = "len" - - // TagValue is the value the tag must have to be serialized. - TagValue = "true" -) +// TagValue is the value the tag must have to be serialized. +const TagValue = "true" var _ StructFielder = (*structFielder)(nil) -type FieldDesc struct { - Index int - MaxSliceLen uint32 -} - // StructFielder handles discovery of serializable fields in a struct. type StructFielder interface { // Returns the fields that have been marked as serializable in [t], which is - // a struct type. Additionally, returns the custom maximum length slice that - // may be serialized into the field, if any. + // a struct type. // Returns an error if a field has tag "[tagName]: [TagValue]" but the field // is un-exported. // GetSerializedField(Foo) --> [1,5,8] means Foo.Field(1), Foo.Field(5), // Foo.Field(8) are to be serialized/deserialized. - GetSerializedFields(t reflect.Type) ([]FieldDesc, error) + GetSerializedFields(t reflect.Type) ([]int, error) } -func NewStructFielder(tagNames []string, maxSliceLen uint32) StructFielder { +func NewStructFielder(tagNames []string) StructFielder { return &structFielder{ tags: tagNames, - maxSliceLen: maxSliceLen, - serializedFieldIndices: make(map[reflect.Type][]FieldDesc), + serializedFieldIndices: make(map[reflect.Type][]int), } } @@ -54,17 +41,15 @@ type structFielder struct { // if it has at least one of the specified tags. tags []string - maxSliceLen uint32 - // Key: a struct type // Value: Slice where each element is index in the struct type of a field // that is serialized/deserialized e.g. Foo --> [1,5,8] means Foo.Field(1), // etc. are to be serialized/deserialized. We assume this cache is pretty // small (a few hundred keys at most) and doesn't take up much memory. - serializedFieldIndices map[reflect.Type][]FieldDesc + serializedFieldIndices map[reflect.Type][]int } -func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error) { +func (s *structFielder) GetSerializedFields(t reflect.Type) ([]int, error) { if serializedFields, ok := s.getCachedSerializedFields(t); ok { // use pre-computed result return serializedFields, nil } @@ -73,7 +58,7 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error) defer s.lock.Unlock() numFields := t.NumField() - serializedFields := make([]FieldDesc, 0, numFields) + serializedFields := make([]int, 0, numFields) for i := 0; i < numFields; i++ { // Go through all fields of this struct field := t.Field(i) @@ -96,22 +81,13 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]FieldDesc, error) field.Name, ) } - sliceLenField := field.Tag.Get(SliceLenTagName) - maxSliceLen := s.maxSliceLen - - if newLen, err := strconv.ParseUint(sliceLenField, 10, 31); err == nil { - maxSliceLen = uint32(newLen) - } - serializedFields = append(serializedFields, FieldDesc{ - Index: i, - MaxSliceLen: maxSliceLen, - }) + serializedFields = append(serializedFields, i) } s.serializedFieldIndices[t] = serializedFields // cache result return serializedFields, nil } -func (s *structFielder) getCachedSerializedFields(t reflect.Type) ([]FieldDesc, bool) { +func (s *structFielder) getCachedSerializedFields(t reflect.Type) ([]int, bool) { s.lock.RLock() defer s.lock.RUnlock() diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index 9ff06a9eba4d..ad2e11378163 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -81,7 +81,7 @@ func New(typer TypeCodec, tagNames []string, maxSliceLen uint32) codec.Codec { return &genericCodec{ typer: typer, maxSliceLen: maxSliceLen, - fielder: NewStructFielder(tagNames, maxSliceLen), + fielder: NewStructFielder(tagNames), } } @@ -208,8 +208,8 @@ func (c *genericCodec) size( size int constSize = true ) - for _, fieldDesc := range serializedFields { - innerSize, innerConstSize, err := c.size(value.Field(fieldDesc.Index), typeStack) + for _, fieldIndex := range serializedFields { + innerSize, innerConstSize, err := c.size(value.Field(fieldIndex), typeStack) if err != nil { return 0, false, err } @@ -292,7 +292,7 @@ func (c *genericCodec) MarshalInto(value interface{}, p *wrappers.Packer) error return errMarshalNil // can't marshal nil } - return c.marshal(reflect.ValueOf(value), p, c.maxSliceLen, nil /*=typeStack*/) + return c.marshal(reflect.ValueOf(value), p, nil /*=typeStack*/) } // marshal writes the byte representation of [value] to [p] @@ -301,7 +301,6 @@ func (c *genericCodec) MarshalInto(value interface{}, p *wrappers.Packer) error func (c *genericCodec) marshal( value reflect.Value, p *wrappers.Packer, - maxSliceLen uint32, typeStack set.Set[reflect.Type], ) error { switch valueKind := value.Kind(); valueKind { @@ -340,7 +339,7 @@ func (c *genericCodec) marshal( return errMarshalNil } - return c.marshal(value.Elem(), p, c.maxSliceLen, typeStack) + return c.marshal(value.Elem(), p, typeStack) case reflect.Interface: if value.IsNil() { return errMarshalNil @@ -355,18 +354,18 @@ func (c *genericCodec) marshal( if err := c.typer.PackPrefix(p, underlyingType); err != nil { return err } - if err := c.marshal(value.Elem(), p, c.maxSliceLen, typeStack); err != nil { + if err := c.marshal(value.Elem(), p, typeStack); err != nil { return err } typeStack.Remove(underlyingType) return p.Err case reflect.Slice: numElts := value.Len() // # elements in the slice/array. 0 if this slice is nil. - if uint32(numElts) > maxSliceLen { + if uint32(numElts) > c.maxSliceLen { return fmt.Errorf("%w; slice length, %d, exceeds maximum length, %d", codec.ErrMaxSliceLenExceeded, numElts, - maxSliceLen, + c.maxSliceLen, ) } p.PackInt(uint32(numElts)) // pack # elements @@ -386,7 +385,7 @@ func (c *genericCodec) marshal( return p.Err } for i := 0; i < numElts; i++ { // Process each element in the slice - if err := c.marshal(value.Index(i), p, c.maxSliceLen, typeStack); err != nil { + if err := c.marshal(value.Index(i), p, typeStack); err != nil { return err } } @@ -406,7 +405,7 @@ func (c *genericCodec) marshal( ) } for i := 0; i < numElts; i++ { // Process each element in the array - if err := c.marshal(value.Index(i), p, c.maxSliceLen, typeStack); err != nil { + if err := c.marshal(value.Index(i), p, typeStack); err != nil { return err } } @@ -416,8 +415,8 @@ func (c *genericCodec) marshal( if err != nil { return err } - for _, fieldDesc := range serializedFields { // Go through all fields of this struct that are serialized - if err := c.marshal(value.Field(fieldDesc.Index), p, fieldDesc.MaxSliceLen, typeStack); err != nil { // Serialize the field and write to byte array + for _, fieldIndex := range serializedFields { // Go through all fields of this struct that are serialized + if err := c.marshal(value.Field(fieldIndex), p, typeStack); err != nil { // Serialize the field and write to byte array return err } } @@ -425,11 +424,11 @@ func (c *genericCodec) marshal( case reflect.Map: keys := value.MapKeys() numElts := len(keys) - if uint32(numElts) > maxSliceLen { + if uint32(numElts) > c.maxSliceLen { return fmt.Errorf("%w; map length, %d, exceeds maximum length, %d", codec.ErrMaxSliceLenExceeded, numElts, - maxSliceLen, + c.maxSliceLen, ) } p.PackInt(uint32(numElts)) // pack # elements @@ -448,7 +447,7 @@ func (c *genericCodec) marshal( startOffset := p.Offset endOffset := p.Offset for i, key := range keys { - if err := c.marshal(key, p, c.maxSliceLen, typeStack); err != nil { + if err := c.marshal(key, p, typeStack); err != nil { return err } if p.Err != nil { @@ -481,7 +480,7 @@ func (c *genericCodec) marshal( } // serialize and pack value - if err := c.marshal(value.MapIndex(key.key), p, c.maxSliceLen, typeStack); err != nil { + if err := c.marshal(value.MapIndex(key.key), p, typeStack); err != nil { return err } } @@ -506,7 +505,7 @@ func (c *genericCodec) Unmarshal(bytes []byte, dest interface{}) error { if destPtr.Kind() != reflect.Ptr { return errNeedPointer } - if err := c.unmarshal(&p, destPtr.Elem(), c.maxSliceLen, nil /*=typeStack*/); err != nil { + if err := c.unmarshal(&p, destPtr.Elem(), nil /*=typeStack*/); err != nil { return err } if p.Offset != len(bytes) { @@ -525,7 +524,6 @@ func (c *genericCodec) Unmarshal(bytes []byte, dest interface{}) error { func (c *genericCodec) unmarshal( p *wrappers.Packer, value reflect.Value, - maxSliceLen uint32, typeStack set.Set[reflect.Type], ) error { switch value.Kind() { @@ -588,11 +586,11 @@ func (c *genericCodec) unmarshal( if p.Err != nil { return fmt.Errorf("couldn't unmarshal slice: %w", p.Err) } - if numElts32 > maxSliceLen { + if numElts32 > c.maxSliceLen { return fmt.Errorf("%w; array length, %d, exceeds maximum length, %d", codec.ErrMaxSliceLenExceeded, numElts32, - maxSliceLen, + c.maxSliceLen, ) } if numElts32 > math.MaxInt32 { @@ -618,7 +616,7 @@ func (c *genericCodec) unmarshal( zeroValue := reflect.Zero(innerType) for i := 0; i < numElts; i++ { value.Set(reflect.Append(value, zeroValue)) - if err := c.unmarshal(p, value.Index(i), c.maxSliceLen, typeStack); err != nil { + if err := c.unmarshal(p, value.Index(i), typeStack); err != nil { return err } } @@ -636,7 +634,7 @@ func (c *genericCodec) unmarshal( return nil } for i := 0; i < numElts; i++ { - if err := c.unmarshal(p, value.Index(i), c.maxSliceLen, typeStack); err != nil { + if err := c.unmarshal(p, value.Index(i), typeStack); err != nil { return err } } @@ -659,7 +657,7 @@ func (c *genericCodec) unmarshal( typeStack.Add(intfImplementorType) // Unmarshal into the struct - if err := c.unmarshal(p, intfImplementor, c.maxSliceLen, typeStack); err != nil { + if err := c.unmarshal(p, intfImplementor, typeStack); err != nil { return err } @@ -673,8 +671,8 @@ func (c *genericCodec) unmarshal( return fmt.Errorf("couldn't unmarshal struct: %w", err) } // Go through the fields and umarshal into them - for _, fieldDesc := range serializedFieldIndices { - if err := c.unmarshal(p, value.Field(fieldDesc.Index), fieldDesc.MaxSliceLen, typeStack); err != nil { + for _, fieldIndex := range serializedFieldIndices { + if err := c.unmarshal(p, value.Field(fieldIndex), typeStack); err != nil { return err } } @@ -685,7 +683,7 @@ func (c *genericCodec) unmarshal( // Create a new pointer to a new value of the underlying type v := reflect.New(t) // Fill the value - if err := c.unmarshal(p, v.Elem(), c.maxSliceLen, typeStack); err != nil { + if err := c.unmarshal(p, v.Elem(), typeStack); err != nil { return err } // Assign to the top-level struct's member @@ -720,7 +718,7 @@ func (c *genericCodec) unmarshal( keyStartOffset := p.Offset - if err := c.unmarshal(p, mapKey, c.maxSliceLen, typeStack); err != nil { + if err := c.unmarshal(p, mapKey, typeStack); err != nil { return err } @@ -738,7 +736,7 @@ func (c *genericCodec) unmarshal( // Get the value mapValue := reflect.New(mapValueType).Elem() - if err := c.unmarshal(p, mapValue, c.maxSliceLen, typeStack); err != nil { + if err := c.unmarshal(p, mapValue, typeStack); err != nil { return err } diff --git a/codec/test_codec.go b/codec/test_codec.go index b24784ac7d6a..3c933816a253 100644 --- a/codec/test_codec.go +++ b/codec/test_codec.go @@ -39,7 +39,6 @@ var ( TestNegativeNumbers, TestTooLargeUnmarshal, TestUnmarshalInvalidInterface, - TestRestrictedSlice, TestExtraSpace, TestSliceLengthOverflow, TestMap, @@ -874,27 +873,6 @@ func TestUnmarshalInvalidInterface(codec GeneralCodec, t testing.TB) { } } -// Ensure deserializing slices that have been length restricted errors correctly -func TestRestrictedSlice(codec GeneralCodec, t testing.TB) { - require := require.New(t) - - type inner struct { - Bytes []byte `serialize:"true" len:"2"` - } - bytes := []byte{0, 0, 0, 0, 0, 3, 0, 1, 2} - - manager := NewDefaultManager() - require.NoError(manager.RegisterCodec(0, codec)) - - s := inner{} - _, err := manager.Unmarshal(bytes, &s) - require.ErrorIs(err, ErrMaxSliceLenExceeded) - - s.Bytes = []byte{0, 1, 2} - _, err = manager.Marshal(0, s) - require.ErrorIs(err, ErrMaxSliceLenExceeded) -} - // Test unmarshaling something with extra data func TestExtraSpace(codec GeneralCodec, t testing.TB) { require := require.New(t) @@ -909,12 +887,12 @@ func TestExtraSpace(codec GeneralCodec, t testing.TB) { require.ErrorIs(err, ErrExtraSpace) } -// Ensure deserializing slices that have been length restricted errors correctly +// Ensure deserializing slices whose lengths exceed MaxInt32 error correctly func TestSliceLengthOverflow(codec GeneralCodec, t testing.TB) { require := require.New(t) type inner struct { - Vals []uint32 `serialize:"true" len:"2"` + Vals []uint32 `serialize:"true"` } bytes := []byte{ // Codec Version: diff --git a/snow/engine/avalanche/vertex/stateless_vertex.go b/snow/engine/avalanche/vertex/stateless_vertex.go index ca772ed8670a..d5e51671bb42 100644 --- a/snow/engine/avalanche/vertex/stateless_vertex.go +++ b/snow/engine/avalanche/vertex/stateless_vertex.go @@ -94,11 +94,11 @@ func (v statelessVertex) Txs() [][]byte { type innerStatelessVertex struct { Version uint16 `json:"version"` - ChainID ids.ID `json:"chainID" serializeV0:"true" serializeV1:"true"` - Height uint64 `json:"height" serializeV0:"true" serializeV1:"true"` - Epoch uint32 `json:"epoch" serializeV0:"true"` - ParentIDs []ids.ID `json:"parentIDs" len:"128" serializeV0:"true" serializeV1:"true"` - Txs [][]byte `json:"txs" len:"128" serializeV0:"true"` + ChainID ids.ID `json:"chainID" serializeV0:"true" serializeV1:"true"` + Height uint64 `json:"height" serializeV0:"true" serializeV1:"true"` + Epoch uint32 `json:"epoch" serializeV0:"true"` + ParentIDs []ids.ID `json:"parentIDs" serializeV0:"true" serializeV1:"true"` + Txs [][]byte `json:"txs" serializeV0:"true"` } func (v innerStatelessVertex) Verify() error { From 0158a53932572a20cb6f98c2c0fc6e2e33d8d0d1 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Sun, 31 Dec 2023 11:59:02 -0500 Subject: [PATCH 219/267] Use more specific type (#2567) --- network/network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/network.go b/network/network.go index 6c182e0554ec..8359bd37841b 100644 --- a/network/network.go +++ b/network/network.go @@ -146,7 +146,7 @@ type network struct { // Cancelled on close onCloseCtx context.Context // Call [onCloseCtxCancel] to cancel [onCloseCtx] during close() - onCloseCtxCancel func() + onCloseCtxCancel context.CancelFunc sendFailRateCalculator safemath.Averager From f56ff2ec5c005ddc29fde667e76c0078be35a5e9 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Sun, 31 Dec 2023 15:48:31 -0500 Subject: [PATCH 220/267] Standardize `onShutdownCtx` (#2568) --- vms/avm/vm.go | 14 ++++++++------ vms/platformvm/vm.go | 16 ++++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 699f95a6e7be..2f3e05541f96 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -114,9 +114,11 @@ type VM struct { txBackend *txexecutor.Backend - context context.Context - startShutdown context.CancelFunc - awaitShutdown sync.WaitGroup + // Cancelled on shutdown + onShutdownCtx context.Context + // Call [onShutdownCtxCancel] to cancel [onShutdownCtx] during Shutdown() + onShutdownCtxCancel context.CancelFunc + awaitShutdown sync.WaitGroup networkConfig network.Config // These values are only initialized after the chain has been linearized. @@ -274,7 +276,7 @@ func (vm *VM) Initialize( Bootstrapped: false, } - vm.context, vm.startShutdown = context.WithCancel(context.Background()) + vm.onShutdownCtx, vm.onShutdownCtxCancel = context.WithCancel(context.Background()) vm.networkConfig = avmConfig.Network return vm.state.Commit() } @@ -318,7 +320,7 @@ func (vm *VM) Shutdown(context.Context) error { return nil } - vm.startShutdown() + vm.onShutdownCtxCancel() vm.awaitShutdown.Wait() return utils.Err( @@ -474,7 +476,7 @@ func (vm *VM) Linearize(ctx context.Context, stopVertexID ids.ID, toEngine chan< defer vm.awaitShutdown.Done() // Invariant: Gossip must never grab the context lock. - vm.network.Gossip(vm.context) + vm.network.Gossip(vm.onShutdownCtx) }() go func() { diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index e9885a9bad94..d8e9d4172406 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -90,8 +90,11 @@ type VM struct { txBuilder txbuilder.Builder manager blockexecutor.Manager - startShutdown context.CancelFunc - awaitShutdown sync.WaitGroup + // Cancelled on shutdown + onShutdownCtx context.Context + // Call [onShutdownCtxCancel] to cancel [onShutdownCtx] during Shutdown() + onShutdownCtxCancel context.CancelFunc + awaitShutdown sync.WaitGroup // TODO: Remove after v1.11.x is activated pruned utils.Atomic[bool] @@ -212,12 +215,13 @@ func (vm *VM) Initialize( return fmt.Errorf("failed to initialize network: %w", err) } - vmCtx, cancel := context.WithCancel(context.Background()) - vm.startShutdown = cancel + vm.onShutdownCtx, vm.onShutdownCtxCancel = context.WithCancel(context.Background()) vm.awaitShutdown.Add(1) go func() { defer vm.awaitShutdown.Done() - vm.Network.Gossip(vmCtx) + + // Invariant: Gossip must never grab the context lock. + vm.Network.Gossip(vm.onShutdownCtx) }() vm.Builder = blockbuilder.New( @@ -375,7 +379,7 @@ func (vm *VM) Shutdown(context.Context) error { return nil } - vm.startShutdown() + vm.onShutdownCtxCancel() vm.awaitShutdown.Wait() vm.Builder.ShutdownBlockTimer() From 89bc40c99f406d18b813e31795f30f815c664416 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 31 Dec 2023 16:05:18 -0500 Subject: [PATCH 221/267] Verify avm mempool txs against the last accepted state (#2569) --- vms/avm/block/executor/block_test.go | 36 ++++++-------- vms/avm/block/executor/manager.go | 9 +--- vms/avm/block/executor/manager_test.go | 68 ++++---------------------- 3 files changed, 27 insertions(+), 86 deletions(-) diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index a235377164b9..d014b3ef499d 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -859,27 +859,25 @@ func TestBlockReject(t *testing.T) { mempool.EXPECT().Add(validTx).Return(nil) // Only add the one that passes verification mempool.EXPECT().RequestBuildBlock() - preferredID := ids.GenerateTestID() - mockPreferredState := state.NewMockDiff(ctrl) - mockPreferredState.EXPECT().GetLastAccepted().Return(ids.GenerateTestID()).AnyTimes() - mockPreferredState.EXPECT().GetTimestamp().Return(time.Now()).AnyTimes() + lastAcceptedID := ids.GenerateTestID() + mockState := state.NewMockState(ctrl) + mockState.EXPECT().GetLastAccepted().Return(lastAcceptedID).AnyTimes() + mockState.EXPECT().GetTimestamp().Return(time.Now()).AnyTimes() return &Block{ Block: mockBlock, manager: &manager{ - preferred: preferredID, - mempool: mempool, - metrics: metrics.NewMockMetrics(ctrl), + lastAccepted: lastAcceptedID, + mempool: mempool, + metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ Bootstrapped: true, Ctx: &snow.Context{ Log: logging.NoLog{}, }, }, + state: mockState, blkIDToState: map[ids.ID]*blockState{ - preferredID: { - onAcceptState: mockPreferredState, - }, blockID: {}, }, }, @@ -919,27 +917,25 @@ func TestBlockReject(t *testing.T) { mempool.EXPECT().Add(tx2).Return(nil) mempool.EXPECT().RequestBuildBlock() - preferredID := ids.GenerateTestID() - mockPreferredState := state.NewMockDiff(ctrl) - mockPreferredState.EXPECT().GetLastAccepted().Return(ids.GenerateTestID()).AnyTimes() - mockPreferredState.EXPECT().GetTimestamp().Return(time.Now()).AnyTimes() + lastAcceptedID := ids.GenerateTestID() + mockState := state.NewMockState(ctrl) + mockState.EXPECT().GetLastAccepted().Return(lastAcceptedID).AnyTimes() + mockState.EXPECT().GetTimestamp().Return(time.Now()).AnyTimes() return &Block{ Block: mockBlock, manager: &manager{ - preferred: preferredID, - mempool: mempool, - metrics: metrics.NewMockMetrics(ctrl), + lastAccepted: lastAcceptedID, + mempool: mempool, + metrics: metrics.NewMockMetrics(ctrl), backend: &executor.Backend{ Bootstrapped: true, Ctx: &snow.Context{ Log: logging.NoLog{}, }, }, + state: mockState, blkIDToState: map[ids.ID]*blockState{ - preferredID: { - onAcceptState: mockPreferredState, - }, blockID: {}, }, }, diff --git a/vms/avm/block/executor/manager.go b/vms/avm/block/executor/manager.go index 4ee6c37046ec..9ffcb36c9a61 100644 --- a/vms/avm/block/executor/manager.go +++ b/vms/avm/block/executor/manager.go @@ -155,7 +155,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { return err } - stateDiff, err := state.NewDiff(m.preferred, m) + stateDiff, err := state.NewDiff(m.lastAccepted, m) if err != nil { return err } @@ -174,12 +174,7 @@ func (m *manager) VerifyTx(tx *txs.Tx) error { State: stateDiff, Tx: tx, } - err = tx.Unsigned.Visit(executor) - if err != nil { - return err - } - - return m.VerifyUniqueInputs(m.preferred, executor.Inputs) + return tx.Unsigned.Visit(executor) } func (m *manager) VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error { diff --git a/vms/avm/block/executor/manager_test.go b/vms/avm/block/executor/manager_test.go index 904154bf7030..542cf386afee 100644 --- a/vms/avm/block/executor/manager_test.go +++ b/vms/avm/block/executor/manager_test.go @@ -116,7 +116,6 @@ func TestManagerVerifyTx(t *testing.T) { expectedErr error } - inputID := ids.GenerateTestID() tests := []test{ { name: "not bootstrapped", @@ -161,11 +160,11 @@ func TestManagerVerifyTx(t *testing.T) { } }, managerF: func(ctrl *gomock.Controller) *manager { - preferred := ids.GenerateTestID() + lastAcceptedID := ids.GenerateTestID() // These values don't matter for this test state := state.NewMockState(ctrl) - state.EXPECT().GetLastAccepted().Return(preferred) + state.EXPECT().GetLastAccepted().Return(lastAcceptedID) state.EXPECT().GetTimestamp().Return(time.Time{}) return &manager{ @@ -173,8 +172,7 @@ func TestManagerVerifyTx(t *testing.T) { Bootstrapped: true, }, state: state, - lastAccepted: preferred, - preferred: preferred, + lastAccepted: lastAcceptedID, } }, expectedErr: errTestSemanticVerifyFail, @@ -194,11 +192,11 @@ func TestManagerVerifyTx(t *testing.T) { } }, managerF: func(ctrl *gomock.Controller) *manager { - preferred := ids.GenerateTestID() + lastAcceptedID := ids.GenerateTestID() // These values don't matter for this test state := state.NewMockState(ctrl) - state.EXPECT().GetLastAccepted().Return(preferred) + state.EXPECT().GetLastAccepted().Return(lastAcceptedID) state.EXPECT().GetTimestamp().Return(time.Time{}) return &manager{ @@ -206,57 +204,10 @@ func TestManagerVerifyTx(t *testing.T) { Bootstrapped: true, }, state: state, - lastAccepted: preferred, - preferred: preferred, - } - }, - expectedErr: errTestExecutionFail, - }, - { - name: "non-unique inputs", - txF: func(ctrl *gomock.Controller) *txs.Tx { - unsigned := txs.NewMockUnsignedTx(ctrl) - // Syntactic verification passes - unsigned.EXPECT().Visit(gomock.Any()).Return(nil) - // Semantic verification passes - unsigned.EXPECT().Visit(gomock.Any()).Return(nil) - // Execution passes - unsigned.EXPECT().Visit(gomock.Any()).DoAndReturn(func(e *executor.Executor) error { - e.Inputs.Add(inputID) - return nil - }) - return &txs.Tx{ - Unsigned: unsigned, - } - }, - managerF: func(ctrl *gomock.Controller) *manager { - lastAcceptedID := ids.GenerateTestID() - - preferredID := ids.GenerateTestID() - preferred := block.NewMockBlock(ctrl) - preferred.EXPECT().Parent().Return(lastAcceptedID).AnyTimes() - - // These values don't matter for this test - diffState := state.NewMockDiff(ctrl) - diffState.EXPECT().GetLastAccepted().Return(preferredID) - diffState.EXPECT().GetTimestamp().Return(time.Time{}) - - return &manager{ - backend: &executor.Backend{ - Bootstrapped: true, - }, - blkIDToState: map[ids.ID]*blockState{ - preferredID: { - statelessBlock: preferred, - onAcceptState: diffState, - importedInputs: set.Of(inputID), - }, - }, lastAccepted: lastAcceptedID, - preferred: preferredID, } }, - expectedErr: ErrConflictingParentTxs, + expectedErr: errTestExecutionFail, }, { name: "happy path", @@ -273,11 +224,11 @@ func TestManagerVerifyTx(t *testing.T) { } }, managerF: func(ctrl *gomock.Controller) *manager { - preferred := ids.GenerateTestID() + lastAcceptedID := ids.GenerateTestID() // These values don't matter for this test state := state.NewMockState(ctrl) - state.EXPECT().GetLastAccepted().Return(preferred) + state.EXPECT().GetLastAccepted().Return(lastAcceptedID) state.EXPECT().GetTimestamp().Return(time.Time{}) return &manager{ @@ -285,8 +236,7 @@ func TestManagerVerifyTx(t *testing.T) { Bootstrapped: true, }, state: state, - lastAccepted: preferred, - preferred: preferred, + lastAccepted: lastAcceptedID, } }, expectedErr: nil, From 561efd78323b25cf4849bcbdb45d6c9564a3ac00 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Mon, 1 Jan 2024 11:06:37 -0500 Subject: [PATCH 222/267] Update `CODEOWNERS` (#2570) --- .github/CODEOWNERS | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5df26b4a9d9a..c9737ad46f63 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,15 +9,14 @@ /message/ @gyuho /network/ @danlaine @joshua-kim @StephenButtolph /network/throttling/ @danlaine @dboehm-avalabs @StephenButtolph -/proto/ @gyuho @hexfusion +/proto/ @gyuho /snow/ @danlaine @StephenButtolph /snow/consensus/ @gyuho @StephenButtolph /snow/engine/snowman/syncer/ @abi87 /snow/uptime/ @ceyonur /utils/logging/ @ceyonur -/vms/platformvm/ @abi87 @danlaine @StephenButtolph +/vms/platformvm/ @abi87 @danlaine @dhrubabasu @StephenButtolph /vms/proposervm/ @abi87 @StephenButtolph -/vms/rpcchainvm/ @hexfusion @StephenButtolph /vms/registry/ @joshua-kim /tests/ @abi87 @gyuho @marun /x/ @danlaine @darioush @dboehm-avalabs From e26d9c9fdb2e288ccbebb17c6e50b5a175cc6c2d Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 2 Jan 2024 03:12:40 -0500 Subject: [PATCH 223/267] Remove license from mocks (#2574) --- api/server/mock_server.go | 3 -- chains/atomic/mock_shared_memory.go | 3 -- codec/mock_manager.go | 3 -- database/mock_batch.go | 3 -- database/mock_iterator.go | 3 -- indexer/indexer_test.go | 8 ++--- message/mock_message.go | 3 -- message/mock_outbound_message_builder.go | 3 -- scripts/mock.gen.sh | 10 ------ scripts/mocks.mockgen.txt | 8 ++--- snow/consensus/snowman/mock_block.go | 3 -- snow/engine/avalanche/vertex/mock_vm.go | 3 -- ...go => mock_build_block_with_context_vm.go} | 10 ++---- .../{mocks/chain_vm.go => mock_chain_vm.go} | 7 ++-- ...ncable_vm.go => mock_state_syncable_vm.go} | 24 ++++++-------- ...context.go => mock_with_verify_context.go} | 10 ++---- snow/engine/snowman/getter/getter_test.go | 5 ++- snow/networking/handler/mock_handler.go | 3 -- snow/networking/timeout/mock_manager.go | 3 -- .../tracker/mock_resource_tracker.go | 3 -- snow/networking/tracker/mock_targeter.go | 3 -- snow/uptime/mock_calculator.go | 3 -- snow/validators/mock_state.go | 3 -- snow/validators/mock_subnet_connector.go | 3 -- utils/crypto/keychain/mock_ledger.go | 3 -- utils/filesystem/mock_io.go | 3 -- utils/hashing/mock_hasher.go | 3 -- utils/resource/mock_user.go | 3 -- vms/avm/block/mock_block.go | 3 -- vms/avm/metrics/mock_metrics.go | 3 -- vms/avm/state/mock_state.go | 3 -- vms/avm/txs/mempool/mock_mempool.go | 3 -- vms/components/avax/mock_transferable_in.go | 3 -- vms/components/verify/mock_verifiable.go | 3 -- vms/mock_manager.go | 3 -- vms/platformvm/block/mock_block.go | 3 -- vms/platformvm/state/mock_staker_iterator.go | 3 -- vms/platformvm/state/mock_state.go | 3 -- vms/platformvm/txs/mempool/mock_mempool.go | 3 -- vms/platformvm/utxo/mock_verifier.go | 3 -- vms/proposervm/block_test.go | 7 ++-- vms/proposervm/mock_post_fork_block.go | 3 -- vms/proposervm/pre_fork_block_test.go | 11 ++++--- vms/proposervm/proposer/mock_windower.go | 3 -- vms/proposervm/scheduler/mock_scheduler.go | 3 -- vms/proposervm/state/mock_state.go | 3 -- vms/proposervm/vm_test.go | 13 ++++---- vms/registry/mock_vm_getter.go | 3 -- vms/registry/mock_vm_registerer.go | 3 -- vms/registry/mock_vm_registry.go | 3 -- vms/registry/vm_registerer_test.go | 26 +++++++-------- vms/rpcchainvm/batched_vm_test.go | 3 +- vms/rpcchainvm/state_syncable_vm_test.go | 33 +++++++++---------- vms/rpcchainvm/vm_test.go | 3 +- vms/rpcchainvm/with_context_vm_test.go | 13 ++++---- x/sync/mock_client.go | 3 -- 56 files changed, 80 insertions(+), 231 deletions(-) rename snow/engine/snowman/block/{mocks/build_block_with_context_vm.go => mock_build_block_with_context_vm.go} (86%) rename snow/engine/snowman/block/{mocks/chain_vm.go => mock_chain_vm.go} (98%) rename snow/engine/snowman/block/{mocks/state_syncable_vm.go => mock_state_syncable_vm.go} (87%) rename snow/engine/snowman/block/{mocks/with_verify_context.go => mock_with_verify_context.go} (89%) diff --git a/api/server/mock_server.go b/api/server/mock_server.go index 1d29c7054db3..b30b36e50ac8 100644 --- a/api/server/mock_server.go +++ b/api/server/mock_server.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/api/server (interfaces: Server) diff --git a/chains/atomic/mock_shared_memory.go b/chains/atomic/mock_shared_memory.go index d22bd0f995ff..b6afac750e70 100644 --- a/chains/atomic/mock_shared_memory.go +++ b/chains/atomic/mock_shared_memory.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/chains/atomic (interfaces: SharedMemory) diff --git a/codec/mock_manager.go b/codec/mock_manager.go index 91961806bf4f..53fe543f8984 100644 --- a/codec/mock_manager.go +++ b/codec/mock_manager.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/codec (interfaces: Manager) diff --git a/database/mock_batch.go b/database/mock_batch.go index b20ae92473f1..552d917fc95f 100644 --- a/database/mock_batch.go +++ b/database/mock_batch.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/database (interfaces: Batch) diff --git a/database/mock_iterator.go b/database/mock_iterator.go index 4fa36ae24f69..7703e89206a3 100644 --- a/database/mock_iterator.go +++ b/database/mock_iterator.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/database (interfaces: Iterator) diff --git a/indexer/indexer_test.go b/indexer/indexer_test.go index df9bce500eff..16c4aa7bc381 100644 --- a/indexer/indexer_test.go +++ b/indexer/indexer_test.go @@ -20,7 +20,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" + "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" @@ -163,7 +163,7 @@ func TestIndexer(t *testing.T) { require.False(previouslyIndexed) // Register this chain, creating a new index - chainVM := mocks.NewMockChainVM(ctrl) + chainVM := block.NewMockChainVM(ctrl) idxr.RegisterChain("chain1", chain1Ctx, chainVM) isIncomplete, err = idxr.isIncomplete(chain1Ctx.ChainID) require.NoError(err) @@ -426,7 +426,7 @@ func TestIncompleteIndex(t *testing.T) { previouslyIndexed, err := idxr.previouslyIndexed(chain1Ctx.ChainID) require.NoError(err) require.False(previouslyIndexed) - chainVM := mocks.NewMockChainVM(ctrl) + chainVM := block.NewMockChainVM(ctrl) idxr.RegisterChain("chain1", chain1Ctx, chainVM) isIncomplete, err = idxr.isIncomplete(chain1Ctx.ChainID) require.NoError(err) @@ -507,7 +507,7 @@ func TestIgnoreNonDefaultChains(t *testing.T) { }) // RegisterChain should return without adding an index for this chain - chainVM := mocks.NewMockChainVM(ctrl) + chainVM := block.NewMockChainVM(ctrl) idxr.RegisterChain("chain1", chain1Ctx, chainVM) require.Empty(idxr.blockIndices) } diff --git a/message/mock_message.go b/message/mock_message.go index 938a90edbb8e..e52a665b7575 100644 --- a/message/mock_message.go +++ b/message/mock_message.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/message (interfaces: OutboundMessage) diff --git a/message/mock_outbound_message_builder.go b/message/mock_outbound_message_builder.go index 1da9934d177f..50af02669546 100644 --- a/message/mock_outbound_message_builder.go +++ b/message/mock_outbound_message_builder.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/message (interfaces: OutboundMsgBuilder) diff --git a/scripts/mock.gen.sh b/scripts/mock.gen.sh index 855dbc94b304..c3feff7a545c 100755 --- a/scripts/mock.gen.sh +++ b/scripts/mock.gen.sh @@ -14,13 +14,6 @@ then go install -v go.uber.org/mock/mockgen@v0.2.0 fi -if ! command -v go-license &> /dev/null -then - echo "go-license not found, installing..." - # https://github.com/palantir/go-license - go install -v github.com/palantir/go-license@v1.25.0 -fi - source ./scripts/constants.sh # tuples of (source interface import path, comma-separated interface names, output file path) @@ -32,9 +25,6 @@ do echo "Generating ${output_path}..." mockgen -package=${package_name} -destination=${output_path} ${src_import_path} ${interface_name} - go-license \ - --config=./header.yml \ - "${output_path}" done < "$input" echo "SUCCESS" diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 2fbfa5b255ab..c3bb7d3ffd24 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -7,10 +7,10 @@ github.com/ava-labs/avalanchego/message=OutboundMessage=message/mock_message.go github.com/ava-labs/avalanchego/message=OutboundMsgBuilder=message/mock_outbound_message_builder.go github.com/ava-labs/avalanchego/snow/consensus/snowman=Block=snow/consensus/snowman/mock_block.go github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex=LinearizableVM=snow/engine/avalanche/vertex/mock_vm.go -github.com/ava-labs/avalanchego/snow/engine/snowman/block=BuildBlockWithContextChainVM=snow/engine/snowman/block/mocks/build_block_with_context_vm.go -github.com/ava-labs/avalanchego/snow/engine/snowman/block=ChainVM=snow/engine/snowman/block/mocks/chain_vm.go -github.com/ava-labs/avalanchego/snow/engine/snowman/block=StateSyncableVM=snow/engine/snowman/block/mocks/state_syncable_vm.go -github.com/ava-labs/avalanchego/snow/engine/snowman/block=WithVerifyContext=snow/engine/snowman/block/mocks/with_verify_context.go +github.com/ava-labs/avalanchego/snow/engine/snowman/block=BuildBlockWithContextChainVM=snow/engine/snowman/block/mock_build_block_with_context_vm.go +github.com/ava-labs/avalanchego/snow/engine/snowman/block=ChainVM=snow/engine/snowman/block/mock_chain_vm.go +github.com/ava-labs/avalanchego/snow/engine/snowman/block=StateSyncableVM=snow/engine/snowman/block/mock_state_syncable_vm.go +github.com/ava-labs/avalanchego/snow/engine/snowman/block=WithVerifyContext=snow/engine/snowman/block/mock_with_verify_context.go github.com/ava-labs/avalanchego/snow/networking/handler=Handler=snow/networking/handler/mock_handler.go github.com/ava-labs/avalanchego/snow/networking/timeout=Manager=snow/networking/timeout/mock_manager.go github.com/ava-labs/avalanchego/snow/networking/tracker=Targeter=snow/networking/tracker/mock_targeter.go diff --git a/snow/consensus/snowman/mock_block.go b/snow/consensus/snowman/mock_block.go index f5b7422190e5..164df8d45e80 100644 --- a/snow/consensus/snowman/mock_block.go +++ b/snow/consensus/snowman/mock_block.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/consensus/snowman (interfaces: Block) diff --git a/snow/engine/avalanche/vertex/mock_vm.go b/snow/engine/avalanche/vertex/mock_vm.go index 045b275586d0..b0c4362b4551 100644 --- a/snow/engine/avalanche/vertex/mock_vm.go +++ b/snow/engine/avalanche/vertex/mock_vm.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex (interfaces: LinearizableVM) diff --git a/snow/engine/snowman/block/mocks/build_block_with_context_vm.go b/snow/engine/snowman/block/mock_build_block_with_context_vm.go similarity index 86% rename from snow/engine/snowman/block/mocks/build_block_with_context_vm.go rename to snow/engine/snowman/block/mock_build_block_with_context_vm.go index 2a72ada73e2c..9cb5f3e77833 100644 --- a/snow/engine/snowman/block/mocks/build_block_with_context_vm.go +++ b/snow/engine/snowman/block/mock_build_block_with_context_vm.go @@ -1,18 +1,14 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/snowman/block (interfaces: BuildBlockWithContextChainVM) -// Package mocks is a generated GoMock package. -package mocks +// Package block is a generated GoMock package. +package block import ( context "context" reflect "reflect" snowman "github.com/ava-labs/avalanchego/snow/consensus/snowman" - block "github.com/ava-labs/avalanchego/snow/engine/snowman/block" gomock "go.uber.org/mock/gomock" ) @@ -40,7 +36,7 @@ func (m *MockBuildBlockWithContextChainVM) EXPECT() *MockBuildBlockWithContextCh } // BuildBlockWithContext mocks base method. -func (m *MockBuildBlockWithContextChainVM) BuildBlockWithContext(arg0 context.Context, arg1 *block.Context) (snowman.Block, error) { +func (m *MockBuildBlockWithContextChainVM) BuildBlockWithContext(arg0 context.Context, arg1 *Context) (snowman.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BuildBlockWithContext", arg0, arg1) ret0, _ := ret[0].(snowman.Block) diff --git a/snow/engine/snowman/block/mocks/chain_vm.go b/snow/engine/snowman/block/mock_chain_vm.go similarity index 98% rename from snow/engine/snowman/block/mocks/chain_vm.go rename to snow/engine/snowman/block/mock_chain_vm.go index fc75a0f344a8..27b6aef75ed6 100644 --- a/snow/engine/snowman/block/mocks/chain_vm.go +++ b/snow/engine/snowman/block/mock_chain_vm.go @@ -1,11 +1,8 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/snowman/block (interfaces: ChainVM) -// Package mocks is a generated GoMock package. -package mocks +// Package block is a generated GoMock package. +package block import ( context "context" diff --git a/snow/engine/snowman/block/mocks/state_syncable_vm.go b/snow/engine/snowman/block/mock_state_syncable_vm.go similarity index 87% rename from snow/engine/snowman/block/mocks/state_syncable_vm.go rename to snow/engine/snowman/block/mock_state_syncable_vm.go index 50a1fe92e117..f728b9b5a7a7 100644 --- a/snow/engine/snowman/block/mocks/state_syncable_vm.go +++ b/snow/engine/snowman/block/mock_state_syncable_vm.go @@ -1,17 +1,13 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/snowman/block (interfaces: StateSyncableVM) -// Package mocks is a generated GoMock package. -package mocks +// Package block is a generated GoMock package. +package block import ( context "context" reflect "reflect" - block "github.com/ava-labs/avalanchego/snow/engine/snowman/block" gomock "go.uber.org/mock/gomock" ) @@ -39,10 +35,10 @@ func (m *MockStateSyncableVM) EXPECT() *MockStateSyncableVMMockRecorder { } // GetLastStateSummary mocks base method. -func (m *MockStateSyncableVM) GetLastStateSummary(arg0 context.Context) (block.StateSummary, error) { +func (m *MockStateSyncableVM) GetLastStateSummary(arg0 context.Context) (StateSummary, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLastStateSummary", arg0) - ret0, _ := ret[0].(block.StateSummary) + ret0, _ := ret[0].(StateSummary) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -54,10 +50,10 @@ func (mr *MockStateSyncableVMMockRecorder) GetLastStateSummary(arg0 interface{}) } // GetOngoingSyncStateSummary mocks base method. -func (m *MockStateSyncableVM) GetOngoingSyncStateSummary(arg0 context.Context) (block.StateSummary, error) { +func (m *MockStateSyncableVM) GetOngoingSyncStateSummary(arg0 context.Context) (StateSummary, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetOngoingSyncStateSummary", arg0) - ret0, _ := ret[0].(block.StateSummary) + ret0, _ := ret[0].(StateSummary) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -69,10 +65,10 @@ func (mr *MockStateSyncableVMMockRecorder) GetOngoingSyncStateSummary(arg0 inter } // GetStateSummary mocks base method. -func (m *MockStateSyncableVM) GetStateSummary(arg0 context.Context, arg1 uint64) (block.StateSummary, error) { +func (m *MockStateSyncableVM) GetStateSummary(arg0 context.Context, arg1 uint64) (StateSummary, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStateSummary", arg0, arg1) - ret0, _ := ret[0].(block.StateSummary) + ret0, _ := ret[0].(StateSummary) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -84,10 +80,10 @@ func (mr *MockStateSyncableVMMockRecorder) GetStateSummary(arg0, arg1 interface{ } // ParseStateSummary mocks base method. -func (m *MockStateSyncableVM) ParseStateSummary(arg0 context.Context, arg1 []byte) (block.StateSummary, error) { +func (m *MockStateSyncableVM) ParseStateSummary(arg0 context.Context, arg1 []byte) (StateSummary, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ParseStateSummary", arg0, arg1) - ret0, _ := ret[0].(block.StateSummary) + ret0, _ := ret[0].(StateSummary) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/snow/engine/snowman/block/mocks/with_verify_context.go b/snow/engine/snowman/block/mock_with_verify_context.go similarity index 89% rename from snow/engine/snowman/block/mocks/with_verify_context.go rename to snow/engine/snowman/block/mock_with_verify_context.go index ea509980f130..23ce5a2fd4d5 100644 --- a/snow/engine/snowman/block/mocks/with_verify_context.go +++ b/snow/engine/snowman/block/mock_with_verify_context.go @@ -1,17 +1,13 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/snowman/block (interfaces: WithVerifyContext) -// Package mocks is a generated GoMock package. -package mocks +// Package block is a generated GoMock package. +package block import ( context "context" reflect "reflect" - block "github.com/ava-labs/avalanchego/snow/engine/snowman/block" gomock "go.uber.org/mock/gomock" ) @@ -54,7 +50,7 @@ func (mr *MockWithVerifyContextMockRecorder) ShouldVerifyWithContext(arg0 interf } // VerifyWithContext mocks base method. -func (m *MockWithVerifyContext) VerifyWithContext(arg0 context.Context, arg1 *block.Context) error { +func (m *MockWithVerifyContext) VerifyWithContext(arg0 context.Context, arg1 *Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "VerifyWithContext", arg0, arg1) ret0, _ := ret[0].(error) diff --git a/snow/engine/snowman/getter/getter_test.go b/snow/engine/snowman/getter/getter_test.go index 12ecd1abdd80..1e0647b1911e 100644 --- a/snow/engine/snowman/getter/getter_test.go +++ b/snow/engine/snowman/getter/getter_test.go @@ -20,7 +20,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" ) @@ -29,7 +28,7 @@ var errUnknownBlock = errors.New("unknown block") type StateSyncEnabledMock struct { *block.TestVM - *mocks.MockStateSyncableVM + *block.MockStateSyncableVM } func newTest(t *testing.T) (common.AllGetsServer, StateSyncEnabledMock, *common.SenderTest) { @@ -37,7 +36,7 @@ func newTest(t *testing.T) (common.AllGetsServer, StateSyncEnabledMock, *common. vm := StateSyncEnabledMock{ TestVM: &block.TestVM{}, - MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), + MockStateSyncableVM: block.NewMockStateSyncableVM(ctrl), } sender := &common.SenderTest{ diff --git a/snow/networking/handler/mock_handler.go b/snow/networking/handler/mock_handler.go index dd231641e8ac..3346da7960d8 100644 --- a/snow/networking/handler/mock_handler.go +++ b/snow/networking/handler/mock_handler.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/networking/handler (interfaces: Handler) diff --git a/snow/networking/timeout/mock_manager.go b/snow/networking/timeout/mock_manager.go index 5a1bda7cb0b6..1033ad335afe 100644 --- a/snow/networking/timeout/mock_manager.go +++ b/snow/networking/timeout/mock_manager.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/networking/timeout (interfaces: Manager) diff --git a/snow/networking/tracker/mock_resource_tracker.go b/snow/networking/tracker/mock_resource_tracker.go index 4ba16ec98997..cfe8d59bdcd0 100644 --- a/snow/networking/tracker/mock_resource_tracker.go +++ b/snow/networking/tracker/mock_resource_tracker.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/networking/tracker (interfaces: Tracker) diff --git a/snow/networking/tracker/mock_targeter.go b/snow/networking/tracker/mock_targeter.go index d6fe7b540c8f..165bf7a95c59 100644 --- a/snow/networking/tracker/mock_targeter.go +++ b/snow/networking/tracker/mock_targeter.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/networking/tracker (interfaces: Targeter) diff --git a/snow/uptime/mock_calculator.go b/snow/uptime/mock_calculator.go index 389c029e68fe..f0ece236f88c 100644 --- a/snow/uptime/mock_calculator.go +++ b/snow/uptime/mock_calculator.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/uptime (interfaces: Calculator) diff --git a/snow/validators/mock_state.go b/snow/validators/mock_state.go index a438b0eb46ef..07447721c28c 100644 --- a/snow/validators/mock_state.go +++ b/snow/validators/mock_state.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/validators (interfaces: State) diff --git a/snow/validators/mock_subnet_connector.go b/snow/validators/mock_subnet_connector.go index e5c985bd56cc..4719be84ef88 100644 --- a/snow/validators/mock_subnet_connector.go +++ b/snow/validators/mock_subnet_connector.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/validators (interfaces: SubnetConnector) diff --git a/utils/crypto/keychain/mock_ledger.go b/utils/crypto/keychain/mock_ledger.go index 8f270bfbc032..d17500564097 100644 --- a/utils/crypto/keychain/mock_ledger.go +++ b/utils/crypto/keychain/mock_ledger.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/utils/crypto/keychain (interfaces: Ledger) diff --git a/utils/filesystem/mock_io.go b/utils/filesystem/mock_io.go index 9ec15c548e39..43f28011cbfb 100644 --- a/utils/filesystem/mock_io.go +++ b/utils/filesystem/mock_io.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/utils/filesystem (interfaces: Reader) diff --git a/utils/hashing/mock_hasher.go b/utils/hashing/mock_hasher.go index 26b4130c5d72..bc9a0abed2d0 100644 --- a/utils/hashing/mock_hasher.go +++ b/utils/hashing/mock_hasher.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/utils/hashing (interfaces: Hasher) diff --git a/utils/resource/mock_user.go b/utils/resource/mock_user.go index 64b156ac1c1f..28f0059e1c88 100644 --- a/utils/resource/mock_user.go +++ b/utils/resource/mock_user.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/utils/resource (interfaces: User) diff --git a/vms/avm/block/mock_block.go b/vms/avm/block/mock_block.go index 770dbae29b7d..296fc149f253 100644 --- a/vms/avm/block/mock_block.go +++ b/vms/avm/block/mock_block.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/avm/block (interfaces: Block) diff --git a/vms/avm/metrics/mock_metrics.go b/vms/avm/metrics/mock_metrics.go index b83a065e3fa0..25ae52fef2d0 100644 --- a/vms/avm/metrics/mock_metrics.go +++ b/vms/avm/metrics/mock_metrics.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/avm/metrics (interfaces: Metrics) diff --git a/vms/avm/state/mock_state.go b/vms/avm/state/mock_state.go index 3bb615283ce6..162f6328ccdb 100644 --- a/vms/avm/state/mock_state.go +++ b/vms/avm/state/mock_state.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/avm/state (interfaces: Chain,State,Diff) diff --git a/vms/avm/txs/mempool/mock_mempool.go b/vms/avm/txs/mempool/mock_mempool.go index 15125b1ce675..b94d2db095bf 100644 --- a/vms/avm/txs/mempool/mock_mempool.go +++ b/vms/avm/txs/mempool/mock_mempool.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/avm/txs/mempool (interfaces: Mempool) diff --git a/vms/components/avax/mock_transferable_in.go b/vms/components/avax/mock_transferable_in.go index cfd7e419dc26..cbe350801e3b 100644 --- a/vms/components/avax/mock_transferable_in.go +++ b/vms/components/avax/mock_transferable_in.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/components/avax (interfaces: TransferableIn) diff --git a/vms/components/verify/mock_verifiable.go b/vms/components/verify/mock_verifiable.go index 915491142014..3b2609f6eb0f 100644 --- a/vms/components/verify/mock_verifiable.go +++ b/vms/components/verify/mock_verifiable.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/components/verify (interfaces: Verifiable) diff --git a/vms/mock_manager.go b/vms/mock_manager.go index 9726f085c513..70f3dc5ca840 100644 --- a/vms/mock_manager.go +++ b/vms/mock_manager.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms (interfaces: Factory,Manager) diff --git a/vms/platformvm/block/mock_block.go b/vms/platformvm/block/mock_block.go index 9cc2541de0d2..fde27ecbdc04 100644 --- a/vms/platformvm/block/mock_block.go +++ b/vms/platformvm/block/mock_block.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/block (interfaces: Block) diff --git a/vms/platformvm/state/mock_staker_iterator.go b/vms/platformvm/state/mock_staker_iterator.go index 6ef7e9fb2d51..a04f79c628da 100644 --- a/vms/platformvm/state/mock_staker_iterator.go +++ b/vms/platformvm/state/mock_staker_iterator.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: StakerIterator) diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index 8a3aac7d81f1..051bc729ac21 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Chain,Diff,State,Versions) diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index 949d99f1b41d..0cfd9b141def 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool (interfaces: Mempool) diff --git a/vms/platformvm/utxo/mock_verifier.go b/vms/platformvm/utxo/mock_verifier.go index 1c1d9c9c75f9..15766981f685 100644 --- a/vms/platformvm/utxo/mock_verifier.go +++ b/vms/platformvm/utxo/mock_verifier.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/utxo (interfaces: Verifier) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 8297e3681b2c..35e3da7deee4 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -21,7 +21,6 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/logging" @@ -56,8 +55,8 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { builtBlk.EXPECT().ID().Return(ids.GenerateTestID()).AnyTimes() builtBlk.EXPECT().Height().Return(pChainHeight).AnyTimes() - innerVM := mocks.NewMockChainVM(ctrl) - innerBlockBuilderVM := mocks.NewMockBuildBlockWithContextChainVM(ctrl) + innerVM := block.NewMockChainVM(ctrl) + innerBlockBuilderVM := block.NewMockBuildBlockWithContextChainVM(ctrl) innerBlockBuilderVM.EXPECT().BuildBlockWithContext(gomock.Any(), &block.Context{ PChainHeight: pChainHeight - 1, }).Return(builtBlk, nil).AnyTimes() @@ -410,7 +409,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, - ChainVM: mocks.NewMockChainVM(ctrl), + ChainVM: block.NewMockChainVM(ctrl), ctx: &snow.Context{ NodeID: thisNodeID, ValidatorState: vdrState, diff --git a/vms/proposervm/mock_post_fork_block.go b/vms/proposervm/mock_post_fork_block.go index 4f0847424253..23c87ea5fa00 100644 --- a/vms/proposervm/mock_post_fork_block.go +++ b/vms/proposervm/mock_post_fork_block.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/proposervm (interfaces: PostForkBlock) diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 42dfe14789f5..6215a5c8465d 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -18,11 +18,12 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" + "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" - "github.com/ava-labs/avalanchego/vms/proposervm/block" + + statelessblock "github.com/ava-labs/avalanchego/vms/proposervm/block" ) func TestOracle_PreForkBlkImplementsInterface(t *testing.T) { @@ -353,7 +354,7 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { require.NoError(preForkChild.Verify(context.Background())) // postFork block does NOT verify if parent is before fork activation time - postForkStatelessChild, err := block.Build( + postForkStatelessChild, err := statelessblock.Build( coreGenBlk.ID(), coreBlk.Timestamp(), 0, // pChainHeight @@ -768,7 +769,7 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { require.NoError(firstBlock.Verify(context.Background())) - slb, err := block.Build( + slb, err := statelessblock.Build( firstBlock.ID(), // refer unknown parent firstBlock.Timestamp(), 0, // pChainHeight, @@ -805,7 +806,7 @@ func TestPreForkBlock_BuildBlockWithContext(t *testing.T) { builtBlk.EXPECT().Bytes().Return([]byte{1, 2, 3}).AnyTimes() builtBlk.EXPECT().ID().Return(ids.GenerateTestID()).AnyTimes() builtBlk.EXPECT().Height().Return(pChainHeight).AnyTimes() - innerVM := mocks.NewMockChainVM(ctrl) + innerVM := block.NewMockChainVM(ctrl) innerVM.EXPECT().BuildBlock(gomock.Any()).Return(builtBlk, nil).AnyTimes() vdrState := validators.NewMockState(ctrl) vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index 7df10ee28bcf..d5e142b93791 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/proposervm/proposer (interfaces: Windower) diff --git a/vms/proposervm/scheduler/mock_scheduler.go b/vms/proposervm/scheduler/mock_scheduler.go index bb4c19b941f1..9018cad9b5ff 100644 --- a/vms/proposervm/scheduler/mock_scheduler.go +++ b/vms/proposervm/scheduler/mock_scheduler.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/proposervm/scheduler (interfaces: Scheduler) diff --git a/vms/proposervm/state/mock_state.go b/vms/proposervm/state/mock_state.go index 40ef830a1365..fcd266f2d790 100644 --- a/vms/proposervm/state/mock_state.go +++ b/vms/proposervm/state/mock_state.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/proposervm/state (interfaces: State) diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 8308141b6622..04d1e1c35810 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -25,7 +25,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" @@ -2268,7 +2267,7 @@ func TestVMInnerBlkCache(t *testing.T) { ctrl := gomock.NewController(t) // Create a VM - innerVM := mocks.NewMockChainVM(ctrl) + innerVM := block.NewMockChainVM(ctrl) vm := New( innerVM, Config{ @@ -2495,7 +2494,7 @@ func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { type blockWithVerifyContext struct { *snowman.MockBlock - *mocks.MockWithVerifyContext + *block.MockWithVerifyContext } // Ensures that we call [VerifyWithContext] rather than [Verify] on blocks that @@ -2506,7 +2505,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { ctrl := gomock.NewController(t) // Create a VM - innerVM := mocks.NewMockChainVM(ctrl) + innerVM := block.NewMockChainVM(ctrl) vm := New( innerVM, Config{ @@ -2566,7 +2565,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { pChainHeight := uint64(0) innerBlk := blockWithVerifyContext{ MockBlock: snowman.NewMockBlock(ctrl), - MockWithVerifyContext: mocks.NewMockWithVerifyContext(ctrl), + MockWithVerifyContext: block.NewMockWithVerifyContext(ctrl), } innerBlk.MockWithVerifyContext.EXPECT().ShouldVerifyWithContext(gomock.Any()).Return(true, nil).Times(2) innerBlk.MockWithVerifyContext.EXPECT().VerifyWithContext(context.Background(), @@ -2614,7 +2613,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { // false for ShouldVerifyWithContext innerBlk := blockWithVerifyContext{ MockBlock: snowman.NewMockBlock(ctrl), - MockWithVerifyContext: mocks.NewMockWithVerifyContext(ctrl), + MockWithVerifyContext: block.NewMockWithVerifyContext(ctrl), } innerBlk.MockWithVerifyContext.EXPECT().ShouldVerifyWithContext(gomock.Any()).Return(false, nil) innerBlk.MockBlock.EXPECT().Verify(gomock.Any()).Return(nil) @@ -2637,7 +2636,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { // Ensure we call Verify on a block that doesn't have a valid context innerBlk := blockWithVerifyContext{ MockBlock: snowman.NewMockBlock(ctrl), - MockWithVerifyContext: mocks.NewMockWithVerifyContext(ctrl), + MockWithVerifyContext: block.NewMockWithVerifyContext(ctrl), } innerBlk.MockBlock.EXPECT().Verify(gomock.Any()).Return(nil) innerBlk.MockBlock.EXPECT().Parent().Return(ids.GenerateTestID()).AnyTimes() diff --git a/vms/registry/mock_vm_getter.go b/vms/registry/mock_vm_getter.go index 52a1d67fc61a..1645c521c518 100644 --- a/vms/registry/mock_vm_getter.go +++ b/vms/registry/mock_vm_getter.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/registry (interfaces: VMGetter) diff --git a/vms/registry/mock_vm_registerer.go b/vms/registry/mock_vm_registerer.go index 563893d765ed..dbddd9ec02c3 100644 --- a/vms/registry/mock_vm_registerer.go +++ b/vms/registry/mock_vm_registerer.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/registry (interfaces: VMRegisterer) diff --git a/vms/registry/mock_vm_registry.go b/vms/registry/mock_vm_registry.go index 32360ab1b169..eb54c8e65aab 100644 --- a/vms/registry/mock_vm_registry.go +++ b/vms/registry/mock_vm_registry.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/registry (interfaces: VMRegistry) diff --git a/vms/registry/vm_registerer_test.go b/vms/registry/vm_registerer_test.go index f5ad6c2f1349..a8910d4c33ad 100644 --- a/vms/registry/vm_registerer_test.go +++ b/vms/registry/vm_registerer_test.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/api/server" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" + "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms" @@ -56,7 +56,7 @@ func TestRegisterCreateHandlersAndShutdownFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) @@ -73,7 +73,7 @@ func TestRegisterCreateHandlersFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) @@ -90,7 +90,7 @@ func TestRegisterAddRouteFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) handlers := map[string]http.Handler{ "foo": nil, @@ -118,7 +118,7 @@ func TestRegisterAliasLookupFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) handlers := map[string]http.Handler{ "foo": nil, @@ -147,7 +147,7 @@ func TestRegisterAddAliasesFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) handlers := map[string]http.Handler{ "foo": nil, @@ -184,7 +184,7 @@ func TestRegisterHappyCase(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) handlers := map[string]http.Handler{ "foo": nil, @@ -248,7 +248,7 @@ func TestRegisterWithReadLockCreateHandlersAndShutdownFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) @@ -265,7 +265,7 @@ func TestRegisterWithReadLockCreateHandlersFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) @@ -282,7 +282,7 @@ func TestRegisterWithReadLockAddRouteWithReadLockFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) handlers := map[string]http.Handler{ "foo": nil, @@ -310,7 +310,7 @@ func TestRegisterWithReadLockAliasLookupFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) handlers := map[string]http.Handler{ "foo": nil, @@ -339,7 +339,7 @@ func TestRegisterWithReadLockAddAliasesFails(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) handlers := map[string]http.Handler{ "foo": nil, @@ -376,7 +376,7 @@ func TestRegisterWithReadLockHappyCase(t *testing.T) { resources := initRegistererTest(t) vmFactory := vms.NewMockFactory(resources.ctrl) - vm := mocks.NewMockChainVM(resources.ctrl) + vm := block.NewMockChainVM(resources.ctrl) handlers := map[string]http.Handler{ "foo": nil, diff --git a/vms/rpcchainvm/batched_vm_test.go b/vms/rpcchainvm/batched_vm_test.go index c00ca4e6fc60..ebe5d68bc2a1 100644 --- a/vms/rpcchainvm/batched_vm_test.go +++ b/vms/rpcchainvm/batched_vm_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/chain" ) @@ -42,7 +41,7 @@ func batchedParseBlockCachingTestPlugin(t *testing.T, loadExpectations bool) blo // create mock ctrl := gomock.NewController(t) - vm := mocks.NewMockChainVM(ctrl) + vm := block.NewMockChainVM(ctrl) if loadExpectations { blk1 := snowman.NewMockBlock(ctrl) diff --git a/vms/rpcchainvm/state_syncable_vm_test.go b/vms/rpcchainvm/state_syncable_vm_test.go index 640255e80ee4..d0df51c71779 100644 --- a/vms/rpcchainvm/state_syncable_vm_test.go +++ b/vms/rpcchainvm/state_syncable_vm_test.go @@ -20,7 +20,6 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/rpcchainvm/grpcutils" @@ -67,8 +66,8 @@ var ( ) type StateSyncEnabledMock struct { - *mocks.MockChainVM - *mocks.MockStateSyncableVM + *block.MockChainVM + *block.MockStateSyncableVM } func stateSyncEnabledTestPlugin(t *testing.T, loadExpectations bool) block.ChainVM { @@ -77,8 +76,8 @@ func stateSyncEnabledTestPlugin(t *testing.T, loadExpectations bool) block.Chain // create mock ctrl := gomock.NewController(t) ssVM := StateSyncEnabledMock{ - MockChainVM: mocks.NewMockChainVM(ctrl), - MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), + MockChainVM: block.NewMockChainVM(ctrl), + MockStateSyncableVM: block.NewMockStateSyncableVM(ctrl), } if loadExpectations { @@ -99,8 +98,8 @@ func getOngoingSyncStateSummaryTestPlugin(t *testing.T, loadExpectations bool) b // create mock ctrl := gomock.NewController(t) ssVM := StateSyncEnabledMock{ - MockChainVM: mocks.NewMockChainVM(ctrl), - MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), + MockChainVM: block.NewMockChainVM(ctrl), + MockStateSyncableVM: block.NewMockStateSyncableVM(ctrl), } if loadExpectations { @@ -120,8 +119,8 @@ func getLastStateSummaryTestPlugin(t *testing.T, loadExpectations bool) block.Ch // create mock ctrl := gomock.NewController(t) ssVM := StateSyncEnabledMock{ - MockChainVM: mocks.NewMockChainVM(ctrl), - MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), + MockChainVM: block.NewMockChainVM(ctrl), + MockStateSyncableVM: block.NewMockStateSyncableVM(ctrl), } if loadExpectations { @@ -141,8 +140,8 @@ func parseStateSummaryTestPlugin(t *testing.T, loadExpectations bool) block.Chai // create mock ctrl := gomock.NewController(t) ssVM := StateSyncEnabledMock{ - MockChainVM: mocks.NewMockChainVM(ctrl), - MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), + MockChainVM: block.NewMockChainVM(ctrl), + MockStateSyncableVM: block.NewMockStateSyncableVM(ctrl), } if loadExpectations { @@ -163,8 +162,8 @@ func getStateSummaryTestPlugin(t *testing.T, loadExpectations bool) block.ChainV // create mock ctrl := gomock.NewController(t) ssVM := StateSyncEnabledMock{ - MockChainVM: mocks.NewMockChainVM(ctrl), - MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), + MockChainVM: block.NewMockChainVM(ctrl), + MockStateSyncableVM: block.NewMockStateSyncableVM(ctrl), } if loadExpectations { @@ -184,8 +183,8 @@ func acceptStateSummaryTestPlugin(t *testing.T, loadExpectations bool) block.Cha // create mock ctrl := gomock.NewController(t) ssVM := StateSyncEnabledMock{ - MockChainVM: mocks.NewMockChainVM(ctrl), - MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), + MockChainVM: block.NewMockChainVM(ctrl), + MockStateSyncableVM: block.NewMockStateSyncableVM(ctrl), } if loadExpectations { @@ -230,8 +229,8 @@ func lastAcceptedBlockPostStateSummaryAcceptTestPlugin(t *testing.T, loadExpecta // create mock ctrl := gomock.NewController(t) ssVM := StateSyncEnabledMock{ - MockChainVM: mocks.NewMockChainVM(ctrl), - MockStateSyncableVM: mocks.NewMockStateSyncableVM(ctrl), + MockChainVM: block.NewMockChainVM(ctrl), + MockStateSyncableVM: block.NewMockStateSyncableVM(ctrl), } if loadExpectations { diff --git a/vms/rpcchainvm/vm_test.go b/vms/rpcchainvm/vm_test.go index 1e299c35ee5e..fa8cb3d22fdf 100644 --- a/vms/rpcchainvm/vm_test.go +++ b/vms/rpcchainvm/vm_test.go @@ -19,7 +19,6 @@ import ( "golang.org/x/exp/slices" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/rpcchainvm/grpcutils" "github.com/ava-labs/avalanchego/vms/rpcchainvm/runtime" @@ -172,7 +171,7 @@ func TestRuntimeSubprocessBootstrap(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - vm := mocks.NewMockChainVM(ctrl) + vm := block.NewMockChainVM(ctrl) listener, err := grpcutils.NewListener() require.NoError(err) diff --git a/vms/rpcchainvm/with_context_vm_test.go b/vms/rpcchainvm/with_context_vm_test.go index 192a7658e451..5c2c242b94a9 100644 --- a/vms/rpcchainvm/with_context_vm_test.go +++ b/vms/rpcchainvm/with_context_vm_test.go @@ -16,7 +16,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block/mocks" "github.com/ava-labs/avalanchego/snow/snowtest" ) @@ -37,13 +36,13 @@ var ( ) type ContextEnabledVMMock struct { - *mocks.MockChainVM - *mocks.MockBuildBlockWithContextChainVM + *block.MockChainVM + *block.MockBuildBlockWithContextChainVM } type ContextEnabledBlockMock struct { *snowman.MockBlock - *mocks.MockWithVerifyContext + *block.MockWithVerifyContext } func contextEnabledTestPlugin(t *testing.T, loadExpectations bool) block.ChainVM { @@ -52,14 +51,14 @@ func contextEnabledTestPlugin(t *testing.T, loadExpectations bool) block.ChainVM // create mock ctrl := gomock.NewController(t) ctxVM := ContextEnabledVMMock{ - MockChainVM: mocks.NewMockChainVM(ctrl), - MockBuildBlockWithContextChainVM: mocks.NewMockBuildBlockWithContextChainVM(ctrl), + MockChainVM: block.NewMockChainVM(ctrl), + MockBuildBlockWithContextChainVM: block.NewMockBuildBlockWithContextChainVM(ctrl), } if loadExpectations { ctxBlock := ContextEnabledBlockMock{ MockBlock: snowman.NewMockBlock(ctrl), - MockWithVerifyContext: mocks.NewMockWithVerifyContext(ctrl), + MockWithVerifyContext: block.NewMockWithVerifyContext(ctrl), } gomock.InOrder( // Initialize diff --git a/x/sync/mock_client.go b/x/sync/mock_client.go index 153cfb5de5a7..9bbd81127e35 100644 --- a/x/sync/mock_client.go +++ b/x/sync/mock_client.go @@ -1,6 +1,3 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/x/sync (interfaces: Client) From d825ec228b7f78de383d9feea72fcbcf6a0442a8 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:00:38 -0500 Subject: [PATCH 224/267] Add missing import (#2573) Co-authored-by: Stephen Buttolph --- utils/ulimit/ulimit_bsd.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/ulimit/ulimit_bsd.go b/utils/ulimit/ulimit_bsd.go index 191b788286d2..58204fd62a19 100644 --- a/utils/ulimit/ulimit_bsd.go +++ b/utils/ulimit/ulimit_bsd.go @@ -10,6 +10,8 @@ import ( "fmt" "syscall" + "go.uber.org/zap" + "github.com/ava-labs/avalanchego/utils/logging" ) From 021f4f797cfdbe090e23abfe2168e2774a71af5a Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Tue, 2 Jan 2024 11:46:09 -0500 Subject: [PATCH 225/267] `vms/platformvm`: Prune mempool periodically (#2566) --- vms/platformvm/block/builder/builder.go | 33 +++++++- vms/platformvm/config/execution_config.go | 3 + .../config/execution_config_test.go | 6 +- vms/platformvm/vm.go | 46 +++++++++++ vms/platformvm/vm_test.go | 79 +++++++++++++++++++ 5 files changed, 163 insertions(+), 4 deletions(-) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 93716733ac09..34f9a74e7f37 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -60,6 +60,13 @@ type Builder interface { // BuildBlock can be called to attempt to create a new block BuildBlock(context.Context) (snowman.Block, error) + + // PackBlockTxs returns an array of txs that can fit into a valid block of + // size [targetBlockSize]. The returned txs are all verified against the + // preferred state. + // + // Note: This function does not call the consensus engine. + PackBlockTxs(targetBlockSize int) ([]*txs.Tx, error) } // builder implements a simple builder to convert txs into valid blocks @@ -232,6 +239,24 @@ func (b *builder) BuildBlock(context.Context) (snowman.Block, error) { return b.blkManager.NewBlock(statelessBlk), nil } +func (b *builder) PackBlockTxs(targetBlockSize int) ([]*txs.Tx, error) { + preferredID := b.blkManager.Preferred() + preferredState, ok := b.blkManager.GetState(preferredID) + if !ok { + return nil, fmt.Errorf("%w: %s", errMissingPreferredState, preferredID) + } + + return packBlockTxs( + preferredID, + preferredState, + b.Mempool, + b.txExecutorBackend, + b.blkManager, + b.txExecutorBackend.Clk.Time(), + targetBlockSize, + ) +} + // [timestamp] is min(max(now, parent timestamp), next staker change time) func buildBlock( builder *builder, @@ -264,6 +289,7 @@ func buildBlock( builder.txExecutorBackend, builder.blkManager, timestamp, + targetBlockSize, ) if err != nil { return nil, fmt.Errorf("failed to pack block txs: %w", err) @@ -286,6 +312,7 @@ func buildBlock( builder.txExecutorBackend, builder.blkManager, timestamp, + targetBlockSize, ) if err != nil { return nil, fmt.Errorf("failed to pack block txs: %w", err) @@ -313,6 +340,7 @@ func packBlockTxs( backend *txexecutor.Backend, manager blockexecutor.Manager, timestamp time.Time, + remainingSize int, ) ([]*txs.Tx, error) { stateDiff, err := state.NewDiffOn(parentState) if err != nil { @@ -327,9 +355,8 @@ func packBlockTxs( stateDiff.SetTimestamp(timestamp) var ( - blockTxs []*txs.Tx - inputs set.Set[ids.ID] - remainingSize = targetBlockSize + blockTxs []*txs.Tx + inputs set.Set[ids.ID] ) for { diff --git a/vms/platformvm/config/execution_config.go b/vms/platformvm/config/execution_config.go index 964e72f51a57..b21aae48e8e4 100644 --- a/vms/platformvm/config/execution_config.go +++ b/vms/platformvm/config/execution_config.go @@ -5,6 +5,7 @@ package config import ( "encoding/json" + "time" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/platformvm/network" @@ -21,6 +22,7 @@ var DefaultExecutionConfig = ExecutionConfig{ BlockIDCacheSize: 8192, FxOwnerCacheSize: 4 * units.MiB, ChecksumsEnabled: false, + MempoolPruneFrequency: 30 * time.Minute, } // ExecutionConfig provides execution parameters of PlatformVM @@ -35,6 +37,7 @@ type ExecutionConfig struct { BlockIDCacheSize int `json:"block-id-cache-size"` FxOwnerCacheSize int `json:"fx-owner-cache-size"` ChecksumsEnabled bool `json:"checksums-enabled"` + MempoolPruneFrequency time.Duration `json:"mempool-prune-frequency"` } // GetExecutionConfig returns an ExecutionConfig diff --git a/vms/platformvm/config/execution_config_test.go b/vms/platformvm/config/execution_config_test.go index 6ba78df133ed..1680058819ae 100644 --- a/vms/platformvm/config/execution_config_test.go +++ b/vms/platformvm/config/execution_config_test.go @@ -5,6 +5,7 @@ package config import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -61,7 +62,8 @@ func TestExecutionConfigUnmarshal(t *testing.T) { "chain-db-cache-size": 7, "block-id-cache-size": 8, "fx-owner-cache-size": 9, - "checksums-enabled": true + "checksums-enabled": true, + "mempool-prune-frequency": 60000000000 }`) ec, err := GetExecutionConfig(b) require.NoError(err) @@ -87,6 +89,7 @@ func TestExecutionConfigUnmarshal(t *testing.T) { BlockIDCacheSize: 8, FxOwnerCacheSize: 9, ChecksumsEnabled: true, + MempoolPruneFrequency: time.Minute, } require.Equal(expected, ec) }) @@ -135,6 +138,7 @@ func TestExecutionConfigUnmarshal(t *testing.T) { BlockIDCacheSize: 8, FxOwnerCacheSize: 9, ChecksumsEnabled: true, + MempoolPruneFrequency: 30 * time.Minute, } require.Equal(expected, ec) }) diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index d8e9d4172406..10dc515a5a62 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -7,8 +7,10 @@ import ( "context" "errors" "fmt" + "math" "net/http" "sync" + "time" "github.com/gorilla/rpc/v2" @@ -247,6 +249,10 @@ func (vm *VM) Initialize( return err } + // Incrementing [awaitShutdown] would cause a deadlock since + // [periodicallyPruneMempool] grabs the context lock. + go vm.periodicallyPruneMempool(execConfig.MempoolPruneFrequency) + shouldPrune, err := vm.state.ShouldPrune() if err != nil { return fmt.Errorf( @@ -274,6 +280,46 @@ func (vm *VM) Initialize( return nil } +func (vm *VM) periodicallyPruneMempool(frequency time.Duration) { + ticker := time.NewTicker(frequency) + defer ticker.Stop() + + for { + select { + case <-vm.onShutdownCtx.Done(): + return + case <-ticker.C: + if err := vm.pruneMempool(); err != nil { + vm.ctx.Log.Debug("pruning mempool failed", + zap.Error(err), + ) + } + } + } +} + +func (vm *VM) pruneMempool() error { + vm.ctx.Lock.Lock() + defer vm.ctx.Lock.Unlock() + + blockTxs, err := vm.Builder.PackBlockTxs(math.MaxInt) + if err != nil { + return err + } + + for _, tx := range blockTxs { + if err := vm.Builder.Add(tx); err != nil { + vm.ctx.Log.Debug( + "failed to reissue tx", + zap.Stringer("txID", tx.ID()), + zap.Error(err), + ) + } + } + + return nil +} + // Create all chains that exist that this node validates. func (vm *VM) initBlockchains() error { if vm.Config.PartialSyncPrimaryNetwork { diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index ce074150c1c8..7ac1638f8b84 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -2271,3 +2271,82 @@ func TestBaseTx(t *testing.T) { require.NoError(baseTxBlock.Accept(context.Background())) require.NoError(vm.SetPreference(context.Background(), vm.manager.LastAccepted())) } + +func TestPruneMempool(t *testing.T) { + require := require.New(t) + vm, _, _ := defaultVM(t, latestFork) + vm.ctx.Lock.Lock() + defer func() { + require.NoError(vm.Shutdown(context.Background())) + vm.ctx.Lock.Unlock() + }() + + // Create a tx that will be valid regardless of timestamp. + sendAmt := uint64(100000) + changeAddr := ids.ShortEmpty + + baseTx, err := vm.txBuilder.NewBaseTx( + sendAmt, + secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keys[1].Address(), + }, + }, + []*secp256k1.PrivateKey{keys[0]}, + changeAddr, + ) + require.NoError(err) + + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), baseTx)) + vm.ctx.Lock.Lock() + + // [baseTx] should be in the mempool. + baseTxID := baseTx.ID() + _, ok := vm.Builder.Get(baseTxID) + require.True(ok) + + // Create a tx that will be invalid after time advancement. + var ( + startTime = vm.clock.Time() + endTime = startTime.Add(vm.MinStakeDuration) + ) + + addValidatorTx, err := vm.txBuilder.NewAddValidatorTx( + defaultMinValidatorStake, + uint64(startTime.Unix()), + uint64(endTime.Unix()), + ids.GenerateTestNodeID(), + keys[2].Address(), + 20000, + []*secp256k1.PrivateKey{keys[1]}, + ids.ShortEmpty, + ) + require.NoError(err) + + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), addValidatorTx)) + vm.ctx.Lock.Lock() + + // Advance clock to [endTime], making [addValidatorTx] invalid. + vm.clock.Set(endTime) + + // [addValidatorTx] and [baseTx] should still be in the mempool. + addValidatorTxID := addValidatorTx.ID() + _, ok = vm.Builder.Get(addValidatorTxID) + require.True(ok) + _, ok = vm.Builder.Get(baseTxID) + require.True(ok) + + vm.ctx.Lock.Unlock() + require.NoError(vm.pruneMempool()) + vm.ctx.Lock.Lock() + + // [addValidatorTx] should be ejected from the mempool. + // [baseTx] should still be in the mempool. + _, ok = vm.Builder.Get(addValidatorTxID) + require.False(ok) + _, ok = vm.Builder.Get(baseTxID) + require.True(ok) +} From 0c4efd743e1d737f4e8970d0e0ebf229ea44406c Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 3 Jan 2024 11:27:42 -0500 Subject: [PATCH 226/267] Update license header to 2024 (#2572) --- api/admin/client.go | 2 +- api/admin/client_test.go | 2 +- api/admin/service.go | 2 +- api/admin/service_test.go | 2 +- api/auth/auth.go | 2 +- api/auth/auth_test.go | 2 +- api/auth/claims.go | 2 +- api/auth/response.go | 2 +- api/auth/service.go | 2 +- api/common_args_responses.go | 2 +- api/health/checker.go | 2 +- api/health/client.go | 2 +- api/health/client_test.go | 2 +- api/health/handler.go | 2 +- api/health/health.go | 2 +- api/health/health_test.go | 2 +- api/health/metrics.go | 2 +- api/health/result.go | 2 +- api/health/service.go | 2 +- api/health/service_test.go | 2 +- api/health/worker.go | 2 +- api/info/client.go | 2 +- api/info/client_test.go | 2 +- api/info/service.go | 2 +- api/info/service_test.go | 2 +- api/ipcs/client.go | 2 +- api/ipcs/service.go | 2 +- api/keystore/blockchain_keystore.go | 2 +- api/keystore/client.go | 2 +- api/keystore/codec.go | 2 +- api/keystore/gkeystore/keystore_client.go | 2 +- api/keystore/gkeystore/keystore_server.go | 2 +- api/keystore/keystore.go | 2 +- api/keystore/service.go | 2 +- api/keystore/service_test.go | 2 +- api/metrics/gatherer_test.go | 2 +- api/metrics/multi_gatherer.go | 2 +- api/metrics/multi_gatherer_test.go | 2 +- api/metrics/optional_gatherer.go | 2 +- api/metrics/optional_gatherer_test.go | 2 +- api/server/allowed_hosts.go | 2 +- api/server/allowed_hosts_test.go | 2 +- api/server/metrics.go | 2 +- api/server/router.go | 2 +- api/server/router_test.go | 2 +- api/server/server.go | 2 +- api/server/server_test.go | 2 +- api/server/wrapper.go | 2 +- api/traced_handler.go | 2 +- app/app.go | 2 +- cache/cache.go | 2 +- cache/empty_cache.go | 2 +- cache/lru_cache.go | 2 +- cache/lru_cache_benchmark_test.go | 2 +- cache/lru_cache_test.go | 2 +- cache/lru_sized_cache.go | 2 +- cache/lru_sized_cache_test.go | 2 +- cache/metercacher/cache.go | 2 +- cache/metercacher/cache_test.go | 2 +- cache/metercacher/metrics.go | 2 +- cache/test_cacher.go | 2 +- cache/unique_cache.go | 2 +- cache/unique_cache_test.go | 2 +- chains/atomic/codec.go | 2 +- chains/atomic/gsharedmemory/filtered_batch.go | 2 +- chains/atomic/gsharedmemory/shared_memory_client.go | 2 +- chains/atomic/gsharedmemory/shared_memory_server.go | 2 +- chains/atomic/gsharedmemory/shared_memory_test.go | 2 +- chains/atomic/memory.go | 2 +- chains/atomic/memory_test.go | 2 +- chains/atomic/prefixes.go | 2 +- chains/atomic/shared_memory.go | 2 +- chains/atomic/shared_memory_test.go | 2 +- chains/atomic/state.go | 2 +- chains/atomic/test_shared_memory.go | 2 +- chains/atomic/writer.go | 2 +- chains/linearizable_vm.go | 2 +- chains/manager.go | 2 +- chains/registrant.go | 2 +- chains/test_manager.go | 2 +- codec/codec.go | 2 +- codec/general_codec.go | 2 +- codec/hierarchycodec/codec.go | 2 +- codec/hierarchycodec/codec_test.go | 2 +- codec/linearcodec/codec.go | 2 +- codec/linearcodec/codec_test.go | 2 +- codec/manager.go | 2 +- codec/reflectcodec/struct_fielder.go | 2 +- codec/reflectcodec/type_codec.go | 2 +- codec/registry.go | 2 +- codec/test_codec.go | 2 +- config/config.go | 2 +- config/config_test.go | 2 +- config/flags.go | 2 +- config/keys.go | 2 +- config/viper.go | 2 +- database/batch.go | 2 +- database/benchmark_database.go | 2 +- database/common.go | 2 +- database/corruptabledb/db.go | 2 +- database/corruptabledb/db_test.go | 2 +- database/database.go | 2 +- database/encdb/codec.go | 2 +- database/encdb/db.go | 2 +- database/encdb/db_test.go | 2 +- database/errors.go | 2 +- database/helpers.go | 2 +- database/helpers_test.go | 2 +- database/iterator.go | 2 +- database/leveldb/db.go | 2 +- database/leveldb/db_test.go | 2 +- database/leveldb/metrics.go | 2 +- database/linkeddb/codec.go | 2 +- database/linkeddb/linkeddb.go | 2 +- database/linkeddb/linkeddb_test.go | 2 +- database/memdb/db.go | 2 +- database/memdb/db_test.go | 2 +- database/meterdb/db.go | 2 +- database/meterdb/db_test.go | 2 +- database/meterdb/metrics.go | 2 +- database/pebble/batch.go | 2 +- database/pebble/batch_test.go | 2 +- database/pebble/db.go | 2 +- database/pebble/db_test.go | 2 +- database/pebble/iterator.go | 2 +- database/prefixdb/db.go | 2 +- database/prefixdb/db_test.go | 2 +- database/rpcdb/db_client.go | 2 +- database/rpcdb/db_server.go | 2 +- database/rpcdb/db_test.go | 2 +- database/rpcdb/errors.go | 2 +- database/test_database.go | 2 +- database/versiondb/db.go | 2 +- database/versiondb/db_test.go | 2 +- genesis/aliases.go | 2 +- genesis/bootstrappers.go | 2 +- genesis/bootstrappers_test.go | 2 +- genesis/config.go | 2 +- genesis/config_test.go | 2 +- genesis/genesis.go | 2 +- genesis/genesis_fuji.go | 2 +- genesis/genesis_local.go | 2 +- genesis/genesis_mainnet.go | 2 +- genesis/genesis_test.go | 2 +- genesis/params.go | 2 +- genesis/unparsed_config.go | 2 +- ids/aliases.go | 2 +- ids/aliases_test.go | 2 +- ids/bits.go | 2 +- ids/bits_test.go | 2 +- ids/galiasreader/alias_reader_client.go | 2 +- ids/galiasreader/alias_reader_server.go | 2 +- ids/galiasreader/alias_reader_test.go | 2 +- ids/id.go | 2 +- ids/id_test.go | 2 +- ids/node_id.go | 2 +- ids/node_id_test.go | 2 +- ids/request_id.go | 2 +- ids/short.go | 2 +- ids/test_aliases.go | 2 +- ids/test_generator.go | 2 +- indexer/client.go | 2 +- indexer/client_test.go | 2 +- indexer/codec.go | 2 +- indexer/container.go | 2 +- indexer/examples/p-chain/main.go | 2 +- indexer/examples/x-chain-blocks/main.go | 2 +- indexer/index.go | 2 +- indexer/index_test.go | 2 +- indexer/indexer.go | 2 +- indexer/indexer_test.go | 2 +- indexer/service.go | 2 +- ipcs/chainipc.go | 2 +- ipcs/eventsocket.go | 2 +- ipcs/socket/socket.go | 2 +- ipcs/socket/socket_test.go | 2 +- ipcs/socket/socket_unix.go | 2 +- ipcs/socket/socket_windows.go | 2 +- main/main.go | 2 +- message/creator.go | 2 +- message/fields.go | 2 +- message/inbound_msg_builder.go | 2 +- message/inbound_msg_builder_test.go | 2 +- message/internal_msg_builder.go | 2 +- message/messages.go | 2 +- message/messages_benchmark_test.go | 2 +- message/messages_test.go | 2 +- message/ops.go | 2 +- message/outbound_msg_builder.go | 2 +- message/outbound_msg_builder_test.go | 2 +- nat/nat.go | 2 +- nat/no_router.go | 2 +- nat/pmp.go | 2 +- nat/upnp.go | 2 +- network/certs_test.go | 2 +- network/config.go | 2 +- network/conn_test.go | 2 +- network/dialer/dialer.go | 2 +- network/dialer/dialer_test.go | 2 +- network/dialer_test.go | 2 +- network/example_test.go | 2 +- network/handler_test.go | 2 +- network/listener_test.go | 2 +- network/metrics.go | 2 +- network/network.go | 2 +- network/network_test.go | 2 +- network/p2p/client.go | 2 +- network/p2p/gossip/bloom.go | 2 +- network/p2p/gossip/bloom_test.go | 2 +- network/p2p/gossip/gossip.go | 2 +- network/p2p/gossip/gossip_test.go | 2 +- network/p2p/gossip/gossipable.go | 2 +- network/p2p/gossip/handler.go | 2 +- network/p2p/gossip/test_gossip.go | 2 +- network/p2p/handler.go | 2 +- network/p2p/handler_test.go | 2 +- network/p2p/network.go | 2 +- network/p2p/network_test.go | 2 +- network/p2p/node_sampler.go | 2 +- network/p2p/peer_tracker.go | 2 +- network/p2p/peer_tracker_test.go | 2 +- network/p2p/router.go | 2 +- network/p2p/throttler.go | 2 +- network/p2p/throttler_handler.go | 2 +- network/p2p/throttler_handler_test.go | 2 +- network/p2p/throttler_test.go | 2 +- network/p2p/validators.go | 2 +- network/p2p/validators_test.go | 2 +- network/peer/config.go | 2 +- network/peer/example_test.go | 2 +- network/peer/gossip_tracker.go | 2 +- network/peer/gossip_tracker_callback.go | 2 +- network/peer/gossip_tracker_metrics.go | 2 +- network/peer/gossip_tracker_test.go | 2 +- network/peer/info.go | 2 +- network/peer/ip.go | 2 +- network/peer/ip_signer.go | 2 +- network/peer/ip_signer_test.go | 2 +- network/peer/message_queue.go | 2 +- network/peer/message_queue_test.go | 2 +- network/peer/metrics.go | 2 +- network/peer/msg_length.go | 2 +- network/peer/msg_length_test.go | 2 +- network/peer/network.go | 2 +- network/peer/peer.go | 2 +- network/peer/peer_test.go | 2 +- network/peer/set.go | 2 +- network/peer/set_test.go | 2 +- network/peer/test_network.go | 2 +- network/peer/test_peer.go | 2 +- network/peer/tls_config.go | 2 +- network/peer/upgrader.go | 2 +- network/peer/validator_id.go | 2 +- network/test_network.go | 2 +- network/throttling/bandwidth_throttler.go | 2 +- network/throttling/bandwidth_throttler_test.go | 2 +- network/throttling/common.go | 2 +- network/throttling/dial_throttler.go | 2 +- network/throttling/dial_throttler_test.go | 2 +- network/throttling/inbound_conn_throttler.go | 2 +- network/throttling/inbound_conn_throttler_test.go | 2 +- network/throttling/inbound_conn_upgrade_throttler.go | 2 +- network/throttling/inbound_conn_upgrade_throttler_test.go | 2 +- network/throttling/inbound_msg_buffer_throttler.go | 2 +- network/throttling/inbound_msg_buffer_throttler_test.go | 2 +- network/throttling/inbound_msg_byte_throttler.go | 2 +- network/throttling/inbound_msg_byte_throttler_test.go | 2 +- network/throttling/inbound_msg_throttler.go | 2 +- network/throttling/inbound_resource_throttler.go | 2 +- network/throttling/inbound_resource_throttler_test.go | 2 +- network/throttling/no_inbound_msg_throttler.go | 2 +- network/throttling/outbound_msg_throttler.go | 2 +- network/throttling/outbound_msg_throttler_test.go | 2 +- network/throttling/release_func.go | 2 +- network/tracked_ip.go | 2 +- network/tracked_ip_test.go | 2 +- node/beacon_manager.go | 2 +- node/beacon_manager_test.go | 2 +- node/config.go | 2 +- node/insecure_validator_manager.go | 2 +- node/node.go | 2 +- node/overridden_manager.go | 2 +- node/overridden_manager_test.go | 2 +- pubsub/connection.go | 2 +- pubsub/connections.go | 2 +- pubsub/filter_param.go | 2 +- pubsub/filter_test.go | 2 +- pubsub/filterer.go | 2 +- pubsub/messages.go | 2 +- pubsub/server.go | 2 +- snow/acceptor.go | 2 +- snow/choices/decidable.go | 2 +- snow/choices/status.go | 2 +- snow/choices/status_test.go | 2 +- snow/choices/test_decidable.go | 2 +- snow/consensus/avalanche/test_vertex.go | 2 +- snow/consensus/avalanche/vertex.go | 2 +- snow/consensus/snowball/binary_slush.go | 2 +- snow/consensus/snowball/binary_snowball.go | 2 +- snow/consensus/snowball/binary_snowball_test.go | 2 +- snow/consensus/snowball/binary_snowflake.go | 2 +- snow/consensus/snowball/binary_snowflake_test.go | 2 +- snow/consensus/snowball/consensus.go | 2 +- snow/consensus/snowball/consensus_performance_test.go | 2 +- snow/consensus/snowball/consensus_reversibility_test.go | 2 +- snow/consensus/snowball/consensus_test.go | 2 +- snow/consensus/snowball/flat.go | 2 +- snow/consensus/snowball/flat_test.go | 2 +- snow/consensus/snowball/network_test.go | 2 +- snow/consensus/snowball/nnary_slush.go | 2 +- snow/consensus/snowball/nnary_snowball.go | 2 +- snow/consensus/snowball/nnary_snowball_test.go | 2 +- snow/consensus/snowball/nnary_snowflake.go | 2 +- snow/consensus/snowball/nnary_snowflake_test.go | 2 +- snow/consensus/snowball/parameters.go | 2 +- snow/consensus/snowball/parameters_test.go | 2 +- snow/consensus/snowball/tree.go | 2 +- snow/consensus/snowball/tree_test.go | 2 +- snow/consensus/snowball/unary_snowball.go | 2 +- snow/consensus/snowball/unary_snowball_test.go | 2 +- snow/consensus/snowball/unary_snowflake.go | 2 +- snow/consensus/snowball/unary_snowflake_test.go | 2 +- snow/consensus/snowman/block.go | 2 +- snow/consensus/snowman/bootstrapper/majority.go | 2 +- snow/consensus/snowman/bootstrapper/majority_test.go | 2 +- snow/consensus/snowman/bootstrapper/minority.go | 2 +- snow/consensus/snowman/bootstrapper/minority_test.go | 2 +- snow/consensus/snowman/bootstrapper/noop.go | 2 +- snow/consensus/snowman/bootstrapper/noop_test.go | 2 +- snow/consensus/snowman/bootstrapper/poll.go | 2 +- snow/consensus/snowman/bootstrapper/poll_test.go | 2 +- snow/consensus/snowman/bootstrapper/requests.go | 2 +- snow/consensus/snowman/bootstrapper/sampler.go | 2 +- snow/consensus/snowman/bootstrapper/sampler_test.go | 2 +- snow/consensus/snowman/consensus.go | 2 +- snow/consensus/snowman/consensus_test.go | 2 +- snow/consensus/snowman/factory.go | 2 +- snow/consensus/snowman/metrics.go | 2 +- snow/consensus/snowman/network_test.go | 2 +- snow/consensus/snowman/oracle_block.go | 2 +- snow/consensus/snowman/poll/early_term_no_traversal.go | 2 +- snow/consensus/snowman/poll/early_term_no_traversal_test.go | 2 +- snow/consensus/snowman/poll/interfaces.go | 2 +- snow/consensus/snowman/poll/set.go | 2 +- snow/consensus/snowman/poll/set_test.go | 2 +- snow/consensus/snowman/snowman_block.go | 2 +- snow/consensus/snowman/test_block.go | 2 +- snow/consensus/snowman/topological.go | 2 +- snow/consensus/snowman/topological_test.go | 2 +- snow/consensus/snowman/traced_consensus.go | 2 +- snow/consensus/snowstorm/test_tx.go | 2 +- snow/consensus/snowstorm/tx.go | 2 +- snow/context.go | 2 +- snow/engine/avalanche/bootstrap/bootstrapper.go | 2 +- snow/engine/avalanche/bootstrap/bootstrapper_test.go | 2 +- snow/engine/avalanche/bootstrap/config.go | 2 +- snow/engine/avalanche/bootstrap/metrics.go | 2 +- snow/engine/avalanche/bootstrap/tx_job.go | 2 +- snow/engine/avalanche/bootstrap/vertex_job.go | 2 +- snow/engine/avalanche/engine.go | 2 +- snow/engine/avalanche/getter/getter.go | 2 +- snow/engine/avalanche/getter/getter_test.go | 2 +- snow/engine/avalanche/state/prefixed_state.go | 2 +- snow/engine/avalanche/state/serializer.go | 2 +- snow/engine/avalanche/state/state.go | 2 +- snow/engine/avalanche/state/unique_vertex.go | 2 +- snow/engine/avalanche/state/unique_vertex_test.go | 2 +- snow/engine/avalanche/vertex/builder.go | 2 +- snow/engine/avalanche/vertex/builder_test.go | 2 +- snow/engine/avalanche/vertex/codec.go | 2 +- snow/engine/avalanche/vertex/manager.go | 2 +- snow/engine/avalanche/vertex/parser.go | 2 +- snow/engine/avalanche/vertex/parser_test.go | 2 +- snow/engine/avalanche/vertex/stateless_vertex.go | 2 +- snow/engine/avalanche/vertex/stateless_vertex_test.go | 2 +- snow/engine/avalanche/vertex/storage.go | 2 +- snow/engine/avalanche/vertex/test_builder.go | 2 +- snow/engine/avalanche/vertex/test_manager.go | 2 +- snow/engine/avalanche/vertex/test_parser.go | 2 +- snow/engine/avalanche/vertex/test_storage.go | 2 +- snow/engine/avalanche/vertex/test_vm.go | 2 +- snow/engine/avalanche/vertex/vm.go | 2 +- snow/engine/common/appsender/appsender_client.go | 2 +- snow/engine/common/appsender/appsender_server.go | 2 +- snow/engine/common/bootstrap_tracker.go | 2 +- snow/engine/common/bootstrapable.go | 2 +- snow/engine/common/engine.go | 2 +- snow/engine/common/error.go | 2 +- snow/engine/common/error_test.go | 2 +- snow/engine/common/fx.go | 2 +- snow/engine/common/halter.go | 2 +- snow/engine/common/message.go | 2 +- snow/engine/common/no_ops_handlers.go | 2 +- snow/engine/common/queue/job.go | 2 +- snow/engine/common/queue/jobs.go | 2 +- snow/engine/common/queue/jobs_test.go | 2 +- snow/engine/common/queue/parser.go | 2 +- snow/engine/common/queue/state.go | 2 +- snow/engine/common/queue/test_job.go | 2 +- snow/engine/common/queue/test_parser.go | 2 +- snow/engine/common/request.go | 2 +- snow/engine/common/sender.go | 2 +- snow/engine/common/state_syncer.go | 2 +- snow/engine/common/test_bootstrap_tracker.go | 2 +- snow/engine/common/test_bootstrapper.go | 2 +- snow/engine/common/test_engine.go | 2 +- snow/engine/common/test_sender.go | 2 +- snow/engine/common/test_timer.go | 2 +- snow/engine/common/test_vm.go | 2 +- snow/engine/common/timer.go | 2 +- snow/engine/common/traced_bootstrapable_engine.go | 2 +- snow/engine/common/traced_engine.go | 2 +- snow/engine/common/traced_state_syncer.go | 2 +- snow/engine/common/tracker/accepted.go | 2 +- snow/engine/common/tracker/accepted_test.go | 2 +- snow/engine/common/tracker/peers.go | 2 +- snow/engine/common/tracker/peers_test.go | 2 +- snow/engine/common/tracker/startup.go | 2 +- snow/engine/common/vm.go | 2 +- snow/engine/snowman/ancestor/tree.go | 2 +- snow/engine/snowman/ancestor/tree_test.go | 2 +- snow/engine/snowman/block/batched_vm.go | 2 +- snow/engine/snowman/block/batched_vm_test.go | 2 +- snow/engine/snowman/block/block_context_vm.go | 2 +- snow/engine/snowman/block/state_summary.go | 2 +- snow/engine/snowman/block/state_sync_mode.go | 2 +- snow/engine/snowman/block/state_syncable_vm.go | 2 +- snow/engine/snowman/block/test_batched_vm.go | 2 +- snow/engine/snowman/block/test_state_summary.go | 2 +- snow/engine/snowman/block/test_state_syncable_vm.go | 2 +- snow/engine/snowman/block/test_vm.go | 2 +- snow/engine/snowman/block/vm.go | 2 +- snow/engine/snowman/bootstrap/block_job.go | 2 +- snow/engine/snowman/bootstrap/bootstrapper.go | 2 +- snow/engine/snowman/bootstrap/bootstrapper_test.go | 2 +- snow/engine/snowman/bootstrap/config.go | 2 +- snow/engine/snowman/bootstrap/metrics.go | 2 +- snow/engine/snowman/config.go | 2 +- snow/engine/snowman/config_test.go | 2 +- snow/engine/snowman/engine.go | 2 +- snow/engine/snowman/getter/getter.go | 2 +- snow/engine/snowman/getter/getter_test.go | 2 +- snow/engine/snowman/issuer.go | 2 +- snow/engine/snowman/memory_block.go | 2 +- snow/engine/snowman/metrics.go | 2 +- snow/engine/snowman/syncer/config.go | 2 +- snow/engine/snowman/syncer/state_syncer.go | 2 +- snow/engine/snowman/syncer/state_syncer_test.go | 2 +- snow/engine/snowman/syncer/utils_test.go | 2 +- snow/engine/snowman/test_engine.go | 2 +- snow/engine/snowman/traced_engine.go | 2 +- snow/engine/snowman/transitive.go | 2 +- snow/engine/snowman/transitive_test.go | 2 +- snow/engine/snowman/voter.go | 2 +- snow/event/blockable.go | 2 +- snow/event/blocker.go | 2 +- snow/event/blocker_test.go | 2 +- snow/networking/benchlist/benchable.go | 2 +- snow/networking/benchlist/benchlist.go | 2 +- snow/networking/benchlist/benchlist_test.go | 2 +- snow/networking/benchlist/manager.go | 2 +- snow/networking/benchlist/metrics.go | 2 +- snow/networking/benchlist/test_benchable.go | 2 +- snow/networking/handler/engine.go | 2 +- snow/networking/handler/engine_test.go | 2 +- snow/networking/handler/handler.go | 2 +- snow/networking/handler/handler_test.go | 2 +- snow/networking/handler/health.go | 2 +- snow/networking/handler/health_test.go | 2 +- snow/networking/handler/message_queue.go | 2 +- snow/networking/handler/message_queue_metrics.go | 2 +- snow/networking/handler/message_queue_test.go | 2 +- snow/networking/handler/metrics.go | 2 +- snow/networking/handler/parser.go | 2 +- snow/networking/router/chain_router.go | 2 +- snow/networking/router/chain_router_metrics.go | 2 +- snow/networking/router/chain_router_test.go | 2 +- snow/networking/router/health.go | 2 +- snow/networking/router/inbound_handler.go | 2 +- snow/networking/router/main_test.go | 2 +- snow/networking/router/router.go | 2 +- snow/networking/router/traced_router.go | 2 +- snow/networking/sender/external_sender.go | 2 +- snow/networking/sender/sender.go | 2 +- snow/networking/sender/sender_test.go | 2 +- snow/networking/sender/test_external_sender.go | 2 +- snow/networking/sender/traced_sender.go | 2 +- snow/networking/timeout/main_test.go | 2 +- snow/networking/timeout/manager.go | 2 +- snow/networking/timeout/manager_test.go | 2 +- snow/networking/timeout/metrics.go | 2 +- snow/networking/tracker/resource_tracker.go | 2 +- snow/networking/tracker/resource_tracker_test.go | 2 +- snow/networking/tracker/targeter.go | 2 +- snow/networking/tracker/targeter_test.go | 2 +- snow/snowtest/snowtest.go | 2 +- snow/state.go | 2 +- snow/uptime/locked_calculator.go | 2 +- snow/uptime/locked_calculator_test.go | 2 +- snow/uptime/manager.go | 2 +- snow/uptime/manager_test.go | 2 +- snow/uptime/no_op_calculator.go | 2 +- snow/uptime/state.go | 2 +- snow/uptime/test_state.go | 2 +- snow/validators/connector.go | 2 +- snow/validators/gvalidators/validator_state_client.go | 2 +- snow/validators/gvalidators/validator_state_server.go | 2 +- snow/validators/gvalidators/validator_state_test.go | 2 +- snow/validators/logger.go | 2 +- snow/validators/manager.go | 2 +- snow/validators/manager_test.go | 2 +- snow/validators/set.go | 2 +- snow/validators/set_test.go | 2 +- snow/validators/state.go | 2 +- snow/validators/subnet_connector.go | 2 +- snow/validators/test_state.go | 2 +- snow/validators/traced_state.go | 2 +- snow/validators/unhandled_subnet_connector.go | 2 +- snow/validators/validator.go | 2 +- staking/asn1.go | 2 +- staking/certificate.go | 2 +- staking/parse.go | 2 +- staking/tls.go | 2 +- staking/tls_test.go | 2 +- staking/verify.go | 2 +- staking/verify_test.go | 2 +- subnets/config.go | 2 +- subnets/config_test.go | 2 +- subnets/no_op_allower.go | 2 +- subnets/subnet.go | 2 +- subnets/subnet_test.go | 2 +- tests/colors.go | 2 +- tests/e2e/banff/suites.go | 2 +- tests/e2e/c/dynamic_fees.go | 2 +- tests/e2e/c/hashing_contract.go | 2 +- tests/e2e/c/interchain_workflow.go | 2 +- tests/e2e/e2e_test.go | 2 +- tests/e2e/faultinjection/duplicate_node_id.go | 2 +- tests/e2e/ignore.go | 2 +- tests/e2e/p/interchain_workflow.go | 2 +- tests/e2e/p/permissionless_subnets.go | 2 +- tests/e2e/p/staking_rewards.go | 2 +- tests/e2e/p/workflow.go | 2 +- tests/e2e/static-handlers/suites.go | 2 +- tests/e2e/x/interchain_workflow.go | 2 +- tests/e2e/x/transfer/virtuous.go | 2 +- tests/fixture/e2e/describe.go | 2 +- tests/fixture/e2e/env.go | 2 +- tests/fixture/e2e/flags.go | 2 +- tests/fixture/e2e/helpers.go | 2 +- tests/fixture/test_data_server.go | 2 +- tests/fixture/test_data_server_test.go | 2 +- tests/fixture/tmpnet/cmd/main.go | 2 +- tests/fixture/tmpnet/defaults.go | 2 +- tests/fixture/tmpnet/flags.go | 2 +- tests/fixture/tmpnet/genesis.go | 2 +- tests/fixture/tmpnet/network.go | 2 +- tests/fixture/tmpnet/network_test.go | 2 +- tests/fixture/tmpnet/node.go | 2 +- tests/fixture/tmpnet/node_config.go | 2 +- tests/fixture/tmpnet/node_process.go | 2 +- tests/fixture/tmpnet/utils.go | 2 +- tests/http.go | 2 +- tests/upgrade/upgrade_test.go | 2 +- trace/exporter.go | 2 +- trace/exporter_type.go | 2 +- trace/noop.go | 2 +- trace/tracer.go | 2 +- utils/atomic.go | 2 +- utils/atomic_test.go | 2 +- utils/bag/bag.go | 2 +- utils/bag/bag_benchmark_test.go | 2 +- utils/bag/bag_test.go | 2 +- utils/bag/unique_bag.go | 2 +- utils/bag/unique_bag_test.go | 2 +- utils/beacon/beacon.go | 2 +- utils/beacon/set.go | 2 +- utils/beacon/set_test.go | 2 +- utils/bimap/bimap.go | 2 +- utils/bimap/bimap_test.go | 2 +- utils/bloom/bloom_filter.go | 2 +- utils/bloom/bloom_filter_test.go | 2 +- utils/bloom/map_filter.go | 2 +- utils/buffer/bounded_nonblocking_queue.go | 2 +- utils/buffer/bounded_nonblocking_queue_test.go | 2 +- utils/buffer/unbounded_blocking_deque.go | 2 +- utils/buffer/unbounded_blocking_deque_test.go | 2 +- utils/buffer/unbounded_deque.go | 2 +- utils/buffer/unbounded_deque_test.go | 2 +- utils/bytes.go | 2 +- utils/cb58/cb58.go | 2 +- utils/cb58/cb58_test.go | 2 +- utils/compression/compressor.go | 2 +- utils/compression/compressor_test.go | 2 +- utils/compression/gzip_compressor.go | 2 +- utils/compression/no_compressor.go | 2 +- utils/compression/no_compressor_test.go | 2 +- utils/compression/type.go | 2 +- utils/compression/type_test.go | 2 +- utils/compression/zstd_compressor.go | 2 +- utils/constants/acps.go | 2 +- utils/constants/aliases.go | 2 +- utils/constants/application.go | 2 +- utils/constants/memory.go | 2 +- utils/constants/network_ids.go | 2 +- utils/constants/network_ids_test.go | 2 +- utils/constants/networking.go | 2 +- utils/constants/vm_ids.go | 2 +- utils/context.go | 2 +- utils/crypto/bls/bls_benchmark_test.go | 2 +- utils/crypto/bls/bls_test.go | 2 +- utils/crypto/bls/public.go | 2 +- utils/crypto/bls/public_test.go | 2 +- utils/crypto/bls/secret.go | 2 +- utils/crypto/bls/secret_test.go | 2 +- utils/crypto/bls/signature.go | 2 +- utils/crypto/bls/signature_test.go | 2 +- utils/crypto/keychain/keychain.go | 2 +- utils/crypto/keychain/keychain_test.go | 2 +- utils/crypto/keychain/ledger.go | 2 +- utils/crypto/ledger/ledger.go | 2 +- utils/crypto/ledger/ledger_test.go | 2 +- utils/crypto/secp256k1/rfc6979_test.go | 2 +- utils/crypto/secp256k1/secp256k1.go | 2 +- utils/crypto/secp256k1/secp256k1_benchmark_test.go | 2 +- utils/crypto/secp256k1/secp256k1_test.go | 2 +- utils/crypto/secp256k1/test_keys.go | 2 +- utils/dynamicip/ifconfig_resolver.go | 2 +- utils/dynamicip/no_updater.go | 2 +- utils/dynamicip/opendns_resolver.go | 2 +- utils/dynamicip/resolver.go | 2 +- utils/dynamicip/resolver_test.go | 2 +- utils/dynamicip/updater.go | 2 +- utils/dynamicip/updater_test.go | 2 +- utils/error.go | 2 +- utils/filesystem/io.go | 2 +- utils/filesystem/rename.go | 2 +- utils/filesystem/rename_test.go | 2 +- utils/formatting/address/address.go | 2 +- utils/formatting/address/converter.go | 2 +- utils/formatting/encoding.go | 2 +- utils/formatting/encoding_benchmark_test.go | 2 +- utils/formatting/encoding_test.go | 2 +- utils/formatting/int_format.go | 2 +- utils/formatting/int_format_test.go | 2 +- utils/formatting/prefixed_stringer.go | 2 +- utils/hashing/consistent/hashable.go | 2 +- utils/hashing/consistent/ring.go | 2 +- utils/hashing/consistent/ring_test.go | 2 +- utils/hashing/hasher.go | 2 +- utils/hashing/hashing.go | 2 +- utils/heap/map.go | 2 +- utils/heap/map_test.go | 2 +- utils/heap/queue.go | 2 +- utils/heap/queue_test.go | 2 +- utils/heap/set.go | 2 +- utils/heap/set_test.go | 2 +- utils/ips/claimed_ip_port.go | 2 +- utils/ips/dynamic_ip_port.go | 2 +- utils/ips/ip_port.go | 2 +- utils/ips/ip_test.go | 2 +- utils/ips/lookup.go | 2 +- utils/ips/lookup_test.go | 2 +- utils/json/codec.go | 2 +- utils/json/float32.go | 2 +- utils/json/float32_test.go | 2 +- utils/json/float64.go | 2 +- utils/json/uint16.go | 2 +- utils/json/uint32.go | 2 +- utils/json/uint64.go | 2 +- utils/json/uint8.go | 2 +- utils/linkedhashmap/iterator.go | 2 +- utils/linkedhashmap/linkedhashmap.go | 2 +- utils/linkedhashmap/linkedhashmap_test.go | 2 +- utils/logging/color.go | 2 +- utils/logging/config.go | 2 +- utils/logging/factory.go | 2 +- utils/logging/format.go | 2 +- utils/logging/level.go | 2 +- utils/logging/log.go | 2 +- utils/logging/log_test.go | 2 +- utils/logging/logger.go | 2 +- utils/logging/sanitize.go | 2 +- utils/logging/test_log.go | 2 +- utils/math/averager.go | 2 +- utils/math/averager_heap.go | 2 +- utils/math/averager_heap_test.go | 2 +- utils/math/continuous_averager.go | 2 +- utils/math/continuous_averager_benchmark_test.go | 2 +- utils/math/continuous_averager_test.go | 2 +- utils/math/meter/continuous_meter.go | 2 +- utils/math/meter/factory.go | 2 +- utils/math/meter/meter.go | 2 +- utils/math/meter/meter_benchmark_test.go | 2 +- utils/math/meter/meter_test.go | 2 +- utils/math/safe_math.go | 2 +- utils/math/safe_math_test.go | 2 +- utils/math/sync_averager.go | 2 +- utils/maybe/maybe.go | 2 +- utils/maybe/maybe_test.go | 2 +- utils/metric/api_interceptor.go | 2 +- utils/metric/averager.go | 2 +- utils/password/hash.go | 2 +- utils/password/hash_test.go | 2 +- utils/password/password.go | 2 +- utils/password/password_test.go | 2 +- utils/perms/chmod.go | 2 +- utils/perms/create.go | 2 +- utils/perms/perms.go | 2 +- utils/perms/write_file.go | 2 +- utils/profiler/continuous.go | 2 +- utils/profiler/profiler.go | 2 +- utils/profiler/profiler_test.go | 2 +- utils/resource/metrics.go | 2 +- utils/resource/no_usage.go | 2 +- utils/resource/usage.go | 2 +- utils/resource/usage_test.go | 2 +- utils/rpc/json.go | 2 +- utils/rpc/options.go | 2 +- utils/rpc/requester.go | 2 +- utils/sampler/rand.go | 2 +- utils/sampler/rand_test.go | 2 +- utils/sampler/uniform.go | 2 +- utils/sampler/uniform_benchmark_test.go | 2 +- utils/sampler/uniform_best.go | 2 +- utils/sampler/uniform_replacer.go | 2 +- utils/sampler/uniform_resample.go | 2 +- utils/sampler/uniform_test.go | 2 +- utils/sampler/weighted.go | 2 +- utils/sampler/weighted_array.go | 2 +- utils/sampler/weighted_array_test.go | 2 +- utils/sampler/weighted_benchmark_test.go | 2 +- utils/sampler/weighted_best.go | 2 +- utils/sampler/weighted_heap.go | 2 +- utils/sampler/weighted_heap_test.go | 2 +- utils/sampler/weighted_linear.go | 2 +- utils/sampler/weighted_linear_test.go | 2 +- utils/sampler/weighted_test.go | 2 +- utils/sampler/weighted_uniform.go | 2 +- utils/sampler/weighted_without_replacement.go | 2 +- utils/sampler/weighted_without_replacement_benchmark_test.go | 2 +- utils/sampler/weighted_without_replacement_generic.go | 2 +- utils/sampler/weighted_without_replacement_test.go | 2 +- utils/set/bits.go | 2 +- utils/set/bits_64.go | 2 +- utils/set/bits_64_test.go | 2 +- utils/set/bits_test.go | 2 +- utils/set/sampleable_set.go | 2 +- utils/set/sampleable_set_test.go | 2 +- utils/set/set.go | 2 +- utils/set/set_benchmark_test.go | 2 +- utils/set/set_test.go | 2 +- utils/setmap/setmap.go | 2 +- utils/setmap/setmap_test.go | 2 +- utils/sorting.go | 2 +- utils/sorting_test.go | 2 +- utils/stacktrace.go | 2 +- utils/storage/storage_common.go | 2 +- utils/storage/storage_unix.go | 2 +- utils/storage/storage_windows.go | 2 +- utils/timer/adaptive_timeout_manager.go | 2 +- utils/timer/adaptive_timeout_manager_test.go | 2 +- utils/timer/eta.go | 2 +- utils/timer/meter.go | 2 +- utils/timer/mockable/clock.go | 2 +- utils/timer/mockable/clock_test.go | 2 +- utils/timer/timer.go | 2 +- utils/timer/timer_test.go | 2 +- utils/ulimit/ulimit_bsd.go | 2 +- utils/ulimit/ulimit_darwin.go | 2 +- utils/ulimit/ulimit_unix.go | 2 +- utils/ulimit/ulimit_windows.go | 2 +- utils/units/avax.go | 2 +- utils/units/bytes.go | 2 +- utils/window/window.go | 2 +- utils/window/window_test.go | 2 +- utils/wrappers/closers.go | 2 +- utils/wrappers/errors.go | 2 +- utils/wrappers/packing.go | 2 +- utils/wrappers/packing_test.go | 2 +- utils/zero.go | 2 +- version/application.go | 2 +- version/application_test.go | 2 +- version/compatibility.go | 2 +- version/compatibility_test.go | 2 +- version/constants.go | 2 +- version/constants_test.go | 2 +- version/parser.go | 2 +- version/parser_test.go | 2 +- version/string.go | 2 +- version/version.go | 2 +- version/version_test.go | 2 +- vms/avm/block/block.go | 2 +- vms/avm/block/block_test.go | 2 +- vms/avm/block/builder/builder.go | 2 +- vms/avm/block/builder/builder_test.go | 2 +- vms/avm/block/executor/block.go | 2 +- vms/avm/block/executor/block_test.go | 2 +- vms/avm/block/executor/manager.go | 2 +- vms/avm/block/executor/manager_test.go | 2 +- vms/avm/block/parser.go | 2 +- vms/avm/block/standard_block.go | 2 +- vms/avm/client.go | 2 +- vms/avm/client_test.go | 2 +- vms/avm/config.go | 2 +- vms/avm/config/config.go | 2 +- vms/avm/config_test.go | 2 +- vms/avm/environment_test.go | 2 +- vms/avm/factory.go | 2 +- vms/avm/fx_test.go | 2 +- vms/avm/fxs/fx.go | 2 +- vms/avm/genesis.go | 2 +- vms/avm/genesis_test.go | 2 +- vms/avm/health.go | 2 +- vms/avm/index_test.go | 2 +- vms/avm/metrics/metrics.go | 2 +- vms/avm/metrics/tx_metrics.go | 2 +- vms/avm/network/atomic.go | 2 +- vms/avm/network/config.go | 2 +- vms/avm/network/gossip.go | 2 +- vms/avm/network/gossip_test.go | 2 +- vms/avm/network/network.go | 2 +- vms/avm/network/network_test.go | 2 +- vms/avm/network/tx_verifier.go | 2 +- vms/avm/pubsub_filterer.go | 2 +- vms/avm/pubsub_filterer_test.go | 2 +- vms/avm/service.go | 2 +- vms/avm/service_test.go | 2 +- vms/avm/state/diff.go | 2 +- vms/avm/state/state.go | 2 +- vms/avm/state/state_test.go | 2 +- vms/avm/state/versions.go | 2 +- vms/avm/state_test.go | 2 +- vms/avm/static_client.go | 2 +- vms/avm/static_service.go | 2 +- vms/avm/static_service_test.go | 2 +- vms/avm/tx.go | 2 +- vms/avm/tx_init.go | 2 +- vms/avm/txs/base_tx.go | 2 +- vms/avm/txs/base_tx_test.go | 2 +- vms/avm/txs/codec.go | 2 +- vms/avm/txs/create_asset_tx.go | 2 +- vms/avm/txs/create_asset_tx_test.go | 2 +- vms/avm/txs/executor/backend.go | 2 +- vms/avm/txs/executor/executor.go | 2 +- vms/avm/txs/executor/executor_test.go | 2 +- vms/avm/txs/executor/semantic_verifier.go | 2 +- vms/avm/txs/executor/semantic_verifier_test.go | 2 +- vms/avm/txs/executor/syntactic_verifier.go | 2 +- vms/avm/txs/executor/syntactic_verifier_test.go | 2 +- vms/avm/txs/export_tx.go | 2 +- vms/avm/txs/export_tx_test.go | 2 +- vms/avm/txs/import_tx.go | 2 +- vms/avm/txs/import_tx_test.go | 2 +- vms/avm/txs/initial_state.go | 2 +- vms/avm/txs/initial_state_test.go | 2 +- vms/avm/txs/mempool/mempool.go | 2 +- vms/avm/txs/mempool/mempool_test.go | 2 +- vms/avm/txs/operation.go | 2 +- vms/avm/txs/operation_test.go | 2 +- vms/avm/txs/operation_tx.go | 2 +- vms/avm/txs/parser.go | 2 +- vms/avm/txs/tx.go | 2 +- vms/avm/txs/visitor.go | 2 +- vms/avm/utxo/spender.go | 2 +- vms/avm/vm.go | 2 +- vms/avm/vm_benchmark_test.go | 2 +- vms/avm/vm_regression_test.go | 2 +- vms/avm/vm_test.go | 2 +- vms/avm/wallet_client.go | 2 +- vms/avm/wallet_service.go | 2 +- vms/avm/wallet_service_test.go | 2 +- vms/components/avax/addresses.go | 2 +- vms/components/avax/asset.go | 2 +- vms/components/avax/asset_test.go | 2 +- vms/components/avax/atomic_utxos.go | 2 +- vms/components/avax/base_tx.go | 2 +- vms/components/avax/flow_checker.go | 2 +- vms/components/avax/metadata.go | 2 +- vms/components/avax/metadata_test.go | 2 +- vms/components/avax/state.go | 2 +- vms/components/avax/test_verifiable.go | 2 +- vms/components/avax/transferables.go | 2 +- vms/components/avax/transferables_test.go | 2 +- vms/components/avax/utxo.go | 2 +- vms/components/avax/utxo_fetching.go | 2 +- vms/components/avax/utxo_fetching_test.go | 2 +- vms/components/avax/utxo_handler.go | 2 +- vms/components/avax/utxo_id.go | 2 +- vms/components/avax/utxo_id_test.go | 2 +- vms/components/avax/utxo_state.go | 2 +- vms/components/avax/utxo_state_test.go | 2 +- vms/components/avax/utxo_test.go | 2 +- vms/components/chain/block.go | 2 +- vms/components/chain/state.go | 2 +- vms/components/chain/state_test.go | 2 +- vms/components/index/index.go | 2 +- vms/components/index/metrics.go | 2 +- vms/components/keystore/codec.go | 2 +- vms/components/keystore/user.go | 2 +- vms/components/keystore/user_test.go | 2 +- vms/components/message/codec.go | 2 +- vms/components/message/handler.go | 2 +- vms/components/message/handler_test.go | 2 +- vms/components/message/message.go | 2 +- vms/components/message/message_test.go | 2 +- vms/components/message/tx.go | 2 +- vms/components/message/tx_test.go | 2 +- vms/components/verify/subnet.go | 2 +- vms/components/verify/subnet_test.go | 2 +- vms/components/verify/verification.go | 2 +- vms/components/verify/verification_test.go | 2 +- vms/example/xsvm/api/client.go | 2 +- vms/example/xsvm/api/server.go | 2 +- vms/example/xsvm/block/block.go | 2 +- vms/example/xsvm/block/codec.go | 2 +- vms/example/xsvm/builder/builder.go | 2 +- vms/example/xsvm/chain/block.go | 2 +- vms/example/xsvm/chain/chain.go | 2 +- vms/example/xsvm/cmd/account/cmd.go | 2 +- vms/example/xsvm/cmd/account/flags.go | 2 +- vms/example/xsvm/cmd/chain/cmd.go | 2 +- vms/example/xsvm/cmd/chain/create/cmd.go | 2 +- vms/example/xsvm/cmd/chain/create/flags.go | 2 +- vms/example/xsvm/cmd/chain/genesis/cmd.go | 2 +- vms/example/xsvm/cmd/chain/genesis/flags.go | 2 +- vms/example/xsvm/cmd/issue/cmd.go | 2 +- vms/example/xsvm/cmd/issue/export/cmd.go | 2 +- vms/example/xsvm/cmd/issue/export/flags.go | 2 +- vms/example/xsvm/cmd/issue/importtx/cmd.go | 2 +- vms/example/xsvm/cmd/issue/importtx/flags.go | 2 +- vms/example/xsvm/cmd/issue/transfer/cmd.go | 2 +- vms/example/xsvm/cmd/issue/transfer/flags.go | 2 +- vms/example/xsvm/cmd/run/cmd.go | 2 +- vms/example/xsvm/cmd/version/cmd.go | 2 +- vms/example/xsvm/cmd/xsvm/main.go | 2 +- vms/example/xsvm/constants.go | 2 +- vms/example/xsvm/execute/block.go | 2 +- vms/example/xsvm/execute/expects_context.go | 2 +- vms/example/xsvm/execute/genesis.go | 2 +- vms/example/xsvm/execute/tx.go | 2 +- vms/example/xsvm/factory.go | 2 +- vms/example/xsvm/genesis/codec.go | 2 +- vms/example/xsvm/genesis/genesis.go | 2 +- vms/example/xsvm/genesis/genesis_test.go | 2 +- vms/example/xsvm/state/keys.go | 2 +- vms/example/xsvm/state/storage.go | 2 +- vms/example/xsvm/tx/codec.go | 2 +- vms/example/xsvm/tx/export.go | 2 +- vms/example/xsvm/tx/import.go | 2 +- vms/example/xsvm/tx/payload.go | 2 +- vms/example/xsvm/tx/transfer.go | 2 +- vms/example/xsvm/tx/tx.go | 2 +- vms/example/xsvm/tx/unsigned.go | 2 +- vms/example/xsvm/tx/visitor.go | 2 +- vms/example/xsvm/vm.go | 2 +- vms/manager.go | 2 +- vms/metervm/batched_vm.go | 2 +- vms/metervm/block.go | 2 +- vms/metervm/block_metrics.go | 2 +- vms/metervm/block_vm.go | 2 +- vms/metervm/build_block_with_context_vm.go | 2 +- vms/metervm/metrics.go | 2 +- vms/metervm/state_syncable_vm.go | 2 +- vms/metervm/vertex_metrics.go | 2 +- vms/metervm/vertex_vm.go | 2 +- vms/nftfx/credential.go | 2 +- vms/nftfx/credential_test.go | 2 +- vms/nftfx/factory.go | 2 +- vms/nftfx/factory_test.go | 2 +- vms/nftfx/fx.go | 2 +- vms/nftfx/fx_test.go | 2 +- vms/nftfx/mint_operation.go | 2 +- vms/nftfx/mint_operation_test.go | 2 +- vms/nftfx/mint_output.go | 2 +- vms/nftfx/mint_output_test.go | 2 +- vms/nftfx/transfer_operation.go | 2 +- vms/nftfx/transfer_operation_test.go | 2 +- vms/nftfx/transfer_output.go | 2 +- vms/nftfx/transfer_output_test.go | 2 +- vms/platformvm/api/static_client.go | 2 +- vms/platformvm/api/static_service.go | 2 +- vms/platformvm/api/static_service_test.go | 2 +- vms/platformvm/block/abort_block.go | 2 +- vms/platformvm/block/abort_block_test.go | 2 +- vms/platformvm/block/atomic_block.go | 2 +- vms/platformvm/block/atomic_block_test.go | 2 +- vms/platformvm/block/block.go | 2 +- vms/platformvm/block/builder/builder.go | 2 +- vms/platformvm/block/builder/builder_test.go | 2 +- vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/builder/main_test.go | 2 +- vms/platformvm/block/builder/standard_block_test.go | 2 +- vms/platformvm/block/codec.go | 2 +- vms/platformvm/block/commit_block.go | 2 +- vms/platformvm/block/commit_block_test.go | 2 +- vms/platformvm/block/common_block.go | 2 +- vms/platformvm/block/executor/acceptor.go | 2 +- vms/platformvm/block/executor/acceptor_test.go | 2 +- vms/platformvm/block/executor/backend.go | 2 +- vms/platformvm/block/executor/backend_test.go | 2 +- vms/platformvm/block/executor/block.go | 2 +- vms/platformvm/block/executor/block_state.go | 2 +- vms/platformvm/block/executor/block_test.go | 2 +- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/block/executor/manager.go | 2 +- vms/platformvm/block/executor/manager_test.go | 2 +- vms/platformvm/block/executor/options.go | 2 +- vms/platformvm/block/executor/options_test.go | 2 +- vms/platformvm/block/executor/proposal_block_test.go | 2 +- vms/platformvm/block/executor/rejector.go | 2 +- vms/platformvm/block/executor/rejector_test.go | 2 +- vms/platformvm/block/executor/standard_block_test.go | 2 +- vms/platformvm/block/executor/verifier.go | 2 +- vms/platformvm/block/executor/verifier_test.go | 2 +- vms/platformvm/block/parse.go | 2 +- vms/platformvm/block/parse_test.go | 2 +- vms/platformvm/block/proposal_block.go | 2 +- vms/platformvm/block/proposal_block_test.go | 2 +- vms/platformvm/block/serialization_test.go | 2 +- vms/platformvm/block/standard_block.go | 2 +- vms/platformvm/block/standard_block_test.go | 2 +- vms/platformvm/block/visitor.go | 2 +- vms/platformvm/client.go | 2 +- vms/platformvm/client_permissionless_validator.go | 2 +- vms/platformvm/config/config.go | 2 +- vms/platformvm/config/execution_config.go | 2 +- vms/platformvm/config/execution_config_test.go | 2 +- vms/platformvm/factory.go | 2 +- vms/platformvm/fx/fx.go | 2 +- vms/platformvm/genesis/codec.go | 2 +- vms/platformvm/genesis/genesis.go | 2 +- vms/platformvm/health.go | 2 +- vms/platformvm/main_test.go | 2 +- vms/platformvm/metrics/block_metrics.go | 2 +- vms/platformvm/metrics/metrics.go | 2 +- vms/platformvm/metrics/no_op.go | 2 +- vms/platformvm/metrics/tx_metrics.go | 2 +- vms/platformvm/network/config.go | 2 +- vms/platformvm/network/gossip.go | 2 +- vms/platformvm/network/gossip_test.go | 2 +- vms/platformvm/network/main_test.go | 2 +- vms/platformvm/network/network.go | 2 +- vms/platformvm/network/network_test.go | 2 +- vms/platformvm/network/tx_verifier.go | 2 +- vms/platformvm/reward/calculator.go | 2 +- vms/platformvm/reward/calculator_test.go | 2 +- vms/platformvm/reward/config.go | 2 +- vms/platformvm/service.go | 2 +- vms/platformvm/service_test.go | 2 +- vms/platformvm/signer/empty.go | 2 +- vms/platformvm/signer/empty_test.go | 2 +- vms/platformvm/signer/proof_of_possession.go | 2 +- vms/platformvm/signer/proof_of_possession_test.go | 2 +- vms/platformvm/signer/signer.go | 2 +- vms/platformvm/stakeable/stakeable_lock.go | 2 +- vms/platformvm/stakeable/stakeable_lock_test.go | 2 +- vms/platformvm/state/diff.go | 2 +- vms/platformvm/state/diff_test.go | 2 +- vms/platformvm/state/disk_staker_diff_iterator.go | 2 +- vms/platformvm/state/disk_staker_diff_iterator_test.go | 2 +- vms/platformvm/state/empty_iterator.go | 2 +- vms/platformvm/state/empty_iterator_test.go | 2 +- vms/platformvm/state/masked_iterator.go | 2 +- vms/platformvm/state/masked_iterator_test.go | 2 +- vms/platformvm/state/merged_iterator.go | 2 +- vms/platformvm/state/merged_iterator_test.go | 2 +- vms/platformvm/state/metadata_codec.go | 2 +- vms/platformvm/state/metadata_delegator.go | 2 +- vms/platformvm/state/metadata_delegator_test.go | 2 +- vms/platformvm/state/metadata_validator.go | 2 +- vms/platformvm/state/metadata_validator_test.go | 2 +- vms/platformvm/state/slice_iterator_test.go | 2 +- vms/platformvm/state/staker.go | 2 +- vms/platformvm/state/staker_diff_iterator.go | 2 +- vms/platformvm/state/staker_diff_iterator_test.go | 2 +- vms/platformvm/state/staker_status.go | 2 +- vms/platformvm/state/staker_test.go | 2 +- vms/platformvm/state/stakers.go | 2 +- vms/platformvm/state/stakers_test.go | 2 +- vms/platformvm/state/state.go | 2 +- vms/platformvm/state/state_test.go | 2 +- vms/platformvm/state/tree_iterator.go | 2 +- vms/platformvm/state/tree_iterator_test.go | 2 +- vms/platformvm/state/versions.go | 2 +- vms/platformvm/status/blockchain_status.go | 2 +- vms/platformvm/status/blockchain_status_test.go | 2 +- vms/platformvm/status/status.go | 2 +- vms/platformvm/status/status_test.go | 2 +- vms/platformvm/txs/add_delegator_test.go | 2 +- vms/platformvm/txs/add_delegator_tx.go | 2 +- vms/platformvm/txs/add_permissionless_delegator_tx.go | 2 +- vms/platformvm/txs/add_permissionless_delegator_tx_test.go | 2 +- vms/platformvm/txs/add_permissionless_validator_tx.go | 2 +- vms/platformvm/txs/add_permissionless_validator_tx_test.go | 2 +- vms/platformvm/txs/add_subnet_validator_test.go | 2 +- vms/platformvm/txs/add_subnet_validator_tx.go | 2 +- vms/platformvm/txs/add_validator_test.go | 2 +- vms/platformvm/txs/add_validator_tx.go | 2 +- vms/platformvm/txs/advance_time_tx.go | 2 +- vms/platformvm/txs/base_tx.go | 2 +- vms/platformvm/txs/base_tx_test.go | 2 +- vms/platformvm/txs/builder/builder.go | 2 +- vms/platformvm/txs/codec.go | 2 +- vms/platformvm/txs/create_chain_test.go | 2 +- vms/platformvm/txs/create_chain_tx.go | 2 +- vms/platformvm/txs/create_subnet_tx.go | 2 +- vms/platformvm/txs/executor/advance_time_test.go | 2 +- vms/platformvm/txs/executor/atomic_tx_executor.go | 2 +- vms/platformvm/txs/executor/backend.go | 2 +- vms/platformvm/txs/executor/create_chain_test.go | 2 +- vms/platformvm/txs/executor/create_subnet_test.go | 2 +- vms/platformvm/txs/executor/export_test.go | 2 +- vms/platformvm/txs/executor/helpers_test.go | 2 +- vms/platformvm/txs/executor/import_test.go | 2 +- vms/platformvm/txs/executor/proposal_tx_executor.go | 2 +- vms/platformvm/txs/executor/proposal_tx_executor_test.go | 2 +- vms/platformvm/txs/executor/reward_validator_test.go | 2 +- vms/platformvm/txs/executor/staker_tx_verification.go | 2 +- vms/platformvm/txs/executor/staker_tx_verification_helpers.go | 2 +- vms/platformvm/txs/executor/staker_tx_verification_test.go | 2 +- vms/platformvm/txs/executor/standard_tx_executor.go | 2 +- vms/platformvm/txs/executor/standard_tx_executor_test.go | 2 +- vms/platformvm/txs/executor/state_changes.go | 2 +- vms/platformvm/txs/executor/subnet_tx_verification.go | 2 +- vms/platformvm/txs/executor/tx_mempool_verifier.go | 2 +- vms/platformvm/txs/export_tx.go | 2 +- vms/platformvm/txs/import_tx.go | 2 +- vms/platformvm/txs/mempool/mempool.go | 2 +- vms/platformvm/txs/mempool/mempool_test.go | 2 +- vms/platformvm/txs/priorities.go | 2 +- vms/platformvm/txs/priorities_test.go | 2 +- vms/platformvm/txs/remove_subnet_validator_tx.go | 2 +- vms/platformvm/txs/remove_subnet_validator_tx_test.go | 2 +- vms/platformvm/txs/reward_validator_tx.go | 2 +- vms/platformvm/txs/staker_tx.go | 2 +- vms/platformvm/txs/subnet_validator.go | 2 +- vms/platformvm/txs/subnet_validator_test.go | 2 +- vms/platformvm/txs/transfer_subnet_ownership_tx.go | 2 +- vms/platformvm/txs/transfer_subnet_ownership_tx_test.go | 2 +- vms/platformvm/txs/transform_subnet_tx.go | 2 +- vms/platformvm/txs/transform_subnet_tx_test.go | 2 +- vms/platformvm/txs/tx.go | 2 +- vms/platformvm/txs/txheap/by_end_time.go | 2 +- vms/platformvm/txs/txheap/by_end_time_test.go | 2 +- vms/platformvm/txs/txheap/heap.go | 2 +- vms/platformvm/txs/unsigned_tx.go | 2 +- vms/platformvm/txs/validator.go | 2 +- vms/platformvm/txs/validator_test.go | 2 +- vms/platformvm/txs/visitor.go | 2 +- vms/platformvm/utxo/handler.go | 2 +- vms/platformvm/utxo/handler_test.go | 2 +- vms/platformvm/validator_set_property_test.go | 2 +- vms/platformvm/validators/manager.go | 2 +- vms/platformvm/validators/manager_benchmark_test.go | 2 +- vms/platformvm/validators/test_manager.go | 2 +- vms/platformvm/vm.go | 2 +- vms/platformvm/vm_regression_test.go | 2 +- vms/platformvm/vm_test.go | 2 +- vms/platformvm/warp/codec.go | 2 +- vms/platformvm/warp/constants.go | 2 +- vms/platformvm/warp/gwarp/client.go | 2 +- vms/platformvm/warp/gwarp/server.go | 2 +- vms/platformvm/warp/gwarp/signer_test.go | 2 +- vms/platformvm/warp/message.go | 2 +- vms/platformvm/warp/message_test.go | 2 +- vms/platformvm/warp/payload/addressed_call.go | 2 +- vms/platformvm/warp/payload/addressed_call_test.go | 2 +- vms/platformvm/warp/payload/codec.go | 2 +- vms/platformvm/warp/payload/hash.go | 2 +- vms/platformvm/warp/payload/hash_test.go | 2 +- vms/platformvm/warp/payload/payload.go | 2 +- vms/platformvm/warp/payload/payload_test.go | 2 +- vms/platformvm/warp/signature.go | 2 +- vms/platformvm/warp/signature_test.go | 2 +- vms/platformvm/warp/signer.go | 2 +- vms/platformvm/warp/signer_test.go | 2 +- vms/platformvm/warp/test_signer.go | 2 +- vms/platformvm/warp/unsigned_message.go | 2 +- vms/platformvm/warp/unsigned_message_test.go | 2 +- vms/platformvm/warp/validator.go | 2 +- vms/platformvm/warp/validator_test.go | 2 +- vms/propertyfx/burn_operation.go | 2 +- vms/propertyfx/burn_operation_test.go | 2 +- vms/propertyfx/credential.go | 2 +- vms/propertyfx/credential_test.go | 2 +- vms/propertyfx/factory.go | 2 +- vms/propertyfx/factory_test.go | 2 +- vms/propertyfx/fx.go | 2 +- vms/propertyfx/fx_test.go | 2 +- vms/propertyfx/mint_operation.go | 2 +- vms/propertyfx/mint_operation_test.go | 2 +- vms/propertyfx/mint_output.go | 2 +- vms/propertyfx/mint_output_test.go | 2 +- vms/propertyfx/owned_output.go | 2 +- vms/propertyfx/owned_output_test.go | 2 +- vms/proposervm/batched_vm.go | 2 +- vms/proposervm/batched_vm_test.go | 2 +- vms/proposervm/block.go | 2 +- vms/proposervm/block/block.go | 2 +- vms/proposervm/block/block_test.go | 2 +- vms/proposervm/block/build.go | 2 +- vms/proposervm/block/build_test.go | 2 +- vms/proposervm/block/codec.go | 2 +- vms/proposervm/block/header.go | 2 +- vms/proposervm/block/header_test.go | 2 +- vms/proposervm/block/option.go | 2 +- vms/proposervm/block/option_test.go | 2 +- vms/proposervm/block/parse.go | 2 +- vms/proposervm/block/parse_test.go | 2 +- vms/proposervm/block_server.go | 2 +- vms/proposervm/block_test.go | 2 +- vms/proposervm/config.go | 2 +- vms/proposervm/height_indexed_vm.go | 2 +- vms/proposervm/indexer/block_server.go | 2 +- vms/proposervm/indexer/block_server_test.go | 2 +- vms/proposervm/indexer/height_indexer.go | 2 +- vms/proposervm/indexer/height_indexer_test.go | 2 +- vms/proposervm/main_test.go | 2 +- vms/proposervm/post_fork_block.go | 2 +- vms/proposervm/post_fork_block_test.go | 2 +- vms/proposervm/post_fork_option.go | 2 +- vms/proposervm/post_fork_option_test.go | 2 +- vms/proposervm/pre_fork_block.go | 2 +- vms/proposervm/pre_fork_block_test.go | 2 +- vms/proposervm/proposer/validators.go | 2 +- vms/proposervm/proposer/validators_test.go | 2 +- vms/proposervm/proposer/windower.go | 2 +- vms/proposervm/proposer/windower_test.go | 2 +- vms/proposervm/scheduler/scheduler.go | 2 +- vms/proposervm/scheduler/scheduler_test.go | 2 +- vms/proposervm/state/block_height_index.go | 2 +- vms/proposervm/state/block_state.go | 2 +- vms/proposervm/state/block_state_test.go | 2 +- vms/proposervm/state/chain_state.go | 2 +- vms/proposervm/state/chain_state_test.go | 2 +- vms/proposervm/state/codec.go | 2 +- vms/proposervm/state/state.go | 2 +- vms/proposervm/state/state_test.go | 2 +- vms/proposervm/state_summary.go | 2 +- vms/proposervm/state_syncable_vm.go | 2 +- vms/proposervm/state_syncable_vm_test.go | 2 +- vms/proposervm/summary/build.go | 2 +- vms/proposervm/summary/build_test.go | 2 +- vms/proposervm/summary/codec.go | 2 +- vms/proposervm/summary/parse.go | 2 +- vms/proposervm/summary/parse_test.go | 2 +- vms/proposervm/summary/state_summary.go | 2 +- vms/proposervm/tree/tree.go | 2 +- vms/proposervm/tree/tree_test.go | 2 +- vms/proposervm/vm.go | 2 +- vms/proposervm/vm_byzantine_test.go | 2 +- vms/proposervm/vm_regression_test.go | 2 +- vms/proposervm/vm_test.go | 2 +- vms/registry/vm_getter.go | 2 +- vms/registry/vm_getter_test.go | 2 +- vms/registry/vm_registerer.go | 2 +- vms/registry/vm_registerer_test.go | 2 +- vms/registry/vm_registry.go | 2 +- vms/registry/vm_registry_test.go | 2 +- vms/rpcchainvm/batched_vm_test.go | 2 +- vms/rpcchainvm/errors.go | 2 +- vms/rpcchainvm/factory.go | 2 +- vms/rpcchainvm/ghttp/gconn/conn_client.go | 2 +- vms/rpcchainvm/ghttp/gconn/conn_server.go | 2 +- vms/rpcchainvm/ghttp/greader/reader_client.go | 2 +- vms/rpcchainvm/ghttp/greader/reader_server.go | 2 +- vms/rpcchainvm/ghttp/gresponsewriter/locked_writer.go | 2 +- vms/rpcchainvm/ghttp/gresponsewriter/writer_client.go | 2 +- vms/rpcchainvm/ghttp/gresponsewriter/writer_server.go | 2 +- vms/rpcchainvm/ghttp/gwriter/writer_client.go | 2 +- vms/rpcchainvm/ghttp/gwriter/writer_server.go | 2 +- vms/rpcchainvm/ghttp/http_client.go | 2 +- vms/rpcchainvm/ghttp/http_server.go | 2 +- vms/rpcchainvm/ghttp/http_test.go | 2 +- vms/rpcchainvm/grpcutils/client.go | 2 +- vms/rpcchainvm/grpcutils/client_test.go | 2 +- vms/rpcchainvm/grpcutils/server.go | 2 +- vms/rpcchainvm/grpcutils/server_closer.go | 2 +- vms/rpcchainvm/grpcutils/util.go | 2 +- vms/rpcchainvm/gruntime/runtime_client.go | 2 +- vms/rpcchainvm/gruntime/runtime_server.go | 2 +- vms/rpcchainvm/messenger/messenger_client.go | 2 +- vms/rpcchainvm/messenger/messenger_server.go | 2 +- vms/rpcchainvm/runtime/manager.go | 2 +- vms/rpcchainvm/runtime/runtime.go | 2 +- vms/rpcchainvm/runtime/subprocess/initializer.go | 2 +- vms/rpcchainvm/runtime/subprocess/linux_stopper.go | 2 +- vms/rpcchainvm/runtime/subprocess/non_linux_stopper.go | 2 +- vms/rpcchainvm/runtime/subprocess/runtime.go | 2 +- vms/rpcchainvm/runtime/subprocess/stopper.go | 2 +- vms/rpcchainvm/state_syncable_vm_test.go | 2 +- vms/rpcchainvm/vm.go | 2 +- vms/rpcchainvm/vm_client.go | 2 +- vms/rpcchainvm/vm_server.go | 2 +- vms/rpcchainvm/vm_test.go | 2 +- vms/rpcchainvm/with_context_vm_test.go | 2 +- vms/secp256k1fx/credential.go | 2 +- vms/secp256k1fx/credential_test.go | 2 +- vms/secp256k1fx/factory.go | 2 +- vms/secp256k1fx/factory_test.go | 2 +- vms/secp256k1fx/fx.go | 2 +- vms/secp256k1fx/fx_test.go | 2 +- vms/secp256k1fx/input.go | 2 +- vms/secp256k1fx/input_test.go | 2 +- vms/secp256k1fx/keychain.go | 2 +- vms/secp256k1fx/keychain_test.go | 2 +- vms/secp256k1fx/mint_operation.go | 2 +- vms/secp256k1fx/mint_operation_test.go | 2 +- vms/secp256k1fx/mint_output.go | 2 +- vms/secp256k1fx/mint_output_test.go | 2 +- vms/secp256k1fx/output_owners.go | 2 +- vms/secp256k1fx/output_owners_test.go | 2 +- vms/secp256k1fx/transfer_input.go | 2 +- vms/secp256k1fx/transfer_input_test.go | 2 +- vms/secp256k1fx/transfer_output.go | 2 +- vms/secp256k1fx/transfer_output_test.go | 2 +- vms/secp256k1fx/tx.go | 2 +- vms/secp256k1fx/vm.go | 2 +- vms/tracedvm/batched_vm.go | 2 +- vms/tracedvm/block.go | 2 +- vms/tracedvm/block_vm.go | 2 +- vms/tracedvm/build_block_with_context_vm.go | 2 +- vms/tracedvm/state_syncable_vm.go | 2 +- vms/tracedvm/tx.go | 2 +- vms/tracedvm/vertex_vm.go | 2 +- vms/types/blob_data.go | 2 +- wallet/chain/c/backend.go | 2 +- wallet/chain/c/builder.go | 2 +- wallet/chain/c/builder_with_options.go | 2 +- wallet/chain/c/context.go | 2 +- wallet/chain/c/signer.go | 2 +- wallet/chain/c/wallet.go | 2 +- wallet/chain/c/wallet_with_options.go | 2 +- wallet/chain/p/backend.go | 2 +- wallet/chain/p/backend_visitor.go | 2 +- wallet/chain/p/builder.go | 2 +- wallet/chain/p/builder_with_options.go | 2 +- wallet/chain/p/context.go | 2 +- wallet/chain/p/signer.go | 2 +- wallet/chain/p/signer_visitor.go | 2 +- wallet/chain/p/wallet.go | 2 +- wallet/chain/p/wallet_with_options.go | 2 +- wallet/chain/x/backend.go | 2 +- wallet/chain/x/backend_visitor.go | 2 +- wallet/chain/x/builder.go | 2 +- wallet/chain/x/builder_with_options.go | 2 +- wallet/chain/x/constants.go | 2 +- wallet/chain/x/context.go | 2 +- wallet/chain/x/signer.go | 2 +- wallet/chain/x/signer_visitor.go | 2 +- wallet/chain/x/wallet.go | 2 +- wallet/chain/x/wallet_with_options.go | 2 +- wallet/subnet/primary/api.go | 2 +- wallet/subnet/primary/common/options.go | 2 +- wallet/subnet/primary/common/spend.go | 2 +- wallet/subnet/primary/common/utxos.go | 2 +- wallet/subnet/primary/example_test.go | 2 +- .../primary/examples/add-permissioned-subnet-validator/main.go | 2 +- wallet/subnet/primary/examples/add-primary-validator/main.go | 2 +- wallet/subnet/primary/examples/c-chain-export/main.go | 2 +- wallet/subnet/primary/examples/c-chain-import/main.go | 2 +- wallet/subnet/primary/examples/create-asset/main.go | 2 +- wallet/subnet/primary/examples/create-chain/main.go | 2 +- wallet/subnet/primary/examples/create-locked-stakeable/main.go | 2 +- wallet/subnet/primary/examples/create-subnet/main.go | 2 +- wallet/subnet/primary/examples/get-p-chain-balance/main.go | 2 +- wallet/subnet/primary/examples/get-x-chain-balance/main.go | 2 +- wallet/subnet/primary/examples/remove-subnet-validator/main.go | 2 +- wallet/subnet/primary/utxos.go | 2 +- wallet/subnet/primary/wallet.go | 2 +- x/archivedb/batch.go | 2 +- x/archivedb/db.go | 2 +- x/archivedb/db_test.go | 2 +- x/archivedb/key.go | 2 +- x/archivedb/key_test.go | 2 +- x/archivedb/prefix_test.go | 2 +- x/archivedb/reader.go | 2 +- x/archivedb/value.go | 2 +- x/merkledb/batch.go | 2 +- x/merkledb/cache.go | 2 +- x/merkledb/cache_test.go | 2 +- x/merkledb/codec.go | 2 +- x/merkledb/codec_test.go | 2 +- x/merkledb/db.go | 2 +- x/merkledb/db_test.go | 2 +- x/merkledb/helpers_test.go | 2 +- x/merkledb/history.go | 2 +- x/merkledb/history_test.go | 2 +- x/merkledb/intermediate_node_db.go | 2 +- x/merkledb/intermediate_node_db_test.go | 2 +- x/merkledb/key.go | 2 +- x/merkledb/key_test.go | 2 +- x/merkledb/metrics.go | 2 +- x/merkledb/metrics_test.go | 2 +- x/merkledb/node.go | 2 +- x/merkledb/node_test.go | 2 +- x/merkledb/proof.go | 2 +- x/merkledb/proof_test.go | 2 +- x/merkledb/tracer.go | 2 +- x/merkledb/trie.go | 2 +- x/merkledb/trie_test.go | 2 +- x/merkledb/value_node_db.go | 2 +- x/merkledb/value_node_db_test.go | 2 +- x/merkledb/view.go | 2 +- x/merkledb/view_iterator.go | 2 +- x/merkledb/view_iterator_test.go | 2 +- x/sync/client.go | 2 +- x/sync/client_test.go | 2 +- x/sync/db.go | 2 +- x/sync/g_db/db_client.go | 2 +- x/sync/g_db/db_server.go | 2 +- x/sync/manager.go | 2 +- x/sync/metrics.go | 2 +- x/sync/network_client.go | 2 +- x/sync/network_server.go | 2 +- x/sync/network_server_test.go | 2 +- x/sync/response_handler.go | 2 +- x/sync/sync_test.go | 2 +- x/sync/workheap.go | 2 +- x/sync/workheap_test.go | 2 +- 1421 files changed, 1421 insertions(+), 1421 deletions(-) diff --git a/api/admin/client.go b/api/admin/client.go index 77f3835f060c..11ee2e5cef2c 100644 --- a/api/admin/client.go +++ b/api/admin/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package admin diff --git a/api/admin/client_test.go b/api/admin/client_test.go index d005c49b448a..486a0a716564 100644 --- a/api/admin/client_test.go +++ b/api/admin/client_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package admin diff --git a/api/admin/service.go b/api/admin/service.go index f94a426b366c..5a60193acce8 100644 --- a/api/admin/service.go +++ b/api/admin/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package admin diff --git a/api/admin/service_test.go b/api/admin/service_test.go index 774c93440bc9..2076a5756b0b 100644 --- a/api/admin/service_test.go +++ b/api/admin/service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package admin diff --git a/api/auth/auth.go b/api/auth/auth.go index a9869fe3ea23..f01b1d2fcd73 100644 --- a/api/auth/auth.go +++ b/api/auth/auth.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package auth diff --git a/api/auth/auth_test.go b/api/auth/auth_test.go index d8b7a4cca59b..caf921ca2a26 100644 --- a/api/auth/auth_test.go +++ b/api/auth/auth_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package auth diff --git a/api/auth/claims.go b/api/auth/claims.go index e2bf55d3078b..1cdda3d4a224 100644 --- a/api/auth/claims.go +++ b/api/auth/claims.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package auth diff --git a/api/auth/response.go b/api/auth/response.go index e87065c71501..eca4b39da9b8 100644 --- a/api/auth/response.go +++ b/api/auth/response.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package auth diff --git a/api/auth/service.go b/api/auth/service.go index 77517c174a5c..badb544c5ccb 100644 --- a/api/auth/service.go +++ b/api/auth/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package auth diff --git a/api/common_args_responses.go b/api/common_args_responses.go index 73624d529d9b..bcb33dcf4136 100644 --- a/api/common_args_responses.go +++ b/api/common_args_responses.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package api diff --git a/api/health/checker.go b/api/health/checker.go index efc895177ed3..b30e450660b8 100644 --- a/api/health/checker.go +++ b/api/health/checker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/client.go b/api/health/client.go index 7c615757f0ce..59daa555cdda 100644 --- a/api/health/client.go +++ b/api/health/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/client_test.go b/api/health/client_test.go index e42be5dbe852..e019829e68e4 100644 --- a/api/health/client_test.go +++ b/api/health/client_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/handler.go b/api/health/handler.go index a8bd8269a158..a95c66a322c0 100644 --- a/api/health/handler.go +++ b/api/health/handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/health.go b/api/health/health.go index 14f1bb7b4b4a..80012cf8c02e 100644 --- a/api/health/health.go +++ b/api/health/health.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/health_test.go b/api/health/health_test.go index 432cefdf6194..64661c710929 100644 --- a/api/health/health_test.go +++ b/api/health/health_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/metrics.go b/api/health/metrics.go index d567bc483d71..fdb7b2ed813b 100644 --- a/api/health/metrics.go +++ b/api/health/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/result.go b/api/health/result.go index df9edb3419cc..e243cba1466d 100644 --- a/api/health/result.go +++ b/api/health/result.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/service.go b/api/health/service.go index 368d986c52bb..7b48507075b2 100644 --- a/api/health/service.go +++ b/api/health/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/service_test.go b/api/health/service_test.go index 0e60d467000a..b25e6dccc017 100644 --- a/api/health/service_test.go +++ b/api/health/service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/health/worker.go b/api/health/worker.go index f0e7a71ed13d..e42e77a4d52c 100644 --- a/api/health/worker.go +++ b/api/health/worker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package health diff --git a/api/info/client.go b/api/info/client.go index f952f62a3c49..6caafd422233 100644 --- a/api/info/client.go +++ b/api/info/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package info diff --git a/api/info/client_test.go b/api/info/client_test.go index 292a1841bd3c..7923ff94aff8 100644 --- a/api/info/client_test.go +++ b/api/info/client_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package info diff --git a/api/info/service.go b/api/info/service.go index 0ce1b38188c9..e315afd259ef 100644 --- a/api/info/service.go +++ b/api/info/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package info diff --git a/api/info/service_test.go b/api/info/service_test.go index ad6320df5a90..b91f87354d1d 100644 --- a/api/info/service_test.go +++ b/api/info/service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package info diff --git a/api/ipcs/client.go b/api/ipcs/client.go index 95391f0f4469..121c1855bc8f 100644 --- a/api/ipcs/client.go +++ b/api/ipcs/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ipcs diff --git a/api/ipcs/service.go b/api/ipcs/service.go index b9bb90479ce9..efe6f2e7280b 100644 --- a/api/ipcs/service.go +++ b/api/ipcs/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ipcs diff --git a/api/keystore/blockchain_keystore.go b/api/keystore/blockchain_keystore.go index 4c163b9627b7..31a3bdc59109 100644 --- a/api/keystore/blockchain_keystore.go +++ b/api/keystore/blockchain_keystore.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/api/keystore/client.go b/api/keystore/client.go index 43442ace79fe..9d12ea0d1df9 100644 --- a/api/keystore/client.go +++ b/api/keystore/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/api/keystore/codec.go b/api/keystore/codec.go index 68025c140564..099bdbfa79e7 100644 --- a/api/keystore/codec.go +++ b/api/keystore/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/api/keystore/gkeystore/keystore_client.go b/api/keystore/gkeystore/keystore_client.go index 6bbfc6f92c1e..87527a640412 100644 --- a/api/keystore/gkeystore/keystore_client.go +++ b/api/keystore/gkeystore/keystore_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gkeystore diff --git a/api/keystore/gkeystore/keystore_server.go b/api/keystore/gkeystore/keystore_server.go index 9244939de3b9..65e6e90e99d9 100644 --- a/api/keystore/gkeystore/keystore_server.go +++ b/api/keystore/gkeystore/keystore_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gkeystore diff --git a/api/keystore/keystore.go b/api/keystore/keystore.go index 02d5f5dc6238..ed3c9d21e57e 100644 --- a/api/keystore/keystore.go +++ b/api/keystore/keystore.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/api/keystore/service.go b/api/keystore/service.go index d4c845743bbb..aa56433ee6e7 100644 --- a/api/keystore/service.go +++ b/api/keystore/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/api/keystore/service_test.go b/api/keystore/service_test.go index 842ab7d76cc7..c011c92e78e1 100644 --- a/api/keystore/service_test.go +++ b/api/keystore/service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/api/metrics/gatherer_test.go b/api/metrics/gatherer_test.go index 2059c1ab584f..334c361ebcc0 100644 --- a/api/metrics/gatherer_test.go +++ b/api/metrics/gatherer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/api/metrics/multi_gatherer.go b/api/metrics/multi_gatherer.go index e3c88778ad4e..79affd4b7b2e 100644 --- a/api/metrics/multi_gatherer.go +++ b/api/metrics/multi_gatherer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/api/metrics/multi_gatherer_test.go b/api/metrics/multi_gatherer_test.go index a2e59a90d51e..033e3e88b1e6 100644 --- a/api/metrics/multi_gatherer_test.go +++ b/api/metrics/multi_gatherer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/api/metrics/optional_gatherer.go b/api/metrics/optional_gatherer.go index f31603281cee..686856efcc86 100644 --- a/api/metrics/optional_gatherer.go +++ b/api/metrics/optional_gatherer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/api/metrics/optional_gatherer_test.go b/api/metrics/optional_gatherer_test.go index 887029a3572b..201750701313 100644 --- a/api/metrics/optional_gatherer_test.go +++ b/api/metrics/optional_gatherer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/api/server/allowed_hosts.go b/api/server/allowed_hosts.go index 6745f0e17565..7d2812b2782a 100644 --- a/api/server/allowed_hosts.go +++ b/api/server/allowed_hosts.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package server diff --git a/api/server/allowed_hosts_test.go b/api/server/allowed_hosts_test.go index ae7a824834a9..47b1a53df0ba 100644 --- a/api/server/allowed_hosts_test.go +++ b/api/server/allowed_hosts_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package server diff --git a/api/server/metrics.go b/api/server/metrics.go index 9859494f3ae4..e3b2d76c83ea 100644 --- a/api/server/metrics.go +++ b/api/server/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package server diff --git a/api/server/router.go b/api/server/router.go index b37c6282c90d..6adadf608be4 100644 --- a/api/server/router.go +++ b/api/server/router.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package server diff --git a/api/server/router_test.go b/api/server/router_test.go index cae75d2c97bd..f6676a3727a3 100644 --- a/api/server/router_test.go +++ b/api/server/router_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package server diff --git a/api/server/server.go b/api/server/server.go index 0f676e0cef7f..a2364b6a17cd 100644 --- a/api/server/server.go +++ b/api/server/server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package server diff --git a/api/server/server_test.go b/api/server/server_test.go index 865e090c10f1..584ad24a7862 100644 --- a/api/server/server_test.go +++ b/api/server/server_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package server diff --git a/api/server/wrapper.go b/api/server/wrapper.go index e467dc968065..b6cca85c731e 100644 --- a/api/server/wrapper.go +++ b/api/server/wrapper.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package server diff --git a/api/traced_handler.go b/api/traced_handler.go index 149be8208edc..9543c2ebbd15 100644 --- a/api/traced_handler.go +++ b/api/traced_handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package api diff --git a/app/app.go b/app/app.go index af651235ba77..c2da07b416a8 100644 --- a/app/app.go +++ b/app/app.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package app diff --git a/cache/cache.go b/cache/cache.go index 3d7206e79050..10ecad2c502f 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/empty_cache.go b/cache/empty_cache.go index 767cf5b74266..3a70ea91fe5d 100644 --- a/cache/empty_cache.go +++ b/cache/empty_cache.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/lru_cache.go b/cache/lru_cache.go index 84d342db9f01..2a8a7ebe6d80 100644 --- a/cache/lru_cache.go +++ b/cache/lru_cache.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/lru_cache_benchmark_test.go b/cache/lru_cache_benchmark_test.go index d8e4f4185933..3ddf03cb06f7 100644 --- a/cache/lru_cache_benchmark_test.go +++ b/cache/lru_cache_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/lru_cache_test.go b/cache/lru_cache_test.go index 9ae277299d94..e8f0b2883c1c 100644 --- a/cache/lru_cache_test.go +++ b/cache/lru_cache_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/lru_sized_cache.go b/cache/lru_sized_cache.go index 6d093e033195..5dc9b5fdec01 100644 --- a/cache/lru_sized_cache.go +++ b/cache/lru_sized_cache.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/lru_sized_cache_test.go b/cache/lru_sized_cache_test.go index 65dbcf8c8ab7..ad1c8b403362 100644 --- a/cache/lru_sized_cache_test.go +++ b/cache/lru_sized_cache_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/metercacher/cache.go b/cache/metercacher/cache.go index 6b6fcd909c81..c2ff666f25e7 100644 --- a/cache/metercacher/cache.go +++ b/cache/metercacher/cache.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metercacher diff --git a/cache/metercacher/cache_test.go b/cache/metercacher/cache_test.go index 7ef1676c0874..3f575acdc1d4 100644 --- a/cache/metercacher/cache_test.go +++ b/cache/metercacher/cache_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metercacher diff --git a/cache/metercacher/metrics.go b/cache/metercacher/metrics.go index a65e31805934..f08082e1be71 100644 --- a/cache/metercacher/metrics.go +++ b/cache/metercacher/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metercacher diff --git a/cache/test_cacher.go b/cache/test_cacher.go index 1b029bcb4b21..2e85502e4a55 100644 --- a/cache/test_cacher.go +++ b/cache/test_cacher.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/unique_cache.go b/cache/unique_cache.go index 24052d79355e..b958b1f3a870 100644 --- a/cache/unique_cache.go +++ b/cache/unique_cache.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/cache/unique_cache_test.go b/cache/unique_cache_test.go index 3f0d40f8dc0d..199bdc87c081 100644 --- a/cache/unique_cache_test.go +++ b/cache/unique_cache_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cache diff --git a/chains/atomic/codec.go b/chains/atomic/codec.go index 49bfd4bf9323..6a947fb27841 100644 --- a/chains/atomic/codec.go +++ b/chains/atomic/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/atomic/gsharedmemory/filtered_batch.go b/chains/atomic/gsharedmemory/filtered_batch.go index df63e8df2d16..a6ba81251f57 100644 --- a/chains/atomic/gsharedmemory/filtered_batch.go +++ b/chains/atomic/gsharedmemory/filtered_batch.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gsharedmemory diff --git a/chains/atomic/gsharedmemory/shared_memory_client.go b/chains/atomic/gsharedmemory/shared_memory_client.go index 649503a0313c..096a8117e7a1 100644 --- a/chains/atomic/gsharedmemory/shared_memory_client.go +++ b/chains/atomic/gsharedmemory/shared_memory_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gsharedmemory diff --git a/chains/atomic/gsharedmemory/shared_memory_server.go b/chains/atomic/gsharedmemory/shared_memory_server.go index 3e2d0d38940e..0aaa71c01f8e 100644 --- a/chains/atomic/gsharedmemory/shared_memory_server.go +++ b/chains/atomic/gsharedmemory/shared_memory_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gsharedmemory diff --git a/chains/atomic/gsharedmemory/shared_memory_test.go b/chains/atomic/gsharedmemory/shared_memory_test.go index 0ce546c94f77..02dfb7324a78 100644 --- a/chains/atomic/gsharedmemory/shared_memory_test.go +++ b/chains/atomic/gsharedmemory/shared_memory_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gsharedmemory diff --git a/chains/atomic/memory.go b/chains/atomic/memory.go index 77c1bb78cec6..76f5b6451d97 100644 --- a/chains/atomic/memory.go +++ b/chains/atomic/memory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/atomic/memory_test.go b/chains/atomic/memory_test.go index 5acdb5233af4..7ca02e6d7275 100644 --- a/chains/atomic/memory_test.go +++ b/chains/atomic/memory_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/atomic/prefixes.go b/chains/atomic/prefixes.go index 08927384317e..adc21c36e2b0 100644 --- a/chains/atomic/prefixes.go +++ b/chains/atomic/prefixes.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/atomic/shared_memory.go b/chains/atomic/shared_memory.go index 7b2f8a562c82..d90c5685fa35 100644 --- a/chains/atomic/shared_memory.go +++ b/chains/atomic/shared_memory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/atomic/shared_memory_test.go b/chains/atomic/shared_memory_test.go index bb3266d80602..1597d662131a 100644 --- a/chains/atomic/shared_memory_test.go +++ b/chains/atomic/shared_memory_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/atomic/state.go b/chains/atomic/state.go index 7751d452b510..a9e9bbd05cd8 100644 --- a/chains/atomic/state.go +++ b/chains/atomic/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/atomic/test_shared_memory.go b/chains/atomic/test_shared_memory.go index d89940c31c2f..82b1cbeff3a5 100644 --- a/chains/atomic/test_shared_memory.go +++ b/chains/atomic/test_shared_memory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/atomic/writer.go b/chains/atomic/writer.go index d117218fe87d..6bcdd86b00b4 100644 --- a/chains/atomic/writer.go +++ b/chains/atomic/writer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package atomic diff --git a/chains/linearizable_vm.go b/chains/linearizable_vm.go index f4fc93f7a696..97fe9eb4d1f4 100644 --- a/chains/linearizable_vm.go +++ b/chains/linearizable_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chains diff --git a/chains/manager.go b/chains/manager.go index 74263c85317e..97f80e1a79c5 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chains diff --git a/chains/registrant.go b/chains/registrant.go index 3a2137048c1b..cd3aa6e9c0bf 100644 --- a/chains/registrant.go +++ b/chains/registrant.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chains diff --git a/chains/test_manager.go b/chains/test_manager.go index e4dabea426f9..d142035b422c 100644 --- a/chains/test_manager.go +++ b/chains/test_manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chains diff --git a/codec/codec.go b/codec/codec.go index 413b6d174be2..7aacb9085848 100644 --- a/codec/codec.go +++ b/codec/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package codec diff --git a/codec/general_codec.go b/codec/general_codec.go index ac32b84e6a87..3688065a021f 100644 --- a/codec/general_codec.go +++ b/codec/general_codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package codec diff --git a/codec/hierarchycodec/codec.go b/codec/hierarchycodec/codec.go index 1b82380bc576..63bd9efa0443 100644 --- a/codec/hierarchycodec/codec.go +++ b/codec/hierarchycodec/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package hierarchycodec diff --git a/codec/hierarchycodec/codec_test.go b/codec/hierarchycodec/codec_test.go index c4c71d76571c..72f3e30982db 100644 --- a/codec/hierarchycodec/codec_test.go +++ b/codec/hierarchycodec/codec_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package hierarchycodec diff --git a/codec/linearcodec/codec.go b/codec/linearcodec/codec.go index 07097aee79eb..0bb0dbf27ed1 100644 --- a/codec/linearcodec/codec.go +++ b/codec/linearcodec/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package linearcodec diff --git a/codec/linearcodec/codec_test.go b/codec/linearcodec/codec_test.go index db8a4e720dd6..1e9b14852a72 100644 --- a/codec/linearcodec/codec_test.go +++ b/codec/linearcodec/codec_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package linearcodec diff --git a/codec/manager.go b/codec/manager.go index 3a5e9eb174fc..6fb48aaad9f8 100644 --- a/codec/manager.go +++ b/codec/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package codec diff --git a/codec/reflectcodec/struct_fielder.go b/codec/reflectcodec/struct_fielder.go index a16212a62103..efac391e8362 100644 --- a/codec/reflectcodec/struct_fielder.go +++ b/codec/reflectcodec/struct_fielder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package reflectcodec diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index ad2e11378163..30a8d9dcc268 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package reflectcodec diff --git a/codec/registry.go b/codec/registry.go index f0f1c2ff8157..de87e1a9b2aa 100644 --- a/codec/registry.go +++ b/codec/registry.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package codec diff --git a/codec/test_codec.go b/codec/test_codec.go index 3c933816a253..931f9bd2e89d 100644 --- a/codec/test_codec.go +++ b/codec/test_codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package codec diff --git a/config/config.go b/config/config.go index 4cae079f3572..0c53f46837a4 100644 --- a/config/config.go +++ b/config/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/config/config_test.go b/config/config_test.go index 037b8ac450cc..4c64e448ac13 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/config/flags.go b/config/flags.go index 333ea302be07..acf965aea3a2 100644 --- a/config/flags.go +++ b/config/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/config/keys.go b/config/keys.go index 078e08465721..45ccdf0a9d83 100644 --- a/config/keys.go +++ b/config/keys.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/config/viper.go b/config/viper.go index 1e236ea32001..59ecf1941687 100644 --- a/config/viper.go +++ b/config/viper.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/database/batch.go b/database/batch.go index b097dc60eea7..8699a90c2960 100644 --- a/database/batch.go +++ b/database/batch.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. // For ease of implementation, our database's interface matches Ethereum's diff --git a/database/benchmark_database.go b/database/benchmark_database.go index 949c071f84f5..b27eec902caa 100644 --- a/database/benchmark_database.go +++ b/database/benchmark_database.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package database diff --git a/database/common.go b/database/common.go index a27b0d27d4d0..651b8fe5719c 100644 --- a/database/common.go +++ b/database/common.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package database diff --git a/database/corruptabledb/db.go b/database/corruptabledb/db.go index cb46953f6858..d5bd6a711353 100644 --- a/database/corruptabledb/db.go +++ b/database/corruptabledb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package corruptabledb diff --git a/database/corruptabledb/db_test.go b/database/corruptabledb/db_test.go index b58c65b4b162..566a6b084e19 100644 --- a/database/corruptabledb/db_test.go +++ b/database/corruptabledb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package corruptabledb diff --git a/database/database.go b/database/database.go index d0c274131d75..938c7f631b93 100644 --- a/database/database.go +++ b/database/database.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. // For ease of implementation, our database's interface matches Ethereum's diff --git a/database/encdb/codec.go b/database/encdb/codec.go index ab9977945f6d..b786bec66916 100644 --- a/database/encdb/codec.go +++ b/database/encdb/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package encdb diff --git a/database/encdb/db.go b/database/encdb/db.go index 27565c87f99b..1b225b38f3cd 100644 --- a/database/encdb/db.go +++ b/database/encdb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package encdb diff --git a/database/encdb/db_test.go b/database/encdb/db_test.go index f49dd7ebb28d..871460a90a41 100644 --- a/database/encdb/db_test.go +++ b/database/encdb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package encdb diff --git a/database/errors.go b/database/errors.go index ee46521b6499..24f93aa8da27 100644 --- a/database/errors.go +++ b/database/errors.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package database diff --git a/database/helpers.go b/database/helpers.go index d4261920dcdf..7e66c58fa770 100644 --- a/database/helpers.go +++ b/database/helpers.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package database diff --git a/database/helpers_test.go b/database/helpers_test.go index 79e37ea74b67..1ad3ccc2b20d 100644 --- a/database/helpers_test.go +++ b/database/helpers_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package database diff --git a/database/iterator.go b/database/iterator.go index c83ceac49639..75126006d4ac 100644 --- a/database/iterator.go +++ b/database/iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. // For ease of implementation, our database's interface matches Ethereum's diff --git a/database/leveldb/db.go b/database/leveldb/db.go index ab08db75a1c8..8ae825ef2fb1 100644 --- a/database/leveldb/db.go +++ b/database/leveldb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package leveldb diff --git a/database/leveldb/db_test.go b/database/leveldb/db_test.go index 23733dacaff4..bf70739ce222 100644 --- a/database/leveldb/db_test.go +++ b/database/leveldb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package leveldb diff --git a/database/leveldb/metrics.go b/database/leveldb/metrics.go index 11bca8ddb07e..055579c8e6f4 100644 --- a/database/leveldb/metrics.go +++ b/database/leveldb/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package leveldb diff --git a/database/linkeddb/codec.go b/database/linkeddb/codec.go index b2607dfbb045..24c5398aa8a1 100644 --- a/database/linkeddb/codec.go +++ b/database/linkeddb/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package linkeddb diff --git a/database/linkeddb/linkeddb.go b/database/linkeddb/linkeddb.go index 6120d182fbc2..f40498812cda 100644 --- a/database/linkeddb/linkeddb.go +++ b/database/linkeddb/linkeddb.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package linkeddb diff --git a/database/linkeddb/linkeddb_test.go b/database/linkeddb/linkeddb_test.go index 6f9cba4501de..815cac730b05 100644 --- a/database/linkeddb/linkeddb_test.go +++ b/database/linkeddb/linkeddb_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package linkeddb diff --git a/database/memdb/db.go b/database/memdb/db.go index 92b687afc0a5..914739f9e206 100644 --- a/database/memdb/db.go +++ b/database/memdb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package memdb diff --git a/database/memdb/db_test.go b/database/memdb/db_test.go index 10d8ebe2be25..21c97909c7fb 100644 --- a/database/memdb/db_test.go +++ b/database/memdb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package memdb diff --git a/database/meterdb/db.go b/database/meterdb/db.go index a2640ca2dc00..fd3b3b77d7a8 100644 --- a/database/meterdb/db.go +++ b/database/meterdb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package meterdb diff --git a/database/meterdb/db_test.go b/database/meterdb/db_test.go index a54d25c21542..cd36a6fb34f2 100644 --- a/database/meterdb/db_test.go +++ b/database/meterdb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package meterdb diff --git a/database/meterdb/metrics.go b/database/meterdb/metrics.go index a0a20e9d5f26..40cdf4566413 100644 --- a/database/meterdb/metrics.go +++ b/database/meterdb/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package meterdb diff --git a/database/pebble/batch.go b/database/pebble/batch.go index b6c9d283b64d..a53b962dc7be 100644 --- a/database/pebble/batch.go +++ b/database/pebble/batch.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pebble diff --git a/database/pebble/batch_test.go b/database/pebble/batch_test.go index a84134708956..66f4075558fd 100644 --- a/database/pebble/batch_test.go +++ b/database/pebble/batch_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pebble diff --git a/database/pebble/db.go b/database/pebble/db.go index 7aa718082a35..4838ff4b0ffe 100644 --- a/database/pebble/db.go +++ b/database/pebble/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pebble diff --git a/database/pebble/db_test.go b/database/pebble/db_test.go index 043caa23c813..2ea3c354f3d8 100644 --- a/database/pebble/db_test.go +++ b/database/pebble/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pebble diff --git a/database/pebble/iterator.go b/database/pebble/iterator.go index 115c122e30f4..5fc73f308a13 100644 --- a/database/pebble/iterator.go +++ b/database/pebble/iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pebble diff --git a/database/prefixdb/db.go b/database/prefixdb/db.go index f4ba04e31b06..64a644918241 100644 --- a/database/prefixdb/db.go +++ b/database/prefixdb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package prefixdb diff --git a/database/prefixdb/db_test.go b/database/prefixdb/db_test.go index a0539b8e0105..109d8c4c9aba 100644 --- a/database/prefixdb/db_test.go +++ b/database/prefixdb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package prefixdb diff --git a/database/rpcdb/db_client.go b/database/rpcdb/db_client.go index 3e92a9a8477a..9f91667b41b6 100644 --- a/database/rpcdb/db_client.go +++ b/database/rpcdb/db_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcdb diff --git a/database/rpcdb/db_server.go b/database/rpcdb/db_server.go index e9e135738e89..6bcbd4e0276b 100644 --- a/database/rpcdb/db_server.go +++ b/database/rpcdb/db_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcdb diff --git a/database/rpcdb/db_test.go b/database/rpcdb/db_test.go index baabc9a69fbf..99323f8bd8c1 100644 --- a/database/rpcdb/db_test.go +++ b/database/rpcdb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcdb diff --git a/database/rpcdb/errors.go b/database/rpcdb/errors.go index 8a1fae2f0a1e..2cd759b6d612 100644 --- a/database/rpcdb/errors.go +++ b/database/rpcdb/errors.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcdb diff --git a/database/test_database.go b/database/test_database.go index fc7e644ae5fd..1ce32bb54257 100644 --- a/database/test_database.go +++ b/database/test_database.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package database diff --git a/database/versiondb/db.go b/database/versiondb/db.go index d65dca947502..479e8af814d1 100644 --- a/database/versiondb/db.go +++ b/database/versiondb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package versiondb diff --git a/database/versiondb/db_test.go b/database/versiondb/db_test.go index c2f57caacf61..c3093a9ee843 100644 --- a/database/versiondb/db_test.go +++ b/database/versiondb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package versiondb diff --git a/genesis/aliases.go b/genesis/aliases.go index b12e50d6f885..c6f8b3df2b74 100644 --- a/genesis/aliases.go +++ b/genesis/aliases.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/bootstrappers.go b/genesis/bootstrappers.go index 4aec33f9c3d9..cac90bb50301 100644 --- a/genesis/bootstrappers.go +++ b/genesis/bootstrappers.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/bootstrappers_test.go b/genesis/bootstrappers_test.go index d14eebbb559a..cde226f283dc 100644 --- a/genesis/bootstrappers_test.go +++ b/genesis/bootstrappers_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/config.go b/genesis/config.go index cedaf90127a9..6e8ea15e7432 100644 --- a/genesis/config.go +++ b/genesis/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/config_test.go b/genesis/config_test.go index d83815cebfba..8a9bc96a9c94 100644 --- a/genesis/config_test.go +++ b/genesis/config_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/genesis.go b/genesis/genesis.go index 567f21f061be..217713520fb0 100644 --- a/genesis/genesis.go +++ b/genesis/genesis.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/genesis_fuji.go b/genesis/genesis_fuji.go index a9bcaffcb956..27c43f79fd0b 100644 --- a/genesis/genesis_fuji.go +++ b/genesis/genesis_fuji.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/genesis_local.go b/genesis/genesis_local.go index de650009fd26..5a76aa25cfcf 100644 --- a/genesis/genesis_local.go +++ b/genesis/genesis_local.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/genesis_mainnet.go b/genesis/genesis_mainnet.go index 4e55c891be73..3808174ebbd1 100644 --- a/genesis/genesis_mainnet.go +++ b/genesis/genesis_mainnet.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/genesis_test.go b/genesis/genesis_test.go index b18bc7f521a3..3257d6a0c271 100644 --- a/genesis/genesis_test.go +++ b/genesis/genesis_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/params.go b/genesis/params.go index 496a573c48f8..e2ae45c697e6 100644 --- a/genesis/params.go +++ b/genesis/params.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/genesis/unparsed_config.go b/genesis/unparsed_config.go index 647443bae482..2ace7647c363 100644 --- a/genesis/unparsed_config.go +++ b/genesis/unparsed_config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/ids/aliases.go b/ids/aliases.go index c7958e1c425e..484c6f8aa4b3 100644 --- a/ids/aliases.go +++ b/ids/aliases.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/aliases_test.go b/ids/aliases_test.go index b25177242ff2..6c77d7443703 100644 --- a/ids/aliases_test.go +++ b/ids/aliases_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/bits.go b/ids/bits.go index a884578f420b..bb3586704c4f 100644 --- a/ids/bits.go +++ b/ids/bits.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/bits_test.go b/ids/bits_test.go index 4b5783dded46..feb381902000 100644 --- a/ids/bits_test.go +++ b/ids/bits_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/galiasreader/alias_reader_client.go b/ids/galiasreader/alias_reader_client.go index aa77f9ec870f..319d7508cbd4 100644 --- a/ids/galiasreader/alias_reader_client.go +++ b/ids/galiasreader/alias_reader_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package galiasreader diff --git a/ids/galiasreader/alias_reader_server.go b/ids/galiasreader/alias_reader_server.go index 48f31bf74e3a..eeb9083ca1e4 100644 --- a/ids/galiasreader/alias_reader_server.go +++ b/ids/galiasreader/alias_reader_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package galiasreader diff --git a/ids/galiasreader/alias_reader_test.go b/ids/galiasreader/alias_reader_test.go index f268d10fc268..899c13a24ed2 100644 --- a/ids/galiasreader/alias_reader_test.go +++ b/ids/galiasreader/alias_reader_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package galiasreader diff --git a/ids/id.go b/ids/id.go index dc22ff0200ae..6cda4b6ec854 100644 --- a/ids/id.go +++ b/ids/id.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/id_test.go b/ids/id_test.go index af12bc78f714..930a323e614c 100644 --- a/ids/id_test.go +++ b/ids/id_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/node_id.go b/ids/node_id.go index f2ce6d9acfb7..7e9e94a12cdd 100644 --- a/ids/node_id.go +++ b/ids/node_id.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/node_id_test.go b/ids/node_id_test.go index 4aac5875b104..2c94450f5b66 100644 --- a/ids/node_id_test.go +++ b/ids/node_id_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/request_id.go b/ids/request_id.go index 779f819d9d4e..e1d9459866f7 100644 --- a/ids/request_id.go +++ b/ids/request_id.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/short.go b/ids/short.go index 8de2a43828b8..7c01dca4785a 100644 --- a/ids/short.go +++ b/ids/short.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/test_aliases.go b/ids/test_aliases.go index 7e2b4fb9790e..ce9991f5f737 100644 --- a/ids/test_aliases.go +++ b/ids/test_aliases.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/ids/test_generator.go b/ids/test_generator.go index 29ecfa8d409c..2df95ec0499f 100644 --- a/ids/test_generator.go +++ b/ids/test_generator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ids diff --git a/indexer/client.go b/indexer/client.go index 785018e3072c..821059a1d6c0 100644 --- a/indexer/client.go +++ b/indexer/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/indexer/client_test.go b/indexer/client_test.go index 004c8eeb283d..95124a2129ab 100644 --- a/indexer/client_test.go +++ b/indexer/client_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/indexer/codec.go b/indexer/codec.go index f41cb8fa80f1..6addc9e3ca19 100644 --- a/indexer/codec.go +++ b/indexer/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/indexer/container.go b/indexer/container.go index c640fdd96d19..2bbb68e5db6f 100644 --- a/indexer/container.go +++ b/indexer/container.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/indexer/examples/p-chain/main.go b/indexer/examples/p-chain/main.go index fb9ec2d6f2f6..9f8966d21546 100644 --- a/indexer/examples/p-chain/main.go +++ b/indexer/examples/p-chain/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/indexer/examples/x-chain-blocks/main.go b/indexer/examples/x-chain-blocks/main.go index a995f9612bbd..92c5f7ad34e7 100644 --- a/indexer/examples/x-chain-blocks/main.go +++ b/indexer/examples/x-chain-blocks/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/indexer/index.go b/indexer/index.go index d182c6938d8e..86d75b37d4cb 100644 --- a/indexer/index.go +++ b/indexer/index.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/indexer/index_test.go b/indexer/index_test.go index 0007c8ae4e12..127aa64bda69 100644 --- a/indexer/index_test.go +++ b/indexer/index_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/indexer/indexer.go b/indexer/indexer.go index 99f475892562..6b16f8245ebc 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/indexer/indexer_test.go b/indexer/indexer_test.go index 16c4aa7bc381..348aa87d13a9 100644 --- a/indexer/indexer_test.go +++ b/indexer/indexer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/indexer/service.go b/indexer/service.go index 5fae26bd3ee2..83f9912f2fea 100644 --- a/indexer/service.go +++ b/indexer/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/ipcs/chainipc.go b/ipcs/chainipc.go index 56d4393360ff..bb78cc175327 100644 --- a/ipcs/chainipc.go +++ b/ipcs/chainipc.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ipcs diff --git a/ipcs/eventsocket.go b/ipcs/eventsocket.go index 109b42bb34af..0dbbe1c92e5a 100644 --- a/ipcs/eventsocket.go +++ b/ipcs/eventsocket.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ipcs diff --git a/ipcs/socket/socket.go b/ipcs/socket/socket.go index d3ca391dd019..77f2d6fdb8e2 100644 --- a/ipcs/socket/socket.go +++ b/ipcs/socket/socket.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package socket diff --git a/ipcs/socket/socket_test.go b/ipcs/socket/socket_test.go index a56329b28c3e..a2c1ec638754 100644 --- a/ipcs/socket/socket_test.go +++ b/ipcs/socket/socket_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package socket diff --git a/ipcs/socket/socket_unix.go b/ipcs/socket/socket_unix.go index 98f4ad492330..14d5aabde4e3 100644 --- a/ipcs/socket/socket_unix.go +++ b/ipcs/socket/socket_unix.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build !windows && !plan9 && !js diff --git a/ipcs/socket/socket_windows.go b/ipcs/socket/socket_windows.go index eb54ccf07066..99590cb674b4 100644 --- a/ipcs/socket/socket_windows.go +++ b/ipcs/socket/socket_windows.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build windows diff --git a/main/main.go b/main/main.go index 2b07898f9072..549ef65f48cf 100644 --- a/main/main.go +++ b/main/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/message/creator.go b/message/creator.go index f1a6def2b21e..a5711375c331 100644 --- a/message/creator.go +++ b/message/creator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/fields.go b/message/fields.go index 87bffe518abd..08e744fab911 100644 --- a/message/fields.go +++ b/message/fields.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/inbound_msg_builder.go b/message/inbound_msg_builder.go index 8541645840aa..b32dbc5d480d 100644 --- a/message/inbound_msg_builder.go +++ b/message/inbound_msg_builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/inbound_msg_builder_test.go b/message/inbound_msg_builder_test.go index 08234b58fd88..b14b3ddedab7 100644 --- a/message/inbound_msg_builder_test.go +++ b/message/inbound_msg_builder_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/internal_msg_builder.go b/message/internal_msg_builder.go index 9b1780b42571..38a95cb78a8c 100644 --- a/message/internal_msg_builder.go +++ b/message/internal_msg_builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //nolint:stylecheck // proto generates interfaces that fail linting diff --git a/message/messages.go b/message/messages.go index 8d9671e63123..fbd3519de30d 100644 --- a/message/messages.go +++ b/message/messages.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/messages_benchmark_test.go b/message/messages_benchmark_test.go index 9864e6a231f8..48ae10acf5dd 100644 --- a/message/messages_benchmark_test.go +++ b/message/messages_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/messages_test.go b/message/messages_test.go index 3ae3cf015119..e164e8993007 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/ops.go b/message/ops.go index 2ecae08db396..2f496713e419 100644 --- a/message/ops.go +++ b/message/ops.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index a6149fd35784..f50f5cf6ae5d 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/message/outbound_msg_builder_test.go b/message/outbound_msg_builder_test.go index 50f273bf4b13..1b6895f3f52c 100644 --- a/message/outbound_msg_builder_test.go +++ b/message/outbound_msg_builder_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/nat/nat.go b/nat/nat.go index 33749ca0e572..20af4fe27ea9 100644 --- a/nat/nat.go +++ b/nat/nat.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nat diff --git a/nat/no_router.go b/nat/no_router.go index 5c894c8c673c..19c68dac5538 100644 --- a/nat/no_router.go +++ b/nat/no_router.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nat diff --git a/nat/pmp.go b/nat/pmp.go index ad2032ec1493..ecee9793f934 100644 --- a/nat/pmp.go +++ b/nat/pmp.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nat diff --git a/nat/upnp.go b/nat/upnp.go index 2571048e367e..aa26d6d82fc6 100644 --- a/nat/upnp.go +++ b/nat/upnp.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nat diff --git a/network/certs_test.go b/network/certs_test.go index 10b92586ed5c..483d6ea4eeee 100644 --- a/network/certs_test.go +++ b/network/certs_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/config.go b/network/config.go index e1a32e4ee1a5..eda7257fa62c 100644 --- a/network/config.go +++ b/network/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/conn_test.go b/network/conn_test.go index 4394cd885e3c..6a44c6153992 100644 --- a/network/conn_test.go +++ b/network/conn_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/dialer/dialer.go b/network/dialer/dialer.go index 22e8c3ba1bfe..109b63cc2002 100644 --- a/network/dialer/dialer.go +++ b/network/dialer/dialer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dialer diff --git a/network/dialer/dialer_test.go b/network/dialer/dialer_test.go index 95011996bcdf..a824b8b03e08 100644 --- a/network/dialer/dialer_test.go +++ b/network/dialer/dialer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dialer diff --git a/network/dialer_test.go b/network/dialer_test.go index b6f2eef15def..ecc506ba2927 100644 --- a/network/dialer_test.go +++ b/network/dialer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/example_test.go b/network/example_test.go index 8f20900a7e8d..bfac03fba44f 100644 --- a/network/example_test.go +++ b/network/example_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/handler_test.go b/network/handler_test.go index 64350b3b289a..08c99a0d4e70 100644 --- a/network/handler_test.go +++ b/network/handler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/listener_test.go b/network/listener_test.go index 1b15b0062536..5d6073c6b383 100644 --- a/network/listener_test.go +++ b/network/listener_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/metrics.go b/network/metrics.go index 3e566a31c99f..e2a3a363b403 100644 --- a/network/metrics.go +++ b/network/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/network.go b/network/network.go index 8359bd37841b..2dc6b2bbfdcb 100644 --- a/network/network.go +++ b/network/network.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/network_test.go b/network/network_test.go index 65d4809101fb..916b527da82b 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/p2p/client.go b/network/p2p/client.go index 982b7c50f1f0..6107f8abb7d9 100644 --- a/network/p2p/client.go +++ b/network/p2p/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/gossip/bloom.go b/network/p2p/gossip/bloom.go index bb588b23bb4f..12fca6bfcad4 100644 --- a/network/p2p/gossip/bloom.go +++ b/network/p2p/gossip/bloom.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gossip diff --git a/network/p2p/gossip/bloom_test.go b/network/p2p/gossip/bloom_test.go index 1a05a7eb9bd5..9eb06a6a2458 100644 --- a/network/p2p/gossip/bloom_test.go +++ b/network/p2p/gossip/bloom_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gossip diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index 60eb5560babf..dfeb50d201a1 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gossip diff --git a/network/p2p/gossip/gossip_test.go b/network/p2p/gossip/gossip_test.go index 25bfac3a4303..94387ebd9420 100644 --- a/network/p2p/gossip/gossip_test.go +++ b/network/p2p/gossip/gossip_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gossip diff --git a/network/p2p/gossip/gossipable.go b/network/p2p/gossip/gossipable.go index bf6ff1644634..a204c465720d 100644 --- a/network/p2p/gossip/gossipable.go +++ b/network/p2p/gossip/gossipable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gossip diff --git a/network/p2p/gossip/handler.go b/network/p2p/gossip/handler.go index 85d2d1413544..380b67ad2dc3 100644 --- a/network/p2p/gossip/handler.go +++ b/network/p2p/gossip/handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gossip diff --git a/network/p2p/gossip/test_gossip.go b/network/p2p/gossip/test_gossip.go index 4603333ba28f..f903693c8054 100644 --- a/network/p2p/gossip/test_gossip.go +++ b/network/p2p/gossip/test_gossip.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gossip diff --git a/network/p2p/handler.go b/network/p2p/handler.go index 6829f0b94213..3ff4de29037e 100644 --- a/network/p2p/handler.go +++ b/network/p2p/handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/handler_test.go b/network/p2p/handler_test.go index 3ed82cb06cbd..0633b70f00a8 100644 --- a/network/p2p/handler_test.go +++ b/network/p2p/handler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/network.go b/network/p2p/network.go index 76b5c13e76ad..604d06db617f 100644 --- a/network/p2p/network.go +++ b/network/p2p/network.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/network_test.go b/network/p2p/network_test.go index f86399809885..6aea3bc554d0 100644 --- a/network/p2p/network_test.go +++ b/network/p2p/network_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/node_sampler.go b/network/p2p/node_sampler.go index 057a175027a4..5bb3815e3b90 100644 --- a/network/p2p/node_sampler.go +++ b/network/p2p/node_sampler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/peer_tracker.go b/network/p2p/peer_tracker.go index 338d890bed22..c0eda693859b 100644 --- a/network/p2p/peer_tracker.go +++ b/network/p2p/peer_tracker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/peer_tracker_test.go b/network/p2p/peer_tracker_test.go index d7c38b828e9d..bf771d177841 100644 --- a/network/p2p/peer_tracker_test.go +++ b/network/p2p/peer_tracker_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/router.go b/network/p2p/router.go index 5c52b3d1aaa2..82fdbf24fbc3 100644 --- a/network/p2p/router.go +++ b/network/p2p/router.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/throttler.go b/network/p2p/throttler.go index de173a655266..c8f34a7ee90f 100644 --- a/network/p2p/throttler.go +++ b/network/p2p/throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/throttler_handler.go b/network/p2p/throttler_handler.go index aee5bee70795..8fa3df93faee 100644 --- a/network/p2p/throttler_handler.go +++ b/network/p2p/throttler_handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/throttler_handler_test.go b/network/p2p/throttler_handler_test.go index 8c18a10dc308..1f5a07069d8e 100644 --- a/network/p2p/throttler_handler_test.go +++ b/network/p2p/throttler_handler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/throttler_test.go b/network/p2p/throttler_test.go index c7b0153e671d..3c3c56360dc1 100644 --- a/network/p2p/throttler_test.go +++ b/network/p2p/throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/validators.go b/network/p2p/validators.go index 06a1e913bd0f..3ece6559af42 100644 --- a/network/p2p/validators.go +++ b/network/p2p/validators.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/p2p/validators_test.go b/network/p2p/validators_test.go index 9e90242e201d..a5d4e7724cdd 100644 --- a/network/p2p/validators_test.go +++ b/network/p2p/validators_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p2p diff --git a/network/peer/config.go b/network/peer/config.go index 403ddfeb5334..0a01cf87fb92 100644 --- a/network/peer/config.go +++ b/network/peer/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/example_test.go b/network/peer/example_test.go index 75eaecee53d5..d6c8ba20c913 100644 --- a/network/peer/example_test.go +++ b/network/peer/example_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/gossip_tracker.go b/network/peer/gossip_tracker.go index 5676b0734fc8..105d3e5ce64d 100644 --- a/network/peer/gossip_tracker.go +++ b/network/peer/gossip_tracker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/gossip_tracker_callback.go b/network/peer/gossip_tracker_callback.go index 28514ac163a6..5863b236e069 100644 --- a/network/peer/gossip_tracker_callback.go +++ b/network/peer/gossip_tracker_callback.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/gossip_tracker_metrics.go b/network/peer/gossip_tracker_metrics.go index e80f31765b9c..080f37fde5c1 100644 --- a/network/peer/gossip_tracker_metrics.go +++ b/network/peer/gossip_tracker_metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/gossip_tracker_test.go b/network/peer/gossip_tracker_test.go index 1bd420c4f433..c9ab1ef8e026 100644 --- a/network/peer/gossip_tracker_test.go +++ b/network/peer/gossip_tracker_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/info.go b/network/peer/info.go index 468d00be9fef..00ccaec7953b 100644 --- a/network/peer/info.go +++ b/network/peer/info.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/ip.go b/network/peer/ip.go index 8fb9d744f974..0112374b9b80 100644 --- a/network/peer/ip.go +++ b/network/peer/ip.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/ip_signer.go b/network/peer/ip_signer.go index b524d3463619..cfe85f387819 100644 --- a/network/peer/ip_signer.go +++ b/network/peer/ip_signer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/ip_signer_test.go b/network/peer/ip_signer_test.go index 382501a825bc..7e5314f5f58a 100644 --- a/network/peer/ip_signer_test.go +++ b/network/peer/ip_signer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/message_queue.go b/network/peer/message_queue.go index b9d38996723b..f2ccef6dc915 100644 --- a/network/peer/message_queue.go +++ b/network/peer/message_queue.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/message_queue_test.go b/network/peer/message_queue_test.go index 2e1e46f5e2f5..496f19425f20 100644 --- a/network/peer/message_queue_test.go +++ b/network/peer/message_queue_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/metrics.go b/network/peer/metrics.go index 602726131134..cad8797addfb 100644 --- a/network/peer/metrics.go +++ b/network/peer/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/msg_length.go b/network/peer/msg_length.go index 27a48dea3060..625034913d9f 100644 --- a/network/peer/msg_length.go +++ b/network/peer/msg_length.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/msg_length_test.go b/network/peer/msg_length_test.go index 52767888c8c2..97866a7d95cf 100644 --- a/network/peer/msg_length_test.go +++ b/network/peer/msg_length_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/network.go b/network/peer/network.go index fc136f0bcb9c..8c18ef0ac899 100644 --- a/network/peer/network.go +++ b/network/peer/network.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/peer.go b/network/peer/peer.go index 37824f16990a..5b6f38c6f19f 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index 95c756b4d454..77dd47e73f2c 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/set.go b/network/peer/set.go index bc3fbe60743d..cbb9675ec305 100644 --- a/network/peer/set.go +++ b/network/peer/set.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/set_test.go b/network/peer/set_test.go index fb67d25ef05f..fbdbc3e84643 100644 --- a/network/peer/set_test.go +++ b/network/peer/set_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/test_network.go b/network/peer/test_network.go index 9bac6260bece..1ba047e1d423 100644 --- a/network/peer/test_network.go +++ b/network/peer/test_network.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/test_peer.go b/network/peer/test_peer.go index 62717e27dca1..74627930c952 100644 --- a/network/peer/test_peer.go +++ b/network/peer/test_peer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/tls_config.go b/network/peer/tls_config.go index 733812db5f7e..7de848ed062a 100644 --- a/network/peer/tls_config.go +++ b/network/peer/tls_config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/upgrader.go b/network/peer/upgrader.go index b601ee370947..dd973af1b825 100644 --- a/network/peer/upgrader.go +++ b/network/peer/upgrader.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/peer/validator_id.go b/network/peer/validator_id.go index 5471fda20118..078929d0f90a 100644 --- a/network/peer/validator_id.go +++ b/network/peer/validator_id.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package peer diff --git a/network/test_network.go b/network/test_network.go index 1d3bcd933844..e1c76e92774a 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/throttling/bandwidth_throttler.go b/network/throttling/bandwidth_throttler.go index 5adfcb0062a2..d8244eb37974 100644 --- a/network/throttling/bandwidth_throttler.go +++ b/network/throttling/bandwidth_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/bandwidth_throttler_test.go b/network/throttling/bandwidth_throttler_test.go index 5d51555baa9f..11a687f3a91b 100644 --- a/network/throttling/bandwidth_throttler_test.go +++ b/network/throttling/bandwidth_throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/common.go b/network/throttling/common.go index 9350fb4f684c..cedd5d732dbb 100644 --- a/network/throttling/common.go +++ b/network/throttling/common.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/dial_throttler.go b/network/throttling/dial_throttler.go index 491c312b95ef..07c04aefb812 100644 --- a/network/throttling/dial_throttler.go +++ b/network/throttling/dial_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/dial_throttler_test.go b/network/throttling/dial_throttler_test.go index db1776e8e24b..1dd57c2e78ad 100644 --- a/network/throttling/dial_throttler_test.go +++ b/network/throttling/dial_throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_conn_throttler.go b/network/throttling/inbound_conn_throttler.go index 7f2206396ca8..5e1528074135 100644 --- a/network/throttling/inbound_conn_throttler.go +++ b/network/throttling/inbound_conn_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_conn_throttler_test.go b/network/throttling/inbound_conn_throttler_test.go index 0b5d1ccd7fb8..9e2fde15e825 100644 --- a/network/throttling/inbound_conn_throttler_test.go +++ b/network/throttling/inbound_conn_throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_conn_upgrade_throttler.go b/network/throttling/inbound_conn_upgrade_throttler.go index 9d058e29ba12..4df5ee39b776 100644 --- a/network/throttling/inbound_conn_upgrade_throttler.go +++ b/network/throttling/inbound_conn_upgrade_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_conn_upgrade_throttler_test.go b/network/throttling/inbound_conn_upgrade_throttler_test.go index d0e1fe93c84a..2f6cd926451e 100644 --- a/network/throttling/inbound_conn_upgrade_throttler_test.go +++ b/network/throttling/inbound_conn_upgrade_throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_msg_buffer_throttler.go b/network/throttling/inbound_msg_buffer_throttler.go index d06177839ea2..65306eea7d51 100644 --- a/network/throttling/inbound_msg_buffer_throttler.go +++ b/network/throttling/inbound_msg_buffer_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_msg_buffer_throttler_test.go b/network/throttling/inbound_msg_buffer_throttler_test.go index 76f399b6e94e..11d655c1c4fc 100644 --- a/network/throttling/inbound_msg_buffer_throttler_test.go +++ b/network/throttling/inbound_msg_buffer_throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_msg_byte_throttler.go b/network/throttling/inbound_msg_byte_throttler.go index 659d9f398309..459df7a11b5d 100644 --- a/network/throttling/inbound_msg_byte_throttler.go +++ b/network/throttling/inbound_msg_byte_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_msg_byte_throttler_test.go b/network/throttling/inbound_msg_byte_throttler_test.go index e71f0abba238..68a12965ff1e 100644 --- a/network/throttling/inbound_msg_byte_throttler_test.go +++ b/network/throttling/inbound_msg_byte_throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_msg_throttler.go b/network/throttling/inbound_msg_throttler.go index 3d79f640ae1a..86e20085466c 100644 --- a/network/throttling/inbound_msg_throttler.go +++ b/network/throttling/inbound_msg_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_resource_throttler.go b/network/throttling/inbound_resource_throttler.go index 42873fe42d6a..eb0e939b8d9e 100644 --- a/network/throttling/inbound_resource_throttler.go +++ b/network/throttling/inbound_resource_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/inbound_resource_throttler_test.go b/network/throttling/inbound_resource_throttler_test.go index eebbaf7dc851..bfc5a726c14b 100644 --- a/network/throttling/inbound_resource_throttler_test.go +++ b/network/throttling/inbound_resource_throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/no_inbound_msg_throttler.go b/network/throttling/no_inbound_msg_throttler.go index de6e03f81502..6f7af32fb135 100644 --- a/network/throttling/no_inbound_msg_throttler.go +++ b/network/throttling/no_inbound_msg_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/outbound_msg_throttler.go b/network/throttling/outbound_msg_throttler.go index 6f5ad24561f3..e1656c04ffe1 100644 --- a/network/throttling/outbound_msg_throttler.go +++ b/network/throttling/outbound_msg_throttler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/outbound_msg_throttler_test.go b/network/throttling/outbound_msg_throttler_test.go index 09d8b6f272ef..1930d935171b 100644 --- a/network/throttling/outbound_msg_throttler_test.go +++ b/network/throttling/outbound_msg_throttler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/throttling/release_func.go b/network/throttling/release_func.go index 0abe2bf4270d..e2cbcf1b1b20 100644 --- a/network/throttling/release_func.go +++ b/network/throttling/release_func.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package throttling diff --git a/network/tracked_ip.go b/network/tracked_ip.go index ca673f76b91d..6a95bbee5a47 100644 --- a/network/tracked_ip.go +++ b/network/tracked_ip.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/network/tracked_ip_test.go b/network/tracked_ip_test.go index bbf6267d86db..956f02cc19b4 100644 --- a/network/tracked_ip_test.go +++ b/network/tracked_ip_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/node/beacon_manager.go b/node/beacon_manager.go index 8e6ddeb23cc1..9b6806fdf037 100644 --- a/node/beacon_manager.go +++ b/node/beacon_manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package node diff --git a/node/beacon_manager_test.go b/node/beacon_manager_test.go index 2e282d06015c..82b47efdacd6 100644 --- a/node/beacon_manager_test.go +++ b/node/beacon_manager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package node diff --git a/node/config.go b/node/config.go index 5839da75960a..768f23cab3e9 100644 --- a/node/config.go +++ b/node/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package node diff --git a/node/insecure_validator_manager.go b/node/insecure_validator_manager.go index d2cdab94cc89..0e23b8b90cc3 100644 --- a/node/insecure_validator_manager.go +++ b/node/insecure_validator_manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package node diff --git a/node/node.go b/node/node.go index 22be7d5436eb..c5d75c2e1d59 100644 --- a/node/node.go +++ b/node/node.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package node diff --git a/node/overridden_manager.go b/node/overridden_manager.go index 91d8c198a4c3..4dd49b65eab6 100644 --- a/node/overridden_manager.go +++ b/node/overridden_manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package node diff --git a/node/overridden_manager_test.go b/node/overridden_manager_test.go index 80dfabe10552..8af93ff68071 100644 --- a/node/overridden_manager_test.go +++ b/node/overridden_manager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package node diff --git a/pubsub/connection.go b/pubsub/connection.go index 2dae38acd1e6..f5f471c64c08 100644 --- a/pubsub/connection.go +++ b/pubsub/connection.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pubsub diff --git a/pubsub/connections.go b/pubsub/connections.go index 417e1aa8f365..25d35ac8cd82 100644 --- a/pubsub/connections.go +++ b/pubsub/connections.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pubsub diff --git a/pubsub/filter_param.go b/pubsub/filter_param.go index e7e2453c3e95..1a1306c8d10d 100644 --- a/pubsub/filter_param.go +++ b/pubsub/filter_param.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pubsub diff --git a/pubsub/filter_test.go b/pubsub/filter_test.go index edc88794fa34..d32c3e87bdfd 100644 --- a/pubsub/filter_test.go +++ b/pubsub/filter_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pubsub diff --git a/pubsub/filterer.go b/pubsub/filterer.go index 389448ea7af2..3ec2910a9c4c 100644 --- a/pubsub/filterer.go +++ b/pubsub/filterer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pubsub diff --git a/pubsub/messages.go b/pubsub/messages.go index 525ae035f15a..ec41af813cdb 100644 --- a/pubsub/messages.go +++ b/pubsub/messages.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pubsub diff --git a/pubsub/server.go b/pubsub/server.go index b7e4eaf74377..6cc8b649296c 100644 --- a/pubsub/server.go +++ b/pubsub/server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package pubsub diff --git a/snow/acceptor.go b/snow/acceptor.go index 9c07a2aa0235..83575e5cf3e2 100644 --- a/snow/acceptor.go +++ b/snow/acceptor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snow diff --git a/snow/choices/decidable.go b/snow/choices/decidable.go index b49cd75d3a1d..4c9ba886b105 100644 --- a/snow/choices/decidable.go +++ b/snow/choices/decidable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package choices diff --git a/snow/choices/status.go b/snow/choices/status.go index 9a8d410cf005..ff530e9b7547 100644 --- a/snow/choices/status.go +++ b/snow/choices/status.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package choices diff --git a/snow/choices/status_test.go b/snow/choices/status_test.go index 59d2c4071fc5..5134ca2b752f 100644 --- a/snow/choices/status_test.go +++ b/snow/choices/status_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package choices diff --git a/snow/choices/test_decidable.go b/snow/choices/test_decidable.go index 055a54050d32..39e8ed67b7c1 100644 --- a/snow/choices/test_decidable.go +++ b/snow/choices/test_decidable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package choices diff --git a/snow/consensus/avalanche/test_vertex.go b/snow/consensus/avalanche/test_vertex.go index 60bfdc10c1b0..a3bc2fb06723 100644 --- a/snow/consensus/avalanche/test_vertex.go +++ b/snow/consensus/avalanche/test_vertex.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avalanche diff --git a/snow/consensus/avalanche/vertex.go b/snow/consensus/avalanche/vertex.go index 9f8af73264fe..0356dc1902da 100644 --- a/snow/consensus/avalanche/vertex.go +++ b/snow/consensus/avalanche/vertex.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avalanche diff --git a/snow/consensus/snowball/binary_slush.go b/snow/consensus/snowball/binary_slush.go index b4e1bc2ace08..a440fce0e1ec 100644 --- a/snow/consensus/snowball/binary_slush.go +++ b/snow/consensus/snowball/binary_slush.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/binary_snowball.go b/snow/consensus/snowball/binary_snowball.go index aa1dc37bbe34..f1b213ad98fc 100644 --- a/snow/consensus/snowball/binary_snowball.go +++ b/snow/consensus/snowball/binary_snowball.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/binary_snowball_test.go b/snow/consensus/snowball/binary_snowball_test.go index 42b6b404caa0..2c2a8421e043 100644 --- a/snow/consensus/snowball/binary_snowball_test.go +++ b/snow/consensus/snowball/binary_snowball_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/binary_snowflake.go b/snow/consensus/snowball/binary_snowflake.go index d95ef9709ec6..139bd40361f7 100644 --- a/snow/consensus/snowball/binary_snowflake.go +++ b/snow/consensus/snowball/binary_snowflake.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/binary_snowflake_test.go b/snow/consensus/snowball/binary_snowflake_test.go index 2f14396da959..085b94c5f450 100644 --- a/snow/consensus/snowball/binary_snowflake_test.go +++ b/snow/consensus/snowball/binary_snowflake_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/consensus.go b/snow/consensus/snowball/consensus.go index 3f3c508af053..e28f4cad4d36 100644 --- a/snow/consensus/snowball/consensus.go +++ b/snow/consensus/snowball/consensus.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/consensus_performance_test.go b/snow/consensus/snowball/consensus_performance_test.go index febb7c6877e6..9ebb3362720d 100644 --- a/snow/consensus/snowball/consensus_performance_test.go +++ b/snow/consensus/snowball/consensus_performance_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/consensus_reversibility_test.go b/snow/consensus/snowball/consensus_reversibility_test.go index a3c5d3e98690..d0f3065a9db9 100644 --- a/snow/consensus/snowball/consensus_reversibility_test.go +++ b/snow/consensus/snowball/consensus_reversibility_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/consensus_test.go b/snow/consensus/snowball/consensus_test.go index 484c5c9fbc87..264edaa733d9 100644 --- a/snow/consensus/snowball/consensus_test.go +++ b/snow/consensus/snowball/consensus_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/flat.go b/snow/consensus/snowball/flat.go index 7f633efb8006..97c549816be0 100644 --- a/snow/consensus/snowball/flat.go +++ b/snow/consensus/snowball/flat.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/flat_test.go b/snow/consensus/snowball/flat_test.go index dac78fc0cede..38ca57d83b0e 100644 --- a/snow/consensus/snowball/flat_test.go +++ b/snow/consensus/snowball/flat_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/network_test.go b/snow/consensus/snowball/network_test.go index 747b51087926..56e7d0ca7dbc 100644 --- a/snow/consensus/snowball/network_test.go +++ b/snow/consensus/snowball/network_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/nnary_slush.go b/snow/consensus/snowball/nnary_slush.go index 2987861f7943..dad85252906f 100644 --- a/snow/consensus/snowball/nnary_slush.go +++ b/snow/consensus/snowball/nnary_slush.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/nnary_snowball.go b/snow/consensus/snowball/nnary_snowball.go index 0fe8c25f8617..2a968c0ba91c 100644 --- a/snow/consensus/snowball/nnary_snowball.go +++ b/snow/consensus/snowball/nnary_snowball.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/nnary_snowball_test.go b/snow/consensus/snowball/nnary_snowball_test.go index 10b63ce647cb..18bea5eef65e 100644 --- a/snow/consensus/snowball/nnary_snowball_test.go +++ b/snow/consensus/snowball/nnary_snowball_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/nnary_snowflake.go b/snow/consensus/snowball/nnary_snowflake.go index 503fcd614c7b..de898f155f38 100644 --- a/snow/consensus/snowball/nnary_snowflake.go +++ b/snow/consensus/snowball/nnary_snowflake.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/nnary_snowflake_test.go b/snow/consensus/snowball/nnary_snowflake_test.go index 07601a6065eb..5df8c2966335 100644 --- a/snow/consensus/snowball/nnary_snowflake_test.go +++ b/snow/consensus/snowball/nnary_snowflake_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/parameters.go b/snow/consensus/snowball/parameters.go index 00f6d5bb95c4..640b8702817e 100644 --- a/snow/consensus/snowball/parameters.go +++ b/snow/consensus/snowball/parameters.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/parameters_test.go b/snow/consensus/snowball/parameters_test.go index 26ffab8763c7..525001fd535f 100644 --- a/snow/consensus/snowball/parameters_test.go +++ b/snow/consensus/snowball/parameters_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/tree.go b/snow/consensus/snowball/tree.go index 052e75ec8d35..2278975f8843 100644 --- a/snow/consensus/snowball/tree.go +++ b/snow/consensus/snowball/tree.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/tree_test.go b/snow/consensus/snowball/tree_test.go index 9d96c53bd7d5..99bf25769f98 100644 --- a/snow/consensus/snowball/tree_test.go +++ b/snow/consensus/snowball/tree_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //nolint:goconst diff --git a/snow/consensus/snowball/unary_snowball.go b/snow/consensus/snowball/unary_snowball.go index 6223d6f3a0cc..3e4477b4b82a 100644 --- a/snow/consensus/snowball/unary_snowball.go +++ b/snow/consensus/snowball/unary_snowball.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/unary_snowball_test.go b/snow/consensus/snowball/unary_snowball_test.go index 6fd6cd9b40c7..d94d2b61d63d 100644 --- a/snow/consensus/snowball/unary_snowball_test.go +++ b/snow/consensus/snowball/unary_snowball_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/unary_snowflake.go b/snow/consensus/snowball/unary_snowflake.go index 68def8663724..6bcfebe23fe8 100644 --- a/snow/consensus/snowball/unary_snowflake.go +++ b/snow/consensus/snowball/unary_snowflake.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowball/unary_snowflake_test.go b/snow/consensus/snowball/unary_snowflake_test.go index 162f4a56e200..0791b688065e 100644 --- a/snow/consensus/snowball/unary_snowflake_test.go +++ b/snow/consensus/snowball/unary_snowflake_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowball diff --git a/snow/consensus/snowman/block.go b/snow/consensus/snowman/block.go index b5d79983ef6a..c950ac3c29ee 100644 --- a/snow/consensus/snowman/block.go +++ b/snow/consensus/snowman/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/bootstrapper/majority.go b/snow/consensus/snowman/bootstrapper/majority.go index 1decb837ef40..7fe028288656 100644 --- a/snow/consensus/snowman/bootstrapper/majority.go +++ b/snow/consensus/snowman/bootstrapper/majority.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/majority_test.go b/snow/consensus/snowman/bootstrapper/majority_test.go index d276566fb910..819840f28311 100644 --- a/snow/consensus/snowman/bootstrapper/majority_test.go +++ b/snow/consensus/snowman/bootstrapper/majority_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/minority.go b/snow/consensus/snowman/bootstrapper/minority.go index 52b45c4407ba..4674921aaf6b 100644 --- a/snow/consensus/snowman/bootstrapper/minority.go +++ b/snow/consensus/snowman/bootstrapper/minority.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/minority_test.go b/snow/consensus/snowman/bootstrapper/minority_test.go index f720ee18025a..c44b314f3443 100644 --- a/snow/consensus/snowman/bootstrapper/minority_test.go +++ b/snow/consensus/snowman/bootstrapper/minority_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/noop.go b/snow/consensus/snowman/bootstrapper/noop.go index 1cd3bffd58b7..6d97eed069a8 100644 --- a/snow/consensus/snowman/bootstrapper/noop.go +++ b/snow/consensus/snowman/bootstrapper/noop.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/noop_test.go b/snow/consensus/snowman/bootstrapper/noop_test.go index 0a485a8fae76..e0bccb8aad7f 100644 --- a/snow/consensus/snowman/bootstrapper/noop_test.go +++ b/snow/consensus/snowman/bootstrapper/noop_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/poll.go b/snow/consensus/snowman/bootstrapper/poll.go index 450341d9d64d..0d3eb7143167 100644 --- a/snow/consensus/snowman/bootstrapper/poll.go +++ b/snow/consensus/snowman/bootstrapper/poll.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/poll_test.go b/snow/consensus/snowman/bootstrapper/poll_test.go index 134867ae1822..bbdcc0db51a4 100644 --- a/snow/consensus/snowman/bootstrapper/poll_test.go +++ b/snow/consensus/snowman/bootstrapper/poll_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/requests.go b/snow/consensus/snowman/bootstrapper/requests.go index 28fc25ce1643..ebeaf57ac70f 100644 --- a/snow/consensus/snowman/bootstrapper/requests.go +++ b/snow/consensus/snowman/bootstrapper/requests.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/sampler.go b/snow/consensus/snowman/bootstrapper/sampler.go index 9511a1e4243f..e23253864669 100644 --- a/snow/consensus/snowman/bootstrapper/sampler.go +++ b/snow/consensus/snowman/bootstrapper/sampler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/bootstrapper/sampler_test.go b/snow/consensus/snowman/bootstrapper/sampler_test.go index 1b9e366decc7..b438a5fb2629 100644 --- a/snow/consensus/snowman/bootstrapper/sampler_test.go +++ b/snow/consensus/snowman/bootstrapper/sampler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrapper diff --git a/snow/consensus/snowman/consensus.go b/snow/consensus/snowman/consensus.go index 25b2c7242ec1..3f1006416366 100644 --- a/snow/consensus/snowman/consensus.go +++ b/snow/consensus/snowman/consensus.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/consensus_test.go b/snow/consensus/snowman/consensus_test.go index 375f81d5b3a8..15e56709dd28 100644 --- a/snow/consensus/snowman/consensus_test.go +++ b/snow/consensus/snowman/consensus_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/factory.go b/snow/consensus/snowman/factory.go index 06341981aef4..c2fc76e83ef9 100644 --- a/snow/consensus/snowman/factory.go +++ b/snow/consensus/snowman/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/metrics.go b/snow/consensus/snowman/metrics.go index 6e5159d6c1a5..a052db5144d4 100644 --- a/snow/consensus/snowman/metrics.go +++ b/snow/consensus/snowman/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/network_test.go b/snow/consensus/snowman/network_test.go index 9b402450c2de..aead346fb5e4 100644 --- a/snow/consensus/snowman/network_test.go +++ b/snow/consensus/snowman/network_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/oracle_block.go b/snow/consensus/snowman/oracle_block.go index 0ead79d03d22..4688927e566e 100644 --- a/snow/consensus/snowman/oracle_block.go +++ b/snow/consensus/snowman/oracle_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/poll/early_term_no_traversal.go b/snow/consensus/snowman/poll/early_term_no_traversal.go index fcad5b71932b..460805ab7820 100644 --- a/snow/consensus/snowman/poll/early_term_no_traversal.go +++ b/snow/consensus/snowman/poll/early_term_no_traversal.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package poll diff --git a/snow/consensus/snowman/poll/early_term_no_traversal_test.go b/snow/consensus/snowman/poll/early_term_no_traversal_test.go index 8255818abdbb..9d215c246eec 100644 --- a/snow/consensus/snowman/poll/early_term_no_traversal_test.go +++ b/snow/consensus/snowman/poll/early_term_no_traversal_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package poll diff --git a/snow/consensus/snowman/poll/interfaces.go b/snow/consensus/snowman/poll/interfaces.go index cab31cfc54ce..c1a776b4dc5f 100644 --- a/snow/consensus/snowman/poll/interfaces.go +++ b/snow/consensus/snowman/poll/interfaces.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package poll diff --git a/snow/consensus/snowman/poll/set.go b/snow/consensus/snowman/poll/set.go index e58059f20c3d..4c085b7aa4bc 100644 --- a/snow/consensus/snowman/poll/set.go +++ b/snow/consensus/snowman/poll/set.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package poll diff --git a/snow/consensus/snowman/poll/set_test.go b/snow/consensus/snowman/poll/set_test.go index 84ed8f7a5c8c..cdcf0e7d8903 100644 --- a/snow/consensus/snowman/poll/set_test.go +++ b/snow/consensus/snowman/poll/set_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package poll diff --git a/snow/consensus/snowman/snowman_block.go b/snow/consensus/snowman/snowman_block.go index 782c77d8e415..a25099b4519f 100644 --- a/snow/consensus/snowman/snowman_block.go +++ b/snow/consensus/snowman/snowman_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/test_block.go b/snow/consensus/snowman/test_block.go index f340a0291b00..b59eb2ed5f89 100644 --- a/snow/consensus/snowman/test_block.go +++ b/snow/consensus/snowman/test_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/topological.go b/snow/consensus/snowman/topological.go index f3fc838a8f8b..5b12ce3f2e6b 100644 --- a/snow/consensus/snowman/topological.go +++ b/snow/consensus/snowman/topological.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/topological_test.go b/snow/consensus/snowman/topological_test.go index 53a1b4416d9a..540b5a8f2eb1 100644 --- a/snow/consensus/snowman/topological_test.go +++ b/snow/consensus/snowman/topological_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowman/traced_consensus.go b/snow/consensus/snowman/traced_consensus.go index 67a8797b294a..363fa15334b0 100644 --- a/snow/consensus/snowman/traced_consensus.go +++ b/snow/consensus/snowman/traced_consensus.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/consensus/snowstorm/test_tx.go b/snow/consensus/snowstorm/test_tx.go index 8c5aa9aa3544..a8b514c8164d 100644 --- a/snow/consensus/snowstorm/test_tx.go +++ b/snow/consensus/snowstorm/test_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowstorm diff --git a/snow/consensus/snowstorm/tx.go b/snow/consensus/snowstorm/tx.go index 54a56a42f5b4..cc1cf649e9a8 100644 --- a/snow/consensus/snowstorm/tx.go +++ b/snow/consensus/snowstorm/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowstorm diff --git a/snow/context.go b/snow/context.go index 60e2a305eb2b..2cbbedb38b47 100644 --- a/snow/context.go +++ b/snow/context.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snow diff --git a/snow/engine/avalanche/bootstrap/bootstrapper.go b/snow/engine/avalanche/bootstrap/bootstrapper.go index 162937dc7860..cd530d1cb1f8 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/avalanche/bootstrap/bootstrapper_test.go b/snow/engine/avalanche/bootstrap/bootstrapper_test.go index 1ef3ef7102ef..7da0b99a8736 100644 --- a/snow/engine/avalanche/bootstrap/bootstrapper_test.go +++ b/snow/engine/avalanche/bootstrap/bootstrapper_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/avalanche/bootstrap/config.go b/snow/engine/avalanche/bootstrap/config.go index 54fe7f2e45fa..a674c2758460 100644 --- a/snow/engine/avalanche/bootstrap/config.go +++ b/snow/engine/avalanche/bootstrap/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/avalanche/bootstrap/metrics.go b/snow/engine/avalanche/bootstrap/metrics.go index b9d5824ec95a..cc357f25901f 100644 --- a/snow/engine/avalanche/bootstrap/metrics.go +++ b/snow/engine/avalanche/bootstrap/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/avalanche/bootstrap/tx_job.go b/snow/engine/avalanche/bootstrap/tx_job.go index 615108c992ba..9bb939d3d186 100644 --- a/snow/engine/avalanche/bootstrap/tx_job.go +++ b/snow/engine/avalanche/bootstrap/tx_job.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/avalanche/bootstrap/vertex_job.go b/snow/engine/avalanche/bootstrap/vertex_job.go index 3001ce89904c..30d33c5dc9fb 100644 --- a/snow/engine/avalanche/bootstrap/vertex_job.go +++ b/snow/engine/avalanche/bootstrap/vertex_job.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/avalanche/engine.go b/snow/engine/avalanche/engine.go index 375666c99598..530a319e0fc6 100644 --- a/snow/engine/avalanche/engine.go +++ b/snow/engine/avalanche/engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avalanche diff --git a/snow/engine/avalanche/getter/getter.go b/snow/engine/avalanche/getter/getter.go index a93d2f1d069e..8903eec1b3ba 100644 --- a/snow/engine/avalanche/getter/getter.go +++ b/snow/engine/avalanche/getter/getter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package getter diff --git a/snow/engine/avalanche/getter/getter_test.go b/snow/engine/avalanche/getter/getter_test.go index 4d25e29f296b..4977d53fa7ee 100644 --- a/snow/engine/avalanche/getter/getter_test.go +++ b/snow/engine/avalanche/getter/getter_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package getter diff --git a/snow/engine/avalanche/state/prefixed_state.go b/snow/engine/avalanche/state/prefixed_state.go index 5fac890b9ed1..1ff634d5c61e 100644 --- a/snow/engine/avalanche/state/prefixed_state.go +++ b/snow/engine/avalanche/state/prefixed_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/snow/engine/avalanche/state/serializer.go b/snow/engine/avalanche/state/serializer.go index 88dc7afefae4..b305100b9ce2 100644 --- a/snow/engine/avalanche/state/serializer.go +++ b/snow/engine/avalanche/state/serializer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. // Package state manages the meta-data required by consensus for an avalanche diff --git a/snow/engine/avalanche/state/state.go b/snow/engine/avalanche/state/state.go index f7f94c5e6923..021a4c7e1d68 100644 --- a/snow/engine/avalanche/state/state.go +++ b/snow/engine/avalanche/state/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/snow/engine/avalanche/state/unique_vertex.go b/snow/engine/avalanche/state/unique_vertex.go index 73c1ef94ccdc..bc245d1b5496 100644 --- a/snow/engine/avalanche/state/unique_vertex.go +++ b/snow/engine/avalanche/state/unique_vertex.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/snow/engine/avalanche/state/unique_vertex_test.go b/snow/engine/avalanche/state/unique_vertex_test.go index cdd503157dbd..6f644680d290 100644 --- a/snow/engine/avalanche/state/unique_vertex_test.go +++ b/snow/engine/avalanche/state/unique_vertex_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/snow/engine/avalanche/vertex/builder.go b/snow/engine/avalanche/vertex/builder.go index dd83016d7ee6..cf3e88ee6a35 100644 --- a/snow/engine/avalanche/vertex/builder.go +++ b/snow/engine/avalanche/vertex/builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/builder_test.go b/snow/engine/avalanche/vertex/builder_test.go index 132ccbc33f73..a70b14ba8ff1 100644 --- a/snow/engine/avalanche/vertex/builder_test.go +++ b/snow/engine/avalanche/vertex/builder_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/codec.go b/snow/engine/avalanche/vertex/codec.go index 65c0ff84cdc2..c6da27f1f57f 100644 --- a/snow/engine/avalanche/vertex/codec.go +++ b/snow/engine/avalanche/vertex/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/manager.go b/snow/engine/avalanche/vertex/manager.go index cf206742b629..a300affdb0e9 100644 --- a/snow/engine/avalanche/vertex/manager.go +++ b/snow/engine/avalanche/vertex/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/parser.go b/snow/engine/avalanche/vertex/parser.go index f0b7a8aa5571..41f848e781c6 100644 --- a/snow/engine/avalanche/vertex/parser.go +++ b/snow/engine/avalanche/vertex/parser.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/parser_test.go b/snow/engine/avalanche/vertex/parser_test.go index 5d765d8384dd..f3016895848d 100644 --- a/snow/engine/avalanche/vertex/parser_test.go +++ b/snow/engine/avalanche/vertex/parser_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/stateless_vertex.go b/snow/engine/avalanche/vertex/stateless_vertex.go index d5e51671bb42..88884d9e90bb 100644 --- a/snow/engine/avalanche/vertex/stateless_vertex.go +++ b/snow/engine/avalanche/vertex/stateless_vertex.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/stateless_vertex_test.go b/snow/engine/avalanche/vertex/stateless_vertex_test.go index a18a045a95d4..35ece98c51da 100644 --- a/snow/engine/avalanche/vertex/stateless_vertex_test.go +++ b/snow/engine/avalanche/vertex/stateless_vertex_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/storage.go b/snow/engine/avalanche/vertex/storage.go index 40ec863d2cba..cac766c6b103 100644 --- a/snow/engine/avalanche/vertex/storage.go +++ b/snow/engine/avalanche/vertex/storage.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/test_builder.go b/snow/engine/avalanche/vertex/test_builder.go index 0bd63b26bcb1..534629372249 100644 --- a/snow/engine/avalanche/vertex/test_builder.go +++ b/snow/engine/avalanche/vertex/test_builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/test_manager.go b/snow/engine/avalanche/vertex/test_manager.go index a2f55ee7f8b8..6954161cdd46 100644 --- a/snow/engine/avalanche/vertex/test_manager.go +++ b/snow/engine/avalanche/vertex/test_manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/test_parser.go b/snow/engine/avalanche/vertex/test_parser.go index 3ca17b3440f1..2ee10add6090 100644 --- a/snow/engine/avalanche/vertex/test_parser.go +++ b/snow/engine/avalanche/vertex/test_parser.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/test_storage.go b/snow/engine/avalanche/vertex/test_storage.go index b5250ee1fca4..8e0b8bc1e84d 100644 --- a/snow/engine/avalanche/vertex/test_storage.go +++ b/snow/engine/avalanche/vertex/test_storage.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/test_vm.go b/snow/engine/avalanche/vertex/test_vm.go index d20e57000da9..ee17c8b13ae0 100644 --- a/snow/engine/avalanche/vertex/test_vm.go +++ b/snow/engine/avalanche/vertex/test_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/avalanche/vertex/vm.go b/snow/engine/avalanche/vertex/vm.go index 67f3fc586b26..9987fe164d35 100644 --- a/snow/engine/avalanche/vertex/vm.go +++ b/snow/engine/avalanche/vertex/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vertex diff --git a/snow/engine/common/appsender/appsender_client.go b/snow/engine/common/appsender/appsender_client.go index c74616d71006..acde7109f751 100644 --- a/snow/engine/common/appsender/appsender_client.go +++ b/snow/engine/common/appsender/appsender_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package appsender diff --git a/snow/engine/common/appsender/appsender_server.go b/snow/engine/common/appsender/appsender_server.go index 3583940db108..84763e17bf11 100644 --- a/snow/engine/common/appsender/appsender_server.go +++ b/snow/engine/common/appsender/appsender_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package appsender diff --git a/snow/engine/common/bootstrap_tracker.go b/snow/engine/common/bootstrap_tracker.go index 04b90a122f98..bd2ef43cf1f3 100644 --- a/snow/engine/common/bootstrap_tracker.go +++ b/snow/engine/common/bootstrap_tracker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/bootstrapable.go b/snow/engine/common/bootstrapable.go index 256acb6d468e..517eba2aa154 100644 --- a/snow/engine/common/bootstrapable.go +++ b/snow/engine/common/bootstrapable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/engine.go b/snow/engine/common/engine.go index aea725ccf8a1..cbd9c37dc10c 100644 --- a/snow/engine/common/engine.go +++ b/snow/engine/common/engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/error.go b/snow/engine/common/error.go index 9e83325ddd4e..261fedaa260c 100644 --- a/snow/engine/common/error.go +++ b/snow/engine/common/error.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/error_test.go b/snow/engine/common/error_test.go index 124eaad33870..0204e010045b 100644 --- a/snow/engine/common/error_test.go +++ b/snow/engine/common/error_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/fx.go b/snow/engine/common/fx.go index 861986462bb2..000c22ed6baf 100644 --- a/snow/engine/common/fx.go +++ b/snow/engine/common/fx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/halter.go b/snow/engine/common/halter.go index bdfe3c9d489e..1fcea981d2e4 100644 --- a/snow/engine/common/halter.go +++ b/snow/engine/common/halter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/message.go b/snow/engine/common/message.go index 6ce1c4501a1c..1bc05991973e 100644 --- a/snow/engine/common/message.go +++ b/snow/engine/common/message.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/no_ops_handlers.go b/snow/engine/common/no_ops_handlers.go index 15a3f2900ccb..870c6694a7a7 100644 --- a/snow/engine/common/no_ops_handlers.go +++ b/snow/engine/common/no_ops_handlers.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/queue/job.go b/snow/engine/common/queue/job.go index 4ac5a60fb835..3b36893f1d96 100644 --- a/snow/engine/common/queue/job.go +++ b/snow/engine/common/queue/job.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package queue diff --git a/snow/engine/common/queue/jobs.go b/snow/engine/common/queue/jobs.go index 5592ad822439..0577602a3729 100644 --- a/snow/engine/common/queue/jobs.go +++ b/snow/engine/common/queue/jobs.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package queue diff --git a/snow/engine/common/queue/jobs_test.go b/snow/engine/common/queue/jobs_test.go index a50b3cb60e8a..a098cb6e6d6d 100644 --- a/snow/engine/common/queue/jobs_test.go +++ b/snow/engine/common/queue/jobs_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package queue diff --git a/snow/engine/common/queue/parser.go b/snow/engine/common/queue/parser.go index ee8f39807f35..07e9df50887d 100644 --- a/snow/engine/common/queue/parser.go +++ b/snow/engine/common/queue/parser.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package queue diff --git a/snow/engine/common/queue/state.go b/snow/engine/common/queue/state.go index cae43f8c2101..68ba67ce38c1 100644 --- a/snow/engine/common/queue/state.go +++ b/snow/engine/common/queue/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package queue diff --git a/snow/engine/common/queue/test_job.go b/snow/engine/common/queue/test_job.go index 98ea33614b50..fd9af544fb62 100644 --- a/snow/engine/common/queue/test_job.go +++ b/snow/engine/common/queue/test_job.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package queue diff --git a/snow/engine/common/queue/test_parser.go b/snow/engine/common/queue/test_parser.go index 85a079cc1435..1cc1cfd2973f 100644 --- a/snow/engine/common/queue/test_parser.go +++ b/snow/engine/common/queue/test_parser.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package queue diff --git a/snow/engine/common/request.go b/snow/engine/common/request.go index d677a485c8f4..f9cccb3b0d29 100644 --- a/snow/engine/common/request.go +++ b/snow/engine/common/request.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/sender.go b/snow/engine/common/sender.go index 885f4d9bd78f..b40084fc714f 100644 --- a/snow/engine/common/sender.go +++ b/snow/engine/common/sender.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/state_syncer.go b/snow/engine/common/state_syncer.go index e23ad126407c..a6d159bb6949 100644 --- a/snow/engine/common/state_syncer.go +++ b/snow/engine/common/state_syncer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/test_bootstrap_tracker.go b/snow/engine/common/test_bootstrap_tracker.go index ba377b39dce3..2e940f1a43b1 100644 --- a/snow/engine/common/test_bootstrap_tracker.go +++ b/snow/engine/common/test_bootstrap_tracker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/test_bootstrapper.go b/snow/engine/common/test_bootstrapper.go index 6ee9e223dc18..259fcb07fb3e 100644 --- a/snow/engine/common/test_bootstrapper.go +++ b/snow/engine/common/test_bootstrapper.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/test_engine.go b/snow/engine/common/test_engine.go index 414048366336..e07352d43713 100644 --- a/snow/engine/common/test_engine.go +++ b/snow/engine/common/test_engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/test_sender.go b/snow/engine/common/test_sender.go index 4ef33192bd93..32af682838fa 100644 --- a/snow/engine/common/test_sender.go +++ b/snow/engine/common/test_sender.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/test_timer.go b/snow/engine/common/test_timer.go index e5e2b232d390..6da0d9251712 100644 --- a/snow/engine/common/test_timer.go +++ b/snow/engine/common/test_timer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/test_vm.go b/snow/engine/common/test_vm.go index 8146a5f6746b..b576e8e389c7 100644 --- a/snow/engine/common/test_vm.go +++ b/snow/engine/common/test_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/timer.go b/snow/engine/common/timer.go index 56312d08a4fa..432bb9170ccb 100644 --- a/snow/engine/common/timer.go +++ b/snow/engine/common/timer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/traced_bootstrapable_engine.go b/snow/engine/common/traced_bootstrapable_engine.go index d387df04ac34..4c64206ae081 100644 --- a/snow/engine/common/traced_bootstrapable_engine.go +++ b/snow/engine/common/traced_bootstrapable_engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/traced_engine.go b/snow/engine/common/traced_engine.go index 13ecc92a97ca..5ffad7c543d7 100644 --- a/snow/engine/common/traced_engine.go +++ b/snow/engine/common/traced_engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/traced_state_syncer.go b/snow/engine/common/traced_state_syncer.go index db2569eef995..e598b6094076 100644 --- a/snow/engine/common/traced_state_syncer.go +++ b/snow/engine/common/traced_state_syncer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/common/tracker/accepted.go b/snow/engine/common/tracker/accepted.go index 0be64bc9035e..f6c63e3ff28d 100644 --- a/snow/engine/common/tracker/accepted.go +++ b/snow/engine/common/tracker/accepted.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/engine/common/tracker/accepted_test.go b/snow/engine/common/tracker/accepted_test.go index 7bb617d789f9..8ff489f51aea 100644 --- a/snow/engine/common/tracker/accepted_test.go +++ b/snow/engine/common/tracker/accepted_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/engine/common/tracker/peers.go b/snow/engine/common/tracker/peers.go index 94d653a53b1f..fdf070613d83 100644 --- a/snow/engine/common/tracker/peers.go +++ b/snow/engine/common/tracker/peers.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/engine/common/tracker/peers_test.go b/snow/engine/common/tracker/peers_test.go index 4af065113385..b627b79a16ed 100644 --- a/snow/engine/common/tracker/peers_test.go +++ b/snow/engine/common/tracker/peers_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/engine/common/tracker/startup.go b/snow/engine/common/tracker/startup.go index 282d88ce832d..c5e75613fcaa 100644 --- a/snow/engine/common/tracker/startup.go +++ b/snow/engine/common/tracker/startup.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/engine/common/vm.go b/snow/engine/common/vm.go index e77bdd552bbf..dc201c95602f 100644 --- a/snow/engine/common/vm.go +++ b/snow/engine/common/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/snow/engine/snowman/ancestor/tree.go b/snow/engine/snowman/ancestor/tree.go index 3d7fda833cbc..9e0eb4e4f02f 100644 --- a/snow/engine/snowman/ancestor/tree.go +++ b/snow/engine/snowman/ancestor/tree.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ancestor diff --git a/snow/engine/snowman/ancestor/tree_test.go b/snow/engine/snowman/ancestor/tree_test.go index 605f2a08572d..d17d38ceb0ca 100644 --- a/snow/engine/snowman/ancestor/tree_test.go +++ b/snow/engine/snowman/ancestor/tree_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ancestor diff --git a/snow/engine/snowman/block/batched_vm.go b/snow/engine/snowman/block/batched_vm.go index 3d5b869b98c1..ad52e3592ae6 100644 --- a/snow/engine/snowman/block/batched_vm.go +++ b/snow/engine/snowman/block/batched_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/batched_vm_test.go b/snow/engine/snowman/block/batched_vm_test.go index 92426c1b474d..b4d251c284ba 100644 --- a/snow/engine/snowman/block/batched_vm_test.go +++ b/snow/engine/snowman/block/batched_vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/block_context_vm.go b/snow/engine/snowman/block/block_context_vm.go index 4a259571a006..6b8b78235431 100644 --- a/snow/engine/snowman/block/block_context_vm.go +++ b/snow/engine/snowman/block/block_context_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/state_summary.go b/snow/engine/snowman/block/state_summary.go index 337a27d9f1d8..d89d77a22396 100644 --- a/snow/engine/snowman/block/state_summary.go +++ b/snow/engine/snowman/block/state_summary.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/state_sync_mode.go b/snow/engine/snowman/block/state_sync_mode.go index 79f5c2e8043e..35da3ab4eda9 100644 --- a/snow/engine/snowman/block/state_sync_mode.go +++ b/snow/engine/snowman/block/state_sync_mode.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/state_syncable_vm.go b/snow/engine/snowman/block/state_syncable_vm.go index 5c25f37a7ad7..0457505183e5 100644 --- a/snow/engine/snowman/block/state_syncable_vm.go +++ b/snow/engine/snowman/block/state_syncable_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/test_batched_vm.go b/snow/engine/snowman/block/test_batched_vm.go index ef7991156070..e5d654ec4a87 100644 --- a/snow/engine/snowman/block/test_batched_vm.go +++ b/snow/engine/snowman/block/test_batched_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/test_state_summary.go b/snow/engine/snowman/block/test_state_summary.go index 089e6dcfd364..7287cff10120 100644 --- a/snow/engine/snowman/block/test_state_summary.go +++ b/snow/engine/snowman/block/test_state_summary.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/test_state_syncable_vm.go b/snow/engine/snowman/block/test_state_syncable_vm.go index b05dd8118683..f1eeb9606642 100644 --- a/snow/engine/snowman/block/test_state_syncable_vm.go +++ b/snow/engine/snowman/block/test_state_syncable_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/test_vm.go b/snow/engine/snowman/block/test_vm.go index 4f3a2835eda5..376dd27066f7 100644 --- a/snow/engine/snowman/block/test_vm.go +++ b/snow/engine/snowman/block/test_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/block/vm.go b/snow/engine/snowman/block/vm.go index 13d4fa75ed02..4153632a7616 100644 --- a/snow/engine/snowman/block/vm.go +++ b/snow/engine/snowman/block/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/snow/engine/snowman/bootstrap/block_job.go b/snow/engine/snowman/bootstrap/block_job.go index 06ae8fbcb84f..696cbddb58a9 100644 --- a/snow/engine/snowman/bootstrap/block_job.go +++ b/snow/engine/snowman/bootstrap/block_job.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index b819c9573b48..29754a24d734 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/snowman/bootstrap/bootstrapper_test.go b/snow/engine/snowman/bootstrap/bootstrapper_test.go index 363af8c11488..08f63f163b80 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper_test.go +++ b/snow/engine/snowman/bootstrap/bootstrapper_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/snowman/bootstrap/config.go b/snow/engine/snowman/bootstrap/config.go index 785654cb72dc..6fb8894db96f 100644 --- a/snow/engine/snowman/bootstrap/config.go +++ b/snow/engine/snowman/bootstrap/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/snowman/bootstrap/metrics.go b/snow/engine/snowman/bootstrap/metrics.go index 9359ecfadb19..f6ad90d16419 100644 --- a/snow/engine/snowman/bootstrap/metrics.go +++ b/snow/engine/snowman/bootstrap/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bootstrap diff --git a/snow/engine/snowman/config.go b/snow/engine/snowman/config.go index 65a24a2ea816..3162471a2476 100644 --- a/snow/engine/snowman/config.go +++ b/snow/engine/snowman/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/config_test.go b/snow/engine/snowman/config_test.go index 2991a092bdfc..fe66256c68db 100644 --- a/snow/engine/snowman/config_test.go +++ b/snow/engine/snowman/config_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/engine.go b/snow/engine/snowman/engine.go index 37985f5b48fa..b5e3fb1020e3 100644 --- a/snow/engine/snowman/engine.go +++ b/snow/engine/snowman/engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/getter/getter.go b/snow/engine/snowman/getter/getter.go index 0f9dc40b0a19..ff8fe13f8fe9 100644 --- a/snow/engine/snowman/getter/getter.go +++ b/snow/engine/snowman/getter/getter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package getter diff --git a/snow/engine/snowman/getter/getter_test.go b/snow/engine/snowman/getter/getter_test.go index 1e0647b1911e..4fc03d4795d6 100644 --- a/snow/engine/snowman/getter/getter_test.go +++ b/snow/engine/snowman/getter/getter_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package getter diff --git a/snow/engine/snowman/issuer.go b/snow/engine/snowman/issuer.go index 3558d47360dc..d952dfe2cc6b 100644 --- a/snow/engine/snowman/issuer.go +++ b/snow/engine/snowman/issuer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/memory_block.go b/snow/engine/snowman/memory_block.go index c3b476b9f496..d91118afa5b3 100644 --- a/snow/engine/snowman/memory_block.go +++ b/snow/engine/snowman/memory_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/metrics.go b/snow/engine/snowman/metrics.go index dfdc92c636db..5dd65d8afa14 100644 --- a/snow/engine/snowman/metrics.go +++ b/snow/engine/snowman/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/syncer/config.go b/snow/engine/snowman/syncer/config.go index 9f7acf7a4910..b5fae133a376 100644 --- a/snow/engine/snowman/syncer/config.go +++ b/snow/engine/snowman/syncer/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package syncer diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index 42db0b264cd1..bc549a0ce93a 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package syncer diff --git a/snow/engine/snowman/syncer/state_syncer_test.go b/snow/engine/snowman/syncer/state_syncer_test.go index bb0ed52e6bae..11faeae69f67 100644 --- a/snow/engine/snowman/syncer/state_syncer_test.go +++ b/snow/engine/snowman/syncer/state_syncer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package syncer diff --git a/snow/engine/snowman/syncer/utils_test.go b/snow/engine/snowman/syncer/utils_test.go index 149d1fe0e681..a5217a4bf0dd 100644 --- a/snow/engine/snowman/syncer/utils_test.go +++ b/snow/engine/snowman/syncer/utils_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package syncer diff --git a/snow/engine/snowman/test_engine.go b/snow/engine/snowman/test_engine.go index ed6e1b1743c5..eada8463a041 100644 --- a/snow/engine/snowman/test_engine.go +++ b/snow/engine/snowman/test_engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/traced_engine.go b/snow/engine/snowman/traced_engine.go index 56b46de45d4e..f736dff48fbf 100644 --- a/snow/engine/snowman/traced_engine.go +++ b/snow/engine/snowman/traced_engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 4b43dcda0acb..34954885a66d 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/transitive_test.go b/snow/engine/snowman/transitive_test.go index c06dc5c924cf..a6b96ced21bd 100644 --- a/snow/engine/snowman/transitive_test.go +++ b/snow/engine/snowman/transitive_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/engine/snowman/voter.go b/snow/engine/snowman/voter.go index 7d267b2efbcf..0a029e870ec2 100644 --- a/snow/engine/snowman/voter.go +++ b/snow/engine/snowman/voter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowman diff --git a/snow/event/blockable.go b/snow/event/blockable.go index 05521dc2fe16..404e95c2aee3 100644 --- a/snow/event/blockable.go +++ b/snow/event/blockable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package event diff --git a/snow/event/blocker.go b/snow/event/blocker.go index 6f8e76b2d476..9c15ffb50604 100644 --- a/snow/event/blocker.go +++ b/snow/event/blocker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package event diff --git a/snow/event/blocker_test.go b/snow/event/blocker_test.go index 838a4f69d24b..d7620bfebe1a 100644 --- a/snow/event/blocker_test.go +++ b/snow/event/blocker_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package event diff --git a/snow/networking/benchlist/benchable.go b/snow/networking/benchlist/benchable.go index e7ed46c678f9..f1cc85d9fe05 100644 --- a/snow/networking/benchlist/benchable.go +++ b/snow/networking/benchlist/benchable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package benchlist diff --git a/snow/networking/benchlist/benchlist.go b/snow/networking/benchlist/benchlist.go index 15b42b76b467..08f7e7d8d65e 100644 --- a/snow/networking/benchlist/benchlist.go +++ b/snow/networking/benchlist/benchlist.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package benchlist diff --git a/snow/networking/benchlist/benchlist_test.go b/snow/networking/benchlist/benchlist_test.go index 5e068e78aef4..45568392297e 100644 --- a/snow/networking/benchlist/benchlist_test.go +++ b/snow/networking/benchlist/benchlist_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package benchlist diff --git a/snow/networking/benchlist/manager.go b/snow/networking/benchlist/manager.go index 7a42e8245267..e6ac45da4400 100644 --- a/snow/networking/benchlist/manager.go +++ b/snow/networking/benchlist/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package benchlist diff --git a/snow/networking/benchlist/metrics.go b/snow/networking/benchlist/metrics.go index 12da52d396a0..25f9e50f7da8 100644 --- a/snow/networking/benchlist/metrics.go +++ b/snow/networking/benchlist/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package benchlist diff --git a/snow/networking/benchlist/test_benchable.go b/snow/networking/benchlist/test_benchable.go index 5e179763d2d1..dabfab564829 100644 --- a/snow/networking/benchlist/test_benchable.go +++ b/snow/networking/benchlist/test_benchable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package benchlist diff --git a/snow/networking/handler/engine.go b/snow/networking/handler/engine.go index 94ae54ff08c6..e3de84ac8989 100644 --- a/snow/networking/handler/engine.go +++ b/snow/networking/handler/engine.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/engine_test.go b/snow/networking/handler/engine_test.go index 142441cfda6d..e9b2b8ae0162 100644 --- a/snow/networking/handler/engine_test.go +++ b/snow/networking/handler/engine_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/handler.go b/snow/networking/handler/handler.go index b11f719cca13..35dc40f57f98 100644 --- a/snow/networking/handler/handler.go +++ b/snow/networking/handler/handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/handler_test.go b/snow/networking/handler/handler_test.go index 71c3042c1807..1f51aa4f1d23 100644 --- a/snow/networking/handler/handler_test.go +++ b/snow/networking/handler/handler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/health.go b/snow/networking/handler/health.go index b68ead089639..3f4af4299d1c 100644 --- a/snow/networking/handler/health.go +++ b/snow/networking/handler/health.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/health_test.go b/snow/networking/handler/health_test.go index 31c3d35ce348..f3fe456fa023 100644 --- a/snow/networking/handler/health_test.go +++ b/snow/networking/handler/health_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/message_queue.go b/snow/networking/handler/message_queue.go index bc6ec7908a0f..58e4f2b3b29e 100644 --- a/snow/networking/handler/message_queue.go +++ b/snow/networking/handler/message_queue.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/message_queue_metrics.go b/snow/networking/handler/message_queue_metrics.go index ce28769a41ca..429295ae04cb 100644 --- a/snow/networking/handler/message_queue_metrics.go +++ b/snow/networking/handler/message_queue_metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/message_queue_test.go b/snow/networking/handler/message_queue_test.go index 266843772c3c..457ba86ceda1 100644 --- a/snow/networking/handler/message_queue_test.go +++ b/snow/networking/handler/message_queue_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/metrics.go b/snow/networking/handler/metrics.go index a8776b30832e..3fe9f2d9a2b3 100644 --- a/snow/networking/handler/metrics.go +++ b/snow/networking/handler/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/handler/parser.go b/snow/networking/handler/parser.go index 148572484ef5..4dc954e4e9f2 100644 --- a/snow/networking/handler/parser.go +++ b/snow/networking/handler/parser.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package handler diff --git a/snow/networking/router/chain_router.go b/snow/networking/router/chain_router.go index b55e77f66f41..f2c6d11775dd 100644 --- a/snow/networking/router/chain_router.go +++ b/snow/networking/router/chain_router.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package router diff --git a/snow/networking/router/chain_router_metrics.go b/snow/networking/router/chain_router_metrics.go index 58440377ba82..bc8f26223586 100644 --- a/snow/networking/router/chain_router_metrics.go +++ b/snow/networking/router/chain_router_metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package router diff --git a/snow/networking/router/chain_router_test.go b/snow/networking/router/chain_router_test.go index d99fecd1af00..1897aae89bc2 100644 --- a/snow/networking/router/chain_router_test.go +++ b/snow/networking/router/chain_router_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package router diff --git a/snow/networking/router/health.go b/snow/networking/router/health.go index d678f0f19aa1..3968f981d084 100644 --- a/snow/networking/router/health.go +++ b/snow/networking/router/health.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package router diff --git a/snow/networking/router/inbound_handler.go b/snow/networking/router/inbound_handler.go index cfd6d5fa222f..81d2d9b810be 100644 --- a/snow/networking/router/inbound_handler.go +++ b/snow/networking/router/inbound_handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package router diff --git a/snow/networking/router/main_test.go b/snow/networking/router/main_test.go index afc1dddb173e..4398ad2eefeb 100644 --- a/snow/networking/router/main_test.go +++ b/snow/networking/router/main_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package router diff --git a/snow/networking/router/router.go b/snow/networking/router/router.go index bba00eb7ae06..4df5614c25fb 100644 --- a/snow/networking/router/router.go +++ b/snow/networking/router/router.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package router diff --git a/snow/networking/router/traced_router.go b/snow/networking/router/traced_router.go index fe493e6717a8..955ccb43bbed 100644 --- a/snow/networking/router/traced_router.go +++ b/snow/networking/router/traced_router.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package router diff --git a/snow/networking/sender/external_sender.go b/snow/networking/sender/external_sender.go index 72d9539d41e5..7d279889e3af 100644 --- a/snow/networking/sender/external_sender.go +++ b/snow/networking/sender/external_sender.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sender diff --git a/snow/networking/sender/sender.go b/snow/networking/sender/sender.go index b6fe0bbb2844..08a05305029a 100644 --- a/snow/networking/sender/sender.go +++ b/snow/networking/sender/sender.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sender diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index 69363b2eeb67..5ad019731857 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sender diff --git a/snow/networking/sender/test_external_sender.go b/snow/networking/sender/test_external_sender.go index 7b8bef90e8eb..ae06187216bf 100644 --- a/snow/networking/sender/test_external_sender.go +++ b/snow/networking/sender/test_external_sender.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sender diff --git a/snow/networking/sender/traced_sender.go b/snow/networking/sender/traced_sender.go index 2011cdc38fb1..c5fdf6dcbc54 100644 --- a/snow/networking/sender/traced_sender.go +++ b/snow/networking/sender/traced_sender.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sender diff --git a/snow/networking/timeout/main_test.go b/snow/networking/timeout/main_test.go index f3bee130e58b..c8a597fa91b1 100644 --- a/snow/networking/timeout/main_test.go +++ b/snow/networking/timeout/main_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timeout diff --git a/snow/networking/timeout/manager.go b/snow/networking/timeout/manager.go index f1db8a1e01a0..95a3be25e166 100644 --- a/snow/networking/timeout/manager.go +++ b/snow/networking/timeout/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timeout diff --git a/snow/networking/timeout/manager_test.go b/snow/networking/timeout/manager_test.go index 582da3a9ea1b..73313322a81a 100644 --- a/snow/networking/timeout/manager_test.go +++ b/snow/networking/timeout/manager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timeout diff --git a/snow/networking/timeout/metrics.go b/snow/networking/timeout/metrics.go index 6be45fd2a97e..def073b56558 100644 --- a/snow/networking/timeout/metrics.go +++ b/snow/networking/timeout/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timeout diff --git a/snow/networking/tracker/resource_tracker.go b/snow/networking/tracker/resource_tracker.go index 7910c2fff475..b4b14a7561cf 100644 --- a/snow/networking/tracker/resource_tracker.go +++ b/snow/networking/tracker/resource_tracker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/networking/tracker/resource_tracker_test.go b/snow/networking/tracker/resource_tracker_test.go index 64a897589f90..a87958708cb1 100644 --- a/snow/networking/tracker/resource_tracker_test.go +++ b/snow/networking/tracker/resource_tracker_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/networking/tracker/targeter.go b/snow/networking/tracker/targeter.go index 4c69ab9508c1..39a7398e391c 100644 --- a/snow/networking/tracker/targeter.go +++ b/snow/networking/tracker/targeter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/networking/tracker/targeter_test.go b/snow/networking/tracker/targeter_test.go index 55974dbf4ac6..cc533791cf91 100644 --- a/snow/networking/tracker/targeter_test.go +++ b/snow/networking/tracker/targeter_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracker diff --git a/snow/snowtest/snowtest.go b/snow/snowtest/snowtest.go index 2450ebaf941d..83fd98925d90 100644 --- a/snow/snowtest/snowtest.go +++ b/snow/snowtest/snowtest.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snowtest diff --git a/snow/state.go b/snow/state.go index bb671f26e672..091cd31f50f1 100644 --- a/snow/state.go +++ b/snow/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package snow diff --git a/snow/uptime/locked_calculator.go b/snow/uptime/locked_calculator.go index 687b5f5905f5..884878ab24f6 100644 --- a/snow/uptime/locked_calculator.go +++ b/snow/uptime/locked_calculator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package uptime diff --git a/snow/uptime/locked_calculator_test.go b/snow/uptime/locked_calculator_test.go index 254497f62d02..3b073726e654 100644 --- a/snow/uptime/locked_calculator_test.go +++ b/snow/uptime/locked_calculator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package uptime diff --git a/snow/uptime/manager.go b/snow/uptime/manager.go index 2fc2e1605298..a64b71ca62de 100644 --- a/snow/uptime/manager.go +++ b/snow/uptime/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package uptime diff --git a/snow/uptime/manager_test.go b/snow/uptime/manager_test.go index de2c038086d5..e04fcc3a9fbe 100644 --- a/snow/uptime/manager_test.go +++ b/snow/uptime/manager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package uptime diff --git a/snow/uptime/no_op_calculator.go b/snow/uptime/no_op_calculator.go index 44c688e31be7..fb308f4f6030 100644 --- a/snow/uptime/no_op_calculator.go +++ b/snow/uptime/no_op_calculator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package uptime diff --git a/snow/uptime/state.go b/snow/uptime/state.go index 5b2592acc70d..f9edeb76a3ee 100644 --- a/snow/uptime/state.go +++ b/snow/uptime/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package uptime diff --git a/snow/uptime/test_state.go b/snow/uptime/test_state.go index 58687e1671b8..23879b5cb3a9 100644 --- a/snow/uptime/test_state.go +++ b/snow/uptime/test_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package uptime diff --git a/snow/validators/connector.go b/snow/validators/connector.go index abb28d084c20..e3e7e1f94ed4 100644 --- a/snow/validators/connector.go +++ b/snow/validators/connector.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/gvalidators/validator_state_client.go b/snow/validators/gvalidators/validator_state_client.go index 51e68592c001..49fa1e641417 100644 --- a/snow/validators/gvalidators/validator_state_client.go +++ b/snow/validators/gvalidators/validator_state_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gvalidators diff --git a/snow/validators/gvalidators/validator_state_server.go b/snow/validators/gvalidators/validator_state_server.go index ad9b75197947..5476dca4db99 100644 --- a/snow/validators/gvalidators/validator_state_server.go +++ b/snow/validators/gvalidators/validator_state_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gvalidators diff --git a/snow/validators/gvalidators/validator_state_test.go b/snow/validators/gvalidators/validator_state_test.go index da8a66570f0b..9b6e692d8645 100644 --- a/snow/validators/gvalidators/validator_state_test.go +++ b/snow/validators/gvalidators/validator_state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gvalidators diff --git a/snow/validators/logger.go b/snow/validators/logger.go index 2e672a1827ba..40613b76b68d 100644 --- a/snow/validators/logger.go +++ b/snow/validators/logger.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/manager.go b/snow/validators/manager.go index c42ea779d96b..5844c1e7f185 100644 --- a/snow/validators/manager.go +++ b/snow/validators/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/manager_test.go b/snow/validators/manager_test.go index 6980510fecd1..781d2e784e1d 100644 --- a/snow/validators/manager_test.go +++ b/snow/validators/manager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/set.go b/snow/validators/set.go index dfa294a70bbe..5e7c81a2310e 100644 --- a/snow/validators/set.go +++ b/snow/validators/set.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/set_test.go b/snow/validators/set_test.go index 48c19e59b11a..4554f930fa37 100644 --- a/snow/validators/set_test.go +++ b/snow/validators/set_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/state.go b/snow/validators/state.go index fa9ef2783165..3f92df35231b 100644 --- a/snow/validators/state.go +++ b/snow/validators/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/subnet_connector.go b/snow/validators/subnet_connector.go index 6b4a24bd85e5..06b02ff90820 100644 --- a/snow/validators/subnet_connector.go +++ b/snow/validators/subnet_connector.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/test_state.go b/snow/validators/test_state.go index eb6af391a1d8..ee4102cf7194 100644 --- a/snow/validators/test_state.go +++ b/snow/validators/test_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/traced_state.go b/snow/validators/traced_state.go index e1f5472001e2..126a2b009eb0 100644 --- a/snow/validators/traced_state.go +++ b/snow/validators/traced_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/unhandled_subnet_connector.go b/snow/validators/unhandled_subnet_connector.go index de7225aa2a80..08447c4582ad 100644 --- a/snow/validators/unhandled_subnet_connector.go +++ b/snow/validators/unhandled_subnet_connector.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/snow/validators/validator.go b/snow/validators/validator.go index 56664ddc00a1..499b5189e424 100644 --- a/snow/validators/validator.go +++ b/snow/validators/validator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/staking/asn1.go b/staking/asn1.go index 13579600eb3c..a21ebc7ff88c 100644 --- a/staking/asn1.go +++ b/staking/asn1.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package staking diff --git a/staking/certificate.go b/staking/certificate.go index 9521f43abef0..53d86a748b97 100644 --- a/staking/certificate.go +++ b/staking/certificate.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package staking diff --git a/staking/parse.go b/staking/parse.go index 04b47aba5a32..6de6b63dd4dd 100644 --- a/staking/parse.go +++ b/staking/parse.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package staking diff --git a/staking/tls.go b/staking/tls.go index fe461d52e32e..fbb5d9e488ae 100644 --- a/staking/tls.go +++ b/staking/tls.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package staking diff --git a/staking/tls_test.go b/staking/tls_test.go index 2282090b4c8e..6de376c2a538 100644 --- a/staking/tls_test.go +++ b/staking/tls_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package staking diff --git a/staking/verify.go b/staking/verify.go index 8da442e8b998..5fc8d77278e1 100644 --- a/staking/verify.go +++ b/staking/verify.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package staking diff --git a/staking/verify_test.go b/staking/verify_test.go index e7cee91c1b43..7fcf0ba8d624 100644 --- a/staking/verify_test.go +++ b/staking/verify_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package staking diff --git a/subnets/config.go b/subnets/config.go index 3ccbab79c50e..9a12c550b833 100644 --- a/subnets/config.go +++ b/subnets/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package subnets diff --git a/subnets/config_test.go b/subnets/config_test.go index 2294a1e5176a..fdb10c4e072a 100644 --- a/subnets/config_test.go +++ b/subnets/config_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package subnets diff --git a/subnets/no_op_allower.go b/subnets/no_op_allower.go index 9d2d51ea26d3..9cb7115e910d 100644 --- a/subnets/no_op_allower.go +++ b/subnets/no_op_allower.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package subnets diff --git a/subnets/subnet.go b/subnets/subnet.go index 31bc9dcb562b..95425ba30500 100644 --- a/subnets/subnet.go +++ b/subnets/subnet.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package subnets diff --git a/subnets/subnet_test.go b/subnets/subnet_test.go index 98a75dfd2813..3a816a158f04 100644 --- a/subnets/subnet_test.go +++ b/subnets/subnet_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package subnets diff --git a/tests/colors.go b/tests/colors.go index 3aa935a5fce9..6cfec4df3dc0 100644 --- a/tests/colors.go +++ b/tests/colors.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tests diff --git a/tests/e2e/banff/suites.go b/tests/e2e/banff/suites.go index 37d0aa90156a..009bad3494b3 100644 --- a/tests/e2e/banff/suites.go +++ b/tests/e2e/banff/suites.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. // Implements tests for the banff network upgrade. diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 5e80573542b4..0978bddc91d2 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/tests/e2e/c/hashing_contract.go b/tests/e2e/c/hashing_contract.go index af5e81eb9057..7bf1db76c7cf 100644 --- a/tests/e2e/c/hashing_contract.go +++ b/tests/e2e/c/hashing_contract.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. // AUTOMATICALLY GENERATED. DO NOT EDIT! diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index e959418e878a..0ce0ace59113 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 3245516262d2..7b9677dd7fc9 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package e2e_test diff --git a/tests/e2e/faultinjection/duplicate_node_id.go b/tests/e2e/faultinjection/duplicate_node_id.go index 938d60f9303f..d20ef1a28c0c 100644 --- a/tests/e2e/faultinjection/duplicate_node_id.go +++ b/tests/e2e/faultinjection/duplicate_node_id.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package faultinjection diff --git a/tests/e2e/ignore.go b/tests/e2e/ignore.go index 50332a1ac80e..ddf89c5d1bcc 100644 --- a/tests/e2e/ignore.go +++ b/tests/e2e/ignore.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package e2e diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 59e90198bed0..8983c46adcbd 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/tests/e2e/p/permissionless_subnets.go b/tests/e2e/p/permissionless_subnets.go index 566e36aa6178..ebb9dc602e6c 100644 --- a/tests/e2e/p/permissionless_subnets.go +++ b/tests/e2e/p/permissionless_subnets.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index 134c055dcde4..43b64456de96 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index 12410f1eeb54..8bf7efca2c2c 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/tests/e2e/static-handlers/suites.go b/tests/e2e/static-handlers/suites.go index 09367186da32..e18f16adaebf 100644 --- a/tests/e2e/static-handlers/suites.go +++ b/tests/e2e/static-handlers/suites.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. // Implements static handlers tests for avm and platformvm diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index f0c2951feb84..eec7b3427c19 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/tests/e2e/x/transfer/virtuous.go b/tests/e2e/x/transfer/virtuous.go index b409f7e5e555..9fc8ae89ec44 100644 --- a/tests/e2e/x/transfer/virtuous.go +++ b/tests/e2e/x/transfer/virtuous.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. // Implements X-chain transfer tests. diff --git a/tests/fixture/e2e/describe.go b/tests/fixture/e2e/describe.go index 5475a7114c96..2810117758c6 100644 --- a/tests/fixture/e2e/describe.go +++ b/tests/fixture/e2e/describe.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package e2e diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index 1ea9dc69f2b9..ddd50580ade5 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package e2e diff --git a/tests/fixture/e2e/flags.go b/tests/fixture/e2e/flags.go index b1354473fe86..6cedf003b3a3 100644 --- a/tests/fixture/e2e/flags.go +++ b/tests/fixture/e2e/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package e2e diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index ddebfbc8b81c..e57949106805 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package e2e diff --git a/tests/fixture/test_data_server.go b/tests/fixture/test_data_server.go index 77e79b278b13..b79dcc2bb26b 100644 --- a/tests/fixture/test_data_server.go +++ b/tests/fixture/test_data_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package fixture diff --git a/tests/fixture/test_data_server_test.go b/tests/fixture/test_data_server_test.go index 7f68a6935da3..6ad7644264d7 100644 --- a/tests/fixture/test_data_server_test.go +++ b/tests/fixture/test_data_server_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package fixture diff --git a/tests/fixture/tmpnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go index 9baf4557bca4..45ed58cef7a5 100644 --- a/tests/fixture/tmpnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index 11e9ab72787d..8ae303cf9af4 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/flags.go b/tests/fixture/tmpnet/flags.go index 556bfbec961e..3084982ea704 100644 --- a/tests/fixture/tmpnet/flags.go +++ b/tests/fixture/tmpnet/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/genesis.go b/tests/fixture/tmpnet/genesis.go index 5ee605702482..a200efb3b065 100644 --- a/tests/fixture/tmpnet/genesis.go +++ b/tests/fixture/tmpnet/genesis.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 5f1eaf5a4513..0c5818efa0ee 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/network_test.go b/tests/fixture/tmpnet/network_test.go index 1a06a07f4a38..a797ff873a25 100644 --- a/tests/fixture/tmpnet/network_test.go +++ b/tests/fixture/tmpnet/network_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/node.go b/tests/fixture/tmpnet/node.go index 955e38dc6995..f0f800802046 100644 --- a/tests/fixture/tmpnet/node.go +++ b/tests/fixture/tmpnet/node.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/node_config.go b/tests/fixture/tmpnet/node_config.go index 8771ce48f2bd..15000ae279fb 100644 --- a/tests/fixture/tmpnet/node_config.go +++ b/tests/fixture/tmpnet/node_config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/node_process.go b/tests/fixture/tmpnet/node_process.go index bec294b20713..c2e2e33139bf 100644 --- a/tests/fixture/tmpnet/node_process.go +++ b/tests/fixture/tmpnet/node_process.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/utils.go b/tests/fixture/tmpnet/utils.go index 74e6e3737069..b363bdec8671 100644 --- a/tests/fixture/tmpnet/utils.go +++ b/tests/fixture/tmpnet/utils.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/http.go b/tests/http.go index 77c309f16f86..073b6d2df126 100644 --- a/tests/http.go +++ b/tests/http.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tests diff --git a/tests/upgrade/upgrade_test.go b/tests/upgrade/upgrade_test.go index 862b08555b4f..9f56c79ad910 100644 --- a/tests/upgrade/upgrade_test.go +++ b/tests/upgrade/upgrade_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package upgrade diff --git a/trace/exporter.go b/trace/exporter.go index 252200975caf..4cca5fe3e53e 100644 --- a/trace/exporter.go +++ b/trace/exporter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package trace diff --git a/trace/exporter_type.go b/trace/exporter_type.go index 52d0124fe2b7..206731acc3bd 100644 --- a/trace/exporter_type.go +++ b/trace/exporter_type.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package trace diff --git a/trace/noop.go b/trace/noop.go index faa512b3429e..153934b143af 100644 --- a/trace/noop.go +++ b/trace/noop.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package trace diff --git a/trace/tracer.go b/trace/tracer.go index c511ff3bb0c9..1c8d40e8347f 100644 --- a/trace/tracer.go +++ b/trace/tracer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package trace diff --git a/utils/atomic.go b/utils/atomic.go index 2d75a4f47d6f..3bb125ee8af6 100644 --- a/utils/atomic.go +++ b/utils/atomic.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/utils/atomic_test.go b/utils/atomic_test.go index 1af2ba490f2f..3fa74063c18a 100644 --- a/utils/atomic_test.go +++ b/utils/atomic_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/utils/bag/bag.go b/utils/bag/bag.go index 496969a01b17..a9af1acbcf49 100644 --- a/utils/bag/bag.go +++ b/utils/bag/bag.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bag diff --git a/utils/bag/bag_benchmark_test.go b/utils/bag/bag_benchmark_test.go index 833ce755af93..e17b27b891bc 100644 --- a/utils/bag/bag_benchmark_test.go +++ b/utils/bag/bag_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bag diff --git a/utils/bag/bag_test.go b/utils/bag/bag_test.go index ffbda6379c77..3b6e0faa07f0 100644 --- a/utils/bag/bag_test.go +++ b/utils/bag/bag_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bag diff --git a/utils/bag/unique_bag.go b/utils/bag/unique_bag.go index 751159f16d9b..f5d679a5b816 100644 --- a/utils/bag/unique_bag.go +++ b/utils/bag/unique_bag.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bag diff --git a/utils/bag/unique_bag_test.go b/utils/bag/unique_bag_test.go index d15ecbf3a5cf..1562b5c9f04c 100644 --- a/utils/bag/unique_bag_test.go +++ b/utils/bag/unique_bag_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bag diff --git a/utils/beacon/beacon.go b/utils/beacon/beacon.go index 47e41032677e..38ac6df5b0f5 100644 --- a/utils/beacon/beacon.go +++ b/utils/beacon/beacon.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package beacon diff --git a/utils/beacon/set.go b/utils/beacon/set.go index 243f8399a915..8b6970b55421 100644 --- a/utils/beacon/set.go +++ b/utils/beacon/set.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package beacon diff --git a/utils/beacon/set_test.go b/utils/beacon/set_test.go index 3f4d6cbc4053..976d0582e3ff 100644 --- a/utils/beacon/set_test.go +++ b/utils/beacon/set_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package beacon diff --git a/utils/bimap/bimap.go b/utils/bimap/bimap.go index 28d20750bace..c44ff0ff60a9 100644 --- a/utils/bimap/bimap.go +++ b/utils/bimap/bimap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bimap diff --git a/utils/bimap/bimap_test.go b/utils/bimap/bimap_test.go index 9914578c6070..dffa80dc008d 100644 --- a/utils/bimap/bimap_test.go +++ b/utils/bimap/bimap_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bimap diff --git a/utils/bloom/bloom_filter.go b/utils/bloom/bloom_filter.go index 498c57d3552f..c4a0ff4c4ae8 100644 --- a/utils/bloom/bloom_filter.go +++ b/utils/bloom/bloom_filter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bloom diff --git a/utils/bloom/bloom_filter_test.go b/utils/bloom/bloom_filter_test.go index 7e810add0f3e..c28443d99912 100644 --- a/utils/bloom/bloom_filter_test.go +++ b/utils/bloom/bloom_filter_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bloom diff --git a/utils/bloom/map_filter.go b/utils/bloom/map_filter.go index 19046bea4c11..d0edcbe88fd0 100644 --- a/utils/bloom/map_filter.go +++ b/utils/bloom/map_filter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bloom diff --git a/utils/buffer/bounded_nonblocking_queue.go b/utils/buffer/bounded_nonblocking_queue.go index 0b5d5f945d52..f8b0030e9687 100644 --- a/utils/buffer/bounded_nonblocking_queue.go +++ b/utils/buffer/bounded_nonblocking_queue.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package buffer diff --git a/utils/buffer/bounded_nonblocking_queue_test.go b/utils/buffer/bounded_nonblocking_queue_test.go index e6a6fdac3e49..323ea92589be 100644 --- a/utils/buffer/bounded_nonblocking_queue_test.go +++ b/utils/buffer/bounded_nonblocking_queue_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package buffer diff --git a/utils/buffer/unbounded_blocking_deque.go b/utils/buffer/unbounded_blocking_deque.go index 078d8d908ee8..a6c7fb66d6e1 100644 --- a/utils/buffer/unbounded_blocking_deque.go +++ b/utils/buffer/unbounded_blocking_deque.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package buffer diff --git a/utils/buffer/unbounded_blocking_deque_test.go b/utils/buffer/unbounded_blocking_deque_test.go index 054d3a2e6bed..1f22db9916b9 100644 --- a/utils/buffer/unbounded_blocking_deque_test.go +++ b/utils/buffer/unbounded_blocking_deque_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package buffer diff --git a/utils/buffer/unbounded_deque.go b/utils/buffer/unbounded_deque.go index 336f0869c907..873f33f14817 100644 --- a/utils/buffer/unbounded_deque.go +++ b/utils/buffer/unbounded_deque.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package buffer diff --git a/utils/buffer/unbounded_deque_test.go b/utils/buffer/unbounded_deque_test.go index 5b759da1c0e9..dfdac4a53412 100644 --- a/utils/buffer/unbounded_deque_test.go +++ b/utils/buffer/unbounded_deque_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package buffer diff --git a/utils/bytes.go b/utils/bytes.go index c025c4915c9e..a32f353cf75e 100644 --- a/utils/bytes.go +++ b/utils/bytes.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/utils/cb58/cb58.go b/utils/cb58/cb58.go index 4d9cbd6f7449..27d8265cd2f9 100644 --- a/utils/cb58/cb58.go +++ b/utils/cb58/cb58.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cb58 diff --git a/utils/cb58/cb58_test.go b/utils/cb58/cb58_test.go index 858c0b8783ba..9d28c6f90fa4 100644 --- a/utils/cb58/cb58_test.go +++ b/utils/cb58/cb58_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package cb58 diff --git a/utils/compression/compressor.go b/utils/compression/compressor.go index f0848357a882..c8624f9baf84 100644 --- a/utils/compression/compressor.go +++ b/utils/compression/compressor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression diff --git a/utils/compression/compressor_test.go b/utils/compression/compressor_test.go index 0467c2c1b234..f4f024e550b9 100644 --- a/utils/compression/compressor_test.go +++ b/utils/compression/compressor_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression diff --git a/utils/compression/gzip_compressor.go b/utils/compression/gzip_compressor.go index a17c46f6d6a3..90067512a771 100644 --- a/utils/compression/gzip_compressor.go +++ b/utils/compression/gzip_compressor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression diff --git a/utils/compression/no_compressor.go b/utils/compression/no_compressor.go index 1eb4237d9766..3c444c71d993 100644 --- a/utils/compression/no_compressor.go +++ b/utils/compression/no_compressor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression diff --git a/utils/compression/no_compressor_test.go b/utils/compression/no_compressor_test.go index 95000667658c..3b99a101814d 100644 --- a/utils/compression/no_compressor_test.go +++ b/utils/compression/no_compressor_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression diff --git a/utils/compression/type.go b/utils/compression/type.go index fd58a21f70fa..6af0cf75407d 100644 --- a/utils/compression/type.go +++ b/utils/compression/type.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression diff --git a/utils/compression/type_test.go b/utils/compression/type_test.go index 13d6b313aa48..eacad3bad598 100644 --- a/utils/compression/type_test.go +++ b/utils/compression/type_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression diff --git a/utils/compression/zstd_compressor.go b/utils/compression/zstd_compressor.go index eafc1071845f..b374fa850ee6 100644 --- a/utils/compression/zstd_compressor.go +++ b/utils/compression/zstd_compressor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package compression diff --git a/utils/constants/acps.go b/utils/constants/acps.go index ea49d7c7812f..6774828cde31 100644 --- a/utils/constants/acps.go +++ b/utils/constants/acps.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package constants diff --git a/utils/constants/aliases.go b/utils/constants/aliases.go index dd94bd363925..494165019688 100644 --- a/utils/constants/aliases.go +++ b/utils/constants/aliases.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package constants diff --git a/utils/constants/application.go b/utils/constants/application.go index 117b85d9eb9e..4e59fd3777fb 100644 --- a/utils/constants/application.go +++ b/utils/constants/application.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package constants diff --git a/utils/constants/memory.go b/utils/constants/memory.go index c8740ceba6f7..cca6ee7af0f9 100644 --- a/utils/constants/memory.go +++ b/utils/constants/memory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package constants diff --git a/utils/constants/network_ids.go b/utils/constants/network_ids.go index fe2819d376ee..d00472a39f32 100644 --- a/utils/constants/network_ids.go +++ b/utils/constants/network_ids.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package constants diff --git a/utils/constants/network_ids_test.go b/utils/constants/network_ids_test.go index 69557096efd8..a368a2d36532 100644 --- a/utils/constants/network_ids_test.go +++ b/utils/constants/network_ids_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package constants diff --git a/utils/constants/networking.go b/utils/constants/networking.go index a9417eac37c9..8d60d27af58a 100644 --- a/utils/constants/networking.go +++ b/utils/constants/networking.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package constants diff --git a/utils/constants/vm_ids.go b/utils/constants/vm_ids.go index 4fb887c425f2..9fda498f1f31 100644 --- a/utils/constants/vm_ids.go +++ b/utils/constants/vm_ids.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package constants diff --git a/utils/context.go b/utils/context.go index 9ff300186881..453c45e948a4 100644 --- a/utils/context.go +++ b/utils/context.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/utils/crypto/bls/bls_benchmark_test.go b/utils/crypto/bls/bls_benchmark_test.go index cd3568005764..b9648b43c04e 100644 --- a/utils/crypto/bls/bls_benchmark_test.go +++ b/utils/crypto/bls/bls_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bls diff --git a/utils/crypto/bls/bls_test.go b/utils/crypto/bls/bls_test.go index f3bb05004376..e8a4a45bb97d 100644 --- a/utils/crypto/bls/bls_test.go +++ b/utils/crypto/bls/bls_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bls diff --git a/utils/crypto/bls/public.go b/utils/crypto/bls/public.go index 8d8237f83d5e..2c3cca7a0181 100644 --- a/utils/crypto/bls/public.go +++ b/utils/crypto/bls/public.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bls diff --git a/utils/crypto/bls/public_test.go b/utils/crypto/bls/public_test.go index 9cd886400b2d..4465b014cff4 100644 --- a/utils/crypto/bls/public_test.go +++ b/utils/crypto/bls/public_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bls diff --git a/utils/crypto/bls/secret.go b/utils/crypto/bls/secret.go index 3f385624520c..049938bdaf8e 100644 --- a/utils/crypto/bls/secret.go +++ b/utils/crypto/bls/secret.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bls diff --git a/utils/crypto/bls/secret_test.go b/utils/crypto/bls/secret_test.go index c01540ac4f98..d3d46e1aa737 100644 --- a/utils/crypto/bls/secret_test.go +++ b/utils/crypto/bls/secret_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bls diff --git a/utils/crypto/bls/signature.go b/utils/crypto/bls/signature.go index cafba33c48e6..0d0d029b796e 100644 --- a/utils/crypto/bls/signature.go +++ b/utils/crypto/bls/signature.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bls diff --git a/utils/crypto/bls/signature_test.go b/utils/crypto/bls/signature_test.go index caf613fc18df..3d43282c487a 100644 --- a/utils/crypto/bls/signature_test.go +++ b/utils/crypto/bls/signature_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package bls diff --git a/utils/crypto/keychain/keychain.go b/utils/crypto/keychain/keychain.go index 5899bb40382a..47d39b59f07c 100644 --- a/utils/crypto/keychain/keychain.go +++ b/utils/crypto/keychain/keychain.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keychain diff --git a/utils/crypto/keychain/keychain_test.go b/utils/crypto/keychain/keychain_test.go index 73aa476122db..1d1dd86b6055 100644 --- a/utils/crypto/keychain/keychain_test.go +++ b/utils/crypto/keychain/keychain_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keychain diff --git a/utils/crypto/keychain/ledger.go b/utils/crypto/keychain/ledger.go index d709ed19c939..955eb4480e24 100644 --- a/utils/crypto/keychain/ledger.go +++ b/utils/crypto/keychain/ledger.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keychain diff --git a/utils/crypto/ledger/ledger.go b/utils/crypto/ledger/ledger.go index 5f8c34fe5715..70f6d4f07b84 100644 --- a/utils/crypto/ledger/ledger.go +++ b/utils/crypto/ledger/ledger.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ledger diff --git a/utils/crypto/ledger/ledger_test.go b/utils/crypto/ledger/ledger_test.go index 118dc8758d1b..160b26365f84 100644 --- a/utils/crypto/ledger/ledger_test.go +++ b/utils/crypto/ledger/ledger_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ledger diff --git a/utils/crypto/secp256k1/rfc6979_test.go b/utils/crypto/secp256k1/rfc6979_test.go index 5d9ee8b4f033..7efc019a3429 100644 --- a/utils/crypto/secp256k1/rfc6979_test.go +++ b/utils/crypto/secp256k1/rfc6979_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1 diff --git a/utils/crypto/secp256k1/secp256k1.go b/utils/crypto/secp256k1/secp256k1.go index 733cee732d74..93ef887bf71d 100644 --- a/utils/crypto/secp256k1/secp256k1.go +++ b/utils/crypto/secp256k1/secp256k1.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1 diff --git a/utils/crypto/secp256k1/secp256k1_benchmark_test.go b/utils/crypto/secp256k1/secp256k1_benchmark_test.go index 1d55f38f7d86..ca4f98e38fb5 100644 --- a/utils/crypto/secp256k1/secp256k1_benchmark_test.go +++ b/utils/crypto/secp256k1/secp256k1_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1 diff --git a/utils/crypto/secp256k1/secp256k1_test.go b/utils/crypto/secp256k1/secp256k1_test.go index a2074dff5229..39a915b9f9b3 100644 --- a/utils/crypto/secp256k1/secp256k1_test.go +++ b/utils/crypto/secp256k1/secp256k1_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1 diff --git a/utils/crypto/secp256k1/test_keys.go b/utils/crypto/secp256k1/test_keys.go index 3122f2617ddf..4ceb567469b2 100644 --- a/utils/crypto/secp256k1/test_keys.go +++ b/utils/crypto/secp256k1/test_keys.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1 diff --git a/utils/dynamicip/ifconfig_resolver.go b/utils/dynamicip/ifconfig_resolver.go index 0bbabcb58612..36c8d5adf04c 100644 --- a/utils/dynamicip/ifconfig_resolver.go +++ b/utils/dynamicip/ifconfig_resolver.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dynamicip diff --git a/utils/dynamicip/no_updater.go b/utils/dynamicip/no_updater.go index 5c9e38bd54a1..e3e7c6155bd0 100644 --- a/utils/dynamicip/no_updater.go +++ b/utils/dynamicip/no_updater.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dynamicip diff --git a/utils/dynamicip/opendns_resolver.go b/utils/dynamicip/opendns_resolver.go index 3bda76c46404..5c39c95535fc 100644 --- a/utils/dynamicip/opendns_resolver.go +++ b/utils/dynamicip/opendns_resolver.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dynamicip diff --git a/utils/dynamicip/resolver.go b/utils/dynamicip/resolver.go index b3a341cd2121..45ad3778bc01 100644 --- a/utils/dynamicip/resolver.go +++ b/utils/dynamicip/resolver.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dynamicip diff --git a/utils/dynamicip/resolver_test.go b/utils/dynamicip/resolver_test.go index e5e53d40f9f3..6af72a98a50a 100644 --- a/utils/dynamicip/resolver_test.go +++ b/utils/dynamicip/resolver_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dynamicip diff --git a/utils/dynamicip/updater.go b/utils/dynamicip/updater.go index 87c99e6db0c5..9a59c9fd25e0 100644 --- a/utils/dynamicip/updater.go +++ b/utils/dynamicip/updater.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dynamicip diff --git a/utils/dynamicip/updater_test.go b/utils/dynamicip/updater_test.go index 98ce26b4a189..66c9a21c4c6a 100644 --- a/utils/dynamicip/updater_test.go +++ b/utils/dynamicip/updater_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package dynamicip diff --git a/utils/error.go b/utils/error.go index b58c60cd001a..0a6a9f323e03 100644 --- a/utils/error.go +++ b/utils/error.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/utils/filesystem/io.go b/utils/filesystem/io.go index 939e635a2ca9..28a0c4aa1e32 100644 --- a/utils/filesystem/io.go +++ b/utils/filesystem/io.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package filesystem diff --git a/utils/filesystem/rename.go b/utils/filesystem/rename.go index 3ab7c147d355..578c46fb6c9e 100644 --- a/utils/filesystem/rename.go +++ b/utils/filesystem/rename.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package filesystem diff --git a/utils/filesystem/rename_test.go b/utils/filesystem/rename_test.go index 305a65092727..53c8a503bcf6 100644 --- a/utils/filesystem/rename_test.go +++ b/utils/filesystem/rename_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package filesystem diff --git a/utils/formatting/address/address.go b/utils/formatting/address/address.go index 321fe692bf57..97d4e0552969 100644 --- a/utils/formatting/address/address.go +++ b/utils/formatting/address/address.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package address diff --git a/utils/formatting/address/converter.go b/utils/formatting/address/converter.go index 8a5812a5bb2c..f043ab6a3489 100644 --- a/utils/formatting/address/converter.go +++ b/utils/formatting/address/converter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package address diff --git a/utils/formatting/encoding.go b/utils/formatting/encoding.go index b80c82779810..742800fee86e 100644 --- a/utils/formatting/encoding.go +++ b/utils/formatting/encoding.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package formatting diff --git a/utils/formatting/encoding_benchmark_test.go b/utils/formatting/encoding_benchmark_test.go index 598ed39310ca..879933418e3e 100644 --- a/utils/formatting/encoding_benchmark_test.go +++ b/utils/formatting/encoding_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package formatting diff --git a/utils/formatting/encoding_test.go b/utils/formatting/encoding_test.go index 29f6c1d5df39..6623e325e9cf 100644 --- a/utils/formatting/encoding_test.go +++ b/utils/formatting/encoding_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package formatting diff --git a/utils/formatting/int_format.go b/utils/formatting/int_format.go index 6cd8c870a43d..7c26655f2aba 100644 --- a/utils/formatting/int_format.go +++ b/utils/formatting/int_format.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package formatting diff --git a/utils/formatting/int_format_test.go b/utils/formatting/int_format_test.go index febf23bca4a2..aa5dce1dc8db 100644 --- a/utils/formatting/int_format_test.go +++ b/utils/formatting/int_format_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package formatting diff --git a/utils/formatting/prefixed_stringer.go b/utils/formatting/prefixed_stringer.go index 15fe720398a8..3c82cddd88a7 100644 --- a/utils/formatting/prefixed_stringer.go +++ b/utils/formatting/prefixed_stringer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package formatting diff --git a/utils/hashing/consistent/hashable.go b/utils/hashing/consistent/hashable.go index df4a08d0ba44..a51ce4dfc817 100644 --- a/utils/hashing/consistent/hashable.go +++ b/utils/hashing/consistent/hashable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package consistent diff --git a/utils/hashing/consistent/ring.go b/utils/hashing/consistent/ring.go index 1ade42ff359f..c99dd276047f 100644 --- a/utils/hashing/consistent/ring.go +++ b/utils/hashing/consistent/ring.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package consistent diff --git a/utils/hashing/consistent/ring_test.go b/utils/hashing/consistent/ring_test.go index ec9e69098b1a..4a8f3ca5b71b 100644 --- a/utils/hashing/consistent/ring_test.go +++ b/utils/hashing/consistent/ring_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package consistent diff --git a/utils/hashing/hasher.go b/utils/hashing/hasher.go index 7519dfbb69ec..be74c160d00f 100644 --- a/utils/hashing/hasher.go +++ b/utils/hashing/hasher.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package hashing diff --git a/utils/hashing/hashing.go b/utils/hashing/hashing.go index f2c79e235a64..0d09fd457247 100644 --- a/utils/hashing/hashing.go +++ b/utils/hashing/hashing.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package hashing diff --git a/utils/heap/map.go b/utils/heap/map.go index dbe06c06446e..1162e95fd15f 100644 --- a/utils/heap/map.go +++ b/utils/heap/map.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package heap diff --git a/utils/heap/map_test.go b/utils/heap/map_test.go index cc774a5a50df..64e3e4e29132 100644 --- a/utils/heap/map_test.go +++ b/utils/heap/map_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package heap diff --git a/utils/heap/queue.go b/utils/heap/queue.go index fc3bebaa0b8d..62687635f93e 100644 --- a/utils/heap/queue.go +++ b/utils/heap/queue.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package heap diff --git a/utils/heap/queue_test.go b/utils/heap/queue_test.go index e7481eddbbe3..66e3417178bd 100644 --- a/utils/heap/queue_test.go +++ b/utils/heap/queue_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package heap diff --git a/utils/heap/set.go b/utils/heap/set.go index 15fab421b278..e1865f1e64f7 100644 --- a/utils/heap/set.go +++ b/utils/heap/set.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package heap diff --git a/utils/heap/set_test.go b/utils/heap/set_test.go index fd93f996d5ff..d475226118ee 100644 --- a/utils/heap/set_test.go +++ b/utils/heap/set_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package heap diff --git a/utils/ips/claimed_ip_port.go b/utils/ips/claimed_ip_port.go index 4ba4a6085e79..76920f31559d 100644 --- a/utils/ips/claimed_ip_port.go +++ b/utils/ips/claimed_ip_port.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ips diff --git a/utils/ips/dynamic_ip_port.go b/utils/ips/dynamic_ip_port.go index 3f30dc0a24b5..0b83ab5924f1 100644 --- a/utils/ips/dynamic_ip_port.go +++ b/utils/ips/dynamic_ip_port.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ips diff --git a/utils/ips/ip_port.go b/utils/ips/ip_port.go index 3ca5bfe176d4..661747cb9cbe 100644 --- a/utils/ips/ip_port.go +++ b/utils/ips/ip_port.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ips diff --git a/utils/ips/ip_test.go b/utils/ips/ip_test.go index 30a72017e6da..903f26a2d070 100644 --- a/utils/ips/ip_test.go +++ b/utils/ips/ip_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ips diff --git a/utils/ips/lookup.go b/utils/ips/lookup.go index 8ae3de470ff0..cdf9176f9568 100644 --- a/utils/ips/lookup.go +++ b/utils/ips/lookup.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ips diff --git a/utils/ips/lookup_test.go b/utils/ips/lookup_test.go index 52c0e5eda860..9fecccc54593 100644 --- a/utils/ips/lookup_test.go +++ b/utils/ips/lookup_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ips diff --git a/utils/json/codec.go b/utils/json/codec.go index 5871d67fd793..0bf51dcee2c2 100644 --- a/utils/json/codec.go +++ b/utils/json/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package json diff --git a/utils/json/float32.go b/utils/json/float32.go index 26694b090b68..ca35a760e3be 100644 --- a/utils/json/float32.go +++ b/utils/json/float32.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package json diff --git a/utils/json/float32_test.go b/utils/json/float32_test.go index 3d336927ced5..519ca7f4d561 100644 --- a/utils/json/float32_test.go +++ b/utils/json/float32_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package json diff --git a/utils/json/float64.go b/utils/json/float64.go index 8467fbf94745..80fb8ae738da 100644 --- a/utils/json/float64.go +++ b/utils/json/float64.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package json diff --git a/utils/json/uint16.go b/utils/json/uint16.go index ae537ab2c9fb..03e0f133d1a9 100644 --- a/utils/json/uint16.go +++ b/utils/json/uint16.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package json diff --git a/utils/json/uint32.go b/utils/json/uint32.go index c367051b2938..bae5b8857496 100644 --- a/utils/json/uint32.go +++ b/utils/json/uint32.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package json diff --git a/utils/json/uint64.go b/utils/json/uint64.go index c28229024284..60bc99887439 100644 --- a/utils/json/uint64.go +++ b/utils/json/uint64.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package json diff --git a/utils/json/uint8.go b/utils/json/uint8.go index c4a34bdb2074..da2ca5270a83 100644 --- a/utils/json/uint8.go +++ b/utils/json/uint8.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package json diff --git a/utils/linkedhashmap/iterator.go b/utils/linkedhashmap/iterator.go index 306e41e872fd..a2869aac2a54 100644 --- a/utils/linkedhashmap/iterator.go +++ b/utils/linkedhashmap/iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package linkedhashmap diff --git a/utils/linkedhashmap/linkedhashmap.go b/utils/linkedhashmap/linkedhashmap.go index fa5a123a0942..9ae5b83ad7ae 100644 --- a/utils/linkedhashmap/linkedhashmap.go +++ b/utils/linkedhashmap/linkedhashmap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package linkedhashmap diff --git a/utils/linkedhashmap/linkedhashmap_test.go b/utils/linkedhashmap/linkedhashmap_test.go index 0c95c30b24a8..372bd24baa4c 100644 --- a/utils/linkedhashmap/linkedhashmap_test.go +++ b/utils/linkedhashmap/linkedhashmap_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package linkedhashmap diff --git a/utils/logging/color.go b/utils/logging/color.go index 323d1d1373f5..8fb7a8b6a29d 100644 --- a/utils/logging/color.go +++ b/utils/logging/color.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/config.go b/utils/logging/config.go index baeb666d753f..06d7f8ca92c4 100644 --- a/utils/logging/config.go +++ b/utils/logging/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/factory.go b/utils/logging/factory.go index b3426257956f..e6bb90272282 100644 --- a/utils/logging/factory.go +++ b/utils/logging/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/format.go b/utils/logging/format.go index 5ea9de28f087..53313c3dad8f 100644 --- a/utils/logging/format.go +++ b/utils/logging/format.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/level.go b/utils/logging/level.go index 173c606c44e2..7c1696b3202f 100644 --- a/utils/logging/level.go +++ b/utils/logging/level.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/log.go b/utils/logging/log.go index a5e6c9d79a05..b9fc8f796ce7 100644 --- a/utils/logging/log.go +++ b/utils/logging/log.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/log_test.go b/utils/logging/log_test.go index c968747ba726..cd7396b6ac6a 100644 --- a/utils/logging/log_test.go +++ b/utils/logging/log_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/logger.go b/utils/logging/logger.go index 50d035e02fa8..2ca95bff104c 100644 --- a/utils/logging/logger.go +++ b/utils/logging/logger.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/sanitize.go b/utils/logging/sanitize.go index c4fdf7124fdd..18fc4021d965 100644 --- a/utils/logging/sanitize.go +++ b/utils/logging/sanitize.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/logging/test_log.go b/utils/logging/test_log.go index 7df7df276a15..a8a85dc78e07 100644 --- a/utils/logging/test_log.go +++ b/utils/logging/test_log.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package logging diff --git a/utils/math/averager.go b/utils/math/averager.go index 14147d7ef54f..8573fbc80bb7 100644 --- a/utils/math/averager.go +++ b/utils/math/averager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/math/averager_heap.go b/utils/math/averager_heap.go index 070593f0eeb8..57d046786a99 100644 --- a/utils/math/averager_heap.go +++ b/utils/math/averager_heap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/math/averager_heap_test.go b/utils/math/averager_heap_test.go index 0586eb77947e..94f160a3a388 100644 --- a/utils/math/averager_heap_test.go +++ b/utils/math/averager_heap_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/math/continuous_averager.go b/utils/math/continuous_averager.go index e60832f23a58..7bc892576b9f 100644 --- a/utils/math/continuous_averager.go +++ b/utils/math/continuous_averager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/math/continuous_averager_benchmark_test.go b/utils/math/continuous_averager_benchmark_test.go index 7a8d30a3736c..3ebee526997d 100644 --- a/utils/math/continuous_averager_benchmark_test.go +++ b/utils/math/continuous_averager_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/math/continuous_averager_test.go b/utils/math/continuous_averager_test.go index 16f0f6913b90..c169f3903066 100644 --- a/utils/math/continuous_averager_test.go +++ b/utils/math/continuous_averager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/math/meter/continuous_meter.go b/utils/math/meter/continuous_meter.go index 4bd3f000524e..378248a15027 100644 --- a/utils/math/meter/continuous_meter.go +++ b/utils/math/meter/continuous_meter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package meter diff --git a/utils/math/meter/factory.go b/utils/math/meter/factory.go index 3fe1c3bb04b4..a4d3722e8f3c 100644 --- a/utils/math/meter/factory.go +++ b/utils/math/meter/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package meter diff --git a/utils/math/meter/meter.go b/utils/math/meter/meter.go index 07c03e37017a..e9ec6782b8c6 100644 --- a/utils/math/meter/meter.go +++ b/utils/math/meter/meter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package meter diff --git a/utils/math/meter/meter_benchmark_test.go b/utils/math/meter/meter_benchmark_test.go index 65f3dcfa56e0..80ed1ad9573c 100644 --- a/utils/math/meter/meter_benchmark_test.go +++ b/utils/math/meter/meter_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package meter diff --git a/utils/math/meter/meter_test.go b/utils/math/meter/meter_test.go index 9bffb77d9d1e..cbe1bd806b61 100644 --- a/utils/math/meter/meter_test.go +++ b/utils/math/meter/meter_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package meter diff --git a/utils/math/safe_math.go b/utils/math/safe_math.go index 834547589806..8397327414a7 100644 --- a/utils/math/safe_math.go +++ b/utils/math/safe_math.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/math/safe_math_test.go b/utils/math/safe_math_test.go index b4ef771eb45e..fc89d2f7f639 100644 --- a/utils/math/safe_math_test.go +++ b/utils/math/safe_math_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/math/sync_averager.go b/utils/math/sync_averager.go index cbe8ba107f7a..92210ab4ca46 100644 --- a/utils/math/sync_averager.go +++ b/utils/math/sync_averager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package math diff --git a/utils/maybe/maybe.go b/utils/maybe/maybe.go index b4dfc7f9a452..fd50b41534c7 100644 --- a/utils/maybe/maybe.go +++ b/utils/maybe/maybe.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package maybe diff --git a/utils/maybe/maybe_test.go b/utils/maybe/maybe_test.go index 60b599000d0a..93d5fc32e85a 100644 --- a/utils/maybe/maybe_test.go +++ b/utils/maybe/maybe_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package maybe diff --git a/utils/metric/api_interceptor.go b/utils/metric/api_interceptor.go index ab8e4fd8d70c..67ae1a936742 100644 --- a/utils/metric/api_interceptor.go +++ b/utils/metric/api_interceptor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metric diff --git a/utils/metric/averager.go b/utils/metric/averager.go index da7f0aa5bd48..0f461a567ee7 100644 --- a/utils/metric/averager.go +++ b/utils/metric/averager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metric diff --git a/utils/password/hash.go b/utils/password/hash.go index 19c6f731f414..fc304bd50118 100644 --- a/utils/password/hash.go +++ b/utils/password/hash.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package password diff --git a/utils/password/hash_test.go b/utils/password/hash_test.go index c2d87a9744c4..07f56d0304f3 100644 --- a/utils/password/hash_test.go +++ b/utils/password/hash_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package password diff --git a/utils/password/password.go b/utils/password/password.go index 1efe3ac8a4f9..fa4d240eed2e 100644 --- a/utils/password/password.go +++ b/utils/password/password.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package password diff --git a/utils/password/password_test.go b/utils/password/password_test.go index 0b445fbf8545..2c4f534c857a 100644 --- a/utils/password/password_test.go +++ b/utils/password/password_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package password diff --git a/utils/perms/chmod.go b/utils/perms/chmod.go index 5b4ff4a3b02c..a5a8710b97b8 100644 --- a/utils/perms/chmod.go +++ b/utils/perms/chmod.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package perms diff --git a/utils/perms/create.go b/utils/perms/create.go index 8d91baea0683..123637e13443 100644 --- a/utils/perms/create.go +++ b/utils/perms/create.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package perms diff --git a/utils/perms/perms.go b/utils/perms/perms.go index e89dcc949984..0bb633d900f7 100644 --- a/utils/perms/perms.go +++ b/utils/perms/perms.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package perms diff --git a/utils/perms/write_file.go b/utils/perms/write_file.go index 4671c8bc66fe..f716459ab678 100644 --- a/utils/perms/write_file.go +++ b/utils/perms/write_file.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package perms diff --git a/utils/profiler/continuous.go b/utils/profiler/continuous.go index c662f172c33d..1f698395fd25 100644 --- a/utils/profiler/continuous.go +++ b/utils/profiler/continuous.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package profiler diff --git a/utils/profiler/profiler.go b/utils/profiler/profiler.go index a792b2bbf63f..00a540cc9766 100644 --- a/utils/profiler/profiler.go +++ b/utils/profiler/profiler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package profiler diff --git a/utils/profiler/profiler_test.go b/utils/profiler/profiler_test.go index 2d7d864aca62..17ae695e38c2 100644 --- a/utils/profiler/profiler_test.go +++ b/utils/profiler/profiler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package profiler diff --git a/utils/resource/metrics.go b/utils/resource/metrics.go index e20458c42fb1..3ce87ade258c 100644 --- a/utils/resource/metrics.go +++ b/utils/resource/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package resource diff --git a/utils/resource/no_usage.go b/utils/resource/no_usage.go index 8a10d11ced2a..baa42437fc11 100644 --- a/utils/resource/no_usage.go +++ b/utils/resource/no_usage.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package resource diff --git a/utils/resource/usage.go b/utils/resource/usage.go index d5a06d990c85..1eedbee04c14 100644 --- a/utils/resource/usage.go +++ b/utils/resource/usage.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package resource diff --git a/utils/resource/usage_test.go b/utils/resource/usage_test.go index 5c1df7814f6a..b0ee74ec07a1 100644 --- a/utils/resource/usage_test.go +++ b/utils/resource/usage_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package resource diff --git a/utils/rpc/json.go b/utils/rpc/json.go index 72ddb3aac8a7..9b87661ea529 100644 --- a/utils/rpc/json.go +++ b/utils/rpc/json.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpc diff --git a/utils/rpc/options.go b/utils/rpc/options.go index ce79bc25920e..79c32c72b152 100644 --- a/utils/rpc/options.go +++ b/utils/rpc/options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpc diff --git a/utils/rpc/requester.go b/utils/rpc/requester.go index 49f3ffa0ef6d..6f2e312f66da 100644 --- a/utils/rpc/requester.go +++ b/utils/rpc/requester.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpc diff --git a/utils/sampler/rand.go b/utils/sampler/rand.go index 0dc347dad659..ce62d4a90ffc 100644 --- a/utils/sampler/rand.go +++ b/utils/sampler/rand.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/rand_test.go b/utils/sampler/rand_test.go index e822d5876cbf..febffa60a4ec 100644 --- a/utils/sampler/rand_test.go +++ b/utils/sampler/rand_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/uniform.go b/utils/sampler/uniform.go index e673aefa2616..5ae9a21d8822 100644 --- a/utils/sampler/uniform.go +++ b/utils/sampler/uniform.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/uniform_benchmark_test.go b/utils/sampler/uniform_benchmark_test.go index 51d180b33db9..915fe45cc749 100644 --- a/utils/sampler/uniform_benchmark_test.go +++ b/utils/sampler/uniform_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/uniform_best.go b/utils/sampler/uniform_best.go index 69f78bd24ce8..21f7870d5bdc 100644 --- a/utils/sampler/uniform_best.go +++ b/utils/sampler/uniform_best.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/uniform_replacer.go b/utils/sampler/uniform_replacer.go index 2053c22e875a..98d3e5acbe0d 100644 --- a/utils/sampler/uniform_replacer.go +++ b/utils/sampler/uniform_replacer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/uniform_resample.go b/utils/sampler/uniform_resample.go index b2ddbdeb09df..1e48d51fa421 100644 --- a/utils/sampler/uniform_resample.go +++ b/utils/sampler/uniform_resample.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/uniform_test.go b/utils/sampler/uniform_test.go index 96aabb73be57..451a26625424 100644 --- a/utils/sampler/uniform_test.go +++ b/utils/sampler/uniform_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted.go b/utils/sampler/weighted.go index 69212d4351c2..2296da08e97a 100644 --- a/utils/sampler/weighted.go +++ b/utils/sampler/weighted.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_array.go b/utils/sampler/weighted_array.go index b2dcb593b79b..e13788422b85 100644 --- a/utils/sampler/weighted_array.go +++ b/utils/sampler/weighted_array.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_array_test.go b/utils/sampler/weighted_array_test.go index 0f44869b7dee..866a0c7d2f2c 100644 --- a/utils/sampler/weighted_array_test.go +++ b/utils/sampler/weighted_array_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_benchmark_test.go b/utils/sampler/weighted_benchmark_test.go index 22c1a5f7def7..897e001935a1 100644 --- a/utils/sampler/weighted_benchmark_test.go +++ b/utils/sampler/weighted_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_best.go b/utils/sampler/weighted_best.go index 276a9b475a9d..59bf60019144 100644 --- a/utils/sampler/weighted_best.go +++ b/utils/sampler/weighted_best.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_heap.go b/utils/sampler/weighted_heap.go index ef5a8feb6e9f..866c23893fc2 100644 --- a/utils/sampler/weighted_heap.go +++ b/utils/sampler/weighted_heap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_heap_test.go b/utils/sampler/weighted_heap_test.go index eb9ff46ab276..03aa94dfa2f9 100644 --- a/utils/sampler/weighted_heap_test.go +++ b/utils/sampler/weighted_heap_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_linear.go b/utils/sampler/weighted_linear.go index 268ba9ea2652..496613aea6dc 100644 --- a/utils/sampler/weighted_linear.go +++ b/utils/sampler/weighted_linear.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_linear_test.go b/utils/sampler/weighted_linear_test.go index 6757158ed8e6..dd86679de627 100644 --- a/utils/sampler/weighted_linear_test.go +++ b/utils/sampler/weighted_linear_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_test.go b/utils/sampler/weighted_test.go index d67d86251c69..ea08230d175a 100644 --- a/utils/sampler/weighted_test.go +++ b/utils/sampler/weighted_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_uniform.go b/utils/sampler/weighted_uniform.go index bff76ead34e4..22dbb6b5ebd5 100644 --- a/utils/sampler/weighted_uniform.go +++ b/utils/sampler/weighted_uniform.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_without_replacement.go b/utils/sampler/weighted_without_replacement.go index 2f592a783bc0..a6b619928742 100644 --- a/utils/sampler/weighted_without_replacement.go +++ b/utils/sampler/weighted_without_replacement.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_without_replacement_benchmark_test.go b/utils/sampler/weighted_without_replacement_benchmark_test.go index 03459a5e757b..58becf9d2311 100644 --- a/utils/sampler/weighted_without_replacement_benchmark_test.go +++ b/utils/sampler/weighted_without_replacement_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_without_replacement_generic.go b/utils/sampler/weighted_without_replacement_generic.go index a62185146f4c..c45d64d0b2b0 100644 --- a/utils/sampler/weighted_without_replacement_generic.go +++ b/utils/sampler/weighted_without_replacement_generic.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/sampler/weighted_without_replacement_test.go b/utils/sampler/weighted_without_replacement_test.go index 79a26075605d..48952d5cac14 100644 --- a/utils/sampler/weighted_without_replacement_test.go +++ b/utils/sampler/weighted_without_replacement_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sampler diff --git a/utils/set/bits.go b/utils/set/bits.go index 344c8dff6781..a6e74fb6c18e 100644 --- a/utils/set/bits.go +++ b/utils/set/bits.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/set/bits_64.go b/utils/set/bits_64.go index eed00afdedc6..d67c405ac922 100644 --- a/utils/set/bits_64.go +++ b/utils/set/bits_64.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/set/bits_64_test.go b/utils/set/bits_64_test.go index 87374b4f297a..b31bf9979730 100644 --- a/utils/set/bits_64_test.go +++ b/utils/set/bits_64_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/set/bits_test.go b/utils/set/bits_test.go index 5541395a5aa4..12efb343acd6 100644 --- a/utils/set/bits_test.go +++ b/utils/set/bits_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/set/sampleable_set.go b/utils/set/sampleable_set.go index 8c4c02461bd9..becd228fac43 100644 --- a/utils/set/sampleable_set.go +++ b/utils/set/sampleable_set.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/set/sampleable_set_test.go b/utils/set/sampleable_set_test.go index 5f19c13db9fe..31bd07712db5 100644 --- a/utils/set/sampleable_set_test.go +++ b/utils/set/sampleable_set_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/set/set.go b/utils/set/set.go index 41d8bb712f10..84cb5d46cd95 100644 --- a/utils/set/set.go +++ b/utils/set/set.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/set/set_benchmark_test.go b/utils/set/set_benchmark_test.go index c762b72cba01..300b8c8c0a71 100644 --- a/utils/set/set_benchmark_test.go +++ b/utils/set/set_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/set/set_test.go b/utils/set/set_test.go index 4e0a3d1fa3ed..3b0a7e1822f8 100644 --- a/utils/set/set_test.go +++ b/utils/set/set_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package set diff --git a/utils/setmap/setmap.go b/utils/setmap/setmap.go index b5d694a967c6..a2924894dac5 100644 --- a/utils/setmap/setmap.go +++ b/utils/setmap/setmap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package setmap diff --git a/utils/setmap/setmap_test.go b/utils/setmap/setmap_test.go index 7d140f5c69e2..f3e70985451f 100644 --- a/utils/setmap/setmap_test.go +++ b/utils/setmap/setmap_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package setmap diff --git a/utils/sorting.go b/utils/sorting.go index cbb982a7f63b..070375811ee3 100644 --- a/utils/sorting.go +++ b/utils/sorting.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/utils/sorting_test.go b/utils/sorting_test.go index 019834907686..632629368518 100644 --- a/utils/sorting_test.go +++ b/utils/sorting_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/utils/stacktrace.go b/utils/stacktrace.go index d68ee4ea69cf..d0e0de56dc9d 100644 --- a/utils/stacktrace.go +++ b/utils/stacktrace.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/utils/storage/storage_common.go b/utils/storage/storage_common.go index cf1fbd3b895f..6fa5692cb86a 100644 --- a/utils/storage/storage_common.go +++ b/utils/storage/storage_common.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package storage diff --git a/utils/storage/storage_unix.go b/utils/storage/storage_unix.go index ae75ed4e833f..247bc2448f36 100644 --- a/utils/storage/storage_unix.go +++ b/utils/storage/storage_unix.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build !windows diff --git a/utils/storage/storage_windows.go b/utils/storage/storage_windows.go index e9242e2d2f1e..2514717c8bea 100644 --- a/utils/storage/storage_windows.go +++ b/utils/storage/storage_windows.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build windows diff --git a/utils/timer/adaptive_timeout_manager.go b/utils/timer/adaptive_timeout_manager.go index a6d00654c064..493769018ba2 100644 --- a/utils/timer/adaptive_timeout_manager.go +++ b/utils/timer/adaptive_timeout_manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timer diff --git a/utils/timer/adaptive_timeout_manager_test.go b/utils/timer/adaptive_timeout_manager_test.go index ec9964bd5a7f..40b4186011f4 100644 --- a/utils/timer/adaptive_timeout_manager_test.go +++ b/utils/timer/adaptive_timeout_manager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timer diff --git a/utils/timer/eta.go b/utils/timer/eta.go index 490574864087..6af353fd1883 100644 --- a/utils/timer/eta.go +++ b/utils/timer/eta.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timer diff --git a/utils/timer/meter.go b/utils/timer/meter.go index c78376e1c62f..e0459e92ee2f 100644 --- a/utils/timer/meter.go +++ b/utils/timer/meter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timer diff --git a/utils/timer/mockable/clock.go b/utils/timer/mockable/clock.go index 23857a22efac..753da957ec97 100644 --- a/utils/timer/mockable/clock.go +++ b/utils/timer/mockable/clock.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package mockable diff --git a/utils/timer/mockable/clock_test.go b/utils/timer/mockable/clock_test.go index eee8922e9e58..a15e71efdcfb 100644 --- a/utils/timer/mockable/clock_test.go +++ b/utils/timer/mockable/clock_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package mockable diff --git a/utils/timer/timer.go b/utils/timer/timer.go index 1b5914fefc76..b4d3453477d9 100644 --- a/utils/timer/timer.go +++ b/utils/timer/timer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timer diff --git a/utils/timer/timer_test.go b/utils/timer/timer_test.go index 228b19f28d32..83994f963bf3 100644 --- a/utils/timer/timer_test.go +++ b/utils/timer/timer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package timer diff --git a/utils/ulimit/ulimit_bsd.go b/utils/ulimit/ulimit_bsd.go index 58204fd62a19..bb4c5e150e6c 100644 --- a/utils/ulimit/ulimit_bsd.go +++ b/utils/ulimit/ulimit_bsd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build freebsd diff --git a/utils/ulimit/ulimit_darwin.go b/utils/ulimit/ulimit_darwin.go index 9eaab72bd0f6..224d8faf056e 100644 --- a/utils/ulimit/ulimit_darwin.go +++ b/utils/ulimit/ulimit_darwin.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build darwin diff --git a/utils/ulimit/ulimit_unix.go b/utils/ulimit/ulimit_unix.go index 898b361cef92..8b23ab701b53 100644 --- a/utils/ulimit/ulimit_unix.go +++ b/utils/ulimit/ulimit_unix.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build linux || netbsd || openbsd diff --git a/utils/ulimit/ulimit_windows.go b/utils/ulimit/ulimit_windows.go index 7646d6f10d1f..82a88273735b 100644 --- a/utils/ulimit/ulimit_windows.go +++ b/utils/ulimit/ulimit_windows.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build windows diff --git a/utils/units/avax.go b/utils/units/avax.go index 341fd8bea8ad..bbd664928b33 100644 --- a/utils/units/avax.go +++ b/utils/units/avax.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package units diff --git a/utils/units/bytes.go b/utils/units/bytes.go index 93678e957a46..42d2526ae257 100644 --- a/utils/units/bytes.go +++ b/utils/units/bytes.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package units diff --git a/utils/window/window.go b/utils/window/window.go index 245941467983..86dba5b717df 100644 --- a/utils/window/window.go +++ b/utils/window/window.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package window diff --git a/utils/window/window_test.go b/utils/window/window_test.go index d8cf20f870bb..332d20b3b329 100644 --- a/utils/window/window_test.go +++ b/utils/window/window_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package window diff --git a/utils/wrappers/closers.go b/utils/wrappers/closers.go index d366e928cba0..b16e4baa2831 100644 --- a/utils/wrappers/closers.go +++ b/utils/wrappers/closers.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package wrappers diff --git a/utils/wrappers/errors.go b/utils/wrappers/errors.go index 641734da16c0..d887ffb4d20a 100644 --- a/utils/wrappers/errors.go +++ b/utils/wrappers/errors.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package wrappers diff --git a/utils/wrappers/packing.go b/utils/wrappers/packing.go index 891f80e49ab2..96d6b9999c0c 100644 --- a/utils/wrappers/packing.go +++ b/utils/wrappers/packing.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package wrappers diff --git a/utils/wrappers/packing_test.go b/utils/wrappers/packing_test.go index 2372e1ed3cfb..bb3e7fe61d38 100644 --- a/utils/wrappers/packing_test.go +++ b/utils/wrappers/packing_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package wrappers diff --git a/utils/zero.go b/utils/zero.go index 9a9173cf3403..c691ed2e653c 100644 --- a/utils/zero.go +++ b/utils/zero.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utils diff --git a/version/application.go b/version/application.go index a4956dfd78d6..2be9d838a89e 100644 --- a/version/application.go +++ b/version/application.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/application_test.go b/version/application_test.go index 09d049edcb77..deade1816e22 100644 --- a/version/application_test.go +++ b/version/application_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/compatibility.go b/version/compatibility.go index 6c3cae20778e..1cde189954a8 100644 --- a/version/compatibility.go +++ b/version/compatibility.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/compatibility_test.go b/version/compatibility_test.go index 1e4cbd03315f..09d3cdcb3336 100644 --- a/version/compatibility_test.go +++ b/version/compatibility_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/constants.go b/version/constants.go index 069868162094..053a57a4585b 100644 --- a/version/constants.go +++ b/version/constants.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/constants_test.go b/version/constants_test.go index 5e409dd91767..aea7ef493510 100644 --- a/version/constants_test.go +++ b/version/constants_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/parser.go b/version/parser.go index be4bd1a54930..abc150450099 100644 --- a/version/parser.go +++ b/version/parser.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/parser_test.go b/version/parser_test.go index 9a1175ea11b8..42adb764c9c2 100644 --- a/version/parser_test.go +++ b/version/parser_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/string.go b/version/string.go index 8d83a51d4d05..9abe555bcebb 100644 --- a/version/string.go +++ b/version/string.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/version.go b/version/version.go index 59fb9b937883..b8fe119b370c 100644 --- a/version/version.go +++ b/version/version.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/version/version_test.go b/version/version_test.go index d66c1212958c..69c494c88650 100644 --- a/version/version_test.go +++ b/version/version_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/vms/avm/block/block.go b/vms/avm/block/block.go index 331c310274e1..376062c0387e 100644 --- a/vms/avm/block/block.go +++ b/vms/avm/block/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/avm/block/block_test.go b/vms/avm/block/block_test.go index 568eef5f5851..db2e3b074b59 100644 --- a/vms/avm/block/block_test.go +++ b/vms/avm/block/block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/avm/block/builder/builder.go b/vms/avm/block/builder/builder.go index 29131f3251e7..80e734812a6c 100644 --- a/vms/avm/block/builder/builder.go +++ b/vms/avm/block/builder/builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/avm/block/builder/builder_test.go b/vms/avm/block/builder/builder_test.go index e034db41cf91..5ff59b8d66f8 100644 --- a/vms/avm/block/builder/builder_test.go +++ b/vms/avm/block/builder/builder_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/avm/block/executor/block.go b/vms/avm/block/executor/block.go index ebad27c2b67f..8663f27ba123 100644 --- a/vms/avm/block/executor/block.go +++ b/vms/avm/block/executor/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index d014b3ef499d..0b6738822c6e 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/block/executor/manager.go b/vms/avm/block/executor/manager.go index 9ffcb36c9a61..9822743b7fd3 100644 --- a/vms/avm/block/executor/manager.go +++ b/vms/avm/block/executor/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/block/executor/manager_test.go b/vms/avm/block/executor/manager_test.go index 542cf386afee..012428d582e4 100644 --- a/vms/avm/block/executor/manager_test.go +++ b/vms/avm/block/executor/manager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/block/parser.go b/vms/avm/block/parser.go index 2394ea8dec0a..bfae841093d1 100644 --- a/vms/avm/block/parser.go +++ b/vms/avm/block/parser.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/avm/block/standard_block.go b/vms/avm/block/standard_block.go index 98c676c7ea52..614c7bdc332c 100644 --- a/vms/avm/block/standard_block.go +++ b/vms/avm/block/standard_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/avm/client.go b/vms/avm/client.go index 8f9ea084c237..63df6543446e 100644 --- a/vms/avm/client.go +++ b/vms/avm/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/client_test.go b/vms/avm/client_test.go index e8013b15d115..28a2d874128a 100644 --- a/vms/avm/client_test.go +++ b/vms/avm/client_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/config.go b/vms/avm/config.go index 75f0194b15a2..f7661bbefd18 100644 --- a/vms/avm/config.go +++ b/vms/avm/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/config/config.go b/vms/avm/config/config.go index 045b4474ca67..08f6ab04240a 100644 --- a/vms/avm/config/config.go +++ b/vms/avm/config/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/vms/avm/config_test.go b/vms/avm/config_test.go index e11115028fd6..27481d78b901 100644 --- a/vms/avm/config_test.go +++ b/vms/avm/config_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index 7811807521e0..d572298dc5e5 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/factory.go b/vms/avm/factory.go index 1e2c6f68a10f..ee71cac0346f 100644 --- a/vms/avm/factory.go +++ b/vms/avm/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/fx_test.go b/vms/avm/fx_test.go index ee0cdbfd8157..7cea92cf3194 100644 --- a/vms/avm/fx_test.go +++ b/vms/avm/fx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/fxs/fx.go b/vms/avm/fxs/fx.go index 512a3bf0da31..2749ee4500a3 100644 --- a/vms/avm/fxs/fx.go +++ b/vms/avm/fxs/fx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package fxs diff --git a/vms/avm/genesis.go b/vms/avm/genesis.go index 20ed5c6ba474..b2d6e7409152 100644 --- a/vms/avm/genesis.go +++ b/vms/avm/genesis.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/genesis_test.go b/vms/avm/genesis_test.go index 8c26e2a13dae..2e5da96fc63e 100644 --- a/vms/avm/genesis_test.go +++ b/vms/avm/genesis_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/health.go b/vms/avm/health.go index 725418b1ec8f..6cb2e14b0776 100644 --- a/vms/avm/health.go +++ b/vms/avm/health.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/index_test.go b/vms/avm/index_test.go index 3a70b4a62948..03a2fd863c6a 100644 --- a/vms/avm/index_test.go +++ b/vms/avm/index_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/metrics/metrics.go b/vms/avm/metrics/metrics.go index 59c4e159a901..9e4053e1fcc6 100644 --- a/vms/avm/metrics/metrics.go +++ b/vms/avm/metrics/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/vms/avm/metrics/tx_metrics.go b/vms/avm/metrics/tx_metrics.go index 217eeb18a346..3ae3e8cdea85 100644 --- a/vms/avm/metrics/tx_metrics.go +++ b/vms/avm/metrics/tx_metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/vms/avm/network/atomic.go b/vms/avm/network/atomic.go index aaa1c5822235..0774ed36603e 100644 --- a/vms/avm/network/atomic.go +++ b/vms/avm/network/atomic.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/avm/network/config.go b/vms/avm/network/config.go index 2ff7828df2e4..8f54a20baf8a 100644 --- a/vms/avm/network/config.go +++ b/vms/avm/network/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/avm/network/gossip.go b/vms/avm/network/gossip.go index ad5d1589d25d..ef3b53d039ec 100644 --- a/vms/avm/network/gossip.go +++ b/vms/avm/network/gossip.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/avm/network/gossip_test.go b/vms/avm/network/gossip_test.go index a3922a23d812..725851e54606 100644 --- a/vms/avm/network/gossip_test.go +++ b/vms/avm/network/gossip_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index 9057ba1df346..d2920bc51af4 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index 4250a82b8bcb..b2df09eec1b2 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/avm/network/tx_verifier.go b/vms/avm/network/tx_verifier.go index fe76f0c45366..09f869283448 100644 --- a/vms/avm/network/tx_verifier.go +++ b/vms/avm/network/tx_verifier.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/avm/pubsub_filterer.go b/vms/avm/pubsub_filterer.go index 242970347901..caf0ba348393 100644 --- a/vms/avm/pubsub_filterer.go +++ b/vms/avm/pubsub_filterer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/pubsub_filterer_test.go b/vms/avm/pubsub_filterer_test.go index 95f4fc3cd229..0059b2218e39 100644 --- a/vms/avm/pubsub_filterer_test.go +++ b/vms/avm/pubsub_filterer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/service.go b/vms/avm/service.go index 7ccc26c278ed..85545546b014 100644 --- a/vms/avm/service.go +++ b/vms/avm/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index 6984d1640a53..c659b8e9de9e 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/state/diff.go b/vms/avm/state/diff.go index 1f1a98d38a96..83e9c5e0d590 100644 --- a/vms/avm/state/diff.go +++ b/vms/avm/state/diff.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/avm/state/state.go b/vms/avm/state/state.go index e290f093aa22..e85907d77a50 100644 --- a/vms/avm/state/state.go +++ b/vms/avm/state/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/avm/state/state_test.go b/vms/avm/state/state_test.go index a9d468d436bb..e0b3c8e1794b 100644 --- a/vms/avm/state/state_test.go +++ b/vms/avm/state/state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/avm/state/versions.go b/vms/avm/state/versions.go index da84182bb683..6afb0fe8e5f2 100644 --- a/vms/avm/state/versions.go +++ b/vms/avm/state/versions.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/avm/state_test.go b/vms/avm/state_test.go index 2c0d61559925..b17604b2ba62 100644 --- a/vms/avm/state_test.go +++ b/vms/avm/state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/static_client.go b/vms/avm/static_client.go index 78014785cba9..f31634313aac 100644 --- a/vms/avm/static_client.go +++ b/vms/avm/static_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/static_service.go b/vms/avm/static_service.go index 275546061354..3599a3faa2de 100644 --- a/vms/avm/static_service.go +++ b/vms/avm/static_service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/static_service_test.go b/vms/avm/static_service_test.go index a18220e5de37..d5bd645190a2 100644 --- a/vms/avm/static_service_test.go +++ b/vms/avm/static_service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/tx.go b/vms/avm/tx.go index 57afe6864d8e..13064a59a18f 100644 --- a/vms/avm/tx.go +++ b/vms/avm/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/tx_init.go b/vms/avm/tx_init.go index 1a7d29ebeb40..00112bf6dd45 100644 --- a/vms/avm/tx_init.go +++ b/vms/avm/tx_init.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/txs/base_tx.go b/vms/avm/txs/base_tx.go index 617769d343d8..5cc0d222dce3 100644 --- a/vms/avm/txs/base_tx.go +++ b/vms/avm/txs/base_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/base_tx_test.go b/vms/avm/txs/base_tx_test.go index ed1665c707fb..4dcb82e38ce7 100644 --- a/vms/avm/txs/base_tx_test.go +++ b/vms/avm/txs/base_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/codec.go b/vms/avm/txs/codec.go index 777e4562a509..2a83f7497ae0 100644 --- a/vms/avm/txs/codec.go +++ b/vms/avm/txs/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/create_asset_tx.go b/vms/avm/txs/create_asset_tx.go index 4a80d018e428..818bea5b9259 100644 --- a/vms/avm/txs/create_asset_tx.go +++ b/vms/avm/txs/create_asset_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/create_asset_tx_test.go b/vms/avm/txs/create_asset_tx_test.go index dfcfb27c1bdd..f71ca13b4de1 100644 --- a/vms/avm/txs/create_asset_tx_test.go +++ b/vms/avm/txs/create_asset_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/executor/backend.go b/vms/avm/txs/executor/backend.go index fbf4a756faec..fdb020423bdb 100644 --- a/vms/avm/txs/executor/backend.go +++ b/vms/avm/txs/executor/backend.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/txs/executor/executor.go b/vms/avm/txs/executor/executor.go index 6a5991cade04..2e7db5659dae 100644 --- a/vms/avm/txs/executor/executor.go +++ b/vms/avm/txs/executor/executor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/txs/executor/executor_test.go b/vms/avm/txs/executor/executor_test.go index 81d301ad6bae..ba5f13e836ef 100644 --- a/vms/avm/txs/executor/executor_test.go +++ b/vms/avm/txs/executor/executor_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/txs/executor/semantic_verifier.go b/vms/avm/txs/executor/semantic_verifier.go index 1fd94fb0e131..946346bc0646 100644 --- a/vms/avm/txs/executor/semantic_verifier.go +++ b/vms/avm/txs/executor/semantic_verifier.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/txs/executor/semantic_verifier_test.go b/vms/avm/txs/executor/semantic_verifier_test.go index bda0f9245631..4678d0548fb2 100644 --- a/vms/avm/txs/executor/semantic_verifier_test.go +++ b/vms/avm/txs/executor/semantic_verifier_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/txs/executor/syntactic_verifier.go b/vms/avm/txs/executor/syntactic_verifier.go index 7419b5738215..81a2f2a715f4 100644 --- a/vms/avm/txs/executor/syntactic_verifier.go +++ b/vms/avm/txs/executor/syntactic_verifier.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/txs/executor/syntactic_verifier_test.go b/vms/avm/txs/executor/syntactic_verifier_test.go index ad5e906a029e..21f2396148a0 100644 --- a/vms/avm/txs/executor/syntactic_verifier_test.go +++ b/vms/avm/txs/executor/syntactic_verifier_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/avm/txs/export_tx.go b/vms/avm/txs/export_tx.go index aec13141497d..e0be45360693 100644 --- a/vms/avm/txs/export_tx.go +++ b/vms/avm/txs/export_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/export_tx_test.go b/vms/avm/txs/export_tx_test.go index e384b8bfc327..b56ae7003e5b 100644 --- a/vms/avm/txs/export_tx_test.go +++ b/vms/avm/txs/export_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/import_tx.go b/vms/avm/txs/import_tx.go index c3066ccc5c40..5ef8929fc641 100644 --- a/vms/avm/txs/import_tx.go +++ b/vms/avm/txs/import_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/import_tx_test.go b/vms/avm/txs/import_tx_test.go index 6b94ea1c7e11..4e4b95a16447 100644 --- a/vms/avm/txs/import_tx_test.go +++ b/vms/avm/txs/import_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/initial_state.go b/vms/avm/txs/initial_state.go index 5df1bc3fd8b6..a093ead5c6b2 100644 --- a/vms/avm/txs/initial_state.go +++ b/vms/avm/txs/initial_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/initial_state_test.go b/vms/avm/txs/initial_state_test.go index 15cf6eb284e1..48c15ae196c4 100644 --- a/vms/avm/txs/initial_state_test.go +++ b/vms/avm/txs/initial_state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index 3e0dd3793560..d5030cbce648 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package mempool diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index d76caebbb2af..3a1a82484267 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package mempool diff --git a/vms/avm/txs/operation.go b/vms/avm/txs/operation.go index ded7671e618a..d37b162955c6 100644 --- a/vms/avm/txs/operation.go +++ b/vms/avm/txs/operation.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/operation_test.go b/vms/avm/txs/operation_test.go index f0dc3ec3c742..ac9cf62530c6 100644 --- a/vms/avm/txs/operation_test.go +++ b/vms/avm/txs/operation_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/operation_tx.go b/vms/avm/txs/operation_tx.go index df143af30b36..8a1b261ca2dd 100644 --- a/vms/avm/txs/operation_tx.go +++ b/vms/avm/txs/operation_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/parser.go b/vms/avm/txs/parser.go index 55722c75b9cf..6ccd34e35bd6 100644 --- a/vms/avm/txs/parser.go +++ b/vms/avm/txs/parser.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/tx.go b/vms/avm/txs/tx.go index 7b900987692a..42e845b07b15 100644 --- a/vms/avm/txs/tx.go +++ b/vms/avm/txs/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/txs/visitor.go b/vms/avm/txs/visitor.go index 8de00c1bf35c..31eccb67834d 100644 --- a/vms/avm/txs/visitor.go +++ b/vms/avm/txs/visitor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/avm/utxo/spender.go b/vms/avm/utxo/spender.go index ed57549da306..02ade0d92eae 100644 --- a/vms/avm/utxo/spender.go +++ b/vms/avm/utxo/spender.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utxo diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 2f3e05541f96..fb42158034a7 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/vm_benchmark_test.go b/vms/avm/vm_benchmark_test.go index cec505f3c2ff..713f809f7f5c 100644 --- a/vms/avm/vm_benchmark_test.go +++ b/vms/avm/vm_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/vm_regression_test.go b/vms/avm/vm_regression_test.go index 0e41c55ef92a..c6ac40df845d 100644 --- a/vms/avm/vm_regression_test.go +++ b/vms/avm/vm_regression_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index ce7c6c43ea61..d8aeaf3b8743 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/wallet_client.go b/vms/avm/wallet_client.go index c74918e6e401..69bdc06f9d74 100644 --- a/vms/avm/wallet_client.go +++ b/vms/avm/wallet_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/wallet_service.go b/vms/avm/wallet_service.go index f73c89425ebb..f10c6eee780b 100644 --- a/vms/avm/wallet_service.go +++ b/vms/avm/wallet_service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/avm/wallet_service_test.go b/vms/avm/wallet_service_test.go index 62860995d8f6..7ffdccdaaa20 100644 --- a/vms/avm/wallet_service_test.go +++ b/vms/avm/wallet_service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avm diff --git a/vms/components/avax/addresses.go b/vms/components/avax/addresses.go index 40929e22f895..a1567f75f4d6 100644 --- a/vms/components/avax/addresses.go +++ b/vms/components/avax/addresses.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/asset.go b/vms/components/avax/asset.go index 90a3eef6dff9..bc165b4d59ed 100644 --- a/vms/components/avax/asset.go +++ b/vms/components/avax/asset.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/asset_test.go b/vms/components/avax/asset_test.go index 68c371ae1b06..ccb6f5549630 100644 --- a/vms/components/avax/asset_test.go +++ b/vms/components/avax/asset_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/atomic_utxos.go b/vms/components/avax/atomic_utxos.go index 20b22420f8cb..3ac9c166ea3c 100644 --- a/vms/components/avax/atomic_utxos.go +++ b/vms/components/avax/atomic_utxos.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/base_tx.go b/vms/components/avax/base_tx.go index 2bcafa24e497..10561ae0ad52 100644 --- a/vms/components/avax/base_tx.go +++ b/vms/components/avax/base_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/flow_checker.go b/vms/components/avax/flow_checker.go index b0ed8c86e551..e02aee717e3b 100644 --- a/vms/components/avax/flow_checker.go +++ b/vms/components/avax/flow_checker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/metadata.go b/vms/components/avax/metadata.go index f03389c46937..1630484131a8 100644 --- a/vms/components/avax/metadata.go +++ b/vms/components/avax/metadata.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/metadata_test.go b/vms/components/avax/metadata_test.go index 01dada2feda7..9569e3e3a465 100644 --- a/vms/components/avax/metadata_test.go +++ b/vms/components/avax/metadata_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/state.go b/vms/components/avax/state.go index ab0d42ab080d..1a7616b2f729 100644 --- a/vms/components/avax/state.go +++ b/vms/components/avax/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/test_verifiable.go b/vms/components/avax/test_verifiable.go index 36ea7d57f8ff..8649b01eaa97 100644 --- a/vms/components/avax/test_verifiable.go +++ b/vms/components/avax/test_verifiable.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/transferables.go b/vms/components/avax/transferables.go index 44bafeef8d6c..18e3cf77542c 100644 --- a/vms/components/avax/transferables.go +++ b/vms/components/avax/transferables.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/transferables_test.go b/vms/components/avax/transferables_test.go index f0bd6332f78d..f46d580e839a 100644 --- a/vms/components/avax/transferables_test.go +++ b/vms/components/avax/transferables_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo.go b/vms/components/avax/utxo.go index afea68914b58..a11c94af80ba 100644 --- a/vms/components/avax/utxo.go +++ b/vms/components/avax/utxo.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo_fetching.go b/vms/components/avax/utxo_fetching.go index 1852513165a4..c5170f1d3123 100644 --- a/vms/components/avax/utxo_fetching.go +++ b/vms/components/avax/utxo_fetching.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo_fetching_test.go b/vms/components/avax/utxo_fetching_test.go index ad34ee9e25b1..25fe3fd91155 100644 --- a/vms/components/avax/utxo_fetching_test.go +++ b/vms/components/avax/utxo_fetching_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo_handler.go b/vms/components/avax/utxo_handler.go index 782d8592e448..c6e705affa2a 100644 --- a/vms/components/avax/utxo_handler.go +++ b/vms/components/avax/utxo_handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo_id.go b/vms/components/avax/utxo_id.go index 5b81f2f091a9..fafc940444b5 100644 --- a/vms/components/avax/utxo_id.go +++ b/vms/components/avax/utxo_id.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo_id_test.go b/vms/components/avax/utxo_id_test.go index e21ef620428b..09887c0312e9 100644 --- a/vms/components/avax/utxo_id_test.go +++ b/vms/components/avax/utxo_id_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo_state.go b/vms/components/avax/utxo_state.go index 5ff20b38dddd..9bc648a6e531 100644 --- a/vms/components/avax/utxo_state.go +++ b/vms/components/avax/utxo_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo_state_test.go b/vms/components/avax/utxo_state_test.go index e5fc8c695638..09213bfa1bc6 100644 --- a/vms/components/avax/utxo_state_test.go +++ b/vms/components/avax/utxo_state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/avax/utxo_test.go b/vms/components/avax/utxo_test.go index 7561f85da2cc..54f8360173a7 100644 --- a/vms/components/avax/utxo_test.go +++ b/vms/components/avax/utxo_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package avax diff --git a/vms/components/chain/block.go b/vms/components/chain/block.go index d03659ed16da..3966dd2005bd 100644 --- a/vms/components/chain/block.go +++ b/vms/components/chain/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chain diff --git a/vms/components/chain/state.go b/vms/components/chain/state.go index 6311e550ce6c..6ada30e73eee 100644 --- a/vms/components/chain/state.go +++ b/vms/components/chain/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chain diff --git a/vms/components/chain/state_test.go b/vms/components/chain/state_test.go index add7723e9fcf..c0583011bd75 100644 --- a/vms/components/chain/state_test.go +++ b/vms/components/chain/state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chain diff --git a/vms/components/index/index.go b/vms/components/index/index.go index a1bced563979..18bdd7337b28 100644 --- a/vms/components/index/index.go +++ b/vms/components/index/index.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package index diff --git a/vms/components/index/metrics.go b/vms/components/index/metrics.go index a38006305548..8531de6982e3 100644 --- a/vms/components/index/metrics.go +++ b/vms/components/index/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package index diff --git a/vms/components/keystore/codec.go b/vms/components/keystore/codec.go index 9739dc4328a4..6cfa131ed183 100644 --- a/vms/components/keystore/codec.go +++ b/vms/components/keystore/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/vms/components/keystore/user.go b/vms/components/keystore/user.go index 561e2f52b819..20749e5b48bf 100644 --- a/vms/components/keystore/user.go +++ b/vms/components/keystore/user.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/vms/components/keystore/user_test.go b/vms/components/keystore/user_test.go index 9f94cf03b7c6..66e331c2f655 100644 --- a/vms/components/keystore/user_test.go +++ b/vms/components/keystore/user_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package keystore diff --git a/vms/components/message/codec.go b/vms/components/message/codec.go index db47a18fc9a5..bb34ed490c4b 100644 --- a/vms/components/message/codec.go +++ b/vms/components/message/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/vms/components/message/handler.go b/vms/components/message/handler.go index afe123518164..2af2f55a3f0c 100644 --- a/vms/components/message/handler.go +++ b/vms/components/message/handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/vms/components/message/handler_test.go b/vms/components/message/handler_test.go index 489c973b68e0..bc2342838efa 100644 --- a/vms/components/message/handler_test.go +++ b/vms/components/message/handler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/vms/components/message/message.go b/vms/components/message/message.go index f0e13aab3d10..a33d4104430a 100644 --- a/vms/components/message/message.go +++ b/vms/components/message/message.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/vms/components/message/message_test.go b/vms/components/message/message_test.go index 38b5099e2b45..a4a12312cddb 100644 --- a/vms/components/message/message_test.go +++ b/vms/components/message/message_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/vms/components/message/tx.go b/vms/components/message/tx.go index 62fdb0dd54f8..4eced1818233 100644 --- a/vms/components/message/tx.go +++ b/vms/components/message/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/vms/components/message/tx_test.go b/vms/components/message/tx_test.go index 3634abb4c71f..8c52828b7977 100644 --- a/vms/components/message/tx_test.go +++ b/vms/components/message/tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package message diff --git a/vms/components/verify/subnet.go b/vms/components/verify/subnet.go index a1030164e145..ba4e65ee2bb3 100644 --- a/vms/components/verify/subnet.go +++ b/vms/components/verify/subnet.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package verify diff --git a/vms/components/verify/subnet_test.go b/vms/components/verify/subnet_test.go index 1bfc6c490350..bcffab905ed0 100644 --- a/vms/components/verify/subnet_test.go +++ b/vms/components/verify/subnet_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package verify diff --git a/vms/components/verify/verification.go b/vms/components/verify/verification.go index 566facbdf865..b712b730e8e8 100644 --- a/vms/components/verify/verification.go +++ b/vms/components/verify/verification.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package verify diff --git a/vms/components/verify/verification_test.go b/vms/components/verify/verification_test.go index 408fc2e94736..57f3b856b3a8 100644 --- a/vms/components/verify/verification_test.go +++ b/vms/components/verify/verification_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package verify diff --git a/vms/example/xsvm/api/client.go b/vms/example/xsvm/api/client.go index d8d6a94f1b4b..d9a6a711950a 100644 --- a/vms/example/xsvm/api/client.go +++ b/vms/example/xsvm/api/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package api diff --git a/vms/example/xsvm/api/server.go b/vms/example/xsvm/api/server.go index 733cf4f2cc44..dd2545e88dcf 100644 --- a/vms/example/xsvm/api/server.go +++ b/vms/example/xsvm/api/server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package api diff --git a/vms/example/xsvm/block/block.go b/vms/example/xsvm/block/block.go index fee3c801de2f..ab6b41d77f2b 100644 --- a/vms/example/xsvm/block/block.go +++ b/vms/example/xsvm/block/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/example/xsvm/block/codec.go b/vms/example/xsvm/block/codec.go index 0edbcaee5302..b4e5c811e29f 100644 --- a/vms/example/xsvm/block/codec.go +++ b/vms/example/xsvm/block/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/example/xsvm/builder/builder.go b/vms/example/xsvm/builder/builder.go index 7135985d3707..231679f5df56 100644 --- a/vms/example/xsvm/builder/builder.go +++ b/vms/example/xsvm/builder/builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/example/xsvm/chain/block.go b/vms/example/xsvm/chain/block.go index 8eb660e23c12..8ab761d515f8 100644 --- a/vms/example/xsvm/chain/block.go +++ b/vms/example/xsvm/chain/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chain diff --git a/vms/example/xsvm/chain/chain.go b/vms/example/xsvm/chain/chain.go index 954cd3729291..7fc60261d159 100644 --- a/vms/example/xsvm/chain/chain.go +++ b/vms/example/xsvm/chain/chain.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chain diff --git a/vms/example/xsvm/cmd/account/cmd.go b/vms/example/xsvm/cmd/account/cmd.go index 3436c3fea1b5..cea0b7b6a227 100644 --- a/vms/example/xsvm/cmd/account/cmd.go +++ b/vms/example/xsvm/cmd/account/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package account diff --git a/vms/example/xsvm/cmd/account/flags.go b/vms/example/xsvm/cmd/account/flags.go index 17092bbe1a21..3a9588ab2c63 100644 --- a/vms/example/xsvm/cmd/account/flags.go +++ b/vms/example/xsvm/cmd/account/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package account diff --git a/vms/example/xsvm/cmd/chain/cmd.go b/vms/example/xsvm/cmd/chain/cmd.go index a87e6911b8a8..679bdea0b9f0 100644 --- a/vms/example/xsvm/cmd/chain/cmd.go +++ b/vms/example/xsvm/cmd/chain/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package chain diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index e562c8567b06..984ff45df8b0 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package create diff --git a/vms/example/xsvm/cmd/chain/create/flags.go b/vms/example/xsvm/cmd/chain/create/flags.go index 80b1eefd67cf..d3e554659e49 100644 --- a/vms/example/xsvm/cmd/chain/create/flags.go +++ b/vms/example/xsvm/cmd/chain/create/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package create diff --git a/vms/example/xsvm/cmd/chain/genesis/cmd.go b/vms/example/xsvm/cmd/chain/genesis/cmd.go index 8ef49baa77ab..be839fced200 100644 --- a/vms/example/xsvm/cmd/chain/genesis/cmd.go +++ b/vms/example/xsvm/cmd/chain/genesis/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/vms/example/xsvm/cmd/chain/genesis/flags.go b/vms/example/xsvm/cmd/chain/genesis/flags.go index 5291327197d5..0bacf0edd29b 100644 --- a/vms/example/xsvm/cmd/chain/genesis/flags.go +++ b/vms/example/xsvm/cmd/chain/genesis/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/vms/example/xsvm/cmd/issue/cmd.go b/vms/example/xsvm/cmd/issue/cmd.go index e973efc31d5b..12c156d06628 100644 --- a/vms/example/xsvm/cmd/issue/cmd.go +++ b/vms/example/xsvm/cmd/issue/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package issue diff --git a/vms/example/xsvm/cmd/issue/export/cmd.go b/vms/example/xsvm/cmd/issue/export/cmd.go index c0a8cd11008c..efde479971cc 100644 --- a/vms/example/xsvm/cmd/issue/export/cmd.go +++ b/vms/example/xsvm/cmd/issue/export/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package export diff --git a/vms/example/xsvm/cmd/issue/export/flags.go b/vms/example/xsvm/cmd/issue/export/flags.go index f14c21ef8f6f..6d7f4e49a233 100644 --- a/vms/example/xsvm/cmd/issue/export/flags.go +++ b/vms/example/xsvm/cmd/issue/export/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package export diff --git a/vms/example/xsvm/cmd/issue/importtx/cmd.go b/vms/example/xsvm/cmd/issue/importtx/cmd.go index 2c8fbb7edb27..5bf104212ef6 100644 --- a/vms/example/xsvm/cmd/issue/importtx/cmd.go +++ b/vms/example/xsvm/cmd/issue/importtx/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package importtx diff --git a/vms/example/xsvm/cmd/issue/importtx/flags.go b/vms/example/xsvm/cmd/issue/importtx/flags.go index 486dfa1a05ea..15b968775fcc 100644 --- a/vms/example/xsvm/cmd/issue/importtx/flags.go +++ b/vms/example/xsvm/cmd/issue/importtx/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package importtx diff --git a/vms/example/xsvm/cmd/issue/transfer/cmd.go b/vms/example/xsvm/cmd/issue/transfer/cmd.go index 5dd15bc4ea26..86c47032a6c0 100644 --- a/vms/example/xsvm/cmd/issue/transfer/cmd.go +++ b/vms/example/xsvm/cmd/issue/transfer/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package transfer diff --git a/vms/example/xsvm/cmd/issue/transfer/flags.go b/vms/example/xsvm/cmd/issue/transfer/flags.go index 5d4667b47458..043c07243e54 100644 --- a/vms/example/xsvm/cmd/issue/transfer/flags.go +++ b/vms/example/xsvm/cmd/issue/transfer/flags.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package transfer diff --git a/vms/example/xsvm/cmd/run/cmd.go b/vms/example/xsvm/cmd/run/cmd.go index 9776b15eb3a7..eace7e85d7ed 100644 --- a/vms/example/xsvm/cmd/run/cmd.go +++ b/vms/example/xsvm/cmd/run/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package run diff --git a/vms/example/xsvm/cmd/version/cmd.go b/vms/example/xsvm/cmd/version/cmd.go index 0827a9e800b7..1c956c6a9b00 100644 --- a/vms/example/xsvm/cmd/version/cmd.go +++ b/vms/example/xsvm/cmd/version/cmd.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package version diff --git a/vms/example/xsvm/cmd/xsvm/main.go b/vms/example/xsvm/cmd/xsvm/main.go index ac370a4a9df2..c6961a8c1741 100644 --- a/vms/example/xsvm/cmd/xsvm/main.go +++ b/vms/example/xsvm/cmd/xsvm/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/vms/example/xsvm/constants.go b/vms/example/xsvm/constants.go index e4b22b742450..eb2199211ef7 100644 --- a/vms/example/xsvm/constants.go +++ b/vms/example/xsvm/constants.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package xsvm diff --git a/vms/example/xsvm/execute/block.go b/vms/example/xsvm/execute/block.go index 3d51c64abaa2..b2938a58f5e8 100644 --- a/vms/example/xsvm/execute/block.go +++ b/vms/example/xsvm/execute/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package execute diff --git a/vms/example/xsvm/execute/expects_context.go b/vms/example/xsvm/execute/expects_context.go index 0109cadc3731..da21b520f314 100644 --- a/vms/example/xsvm/execute/expects_context.go +++ b/vms/example/xsvm/execute/expects_context.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package execute diff --git a/vms/example/xsvm/execute/genesis.go b/vms/example/xsvm/execute/genesis.go index c0a44e2ef6bb..889432d38256 100644 --- a/vms/example/xsvm/execute/genesis.go +++ b/vms/example/xsvm/execute/genesis.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package execute diff --git a/vms/example/xsvm/execute/tx.go b/vms/example/xsvm/execute/tx.go index 01bfc1fb7d6d..f3f6ad504de4 100644 --- a/vms/example/xsvm/execute/tx.go +++ b/vms/example/xsvm/execute/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package execute diff --git a/vms/example/xsvm/factory.go b/vms/example/xsvm/factory.go index 0531a1bcc7d0..99d33b8290d1 100644 --- a/vms/example/xsvm/factory.go +++ b/vms/example/xsvm/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package xsvm diff --git a/vms/example/xsvm/genesis/codec.go b/vms/example/xsvm/genesis/codec.go index 3533e29a0188..c0851cccf146 100644 --- a/vms/example/xsvm/genesis/codec.go +++ b/vms/example/xsvm/genesis/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/vms/example/xsvm/genesis/genesis.go b/vms/example/xsvm/genesis/genesis.go index fddc96716bd6..0fb420f3a4da 100644 --- a/vms/example/xsvm/genesis/genesis.go +++ b/vms/example/xsvm/genesis/genesis.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/vms/example/xsvm/genesis/genesis_test.go b/vms/example/xsvm/genesis/genesis_test.go index f15e72ecc743..ba050d12f801 100644 --- a/vms/example/xsvm/genesis/genesis_test.go +++ b/vms/example/xsvm/genesis/genesis_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/vms/example/xsvm/state/keys.go b/vms/example/xsvm/state/keys.go index 5e78f1b95a0e..e0df1e36cdc0 100644 --- a/vms/example/xsvm/state/keys.go +++ b/vms/example/xsvm/state/keys.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/example/xsvm/state/storage.go b/vms/example/xsvm/state/storage.go index c9b6bf1ae65d..48234e9678de 100644 --- a/vms/example/xsvm/state/storage.go +++ b/vms/example/xsvm/state/storage.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/example/xsvm/tx/codec.go b/vms/example/xsvm/tx/codec.go index 1f8b8fc9dd0e..c15150c4b37f 100644 --- a/vms/example/xsvm/tx/codec.go +++ b/vms/example/xsvm/tx/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tx diff --git a/vms/example/xsvm/tx/export.go b/vms/example/xsvm/tx/export.go index 1192952c4dca..d8de16a69e7e 100644 --- a/vms/example/xsvm/tx/export.go +++ b/vms/example/xsvm/tx/export.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tx diff --git a/vms/example/xsvm/tx/import.go b/vms/example/xsvm/tx/import.go index 8449c79c55b2..ff98b0a01aa2 100644 --- a/vms/example/xsvm/tx/import.go +++ b/vms/example/xsvm/tx/import.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tx diff --git a/vms/example/xsvm/tx/payload.go b/vms/example/xsvm/tx/payload.go index 0d1671535c9d..eecc2f082d11 100644 --- a/vms/example/xsvm/tx/payload.go +++ b/vms/example/xsvm/tx/payload.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tx diff --git a/vms/example/xsvm/tx/transfer.go b/vms/example/xsvm/tx/transfer.go index c895b5e5cc51..a3d29c1432c9 100644 --- a/vms/example/xsvm/tx/transfer.go +++ b/vms/example/xsvm/tx/transfer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tx diff --git a/vms/example/xsvm/tx/tx.go b/vms/example/xsvm/tx/tx.go index 05beec274cb4..8b05d5375b27 100644 --- a/vms/example/xsvm/tx/tx.go +++ b/vms/example/xsvm/tx/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tx diff --git a/vms/example/xsvm/tx/unsigned.go b/vms/example/xsvm/tx/unsigned.go index 2c57f91e26fb..110611412b59 100644 --- a/vms/example/xsvm/tx/unsigned.go +++ b/vms/example/xsvm/tx/unsigned.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tx diff --git a/vms/example/xsvm/tx/visitor.go b/vms/example/xsvm/tx/visitor.go index b411e06f15b0..045b03247479 100644 --- a/vms/example/xsvm/tx/visitor.go +++ b/vms/example/xsvm/tx/visitor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tx diff --git a/vms/example/xsvm/vm.go b/vms/example/xsvm/vm.go index 3150fc59b481..b69360f838d7 100644 --- a/vms/example/xsvm/vm.go +++ b/vms/example/xsvm/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package xsvm diff --git a/vms/manager.go b/vms/manager.go index d1041d3a4693..f4ae49e39cd0 100644 --- a/vms/manager.go +++ b/vms/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package vms diff --git a/vms/metervm/batched_vm.go b/vms/metervm/batched_vm.go index dad17637a918..7b06f0989b89 100644 --- a/vms/metervm/batched_vm.go +++ b/vms/metervm/batched_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/metervm/block.go b/vms/metervm/block.go index 17ffffd5f549..10d44d2c41b6 100644 --- a/vms/metervm/block.go +++ b/vms/metervm/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/metervm/block_metrics.go b/vms/metervm/block_metrics.go index 094e41875aac..160d0eee50ad 100644 --- a/vms/metervm/block_metrics.go +++ b/vms/metervm/block_metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/metervm/block_vm.go b/vms/metervm/block_vm.go index 8f9fee1e247d..73e949180a96 100644 --- a/vms/metervm/block_vm.go +++ b/vms/metervm/block_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/metervm/build_block_with_context_vm.go b/vms/metervm/build_block_with_context_vm.go index 141d68e0ceac..012237ee3178 100644 --- a/vms/metervm/build_block_with_context_vm.go +++ b/vms/metervm/build_block_with_context_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/metervm/metrics.go b/vms/metervm/metrics.go index eb2c2b40736b..f79c5e38e029 100644 --- a/vms/metervm/metrics.go +++ b/vms/metervm/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/metervm/state_syncable_vm.go b/vms/metervm/state_syncable_vm.go index bcb27d682b08..42b5efa8a79e 100644 --- a/vms/metervm/state_syncable_vm.go +++ b/vms/metervm/state_syncable_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/metervm/vertex_metrics.go b/vms/metervm/vertex_metrics.go index 2a4b0a506151..67caa50b610e 100644 --- a/vms/metervm/vertex_metrics.go +++ b/vms/metervm/vertex_metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/metervm/vertex_vm.go b/vms/metervm/vertex_vm.go index 827bb535fcbd..8992b4863283 100644 --- a/vms/metervm/vertex_vm.go +++ b/vms/metervm/vertex_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metervm diff --git a/vms/nftfx/credential.go b/vms/nftfx/credential.go index 64af78587282..a8970b854b1a 100644 --- a/vms/nftfx/credential.go +++ b/vms/nftfx/credential.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/credential_test.go b/vms/nftfx/credential_test.go index c1e83ccab00e..0f05af26a738 100644 --- a/vms/nftfx/credential_test.go +++ b/vms/nftfx/credential_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/factory.go b/vms/nftfx/factory.go index e52d629fe670..a111bc0ed7e2 100644 --- a/vms/nftfx/factory.go +++ b/vms/nftfx/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/factory_test.go b/vms/nftfx/factory_test.go index 10581c8db922..6b4fba9861ac 100644 --- a/vms/nftfx/factory_test.go +++ b/vms/nftfx/factory_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/fx.go b/vms/nftfx/fx.go index f56ffcc10e5d..66ea9460b56b 100644 --- a/vms/nftfx/fx.go +++ b/vms/nftfx/fx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/fx_test.go b/vms/nftfx/fx_test.go index d054d680c305..99a047b11328 100644 --- a/vms/nftfx/fx_test.go +++ b/vms/nftfx/fx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/mint_operation.go b/vms/nftfx/mint_operation.go index 2d1c5bbb5d98..bb01ee52ed23 100644 --- a/vms/nftfx/mint_operation.go +++ b/vms/nftfx/mint_operation.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/mint_operation_test.go b/vms/nftfx/mint_operation_test.go index 4dc1ce2a3eb6..ff397e9a07a3 100644 --- a/vms/nftfx/mint_operation_test.go +++ b/vms/nftfx/mint_operation_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/mint_output.go b/vms/nftfx/mint_output.go index 4c2f53698307..e3a974379a16 100644 --- a/vms/nftfx/mint_output.go +++ b/vms/nftfx/mint_output.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/mint_output_test.go b/vms/nftfx/mint_output_test.go index 583f211f972f..9589fc17f75b 100644 --- a/vms/nftfx/mint_output_test.go +++ b/vms/nftfx/mint_output_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/transfer_operation.go b/vms/nftfx/transfer_operation.go index 010d43890f62..014cd900eca7 100644 --- a/vms/nftfx/transfer_operation.go +++ b/vms/nftfx/transfer_operation.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/transfer_operation_test.go b/vms/nftfx/transfer_operation_test.go index ad896b14ee7d..b8892aec63bd 100644 --- a/vms/nftfx/transfer_operation_test.go +++ b/vms/nftfx/transfer_operation_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/transfer_output.go b/vms/nftfx/transfer_output.go index c87d47984e39..e849e1c462e5 100644 --- a/vms/nftfx/transfer_output.go +++ b/vms/nftfx/transfer_output.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/nftfx/transfer_output_test.go b/vms/nftfx/transfer_output_test.go index 330723144106..0effa6c393a7 100644 --- a/vms/nftfx/transfer_output_test.go +++ b/vms/nftfx/transfer_output_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package nftfx diff --git a/vms/platformvm/api/static_client.go b/vms/platformvm/api/static_client.go index 9dea36664592..c10943fe19d9 100644 --- a/vms/platformvm/api/static_client.go +++ b/vms/platformvm/api/static_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package api diff --git a/vms/platformvm/api/static_service.go b/vms/platformvm/api/static_service.go index dea7ce656aa9..bd6e32d250a1 100644 --- a/vms/platformvm/api/static_service.go +++ b/vms/platformvm/api/static_service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package api diff --git a/vms/platformvm/api/static_service_test.go b/vms/platformvm/api/static_service_test.go index 402a5fc7c766..a0e62fa9a31f 100644 --- a/vms/platformvm/api/static_service_test.go +++ b/vms/platformvm/api/static_service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package api diff --git a/vms/platformvm/block/abort_block.go b/vms/platformvm/block/abort_block.go index 27f2ad25a356..ace8087fd385 100644 --- a/vms/platformvm/block/abort_block.go +++ b/vms/platformvm/block/abort_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/abort_block_test.go b/vms/platformvm/block/abort_block_test.go index 149067aab8e4..a6517cef0137 100644 --- a/vms/platformvm/block/abort_block_test.go +++ b/vms/platformvm/block/abort_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/atomic_block.go b/vms/platformvm/block/atomic_block.go index 470abcbe4674..35deda80c0b5 100644 --- a/vms/platformvm/block/atomic_block.go +++ b/vms/platformvm/block/atomic_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/atomic_block_test.go b/vms/platformvm/block/atomic_block_test.go index 7436a0c24153..d81310184f23 100644 --- a/vms/platformvm/block/atomic_block_test.go +++ b/vms/platformvm/block/atomic_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/block.go b/vms/platformvm/block/block.go index dd9c61e4ce9c..30be125b8b43 100644 --- a/vms/platformvm/block/block.go +++ b/vms/platformvm/block/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 34f9a74e7f37..09e99ba9ac3e 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/platformvm/block/builder/builder_test.go b/vms/platformvm/block/builder/builder_test.go index bba4acbd8832..0dc804ff810d 100644 --- a/vms/platformvm/block/builder/builder_test.go +++ b/vms/platformvm/block/builder/builder_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 6c0c5d6fe16d..7918411b3944 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/platformvm/block/builder/main_test.go b/vms/platformvm/block/builder/main_test.go index 01135c523738..31149bfbcca8 100644 --- a/vms/platformvm/block/builder/main_test.go +++ b/vms/platformvm/block/builder/main_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/platformvm/block/builder/standard_block_test.go b/vms/platformvm/block/builder/standard_block_test.go index 8e94a0791fbd..61dd0d5e2ca1 100644 --- a/vms/platformvm/block/builder/standard_block_test.go +++ b/vms/platformvm/block/builder/standard_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/platformvm/block/codec.go b/vms/platformvm/block/codec.go index 7a730e2720de..b7338ea98a03 100644 --- a/vms/platformvm/block/codec.go +++ b/vms/platformvm/block/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/commit_block.go b/vms/platformvm/block/commit_block.go index 52b260f0f167..ac6dbb1ed88f 100644 --- a/vms/platformvm/block/commit_block.go +++ b/vms/platformvm/block/commit_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/commit_block_test.go b/vms/platformvm/block/commit_block_test.go index 256af6539c96..f89489d521a1 100644 --- a/vms/platformvm/block/commit_block_test.go +++ b/vms/platformvm/block/commit_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/common_block.go b/vms/platformvm/block/common_block.go index 899fd57b7fcb..f4b46b816b87 100644 --- a/vms/platformvm/block/common_block.go +++ b/vms/platformvm/block/common_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/executor/acceptor.go b/vms/platformvm/block/executor/acceptor.go index af26c931d088..8ee4f6e4a04f 100644 --- a/vms/platformvm/block/executor/acceptor.go +++ b/vms/platformvm/block/executor/acceptor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/acceptor_test.go b/vms/platformvm/block/executor/acceptor_test.go index 210d5d810577..fb5fcd5f88af 100644 --- a/vms/platformvm/block/executor/acceptor_test.go +++ b/vms/platformvm/block/executor/acceptor_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/backend.go b/vms/platformvm/block/executor/backend.go index 4d915047f560..c4e56545634d 100644 --- a/vms/platformvm/block/executor/backend.go +++ b/vms/platformvm/block/executor/backend.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/backend_test.go b/vms/platformvm/block/executor/backend_test.go index ce6744369593..19ad55c36d81 100644 --- a/vms/platformvm/block/executor/backend_test.go +++ b/vms/platformvm/block/executor/backend_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/block.go b/vms/platformvm/block/executor/block.go index 733825412008..ef05f38442c5 100644 --- a/vms/platformvm/block/executor/block.go +++ b/vms/platformvm/block/executor/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/block_state.go b/vms/platformvm/block/executor/block_state.go index abec214ae244..ffc6f679b8f6 100644 --- a/vms/platformvm/block/executor/block_state.go +++ b/vms/platformvm/block/executor/block_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/block_test.go b/vms/platformvm/block/executor/block_test.go index 7153ff52d3cf..b1d73cefb7f1 100644 --- a/vms/platformvm/block/executor/block_test.go +++ b/vms/platformvm/block/executor/block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 1d7d58217b15..67ace707bd5a 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/manager.go b/vms/platformvm/block/executor/manager.go index 0f8309020f6d..ed82197a3568 100644 --- a/vms/platformvm/block/executor/manager.go +++ b/vms/platformvm/block/executor/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/manager_test.go b/vms/platformvm/block/executor/manager_test.go index ce887d987992..55cf01d7c8ab 100644 --- a/vms/platformvm/block/executor/manager_test.go +++ b/vms/platformvm/block/executor/manager_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/options.go b/vms/platformvm/block/executor/options.go index 29a1d02922bd..a8ccea315b0f 100644 --- a/vms/platformvm/block/executor/options.go +++ b/vms/platformvm/block/executor/options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/options_test.go b/vms/platformvm/block/executor/options_test.go index bf8e6e3e67b6..54bef77919b7 100644 --- a/vms/platformvm/block/executor/options_test.go +++ b/vms/platformvm/block/executor/options_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index 45f4afe7c9e6..549a3fbe25df 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/rejector.go b/vms/platformvm/block/executor/rejector.go index 6b2565288fca..b5dde1f6e84c 100644 --- a/vms/platformvm/block/executor/rejector.go +++ b/vms/platformvm/block/executor/rejector.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/rejector_test.go b/vms/platformvm/block/executor/rejector_test.go index 5e06a885fd5e..4391ed3d494c 100644 --- a/vms/platformvm/block/executor/rejector_test.go +++ b/vms/platformvm/block/executor/rejector_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 7731d450a533..435ee6618af0 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index f16816d81db7..2af7cb20912a 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/executor/verifier_test.go b/vms/platformvm/block/executor/verifier_test.go index 6d4e32e0bee5..ccac3da3b7e3 100644 --- a/vms/platformvm/block/executor/verifier_test.go +++ b/vms/platformvm/block/executor/verifier_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/block/parse.go b/vms/platformvm/block/parse.go index 1a97dca2e4fd..e667907947e4 100644 --- a/vms/platformvm/block/parse.go +++ b/vms/platformvm/block/parse.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/parse_test.go b/vms/platformvm/block/parse_test.go index 799310aa2f51..d21ae9da9409 100644 --- a/vms/platformvm/block/parse_test.go +++ b/vms/platformvm/block/parse_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/proposal_block.go b/vms/platformvm/block/proposal_block.go index 719bc3a1825a..4160db57c4a9 100644 --- a/vms/platformvm/block/proposal_block.go +++ b/vms/platformvm/block/proposal_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/proposal_block_test.go b/vms/platformvm/block/proposal_block_test.go index bdb65e4a2404..7fbc44191f41 100644 --- a/vms/platformvm/block/proposal_block_test.go +++ b/vms/platformvm/block/proposal_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/serialization_test.go b/vms/platformvm/block/serialization_test.go index 2d936d35e00e..8e2002c3636c 100644 --- a/vms/platformvm/block/serialization_test.go +++ b/vms/platformvm/block/serialization_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/standard_block.go b/vms/platformvm/block/standard_block.go index cff20c92369b..c7d35b12f70d 100644 --- a/vms/platformvm/block/standard_block.go +++ b/vms/platformvm/block/standard_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/standard_block_test.go b/vms/platformvm/block/standard_block_test.go index d417a37fb96a..4162aadb05e1 100644 --- a/vms/platformvm/block/standard_block_test.go +++ b/vms/platformvm/block/standard_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/block/visitor.go b/vms/platformvm/block/visitor.go index f05dc5d05129..6c27b5386c1a 100644 --- a/vms/platformvm/block/visitor.go +++ b/vms/platformvm/block/visitor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/platformvm/client.go b/vms/platformvm/client.go index 3796ad7ff86a..9311fd290a7e 100644 --- a/vms/platformvm/client.go +++ b/vms/platformvm/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/client_permissionless_validator.go b/vms/platformvm/client_permissionless_validator.go index c9baac856073..3974f770658d 100644 --- a/vms/platformvm/client_permissionless_validator.go +++ b/vms/platformvm/client_permissionless_validator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/config/config.go b/vms/platformvm/config/config.go index f9504708f78a..50628c422afd 100644 --- a/vms/platformvm/config/config.go +++ b/vms/platformvm/config/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/vms/platformvm/config/execution_config.go b/vms/platformvm/config/execution_config.go index b21aae48e8e4..e182758e0c50 100644 --- a/vms/platformvm/config/execution_config.go +++ b/vms/platformvm/config/execution_config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/vms/platformvm/config/execution_config_test.go b/vms/platformvm/config/execution_config_test.go index 1680058819ae..89fd5cd55b05 100644 --- a/vms/platformvm/config/execution_config_test.go +++ b/vms/platformvm/config/execution_config_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package config diff --git a/vms/platformvm/factory.go b/vms/platformvm/factory.go index 5673bebefd97..834c9c8f2450 100644 --- a/vms/platformvm/factory.go +++ b/vms/platformvm/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/fx/fx.go b/vms/platformvm/fx/fx.go index 706d86debfcd..4f6eceea5f7a 100644 --- a/vms/platformvm/fx/fx.go +++ b/vms/platformvm/fx/fx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package fx diff --git a/vms/platformvm/genesis/codec.go b/vms/platformvm/genesis/codec.go index f8cbe110bf07..b18c40d60cca 100644 --- a/vms/platformvm/genesis/codec.go +++ b/vms/platformvm/genesis/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/vms/platformvm/genesis/genesis.go b/vms/platformvm/genesis/genesis.go index 4b573b723e3f..795e73cbefa6 100644 --- a/vms/platformvm/genesis/genesis.go +++ b/vms/platformvm/genesis/genesis.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package genesis diff --git a/vms/platformvm/health.go b/vms/platformvm/health.go index 4ceed8f84adc..86c80b807b70 100644 --- a/vms/platformvm/health.go +++ b/vms/platformvm/health.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/main_test.go b/vms/platformvm/main_test.go index 88a571cfa5cb..d353d31664fe 100644 --- a/vms/platformvm/main_test.go +++ b/vms/platformvm/main_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/metrics/block_metrics.go b/vms/platformvm/metrics/block_metrics.go index 7b3a9b2abf6c..193369cbf901 100644 --- a/vms/platformvm/metrics/block_metrics.go +++ b/vms/platformvm/metrics/block_metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/vms/platformvm/metrics/metrics.go b/vms/platformvm/metrics/metrics.go index 7c0e616dd9b2..5357721d9bd6 100644 --- a/vms/platformvm/metrics/metrics.go +++ b/vms/platformvm/metrics/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/vms/platformvm/metrics/no_op.go b/vms/platformvm/metrics/no_op.go index 45100b49bbf5..770e30c961a1 100644 --- a/vms/platformvm/metrics/no_op.go +++ b/vms/platformvm/metrics/no_op.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/vms/platformvm/metrics/tx_metrics.go b/vms/platformvm/metrics/tx_metrics.go index 9ed07bce7ec9..f56c84aac176 100644 --- a/vms/platformvm/metrics/tx_metrics.go +++ b/vms/platformvm/metrics/tx_metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package metrics diff --git a/vms/platformvm/network/config.go b/vms/platformvm/network/config.go index 2ff7828df2e4..8f54a20baf8a 100644 --- a/vms/platformvm/network/config.go +++ b/vms/platformvm/network/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/platformvm/network/gossip.go b/vms/platformvm/network/gossip.go index 5c12ee7a83bc..b2f409c75626 100644 --- a/vms/platformvm/network/gossip.go +++ b/vms/platformvm/network/gossip.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/platformvm/network/gossip_test.go b/vms/platformvm/network/gossip_test.go index 9c3fff9b5ff9..a51c86872297 100644 --- a/vms/platformvm/network/gossip_test.go +++ b/vms/platformvm/network/gossip_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/platformvm/network/main_test.go b/vms/platformvm/network/main_test.go index be0fab18f587..ed2cfd9ecee7 100644 --- a/vms/platformvm/network/main_test.go +++ b/vms/platformvm/network/main_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index 58fb0ec156eb..6844654a41c1 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go index 32e224d971e1..5bb735395767 100644 --- a/vms/platformvm/network/network_test.go +++ b/vms/platformvm/network/network_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/platformvm/network/tx_verifier.go b/vms/platformvm/network/tx_verifier.go index 262171d06848..ee76c8b0056b 100644 --- a/vms/platformvm/network/tx_verifier.go +++ b/vms/platformvm/network/tx_verifier.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/vms/platformvm/reward/calculator.go b/vms/platformvm/reward/calculator.go index 30ba7c3270d7..79a845ef8980 100644 --- a/vms/platformvm/reward/calculator.go +++ b/vms/platformvm/reward/calculator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package reward diff --git a/vms/platformvm/reward/calculator_test.go b/vms/platformvm/reward/calculator_test.go index 1462bd2e3664..d2fd17ff9e2b 100644 --- a/vms/platformvm/reward/calculator_test.go +++ b/vms/platformvm/reward/calculator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package reward diff --git a/vms/platformvm/reward/config.go b/vms/platformvm/reward/config.go index 17a0a0d0e83b..ccabc398f83a 100644 --- a/vms/platformvm/reward/config.go +++ b/vms/platformvm/reward/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package reward diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index 8326f0fbff8b..16e5b16844c6 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/service_test.go b/vms/platformvm/service_test.go index d80aeb5726b2..2c6b72255c3f 100644 --- a/vms/platformvm/service_test.go +++ b/vms/platformvm/service_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/signer/empty.go b/vms/platformvm/signer/empty.go index 7b5dec06cbcf..21412ae6d0b1 100644 --- a/vms/platformvm/signer/empty.go +++ b/vms/platformvm/signer/empty.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package signer diff --git a/vms/platformvm/signer/empty_test.go b/vms/platformvm/signer/empty_test.go index e6a6307b9842..9fe949f4677d 100644 --- a/vms/platformvm/signer/empty_test.go +++ b/vms/platformvm/signer/empty_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package signer diff --git a/vms/platformvm/signer/proof_of_possession.go b/vms/platformvm/signer/proof_of_possession.go index 35ddcb320745..8b32975b4969 100644 --- a/vms/platformvm/signer/proof_of_possession.go +++ b/vms/platformvm/signer/proof_of_possession.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package signer diff --git a/vms/platformvm/signer/proof_of_possession_test.go b/vms/platformvm/signer/proof_of_possession_test.go index 8214554cebfe..9f4f3feefa3c 100644 --- a/vms/platformvm/signer/proof_of_possession_test.go +++ b/vms/platformvm/signer/proof_of_possession_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package signer diff --git a/vms/platformvm/signer/signer.go b/vms/platformvm/signer/signer.go index 7269ad199534..31bf212ddca6 100644 --- a/vms/platformvm/signer/signer.go +++ b/vms/platformvm/signer/signer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package signer diff --git a/vms/platformvm/stakeable/stakeable_lock.go b/vms/platformvm/stakeable/stakeable_lock.go index 5c09cbfdda8a..58149266175e 100644 --- a/vms/platformvm/stakeable/stakeable_lock.go +++ b/vms/platformvm/stakeable/stakeable_lock.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package stakeable diff --git a/vms/platformvm/stakeable/stakeable_lock_test.go b/vms/platformvm/stakeable/stakeable_lock_test.go index b733aa0244c5..0ea53e9cc426 100644 --- a/vms/platformvm/stakeable/stakeable_lock_test.go +++ b/vms/platformvm/stakeable/stakeable_lock_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package stakeable diff --git a/vms/platformvm/state/diff.go b/vms/platformvm/state/diff.go index bb308c9c28e2..907c3c56ef7d 100644 --- a/vms/platformvm/state/diff.go +++ b/vms/platformvm/state/diff.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/diff_test.go b/vms/platformvm/state/diff_test.go index e9eecdb182cb..c4698603855e 100644 --- a/vms/platformvm/state/diff_test.go +++ b/vms/platformvm/state/diff_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/disk_staker_diff_iterator.go b/vms/platformvm/state/disk_staker_diff_iterator.go index efac5ec7b6d7..1c6e88338724 100644 --- a/vms/platformvm/state/disk_staker_diff_iterator.go +++ b/vms/platformvm/state/disk_staker_diff_iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/disk_staker_diff_iterator_test.go b/vms/platformvm/state/disk_staker_diff_iterator_test.go index 543f42a4b9c3..af719e7a0beb 100644 --- a/vms/platformvm/state/disk_staker_diff_iterator_test.go +++ b/vms/platformvm/state/disk_staker_diff_iterator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/empty_iterator.go b/vms/platformvm/state/empty_iterator.go index 69766c194fce..3ec5f04f82a9 100644 --- a/vms/platformvm/state/empty_iterator.go +++ b/vms/platformvm/state/empty_iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/empty_iterator_test.go b/vms/platformvm/state/empty_iterator_test.go index b5bb43d1f640..19cd4f06dc06 100644 --- a/vms/platformvm/state/empty_iterator_test.go +++ b/vms/platformvm/state/empty_iterator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/masked_iterator.go b/vms/platformvm/state/masked_iterator.go index 8551a05889f6..9ceee9712b40 100644 --- a/vms/platformvm/state/masked_iterator.go +++ b/vms/platformvm/state/masked_iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/masked_iterator_test.go b/vms/platformvm/state/masked_iterator_test.go index 8ba719d3e732..ccc37d6ffb3d 100644 --- a/vms/platformvm/state/masked_iterator_test.go +++ b/vms/platformvm/state/masked_iterator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/merged_iterator.go b/vms/platformvm/state/merged_iterator.go index 6c5bdafe801e..059001b3144f 100644 --- a/vms/platformvm/state/merged_iterator.go +++ b/vms/platformvm/state/merged_iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/merged_iterator_test.go b/vms/platformvm/state/merged_iterator_test.go index c85b35941b0f..e6cd52451f73 100644 --- a/vms/platformvm/state/merged_iterator_test.go +++ b/vms/platformvm/state/merged_iterator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/metadata_codec.go b/vms/platformvm/state/metadata_codec.go index 291d425c67bb..400d23e29af2 100644 --- a/vms/platformvm/state/metadata_codec.go +++ b/vms/platformvm/state/metadata_codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/metadata_delegator.go b/vms/platformvm/state/metadata_delegator.go index 9e9ed42d2108..06099d813cde 100644 --- a/vms/platformvm/state/metadata_delegator.go +++ b/vms/platformvm/state/metadata_delegator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/metadata_delegator_test.go b/vms/platformvm/state/metadata_delegator_test.go index 67eceb62ad10..9c9d6c1c0044 100644 --- a/vms/platformvm/state/metadata_delegator_test.go +++ b/vms/platformvm/state/metadata_delegator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/metadata_validator.go b/vms/platformvm/state/metadata_validator.go index 84704cb7a5b7..0c725368505b 100644 --- a/vms/platformvm/state/metadata_validator.go +++ b/vms/platformvm/state/metadata_validator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/metadata_validator_test.go b/vms/platformvm/state/metadata_validator_test.go index bb5cf6a5bd08..3a041a26b2eb 100644 --- a/vms/platformvm/state/metadata_validator_test.go +++ b/vms/platformvm/state/metadata_validator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/slice_iterator_test.go b/vms/platformvm/state/slice_iterator_test.go index 96a686cddf92..408ffe837a27 100644 --- a/vms/platformvm/state/slice_iterator_test.go +++ b/vms/platformvm/state/slice_iterator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/staker.go b/vms/platformvm/state/staker.go index ae070f3c91d2..a9ba52595062 100644 --- a/vms/platformvm/state/staker.go +++ b/vms/platformvm/state/staker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/staker_diff_iterator.go b/vms/platformvm/state/staker_diff_iterator.go index d9c194cd2702..d47ab49ac572 100644 --- a/vms/platformvm/state/staker_diff_iterator.go +++ b/vms/platformvm/state/staker_diff_iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/staker_diff_iterator_test.go b/vms/platformvm/state/staker_diff_iterator_test.go index c008b06fb716..468b8800a23d 100644 --- a/vms/platformvm/state/staker_diff_iterator_test.go +++ b/vms/platformvm/state/staker_diff_iterator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/staker_status.go b/vms/platformvm/state/staker_status.go index b74064c4dc0b..0adc46244f92 100644 --- a/vms/platformvm/state/staker_status.go +++ b/vms/platformvm/state/staker_status.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/staker_test.go b/vms/platformvm/state/staker_test.go index f4a7b8657997..1b72385dbd13 100644 --- a/vms/platformvm/state/staker_test.go +++ b/vms/platformvm/state/staker_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/stakers.go b/vms/platformvm/state/stakers.go index 5276ff4f8204..f787749f72df 100644 --- a/vms/platformvm/state/stakers.go +++ b/vms/platformvm/state/stakers.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/stakers_test.go b/vms/platformvm/state/stakers_test.go index 9894d9479653..5c6d9a8b28f8 100644 --- a/vms/platformvm/state/stakers_test.go +++ b/vms/platformvm/state/stakers_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 2c7785e8d5c7..92e646ed6975 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index 8adcbba07a4b..6986f15a0aa0 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/tree_iterator.go b/vms/platformvm/state/tree_iterator.go index a71b35e21346..920bc1377902 100644 --- a/vms/platformvm/state/tree_iterator.go +++ b/vms/platformvm/state/tree_iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/tree_iterator_test.go b/vms/platformvm/state/tree_iterator_test.go index 57fa5727a4f4..7047d350bae1 100644 --- a/vms/platformvm/state/tree_iterator_test.go +++ b/vms/platformvm/state/tree_iterator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/state/versions.go b/vms/platformvm/state/versions.go index da84182bb683..6afb0fe8e5f2 100644 --- a/vms/platformvm/state/versions.go +++ b/vms/platformvm/state/versions.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/platformvm/status/blockchain_status.go b/vms/platformvm/status/blockchain_status.go index 1ab25e588b3d..5d427e5a9383 100644 --- a/vms/platformvm/status/blockchain_status.go +++ b/vms/platformvm/status/blockchain_status.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package status diff --git a/vms/platformvm/status/blockchain_status_test.go b/vms/platformvm/status/blockchain_status_test.go index 97b96badcb93..d0710d2f2cb1 100644 --- a/vms/platformvm/status/blockchain_status_test.go +++ b/vms/platformvm/status/blockchain_status_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package status diff --git a/vms/platformvm/status/status.go b/vms/platformvm/status/status.go index a67fb6c38e81..2a674250d20e 100644 --- a/vms/platformvm/status/status.go +++ b/vms/platformvm/status/status.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package status diff --git a/vms/platformvm/status/status_test.go b/vms/platformvm/status/status_test.go index 59316f983722..cd6ed5f814f7 100644 --- a/vms/platformvm/status/status_test.go +++ b/vms/platformvm/status/status_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package status diff --git a/vms/platformvm/txs/add_delegator_test.go b/vms/platformvm/txs/add_delegator_test.go index 1989690bb173..ac3290fb2431 100644 --- a/vms/platformvm/txs/add_delegator_test.go +++ b/vms/platformvm/txs/add_delegator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_delegator_tx.go b/vms/platformvm/txs/add_delegator_tx.go index af328cc693bf..3df97cf0af74 100644 --- a/vms/platformvm/txs/add_delegator_tx.go +++ b/vms/platformvm/txs/add_delegator_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_permissionless_delegator_tx.go b/vms/platformvm/txs/add_permissionless_delegator_tx.go index 346a80dd61f7..9c29b97339d0 100644 --- a/vms/platformvm/txs/add_permissionless_delegator_tx.go +++ b/vms/platformvm/txs/add_permissionless_delegator_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_permissionless_delegator_tx_test.go b/vms/platformvm/txs/add_permissionless_delegator_tx_test.go index 79a91c16e485..1099e910f09b 100644 --- a/vms/platformvm/txs/add_permissionless_delegator_tx_test.go +++ b/vms/platformvm/txs/add_permissionless_delegator_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_permissionless_validator_tx.go b/vms/platformvm/txs/add_permissionless_validator_tx.go index 34b13129ade8..0f655c8daea4 100644 --- a/vms/platformvm/txs/add_permissionless_validator_tx.go +++ b/vms/platformvm/txs/add_permissionless_validator_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_permissionless_validator_tx_test.go b/vms/platformvm/txs/add_permissionless_validator_tx_test.go index aed095b16af9..58dd373010b7 100644 --- a/vms/platformvm/txs/add_permissionless_validator_tx_test.go +++ b/vms/platformvm/txs/add_permissionless_validator_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_subnet_validator_test.go b/vms/platformvm/txs/add_subnet_validator_test.go index c1f68cb664c1..8dc8d76782ac 100644 --- a/vms/platformvm/txs/add_subnet_validator_test.go +++ b/vms/platformvm/txs/add_subnet_validator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_subnet_validator_tx.go b/vms/platformvm/txs/add_subnet_validator_tx.go index 53fd43562c02..b6ce0d0fe4da 100644 --- a/vms/platformvm/txs/add_subnet_validator_tx.go +++ b/vms/platformvm/txs/add_subnet_validator_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_validator_test.go b/vms/platformvm/txs/add_validator_test.go index 4046d7c0d984..daf32f66746d 100644 --- a/vms/platformvm/txs/add_validator_test.go +++ b/vms/platformvm/txs/add_validator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/add_validator_tx.go b/vms/platformvm/txs/add_validator_tx.go index a0e82dba7c77..b6ab65b56e8f 100644 --- a/vms/platformvm/txs/add_validator_tx.go +++ b/vms/platformvm/txs/add_validator_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/advance_time_tx.go b/vms/platformvm/txs/advance_time_tx.go index fc889da9ef0b..80b277fcb7e5 100644 --- a/vms/platformvm/txs/advance_time_tx.go +++ b/vms/platformvm/txs/advance_time_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/base_tx.go b/vms/platformvm/txs/base_tx.go index 5ffb308fe425..8a0be1edd76c 100644 --- a/vms/platformvm/txs/base_tx.go +++ b/vms/platformvm/txs/base_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/base_tx_test.go b/vms/platformvm/txs/base_tx_test.go index 7c2dc3ad5208..14bfc7b2f236 100644 --- a/vms/platformvm/txs/base_tx_test.go +++ b/vms/platformvm/txs/base_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/builder/builder.go b/vms/platformvm/txs/builder/builder.go index 6c796d085abb..3427bf2b1015 100644 --- a/vms/platformvm/txs/builder/builder.go +++ b/vms/platformvm/txs/builder/builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package builder diff --git a/vms/platformvm/txs/codec.go b/vms/platformvm/txs/codec.go index 0d011f246546..c0c300c4d79b 100644 --- a/vms/platformvm/txs/codec.go +++ b/vms/platformvm/txs/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/create_chain_test.go b/vms/platformvm/txs/create_chain_test.go index ae2217c5b605..787aaa2a7ccb 100644 --- a/vms/platformvm/txs/create_chain_test.go +++ b/vms/platformvm/txs/create_chain_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/create_chain_tx.go b/vms/platformvm/txs/create_chain_tx.go index 37166e91ff98..84a9c72f43b3 100644 --- a/vms/platformvm/txs/create_chain_tx.go +++ b/vms/platformvm/txs/create_chain_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/create_subnet_tx.go b/vms/platformvm/txs/create_subnet_tx.go index 02f41faefe4c..e560c9dd5f94 100644 --- a/vms/platformvm/txs/create_subnet_tx.go +++ b/vms/platformvm/txs/create_subnet_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/executor/advance_time_test.go b/vms/platformvm/txs/executor/advance_time_test.go index 9db644f4c1be..bb66c7ef7f82 100644 --- a/vms/platformvm/txs/executor/advance_time_test.go +++ b/vms/platformvm/txs/executor/advance_time_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/atomic_tx_executor.go b/vms/platformvm/txs/executor/atomic_tx_executor.go index 3b7dc60ec173..2a35cb45eeab 100644 --- a/vms/platformvm/txs/executor/atomic_tx_executor.go +++ b/vms/platformvm/txs/executor/atomic_tx_executor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/backend.go b/vms/platformvm/txs/executor/backend.go index f043521a56bc..a5e017090701 100644 --- a/vms/platformvm/txs/executor/backend.go +++ b/vms/platformvm/txs/executor/backend.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/create_chain_test.go b/vms/platformvm/txs/executor/create_chain_test.go index ab733337bf63..3b0502616473 100644 --- a/vms/platformvm/txs/executor/create_chain_test.go +++ b/vms/platformvm/txs/executor/create_chain_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/create_subnet_test.go b/vms/platformvm/txs/executor/create_subnet_test.go index 8b33f2a7734a..158eded74867 100644 --- a/vms/platformvm/txs/executor/create_subnet_test.go +++ b/vms/platformvm/txs/executor/create_subnet_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/export_test.go b/vms/platformvm/txs/executor/export_test.go index 1369a5f8bbf3..1272d2815142 100644 --- a/vms/platformvm/txs/executor/export_test.go +++ b/vms/platformvm/txs/executor/export_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index b72c136b5e54..b18498fac1e1 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/import_test.go b/vms/platformvm/txs/executor/import_test.go index 9144a92873b1..5d281da57185 100644 --- a/vms/platformvm/txs/executor/import_test.go +++ b/vms/platformvm/txs/executor/import_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/proposal_tx_executor.go b/vms/platformvm/txs/executor/proposal_tx_executor.go index bd329b3f2576..c3893be429d3 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/proposal_tx_executor_test.go b/vms/platformvm/txs/executor/proposal_tx_executor_test.go index 13ed27e7c5b2..930c0d9c253c 100644 --- a/vms/platformvm/txs/executor/proposal_tx_executor_test.go +++ b/vms/platformvm/txs/executor/proposal_tx_executor_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/reward_validator_test.go b/vms/platformvm/txs/executor/reward_validator_test.go index 71c3e93f330e..973dea4de9be 100644 --- a/vms/platformvm/txs/executor/reward_validator_test.go +++ b/vms/platformvm/txs/executor/reward_validator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index 5a260fd72cfc..a17bbbffc14d 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go index 24f5e1cba8d2..2fb875552b86 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_helpers.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_helpers.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/staker_tx_verification_test.go b/vms/platformvm/txs/executor/staker_tx_verification_test.go index 065e2cb54707..b59daf0da2b0 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification_test.go +++ b/vms/platformvm/txs/executor/staker_tx_verification_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 9bd5b140b314..e780673e6431 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/standard_tx_executor_test.go b/vms/platformvm/txs/executor/standard_tx_executor_test.go index a5617d13b69c..a86c579fee79 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor_test.go +++ b/vms/platformvm/txs/executor/standard_tx_executor_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/state_changes.go b/vms/platformvm/txs/executor/state_changes.go index 7b0c9355e195..2b327c4f8b96 100644 --- a/vms/platformvm/txs/executor/state_changes.go +++ b/vms/platformvm/txs/executor/state_changes.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/subnet_tx_verification.go b/vms/platformvm/txs/executor/subnet_tx_verification.go index bf384be9fa89..f1a75f6f2f3f 100644 --- a/vms/platformvm/txs/executor/subnet_tx_verification.go +++ b/vms/platformvm/txs/executor/subnet_tx_verification.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/executor/tx_mempool_verifier.go b/vms/platformvm/txs/executor/tx_mempool_verifier.go index 378b742ae484..f2e7d09673e6 100644 --- a/vms/platformvm/txs/executor/tx_mempool_verifier.go +++ b/vms/platformvm/txs/executor/tx_mempool_verifier.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package executor diff --git a/vms/platformvm/txs/export_tx.go b/vms/platformvm/txs/export_tx.go index b124263aae12..19dc3a076f7a 100644 --- a/vms/platformvm/txs/export_tx.go +++ b/vms/platformvm/txs/export_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/import_tx.go b/vms/platformvm/txs/import_tx.go index 121986991012..563242dad34a 100644 --- a/vms/platformvm/txs/import_tx.go +++ b/vms/platformvm/txs/import_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 63315d99c5fc..3f202cc3940d 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package mempool diff --git a/vms/platformvm/txs/mempool/mempool_test.go b/vms/platformvm/txs/mempool/mempool_test.go index c4af0fc1c6db..6d569b50c6b2 100644 --- a/vms/platformvm/txs/mempool/mempool_test.go +++ b/vms/platformvm/txs/mempool/mempool_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package mempool diff --git a/vms/platformvm/txs/priorities.go b/vms/platformvm/txs/priorities.go index 6a4fb4dc10a9..a324bdae8e1c 100644 --- a/vms/platformvm/txs/priorities.go +++ b/vms/platformvm/txs/priorities.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/priorities_test.go b/vms/platformvm/txs/priorities_test.go index ce266d5d7adb..5e629a853ca1 100644 --- a/vms/platformvm/txs/priorities_test.go +++ b/vms/platformvm/txs/priorities_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/remove_subnet_validator_tx.go b/vms/platformvm/txs/remove_subnet_validator_tx.go index 2221c2f345ca..ef55cccea290 100644 --- a/vms/platformvm/txs/remove_subnet_validator_tx.go +++ b/vms/platformvm/txs/remove_subnet_validator_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/remove_subnet_validator_tx_test.go b/vms/platformvm/txs/remove_subnet_validator_tx_test.go index 45bf7483cf47..2890b6d8d103 100644 --- a/vms/platformvm/txs/remove_subnet_validator_tx_test.go +++ b/vms/platformvm/txs/remove_subnet_validator_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/reward_validator_tx.go b/vms/platformvm/txs/reward_validator_tx.go index d4b579f1b95b..01b1e34bde46 100644 --- a/vms/platformvm/txs/reward_validator_tx.go +++ b/vms/platformvm/txs/reward_validator_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/staker_tx.go b/vms/platformvm/txs/staker_tx.go index 1cdcdcc337a8..8adb1ac23f7d 100644 --- a/vms/platformvm/txs/staker_tx.go +++ b/vms/platformvm/txs/staker_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/subnet_validator.go b/vms/platformvm/txs/subnet_validator.go index d9da9d31b739..a7c683f35a8f 100644 --- a/vms/platformvm/txs/subnet_validator.go +++ b/vms/platformvm/txs/subnet_validator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/subnet_validator_test.go b/vms/platformvm/txs/subnet_validator_test.go index 7fcbf3e44e4e..cdfbeaf159a5 100644 --- a/vms/platformvm/txs/subnet_validator_test.go +++ b/vms/platformvm/txs/subnet_validator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/transfer_subnet_ownership_tx.go b/vms/platformvm/txs/transfer_subnet_ownership_tx.go index 78dbf28b48b4..4fa2807809ce 100644 --- a/vms/platformvm/txs/transfer_subnet_ownership_tx.go +++ b/vms/platformvm/txs/transfer_subnet_ownership_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/transfer_subnet_ownership_tx_test.go b/vms/platformvm/txs/transfer_subnet_ownership_tx_test.go index e1b57a589461..39866c138e2b 100644 --- a/vms/platformvm/txs/transfer_subnet_ownership_tx_test.go +++ b/vms/platformvm/txs/transfer_subnet_ownership_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/transform_subnet_tx.go b/vms/platformvm/txs/transform_subnet_tx.go index f540ea674f4c..1ba543e1aa05 100644 --- a/vms/platformvm/txs/transform_subnet_tx.go +++ b/vms/platformvm/txs/transform_subnet_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/transform_subnet_tx_test.go b/vms/platformvm/txs/transform_subnet_tx_test.go index 7a9b0b6981be..d5a237667ded 100644 --- a/vms/platformvm/txs/transform_subnet_tx_test.go +++ b/vms/platformvm/txs/transform_subnet_tx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/tx.go b/vms/platformvm/txs/tx.go index 52ee3f80b29c..9874f66e0468 100644 --- a/vms/platformvm/txs/tx.go +++ b/vms/platformvm/txs/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/txheap/by_end_time.go b/vms/platformvm/txs/txheap/by_end_time.go index 2499ce971bc9..9cbba82cef07 100644 --- a/vms/platformvm/txs/txheap/by_end_time.go +++ b/vms/platformvm/txs/txheap/by_end_time.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txheap diff --git a/vms/platformvm/txs/txheap/by_end_time_test.go b/vms/platformvm/txs/txheap/by_end_time_test.go index 5d95a2c66ad7..a629b7b1c3bd 100644 --- a/vms/platformvm/txs/txheap/by_end_time_test.go +++ b/vms/platformvm/txs/txheap/by_end_time_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txheap diff --git a/vms/platformvm/txs/txheap/heap.go b/vms/platformvm/txs/txheap/heap.go index 3727bb891d92..7c9e33d3f989 100644 --- a/vms/platformvm/txs/txheap/heap.go +++ b/vms/platformvm/txs/txheap/heap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txheap diff --git a/vms/platformvm/txs/unsigned_tx.go b/vms/platformvm/txs/unsigned_tx.go index 7fe1702b0197..5b3e62dd1c33 100644 --- a/vms/platformvm/txs/unsigned_tx.go +++ b/vms/platformvm/txs/unsigned_tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/validator.go b/vms/platformvm/txs/validator.go index e8f4a6150806..726ba23b1c5d 100644 --- a/vms/platformvm/txs/validator.go +++ b/vms/platformvm/txs/validator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/validator_test.go b/vms/platformvm/txs/validator_test.go index b51873ad4ee4..0b9e749ca009 100644 --- a/vms/platformvm/txs/validator_test.go +++ b/vms/platformvm/txs/validator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/txs/visitor.go b/vms/platformvm/txs/visitor.go index 05a21c355801..b3fc55af4cf3 100644 --- a/vms/platformvm/txs/visitor.go +++ b/vms/platformvm/txs/visitor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package txs diff --git a/vms/platformvm/utxo/handler.go b/vms/platformvm/utxo/handler.go index 37f53238e4cb..f22a76fd0b8f 100644 --- a/vms/platformvm/utxo/handler.go +++ b/vms/platformvm/utxo/handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utxo diff --git a/vms/platformvm/utxo/handler_test.go b/vms/platformvm/utxo/handler_test.go index 4f1e2e00e8d7..d0224ed4666a 100644 --- a/vms/platformvm/utxo/handler_test.go +++ b/vms/platformvm/utxo/handler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package utxo diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 630124f99009..5ca5bfd6c241 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/validators/manager.go b/vms/platformvm/validators/manager.go index a4c5c87a3040..2c8b025a128b 100644 --- a/vms/platformvm/validators/manager.go +++ b/vms/platformvm/validators/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/vms/platformvm/validators/manager_benchmark_test.go b/vms/platformvm/validators/manager_benchmark_test.go index 0664c085c942..7c84589574df 100644 --- a/vms/platformvm/validators/manager_benchmark_test.go +++ b/vms/platformvm/validators/manager_benchmark_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/vms/platformvm/validators/test_manager.go b/vms/platformvm/validators/test_manager.go index d7ffe993248e..e04742f265c7 100644 --- a/vms/platformvm/validators/test_manager.go +++ b/vms/platformvm/validators/test_manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package validators diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 10dc515a5a62..341e5329666c 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 8dbf16cab605..36186ec32ae0 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index 7ac1638f8b84..23e88a646368 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package platformvm diff --git a/vms/platformvm/warp/codec.go b/vms/platformvm/warp/codec.go index 937cca628ad9..78b194eb6291 100644 --- a/vms/platformvm/warp/codec.go +++ b/vms/platformvm/warp/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/constants.go b/vms/platformvm/warp/constants.go index a91f5f39394f..723cdf50bc82 100644 --- a/vms/platformvm/warp/constants.go +++ b/vms/platformvm/warp/constants.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/gwarp/client.go b/vms/platformvm/warp/gwarp/client.go index 6619b4ff6ab7..0b51a54971f7 100644 --- a/vms/platformvm/warp/gwarp/client.go +++ b/vms/platformvm/warp/gwarp/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gwarp diff --git a/vms/platformvm/warp/gwarp/server.go b/vms/platformvm/warp/gwarp/server.go index 4fbee3a3e736..7857f4e0ee70 100644 --- a/vms/platformvm/warp/gwarp/server.go +++ b/vms/platformvm/warp/gwarp/server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gwarp diff --git a/vms/platformvm/warp/gwarp/signer_test.go b/vms/platformvm/warp/gwarp/signer_test.go index d1d6e8f7147d..306067dc883d 100644 --- a/vms/platformvm/warp/gwarp/signer_test.go +++ b/vms/platformvm/warp/gwarp/signer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gwarp diff --git a/vms/platformvm/warp/message.go b/vms/platformvm/warp/message.go index 454ab9482d17..76383bdafa11 100644 --- a/vms/platformvm/warp/message.go +++ b/vms/platformvm/warp/message.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/message_test.go b/vms/platformvm/warp/message_test.go index 910abd3403c9..99a50b366d95 100644 --- a/vms/platformvm/warp/message_test.go +++ b/vms/platformvm/warp/message_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/payload/addressed_call.go b/vms/platformvm/warp/payload/addressed_call.go index afdecd9e9f01..b3617ce487da 100644 --- a/vms/platformvm/warp/payload/addressed_call.go +++ b/vms/platformvm/warp/payload/addressed_call.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package payload diff --git a/vms/platformvm/warp/payload/addressed_call_test.go b/vms/platformvm/warp/payload/addressed_call_test.go index 0e60ef294c4b..77a885d836d5 100644 --- a/vms/platformvm/warp/payload/addressed_call_test.go +++ b/vms/platformvm/warp/payload/addressed_call_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package payload diff --git a/vms/platformvm/warp/payload/codec.go b/vms/platformvm/warp/payload/codec.go index 57642968e9e5..906b86bc09ed 100644 --- a/vms/platformvm/warp/payload/codec.go +++ b/vms/platformvm/warp/payload/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package payload diff --git a/vms/platformvm/warp/payload/hash.go b/vms/platformvm/warp/payload/hash.go index f3a0eb0c09d3..330f74fd869d 100644 --- a/vms/platformvm/warp/payload/hash.go +++ b/vms/platformvm/warp/payload/hash.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package payload diff --git a/vms/platformvm/warp/payload/hash_test.go b/vms/platformvm/warp/payload/hash_test.go index 1d890a8bd551..d58fe5e6a0c0 100644 --- a/vms/platformvm/warp/payload/hash_test.go +++ b/vms/platformvm/warp/payload/hash_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package payload diff --git a/vms/platformvm/warp/payload/payload.go b/vms/platformvm/warp/payload/payload.go index dbed48ae9c29..c5c09464803e 100644 --- a/vms/platformvm/warp/payload/payload.go +++ b/vms/platformvm/warp/payload/payload.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package payload diff --git a/vms/platformvm/warp/payload/payload_test.go b/vms/platformvm/warp/payload/payload_test.go index da14b8de0dbb..86b584ae33db 100644 --- a/vms/platformvm/warp/payload/payload_test.go +++ b/vms/platformvm/warp/payload/payload_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package payload diff --git a/vms/platformvm/warp/signature.go b/vms/platformvm/warp/signature.go index 2f2b0cae985b..667383376501 100644 --- a/vms/platformvm/warp/signature.go +++ b/vms/platformvm/warp/signature.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/signature_test.go b/vms/platformvm/warp/signature_test.go index c721eb62938d..b50891ede5d4 100644 --- a/vms/platformvm/warp/signature_test.go +++ b/vms/platformvm/warp/signature_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/signer.go b/vms/platformvm/warp/signer.go index 76f8ec02b4cd..8372aef0a728 100644 --- a/vms/platformvm/warp/signer.go +++ b/vms/platformvm/warp/signer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/signer_test.go b/vms/platformvm/warp/signer_test.go index d4e83c24a850..1bc177872d87 100644 --- a/vms/platformvm/warp/signer_test.go +++ b/vms/platformvm/warp/signer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/test_signer.go b/vms/platformvm/warp/test_signer.go index aef578f78ae2..c17b15b215e2 100644 --- a/vms/platformvm/warp/test_signer.go +++ b/vms/platformvm/warp/test_signer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/unsigned_message.go b/vms/platformvm/warp/unsigned_message.go index 873f6995357d..1e66f552c9fa 100644 --- a/vms/platformvm/warp/unsigned_message.go +++ b/vms/platformvm/warp/unsigned_message.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/unsigned_message_test.go b/vms/platformvm/warp/unsigned_message_test.go index f3be73ef6c77..03a140d14c27 100644 --- a/vms/platformvm/warp/unsigned_message_test.go +++ b/vms/platformvm/warp/unsigned_message_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/validator.go b/vms/platformvm/warp/validator.go index 5e193ae1815e..2ada068adc76 100644 --- a/vms/platformvm/warp/validator.go +++ b/vms/platformvm/warp/validator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/platformvm/warp/validator_test.go b/vms/platformvm/warp/validator_test.go index 9af37aed81f6..3fbaf8860dbe 100644 --- a/vms/platformvm/warp/validator_test.go +++ b/vms/platformvm/warp/validator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package warp diff --git a/vms/propertyfx/burn_operation.go b/vms/propertyfx/burn_operation.go index 4217420b3b62..1dedb4c2f448 100644 --- a/vms/propertyfx/burn_operation.go +++ b/vms/propertyfx/burn_operation.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/burn_operation_test.go b/vms/propertyfx/burn_operation_test.go index e9e9735efd3c..b6a995b0307c 100644 --- a/vms/propertyfx/burn_operation_test.go +++ b/vms/propertyfx/burn_operation_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/credential.go b/vms/propertyfx/credential.go index 0a67c182a995..3a464cc29dfe 100644 --- a/vms/propertyfx/credential.go +++ b/vms/propertyfx/credential.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/credential_test.go b/vms/propertyfx/credential_test.go index 4be34acd3247..3ce9bc97f3c3 100644 --- a/vms/propertyfx/credential_test.go +++ b/vms/propertyfx/credential_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/factory.go b/vms/propertyfx/factory.go index 21c69c97cd98..c42b92c84c5f 100644 --- a/vms/propertyfx/factory.go +++ b/vms/propertyfx/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/factory_test.go b/vms/propertyfx/factory_test.go index ec921aef3f69..f40cb2610a80 100644 --- a/vms/propertyfx/factory_test.go +++ b/vms/propertyfx/factory_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/fx.go b/vms/propertyfx/fx.go index 28d211a9b5ad..24a3dff171cb 100644 --- a/vms/propertyfx/fx.go +++ b/vms/propertyfx/fx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/fx_test.go b/vms/propertyfx/fx_test.go index fdab69bb5bf4..10a96e6e5b0b 100644 --- a/vms/propertyfx/fx_test.go +++ b/vms/propertyfx/fx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/mint_operation.go b/vms/propertyfx/mint_operation.go index 535ea1359010..7eecf5de27ad 100644 --- a/vms/propertyfx/mint_operation.go +++ b/vms/propertyfx/mint_operation.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/mint_operation_test.go b/vms/propertyfx/mint_operation_test.go index 138d989d3296..abcc552ace4c 100644 --- a/vms/propertyfx/mint_operation_test.go +++ b/vms/propertyfx/mint_operation_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/mint_output.go b/vms/propertyfx/mint_output.go index 3aebd115a404..7ff60375721c 100644 --- a/vms/propertyfx/mint_output.go +++ b/vms/propertyfx/mint_output.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/mint_output_test.go b/vms/propertyfx/mint_output_test.go index 0b4b76c55f88..4cfa1da038d8 100644 --- a/vms/propertyfx/mint_output_test.go +++ b/vms/propertyfx/mint_output_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/owned_output.go b/vms/propertyfx/owned_output.go index 30e32ca3ddf2..cbe2f4376753 100644 --- a/vms/propertyfx/owned_output.go +++ b/vms/propertyfx/owned_output.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/propertyfx/owned_output_test.go b/vms/propertyfx/owned_output_test.go index dbc7bea63698..a9c9adc57643 100644 --- a/vms/propertyfx/owned_output_test.go +++ b/vms/propertyfx/owned_output_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package propertyfx diff --git a/vms/proposervm/batched_vm.go b/vms/proposervm/batched_vm.go index fd104318cea7..ff1ce6a597a0 100644 --- a/vms/proposervm/batched_vm.go +++ b/vms/proposervm/batched_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 476b12e32bc3..27cdaba0493f 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index fa53d2727968..10a151952a10 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/block/block.go b/vms/proposervm/block/block.go index c4abe5a9f96d..fccbbe2e3718 100644 --- a/vms/proposervm/block/block.go +++ b/vms/proposervm/block/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/block_test.go b/vms/proposervm/block/block_test.go index d0b1a817b941..8a8a57ae3b9d 100644 --- a/vms/proposervm/block/block_test.go +++ b/vms/proposervm/block/block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/build.go b/vms/proposervm/block/build.go index c6f18020507f..7baa89205342 100644 --- a/vms/proposervm/block/build.go +++ b/vms/proposervm/block/build.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/build_test.go b/vms/proposervm/block/build_test.go index 30bdd79460f8..8388e8a434f8 100644 --- a/vms/proposervm/block/build_test.go +++ b/vms/proposervm/block/build_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/codec.go b/vms/proposervm/block/codec.go index fc6910377d47..d3ccce4f1d43 100644 --- a/vms/proposervm/block/codec.go +++ b/vms/proposervm/block/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/header.go b/vms/proposervm/block/header.go index 0098ab7e1932..83c4e813c806 100644 --- a/vms/proposervm/block/header.go +++ b/vms/proposervm/block/header.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/header_test.go b/vms/proposervm/block/header_test.go index bdbfaf3be0fd..a4db59385f01 100644 --- a/vms/proposervm/block/header_test.go +++ b/vms/proposervm/block/header_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/option.go b/vms/proposervm/block/option.go index 180b90e31fd6..c80651b621fc 100644 --- a/vms/proposervm/block/option.go +++ b/vms/proposervm/block/option.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/option_test.go b/vms/proposervm/block/option_test.go index f6d4f409650d..d5af9c100079 100644 --- a/vms/proposervm/block/option_test.go +++ b/vms/proposervm/block/option_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/parse.go b/vms/proposervm/block/parse.go index 1a55e5045981..cf275134d888 100644 --- a/vms/proposervm/block/parse.go +++ b/vms/proposervm/block/parse.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block/parse_test.go b/vms/proposervm/block/parse_test.go index 43a10671e7f5..1d04271c9fec 100644 --- a/vms/proposervm/block/parse_test.go +++ b/vms/proposervm/block/parse_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package block diff --git a/vms/proposervm/block_server.go b/vms/proposervm/block_server.go index e9e2e192a4e5..6a056c8bc827 100644 --- a/vms/proposervm/block_server.go +++ b/vms/proposervm/block_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 35e3da7deee4..fea216120811 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go index 6e4ed9576925..a7eb4ff0db9b 100644 --- a/vms/proposervm/config.go +++ b/vms/proposervm/config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/height_indexed_vm.go b/vms/proposervm/height_indexed_vm.go index 6c8d6967ee14..a29334f6d8dd 100644 --- a/vms/proposervm/height_indexed_vm.go +++ b/vms/proposervm/height_indexed_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/indexer/block_server.go b/vms/proposervm/indexer/block_server.go index e817b9bad830..fcecaf9e9fcf 100644 --- a/vms/proposervm/indexer/block_server.go +++ b/vms/proposervm/indexer/block_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/vms/proposervm/indexer/block_server_test.go b/vms/proposervm/indexer/block_server_test.go index e132926c811c..a973d66a05a9 100644 --- a/vms/proposervm/indexer/block_server_test.go +++ b/vms/proposervm/indexer/block_server_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/vms/proposervm/indexer/height_indexer.go b/vms/proposervm/indexer/height_indexer.go index 697570306f6b..c0a1e4155b3b 100644 --- a/vms/proposervm/indexer/height_indexer.go +++ b/vms/proposervm/indexer/height_indexer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/vms/proposervm/indexer/height_indexer_test.go b/vms/proposervm/indexer/height_indexer_test.go index 0ff9ebcdbb59..2a093530048a 100644 --- a/vms/proposervm/indexer/height_indexer_test.go +++ b/vms/proposervm/indexer/height_indexer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package indexer diff --git a/vms/proposervm/main_test.go b/vms/proposervm/main_test.go index 913e29613f1c..72165ddb6e78 100644 --- a/vms/proposervm/main_test.go +++ b/vms/proposervm/main_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/post_fork_block.go b/vms/proposervm/post_fork_block.go index 28d127d33f70..707b6dc327c7 100644 --- a/vms/proposervm/post_fork_block.go +++ b/vms/proposervm/post_fork_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 4e4a35bf0761..a16d4a7d6219 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/post_fork_option.go b/vms/proposervm/post_fork_option.go index 047a01c477fd..93cfd2550ca6 100644 --- a/vms/proposervm/post_fork_option.go +++ b/vms/proposervm/post_fork_option.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 26000f59ba33..dd16f8cdb518 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/pre_fork_block.go b/vms/proposervm/pre_fork_block.go index 8e952d9d7758..199c1c98db7d 100644 --- a/vms/proposervm/pre_fork_block.go +++ b/vms/proposervm/pre_fork_block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 6215a5c8465d..e6ff5346ea73 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/proposer/validators.go b/vms/proposervm/proposer/validators.go index 89ed964d5983..6af996187b69 100644 --- a/vms/proposervm/proposer/validators.go +++ b/vms/proposervm/proposer/validators.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposer diff --git a/vms/proposervm/proposer/validators_test.go b/vms/proposervm/proposer/validators_test.go index 8be1f4c23d99..e86f2c806a14 100644 --- a/vms/proposervm/proposer/validators_test.go +++ b/vms/proposervm/proposer/validators_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposer diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index beb4a8253f68..6d1d958dd04a 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposer diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 5e3434bb9e38..d3e2ac68817a 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposer diff --git a/vms/proposervm/scheduler/scheduler.go b/vms/proposervm/scheduler/scheduler.go index 5946a67b9b77..8395596a55a8 100644 --- a/vms/proposervm/scheduler/scheduler.go +++ b/vms/proposervm/scheduler/scheduler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package scheduler diff --git a/vms/proposervm/scheduler/scheduler_test.go b/vms/proposervm/scheduler/scheduler_test.go index 821a36883e90..77ed39a67330 100644 --- a/vms/proposervm/scheduler/scheduler_test.go +++ b/vms/proposervm/scheduler/scheduler_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package scheduler diff --git a/vms/proposervm/state/block_height_index.go b/vms/proposervm/state/block_height_index.go index e16100bddd89..b60fca0c363d 100644 --- a/vms/proposervm/state/block_height_index.go +++ b/vms/proposervm/state/block_height_index.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/proposervm/state/block_state.go b/vms/proposervm/state/block_state.go index b0d6d6547c9a..88382f0abc67 100644 --- a/vms/proposervm/state/block_state.go +++ b/vms/proposervm/state/block_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/proposervm/state/block_state_test.go b/vms/proposervm/state/block_state_test.go index 0b50698e2d45..193f3854b4a9 100644 --- a/vms/proposervm/state/block_state_test.go +++ b/vms/proposervm/state/block_state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/proposervm/state/chain_state.go b/vms/proposervm/state/chain_state.go index 0f1a1bfba4e8..e4ed34ddcb78 100644 --- a/vms/proposervm/state/chain_state.go +++ b/vms/proposervm/state/chain_state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/proposervm/state/chain_state_test.go b/vms/proposervm/state/chain_state_test.go index ab14f4228281..6b45585f6041 100644 --- a/vms/proposervm/state/chain_state_test.go +++ b/vms/proposervm/state/chain_state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/proposervm/state/codec.go b/vms/proposervm/state/codec.go index 6c1ecabd919c..21d30d24da86 100644 --- a/vms/proposervm/state/codec.go +++ b/vms/proposervm/state/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/proposervm/state/state.go b/vms/proposervm/state/state.go index c8b80b947920..487e64f71f08 100644 --- a/vms/proposervm/state/state.go +++ b/vms/proposervm/state/state.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/proposervm/state/state_test.go b/vms/proposervm/state/state_test.go index 97980fc36b9b..9ef1e291e539 100644 --- a/vms/proposervm/state/state_test.go +++ b/vms/proposervm/state/state_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package state diff --git a/vms/proposervm/state_summary.go b/vms/proposervm/state_summary.go index 629d2c6491d1..f61c29d6f426 100644 --- a/vms/proposervm/state_summary.go +++ b/vms/proposervm/state_summary.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/state_syncable_vm.go b/vms/proposervm/state_syncable_vm.go index da86d8c36e5c..08a321cab7bb 100644 --- a/vms/proposervm/state_syncable_vm.go +++ b/vms/proposervm/state_syncable_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 2e80c5973e86..c9b6d8b1a0dd 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/summary/build.go b/vms/proposervm/summary/build.go index a166d3c6c33c..516f9d1a9e72 100644 --- a/vms/proposervm/summary/build.go +++ b/vms/proposervm/summary/build.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package summary diff --git a/vms/proposervm/summary/build_test.go b/vms/proposervm/summary/build_test.go index 0e15ac3cd1d7..ad7e5df52748 100644 --- a/vms/proposervm/summary/build_test.go +++ b/vms/proposervm/summary/build_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package summary diff --git a/vms/proposervm/summary/codec.go b/vms/proposervm/summary/codec.go index 188e6470f80f..3eaa15e88683 100644 --- a/vms/proposervm/summary/codec.go +++ b/vms/proposervm/summary/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package summary diff --git a/vms/proposervm/summary/parse.go b/vms/proposervm/summary/parse.go index e4dd8733c091..670bd43a8d77 100644 --- a/vms/proposervm/summary/parse.go +++ b/vms/proposervm/summary/parse.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package summary diff --git a/vms/proposervm/summary/parse_test.go b/vms/proposervm/summary/parse_test.go index b22be83582e2..16fb2aec9f6b 100644 --- a/vms/proposervm/summary/parse_test.go +++ b/vms/proposervm/summary/parse_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package summary diff --git a/vms/proposervm/summary/state_summary.go b/vms/proposervm/summary/state_summary.go index 59269beb112c..14213a665fa6 100644 --- a/vms/proposervm/summary/state_summary.go +++ b/vms/proposervm/summary/state_summary.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package summary diff --git a/vms/proposervm/tree/tree.go b/vms/proposervm/tree/tree.go index 8d1e7333d32e..38125ba9d0e2 100644 --- a/vms/proposervm/tree/tree.go +++ b/vms/proposervm/tree/tree.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tree diff --git a/vms/proposervm/tree/tree_test.go b/vms/proposervm/tree/tree_test.go index 55b6e129341f..1e826e418c21 100644 --- a/vms/proposervm/tree/tree_test.go +++ b/vms/proposervm/tree/tree_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tree diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 290846abe763..99dc045be66d 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index fcb230156c96..c9ad1b98c79b 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index cebc07b3ef43..168dd913d22a 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 04d1e1c35810..2e4c6c3aea16 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package proposervm diff --git a/vms/registry/vm_getter.go b/vms/registry/vm_getter.go index 5115af9e635f..826624744e38 100644 --- a/vms/registry/vm_getter.go +++ b/vms/registry/vm_getter.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package registry diff --git a/vms/registry/vm_getter_test.go b/vms/registry/vm_getter_test.go index 9cea55b2c82f..30bab4232be9 100644 --- a/vms/registry/vm_getter_test.go +++ b/vms/registry/vm_getter_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package registry diff --git a/vms/registry/vm_registerer.go b/vms/registry/vm_registerer.go index 785b2b8cf828..fec5fba78f57 100644 --- a/vms/registry/vm_registerer.go +++ b/vms/registry/vm_registerer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package registry diff --git a/vms/registry/vm_registerer_test.go b/vms/registry/vm_registerer_test.go index a8910d4c33ad..666a9174525a 100644 --- a/vms/registry/vm_registerer_test.go +++ b/vms/registry/vm_registerer_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package registry diff --git a/vms/registry/vm_registry.go b/vms/registry/vm_registry.go index dd6f96d4e719..3c8f5b942e25 100644 --- a/vms/registry/vm_registry.go +++ b/vms/registry/vm_registry.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package registry diff --git a/vms/registry/vm_registry_test.go b/vms/registry/vm_registry_test.go index ecda1c4f5546..5f5eccc1c204 100644 --- a/vms/registry/vm_registry_test.go +++ b/vms/registry/vm_registry_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package registry diff --git a/vms/rpcchainvm/batched_vm_test.go b/vms/rpcchainvm/batched_vm_test.go index ebe5d68bc2a1..f74785ebc5bc 100644 --- a/vms/rpcchainvm/batched_vm_test.go +++ b/vms/rpcchainvm/batched_vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/rpcchainvm/errors.go b/vms/rpcchainvm/errors.go index 3795024378c4..4b434b51d425 100644 --- a/vms/rpcchainvm/errors.go +++ b/vms/rpcchainvm/errors.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/rpcchainvm/factory.go b/vms/rpcchainvm/factory.go index f7ef19749ad1..d61c41d11af8 100644 --- a/vms/rpcchainvm/factory.go +++ b/vms/rpcchainvm/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/rpcchainvm/ghttp/gconn/conn_client.go b/vms/rpcchainvm/ghttp/gconn/conn_client.go index b4bc5a5a4de0..cfa3094bfefe 100644 --- a/vms/rpcchainvm/ghttp/gconn/conn_client.go +++ b/vms/rpcchainvm/ghttp/gconn/conn_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gconn diff --git a/vms/rpcchainvm/ghttp/gconn/conn_server.go b/vms/rpcchainvm/ghttp/gconn/conn_server.go index 07ca0f5a2b3a..57f1cfdb064b 100644 --- a/vms/rpcchainvm/ghttp/gconn/conn_server.go +++ b/vms/rpcchainvm/ghttp/gconn/conn_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gconn diff --git a/vms/rpcchainvm/ghttp/greader/reader_client.go b/vms/rpcchainvm/ghttp/greader/reader_client.go index c06bdce9ba01..be0f2a1a7ee6 100644 --- a/vms/rpcchainvm/ghttp/greader/reader_client.go +++ b/vms/rpcchainvm/ghttp/greader/reader_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package greader diff --git a/vms/rpcchainvm/ghttp/greader/reader_server.go b/vms/rpcchainvm/ghttp/greader/reader_server.go index a5f8f5d76f30..4d85f674ffc6 100644 --- a/vms/rpcchainvm/ghttp/greader/reader_server.go +++ b/vms/rpcchainvm/ghttp/greader/reader_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package greader diff --git a/vms/rpcchainvm/ghttp/gresponsewriter/locked_writer.go b/vms/rpcchainvm/ghttp/gresponsewriter/locked_writer.go index c89eb5099cc6..40528dc79d2c 100644 --- a/vms/rpcchainvm/ghttp/gresponsewriter/locked_writer.go +++ b/vms/rpcchainvm/ghttp/gresponsewriter/locked_writer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gresponsewriter diff --git a/vms/rpcchainvm/ghttp/gresponsewriter/writer_client.go b/vms/rpcchainvm/ghttp/gresponsewriter/writer_client.go index 769d8edce555..1c45567097cf 100644 --- a/vms/rpcchainvm/ghttp/gresponsewriter/writer_client.go +++ b/vms/rpcchainvm/ghttp/gresponsewriter/writer_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gresponsewriter diff --git a/vms/rpcchainvm/ghttp/gresponsewriter/writer_server.go b/vms/rpcchainvm/ghttp/gresponsewriter/writer_server.go index a78e6b002913..b73d24f21024 100644 --- a/vms/rpcchainvm/ghttp/gresponsewriter/writer_server.go +++ b/vms/rpcchainvm/ghttp/gresponsewriter/writer_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gresponsewriter diff --git a/vms/rpcchainvm/ghttp/gwriter/writer_client.go b/vms/rpcchainvm/ghttp/gwriter/writer_client.go index d9a561f2dd4e..f68cefa7c2a6 100644 --- a/vms/rpcchainvm/ghttp/gwriter/writer_client.go +++ b/vms/rpcchainvm/ghttp/gwriter/writer_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gwriter diff --git a/vms/rpcchainvm/ghttp/gwriter/writer_server.go b/vms/rpcchainvm/ghttp/gwriter/writer_server.go index ce85aaced16e..1b216dc2a4ee 100644 --- a/vms/rpcchainvm/ghttp/gwriter/writer_server.go +++ b/vms/rpcchainvm/ghttp/gwriter/writer_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gwriter diff --git a/vms/rpcchainvm/ghttp/http_client.go b/vms/rpcchainvm/ghttp/http_client.go index 62a6b705a338..cd06c46ca156 100644 --- a/vms/rpcchainvm/ghttp/http_client.go +++ b/vms/rpcchainvm/ghttp/http_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ghttp diff --git a/vms/rpcchainvm/ghttp/http_server.go b/vms/rpcchainvm/ghttp/http_server.go index adece6f93679..c602965323fd 100644 --- a/vms/rpcchainvm/ghttp/http_server.go +++ b/vms/rpcchainvm/ghttp/http_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ghttp diff --git a/vms/rpcchainvm/ghttp/http_test.go b/vms/rpcchainvm/ghttp/http_test.go index 2bcf5f3150d8..22d5095d6c6d 100644 --- a/vms/rpcchainvm/ghttp/http_test.go +++ b/vms/rpcchainvm/ghttp/http_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package ghttp diff --git a/vms/rpcchainvm/grpcutils/client.go b/vms/rpcchainvm/grpcutils/client.go index 0a9dfcffef6c..eb9501019768 100644 --- a/vms/rpcchainvm/grpcutils/client.go +++ b/vms/rpcchainvm/grpcutils/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package grpcutils diff --git a/vms/rpcchainvm/grpcutils/client_test.go b/vms/rpcchainvm/grpcutils/client_test.go index 9ef2fa1d6731..e02552995295 100644 --- a/vms/rpcchainvm/grpcutils/client_test.go +++ b/vms/rpcchainvm/grpcutils/client_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package grpcutils diff --git a/vms/rpcchainvm/grpcutils/server.go b/vms/rpcchainvm/grpcutils/server.go index a6746207e427..dbcc439c9ef1 100644 --- a/vms/rpcchainvm/grpcutils/server.go +++ b/vms/rpcchainvm/grpcutils/server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package grpcutils diff --git a/vms/rpcchainvm/grpcutils/server_closer.go b/vms/rpcchainvm/grpcutils/server_closer.go index 35ca2b735a86..67a4141ddfc3 100644 --- a/vms/rpcchainvm/grpcutils/server_closer.go +++ b/vms/rpcchainvm/grpcutils/server_closer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package grpcutils diff --git a/vms/rpcchainvm/grpcutils/util.go b/vms/rpcchainvm/grpcutils/util.go index 8ad042ea55a9..880faf4d2a63 100644 --- a/vms/rpcchainvm/grpcutils/util.go +++ b/vms/rpcchainvm/grpcutils/util.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package grpcutils diff --git a/vms/rpcchainvm/gruntime/runtime_client.go b/vms/rpcchainvm/gruntime/runtime_client.go index 67a1e9864908..8db4adbeb204 100644 --- a/vms/rpcchainvm/gruntime/runtime_client.go +++ b/vms/rpcchainvm/gruntime/runtime_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gruntime diff --git a/vms/rpcchainvm/gruntime/runtime_server.go b/vms/rpcchainvm/gruntime/runtime_server.go index 882c62f5ca02..09be6c121eef 100644 --- a/vms/rpcchainvm/gruntime/runtime_server.go +++ b/vms/rpcchainvm/gruntime/runtime_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gruntime diff --git a/vms/rpcchainvm/messenger/messenger_client.go b/vms/rpcchainvm/messenger/messenger_client.go index e7910eb05d2e..d392b9af79c6 100644 --- a/vms/rpcchainvm/messenger/messenger_client.go +++ b/vms/rpcchainvm/messenger/messenger_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package messenger diff --git a/vms/rpcchainvm/messenger/messenger_server.go b/vms/rpcchainvm/messenger/messenger_server.go index 273ffdfd25b0..fc28a0757bb2 100644 --- a/vms/rpcchainvm/messenger/messenger_server.go +++ b/vms/rpcchainvm/messenger/messenger_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package messenger diff --git a/vms/rpcchainvm/runtime/manager.go b/vms/rpcchainvm/runtime/manager.go index 3e1a9eaac903..425faa731850 100644 --- a/vms/rpcchainvm/runtime/manager.go +++ b/vms/rpcchainvm/runtime/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package runtime diff --git a/vms/rpcchainvm/runtime/runtime.go b/vms/rpcchainvm/runtime/runtime.go index d5be95d96471..1a1a198acbda 100644 --- a/vms/rpcchainvm/runtime/runtime.go +++ b/vms/rpcchainvm/runtime/runtime.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package runtime diff --git a/vms/rpcchainvm/runtime/subprocess/initializer.go b/vms/rpcchainvm/runtime/subprocess/initializer.go index 5ade5f619bd1..bc8d4e41c63a 100644 --- a/vms/rpcchainvm/runtime/subprocess/initializer.go +++ b/vms/rpcchainvm/runtime/subprocess/initializer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package subprocess diff --git a/vms/rpcchainvm/runtime/subprocess/linux_stopper.go b/vms/rpcchainvm/runtime/subprocess/linux_stopper.go index 80a47fa7da3c..5205ea40596f 100644 --- a/vms/rpcchainvm/runtime/subprocess/linux_stopper.go +++ b/vms/rpcchainvm/runtime/subprocess/linux_stopper.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build linux diff --git a/vms/rpcchainvm/runtime/subprocess/non_linux_stopper.go b/vms/rpcchainvm/runtime/subprocess/non_linux_stopper.go index 8c3ce6a138e9..c1a590e31fe7 100644 --- a/vms/rpcchainvm/runtime/subprocess/non_linux_stopper.go +++ b/vms/rpcchainvm/runtime/subprocess/non_linux_stopper.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. //go:build !linux diff --git a/vms/rpcchainvm/runtime/subprocess/runtime.go b/vms/rpcchainvm/runtime/subprocess/runtime.go index 7711d377127c..2cd92a00b04e 100644 --- a/vms/rpcchainvm/runtime/subprocess/runtime.go +++ b/vms/rpcchainvm/runtime/subprocess/runtime.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package subprocess diff --git a/vms/rpcchainvm/runtime/subprocess/stopper.go b/vms/rpcchainvm/runtime/subprocess/stopper.go index b4d026590421..4dfd33c24caa 100644 --- a/vms/rpcchainvm/runtime/subprocess/stopper.go +++ b/vms/rpcchainvm/runtime/subprocess/stopper.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package subprocess diff --git a/vms/rpcchainvm/state_syncable_vm_test.go b/vms/rpcchainvm/state_syncable_vm_test.go index d0df51c71779..45512bbec04d 100644 --- a/vms/rpcchainvm/state_syncable_vm_test.go +++ b/vms/rpcchainvm/state_syncable_vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/rpcchainvm/vm.go b/vms/rpcchainvm/vm.go index e2e57f0284d3..ee2869989575 100644 --- a/vms/rpcchainvm/vm.go +++ b/vms/rpcchainvm/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go index 2441792ac703..0ee7882b96d9 100644 --- a/vms/rpcchainvm/vm_client.go +++ b/vms/rpcchainvm/vm_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/rpcchainvm/vm_server.go b/vms/rpcchainvm/vm_server.go index e3253043fbad..4338d87f1ed2 100644 --- a/vms/rpcchainvm/vm_server.go +++ b/vms/rpcchainvm/vm_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/rpcchainvm/vm_test.go b/vms/rpcchainvm/vm_test.go index fa8cb3d22fdf..b21cd503a74a 100644 --- a/vms/rpcchainvm/vm_test.go +++ b/vms/rpcchainvm/vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/rpcchainvm/with_context_vm_test.go b/vms/rpcchainvm/with_context_vm_test.go index 5c2c242b94a9..8796ff60941b 100644 --- a/vms/rpcchainvm/with_context_vm_test.go +++ b/vms/rpcchainvm/with_context_vm_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package rpcchainvm diff --git a/vms/secp256k1fx/credential.go b/vms/secp256k1fx/credential.go index 707a6b3f43d8..0367c9af96af 100644 --- a/vms/secp256k1fx/credential.go +++ b/vms/secp256k1fx/credential.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/credential_test.go b/vms/secp256k1fx/credential_test.go index 15496e1d7fac..c08548e0bcc7 100644 --- a/vms/secp256k1fx/credential_test.go +++ b/vms/secp256k1fx/credential_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/factory.go b/vms/secp256k1fx/factory.go index ae2463a19deb..fd52fe79a6fe 100644 --- a/vms/secp256k1fx/factory.go +++ b/vms/secp256k1fx/factory.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/factory_test.go b/vms/secp256k1fx/factory_test.go index 435164998581..2b1fa184474d 100644 --- a/vms/secp256k1fx/factory_test.go +++ b/vms/secp256k1fx/factory_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/fx.go b/vms/secp256k1fx/fx.go index c969c9593976..8c1cfa53bf9a 100644 --- a/vms/secp256k1fx/fx.go +++ b/vms/secp256k1fx/fx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/fx_test.go b/vms/secp256k1fx/fx_test.go index c0e2663e6a23..388d7bc14d84 100644 --- a/vms/secp256k1fx/fx_test.go +++ b/vms/secp256k1fx/fx_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/input.go b/vms/secp256k1fx/input.go index d5943a6b686e..7e11556be582 100644 --- a/vms/secp256k1fx/input.go +++ b/vms/secp256k1fx/input.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/input_test.go b/vms/secp256k1fx/input_test.go index 632004799e91..f80b824d7711 100644 --- a/vms/secp256k1fx/input_test.go +++ b/vms/secp256k1fx/input_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/keychain.go b/vms/secp256k1fx/keychain.go index 3246ef95722d..ecb42f209970 100644 --- a/vms/secp256k1fx/keychain.go +++ b/vms/secp256k1fx/keychain.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/keychain_test.go b/vms/secp256k1fx/keychain_test.go index 46fdb1a0695c..65dd984b703f 100644 --- a/vms/secp256k1fx/keychain_test.go +++ b/vms/secp256k1fx/keychain_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/mint_operation.go b/vms/secp256k1fx/mint_operation.go index a21f3061290b..80728ca7588e 100644 --- a/vms/secp256k1fx/mint_operation.go +++ b/vms/secp256k1fx/mint_operation.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/mint_operation_test.go b/vms/secp256k1fx/mint_operation_test.go index 60b60b25f10a..3b751c8dcb33 100644 --- a/vms/secp256k1fx/mint_operation_test.go +++ b/vms/secp256k1fx/mint_operation_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/mint_output.go b/vms/secp256k1fx/mint_output.go index 996f05171bbe..e52ba47025ae 100644 --- a/vms/secp256k1fx/mint_output.go +++ b/vms/secp256k1fx/mint_output.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/mint_output_test.go b/vms/secp256k1fx/mint_output_test.go index 7d092a6772ea..60a72dfc95c4 100644 --- a/vms/secp256k1fx/mint_output_test.go +++ b/vms/secp256k1fx/mint_output_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/output_owners.go b/vms/secp256k1fx/output_owners.go index c0bb243f4b6e..0f838c69800e 100644 --- a/vms/secp256k1fx/output_owners.go +++ b/vms/secp256k1fx/output_owners.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/output_owners_test.go b/vms/secp256k1fx/output_owners_test.go index 97741e6b6f3d..e042726bce64 100644 --- a/vms/secp256k1fx/output_owners_test.go +++ b/vms/secp256k1fx/output_owners_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/transfer_input.go b/vms/secp256k1fx/transfer_input.go index 6dadd558fc49..1659820c26f7 100644 --- a/vms/secp256k1fx/transfer_input.go +++ b/vms/secp256k1fx/transfer_input.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/transfer_input_test.go b/vms/secp256k1fx/transfer_input_test.go index c3019a25a12f..4434584e1a9d 100644 --- a/vms/secp256k1fx/transfer_input_test.go +++ b/vms/secp256k1fx/transfer_input_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/transfer_output.go b/vms/secp256k1fx/transfer_output.go index 234cc1f68dab..ee4c5796c413 100644 --- a/vms/secp256k1fx/transfer_output.go +++ b/vms/secp256k1fx/transfer_output.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/transfer_output_test.go b/vms/secp256k1fx/transfer_output_test.go index 767f93925b7c..b1d8a2170b5a 100644 --- a/vms/secp256k1fx/transfer_output_test.go +++ b/vms/secp256k1fx/transfer_output_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/tx.go b/vms/secp256k1fx/tx.go index 81f4ee4d11e0..5cc483c7c3fc 100644 --- a/vms/secp256k1fx/tx.go +++ b/vms/secp256k1fx/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/secp256k1fx/vm.go b/vms/secp256k1fx/vm.go index ba8a9f1d6c0a..07da2d394236 100644 --- a/vms/secp256k1fx/vm.go +++ b/vms/secp256k1fx/vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package secp256k1fx diff --git a/vms/tracedvm/batched_vm.go b/vms/tracedvm/batched_vm.go index 47f81c9fa114..22dfb212ec6d 100644 --- a/vms/tracedvm/batched_vm.go +++ b/vms/tracedvm/batched_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracedvm diff --git a/vms/tracedvm/block.go b/vms/tracedvm/block.go index a90a110302fe..81949d777225 100644 --- a/vms/tracedvm/block.go +++ b/vms/tracedvm/block.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracedvm diff --git a/vms/tracedvm/block_vm.go b/vms/tracedvm/block_vm.go index 969a6bc09637..10931bf8c287 100644 --- a/vms/tracedvm/block_vm.go +++ b/vms/tracedvm/block_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracedvm diff --git a/vms/tracedvm/build_block_with_context_vm.go b/vms/tracedvm/build_block_with_context_vm.go index 1d9e9319605e..b069b471f26b 100644 --- a/vms/tracedvm/build_block_with_context_vm.go +++ b/vms/tracedvm/build_block_with_context_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracedvm diff --git a/vms/tracedvm/state_syncable_vm.go b/vms/tracedvm/state_syncable_vm.go index 75738462368b..e31507d55735 100644 --- a/vms/tracedvm/state_syncable_vm.go +++ b/vms/tracedvm/state_syncable_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracedvm diff --git a/vms/tracedvm/tx.go b/vms/tracedvm/tx.go index 7e18efcb23b4..638ecd8f5914 100644 --- a/vms/tracedvm/tx.go +++ b/vms/tracedvm/tx.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracedvm diff --git a/vms/tracedvm/vertex_vm.go b/vms/tracedvm/vertex_vm.go index 53189f5cee70..4bc162c6c6ae 100644 --- a/vms/tracedvm/vertex_vm.go +++ b/vms/tracedvm/vertex_vm.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tracedvm diff --git a/vms/types/blob_data.go b/vms/types/blob_data.go index cf5855ad7c7d..cee4fe7ba4d8 100644 --- a/vms/types/blob_data.go +++ b/vms/types/blob_data.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package types diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index 0a735116b646..cefe6befcf6a 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index 81fcf3aa896a..3e387ba3c27b 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 8416dddf9928..fa98725450a6 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index b9cd41cb5667..9e4712b8f7c9 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4fd85ed3b532..7be1a149fb36 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index fb1a83d53dad..304fbe4cf7c8 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index 7d6193683d49..a0a1a60d85a8 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package c diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index bb75692f3908..d06c7a1f9cf9 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index 57d602354428..1a0c8e39e8da 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 6b3b11254cd7..9a8189c4db6b 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/p/builder_with_options.go b/wallet/chain/p/builder_with_options.go index 9060d7639410..46deab976577 100644 --- a/wallet/chain/p/builder_with_options.go +++ b/wallet/chain/p/builder_with_options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/p/context.go b/wallet/chain/p/context.go index 9c3ba67d0dc7..d861dae1dccc 100644 --- a/wallet/chain/p/context.go +++ b/wallet/chain/p/context.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/p/signer.go b/wallet/chain/p/signer.go index a795dd63c539..be2db8ddd2c0 100644 --- a/wallet/chain/p/signer.go +++ b/wallet/chain/p/signer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/p/signer_visitor.go b/wallet/chain/p/signer_visitor.go index 25429b47e50f..c5c444a97f13 100644 --- a/wallet/chain/p/signer_visitor.go +++ b/wallet/chain/p/signer_visitor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index c4d5545818ae..e982a204a9f8 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/p/wallet_with_options.go b/wallet/chain/p/wallet_with_options.go index 8135db0ecfbc..33faa1a86bb0 100644 --- a/wallet/chain/p/wallet_with_options.go +++ b/wallet/chain/p/wallet_with_options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package p diff --git a/wallet/chain/x/backend.go b/wallet/chain/x/backend.go index 56ade31be1b7..6c2f81365daf 100644 --- a/wallet/chain/x/backend.go +++ b/wallet/chain/x/backend.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/backend_visitor.go b/wallet/chain/x/backend_visitor.go index d617638434c6..7ce9aa2acd00 100644 --- a/wallet/chain/x/backend_visitor.go +++ b/wallet/chain/x/backend_visitor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/builder.go b/wallet/chain/x/builder.go index d7af2b62aa25..27932019e1f4 100644 --- a/wallet/chain/x/builder.go +++ b/wallet/chain/x/builder.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/builder_with_options.go b/wallet/chain/x/builder_with_options.go index 63d554009fff..c2b65b05a630 100644 --- a/wallet/chain/x/builder_with_options.go +++ b/wallet/chain/x/builder_with_options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/constants.go b/wallet/chain/x/constants.go index ed43fc07a84d..44ff38393acc 100644 --- a/wallet/chain/x/constants.go +++ b/wallet/chain/x/constants.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/context.go b/wallet/chain/x/context.go index 064080253eb6..de42f01e857b 100644 --- a/wallet/chain/x/context.go +++ b/wallet/chain/x/context.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/signer.go b/wallet/chain/x/signer.go index 98d52d83218d..2c8268199a44 100644 --- a/wallet/chain/x/signer.go +++ b/wallet/chain/x/signer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/signer_visitor.go b/wallet/chain/x/signer_visitor.go index 35b0bd668224..961463ec0256 100644 --- a/wallet/chain/x/signer_visitor.go +++ b/wallet/chain/x/signer_visitor.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/wallet.go b/wallet/chain/x/wallet.go index 4e187d58220f..75b3914e199f 100644 --- a/wallet/chain/x/wallet.go +++ b/wallet/chain/x/wallet.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/chain/x/wallet_with_options.go b/wallet/chain/x/wallet_with_options.go index 810f4e94b32a..d62d02efdd40 100644 --- a/wallet/chain/x/wallet_with_options.go +++ b/wallet/chain/x/wallet_with_options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package x diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 3ac72c217884..445c518aba25 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package primary diff --git a/wallet/subnet/primary/common/options.go b/wallet/subnet/primary/common/options.go index 0c15be3c8b6b..03cc1c7b5f0a 100644 --- a/wallet/subnet/primary/common/options.go +++ b/wallet/subnet/primary/common/options.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/wallet/subnet/primary/common/spend.go b/wallet/subnet/primary/common/spend.go index d7511317c4bd..42c7fc02fc34 100644 --- a/wallet/subnet/primary/common/spend.go +++ b/wallet/subnet/primary/common/spend.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/wallet/subnet/primary/common/utxos.go b/wallet/subnet/primary/common/utxos.go index 36a86bc1f126..23762a0dd5d7 100644 --- a/wallet/subnet/primary/common/utxos.go +++ b/wallet/subnet/primary/common/utxos.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package common diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 483c049d4ac0..2b8d8b8eeec8 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package primary diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index d5e8ce422307..33695b35f649 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index a56dae23db3a..987229d1ec22 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index fec55c899feb..41ecb5ca814e 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index b4dc4e603eb3..387d435db4df 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 30804f083df6..54015dda239d 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 5e6898a1b649..ea98579f6f21 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index e688968e9e8a..32cdcf983ba0 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index add98ea7931c..e471e68f5be9 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/get-p-chain-balance/main.go b/wallet/subnet/primary/examples/get-p-chain-balance/main.go index a19b3d6eae76..fd14eb4ea588 100644 --- a/wallet/subnet/primary/examples/get-p-chain-balance/main.go +++ b/wallet/subnet/primary/examples/get-p-chain-balance/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/get-x-chain-balance/main.go b/wallet/subnet/primary/examples/get-x-chain-balance/main.go index a5474f7e1095..c43d4c9dd229 100644 --- a/wallet/subnet/primary/examples/get-x-chain-balance/main.go +++ b/wallet/subnet/primary/examples/get-x-chain-balance/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 2842c7c0a790..50639943b630 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package main diff --git a/wallet/subnet/primary/utxos.go b/wallet/subnet/primary/utxos.go index f8c9ce20a694..71f7629856e1 100644 --- a/wallet/subnet/primary/utxos.go +++ b/wallet/subnet/primary/utxos.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package primary diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 54de390d029c..3bb3e9965684 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package primary diff --git a/x/archivedb/batch.go b/x/archivedb/batch.go index dc7502fafd2e..720ed6f9d5d3 100644 --- a/x/archivedb/batch.go +++ b/x/archivedb/batch.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package archivedb diff --git a/x/archivedb/db.go b/x/archivedb/db.go index ca638b982cf4..74b658a31736 100644 --- a/x/archivedb/db.go +++ b/x/archivedb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package archivedb diff --git a/x/archivedb/db_test.go b/x/archivedb/db_test.go index a22b7768c812..2b1fbea2a46f 100644 --- a/x/archivedb/db_test.go +++ b/x/archivedb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package archivedb diff --git a/x/archivedb/key.go b/x/archivedb/key.go index c90b02761402..86a884cb6c0f 100644 --- a/x/archivedb/key.go +++ b/x/archivedb/key.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package archivedb diff --git a/x/archivedb/key_test.go b/x/archivedb/key_test.go index 18343e725bc0..e5ea0ff3ced3 100644 --- a/x/archivedb/key_test.go +++ b/x/archivedb/key_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package archivedb diff --git a/x/archivedb/prefix_test.go b/x/archivedb/prefix_test.go index 8c6362d745f4..8558b592bf99 100644 --- a/x/archivedb/prefix_test.go +++ b/x/archivedb/prefix_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package archivedb diff --git a/x/archivedb/reader.go b/x/archivedb/reader.go index 0186cbc12712..abac3d854741 100644 --- a/x/archivedb/reader.go +++ b/x/archivedb/reader.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package archivedb diff --git a/x/archivedb/value.go b/x/archivedb/value.go index 2f7ff3e1f0f3..5f5861e23f43 100644 --- a/x/archivedb/value.go +++ b/x/archivedb/value.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package archivedb diff --git a/x/merkledb/batch.go b/x/merkledb/batch.go index 82ff3533aaaf..033200409b79 100644 --- a/x/merkledb/batch.go +++ b/x/merkledb/batch.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/cache.go b/x/merkledb/cache.go index c4cebd27f8a2..ee2e7f0b2713 100644 --- a/x/merkledb/cache.go +++ b/x/merkledb/cache.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/cache_test.go b/x/merkledb/cache_test.go index e0939df9451d..9883c23af38c 100644 --- a/x/merkledb/cache_test.go +++ b/x/merkledb/cache_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/codec.go b/x/merkledb/codec.go index ea6bc10363f4..02eb5fc3ad5a 100644 --- a/x/merkledb/codec.go +++ b/x/merkledb/codec.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/codec_test.go b/x/merkledb/codec_test.go index 991368a823f4..5972cbb43b9d 100644 --- a/x/merkledb/codec_test.go +++ b/x/merkledb/codec_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/db.go b/x/merkledb/db.go index e3319aee972b..1f96c2a89d0c 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/db_test.go b/x/merkledb/db_test.go index 06f42105e4f6..12bda7c03626 100644 --- a/x/merkledb/db_test.go +++ b/x/merkledb/db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/helpers_test.go b/x/merkledb/helpers_test.go index b7a2908ff377..acb620aba5f1 100644 --- a/x/merkledb/helpers_test.go +++ b/x/merkledb/helpers_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/history.go b/x/merkledb/history.go index 1f55b93c5d58..22d87cd1cb48 100644 --- a/x/merkledb/history.go +++ b/x/merkledb/history.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/history_test.go b/x/merkledb/history_test.go index 6af39e0e08e3..09c84321f50c 100644 --- a/x/merkledb/history_test.go +++ b/x/merkledb/history_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/intermediate_node_db.go b/x/merkledb/intermediate_node_db.go index 91cef6242410..5039c618e7cb 100644 --- a/x/merkledb/intermediate_node_db.go +++ b/x/merkledb/intermediate_node_db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/intermediate_node_db_test.go b/x/merkledb/intermediate_node_db_test.go index 0c27beebfd38..6b6012bccf7b 100644 --- a/x/merkledb/intermediate_node_db_test.go +++ b/x/merkledb/intermediate_node_db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/key.go b/x/merkledb/key.go index 78e35f59924c..dd9938f6aaf0 100644 --- a/x/merkledb/key.go +++ b/x/merkledb/key.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/key_test.go b/x/merkledb/key_test.go index f0819483b1a8..aab666e13afc 100644 --- a/x/merkledb/key_test.go +++ b/x/merkledb/key_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/metrics.go b/x/merkledb/metrics.go index d8a80a02db5a..058b4869904a 100644 --- a/x/merkledb/metrics.go +++ b/x/merkledb/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/metrics_test.go b/x/merkledb/metrics_test.go index 304c3027133b..20c4accbd13c 100644 --- a/x/merkledb/metrics_test.go +++ b/x/merkledb/metrics_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/node.go b/x/merkledb/node.go index 4caad76f294a..701e120e4b52 100644 --- a/x/merkledb/node.go +++ b/x/merkledb/node.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/node_test.go b/x/merkledb/node_test.go index e0cb4dd04b06..3c09679570f3 100644 --- a/x/merkledb/node_test.go +++ b/x/merkledb/node_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/proof.go b/x/merkledb/proof.go index c49cd6bab679..e863ca53c8e5 100644 --- a/x/merkledb/proof.go +++ b/x/merkledb/proof.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/proof_test.go b/x/merkledb/proof_test.go index e00326a56408..fa047e87d4a4 100644 --- a/x/merkledb/proof_test.go +++ b/x/merkledb/proof_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/tracer.go b/x/merkledb/tracer.go index 707028f2c9cd..d4e7a6fce4d7 100644 --- a/x/merkledb/tracer.go +++ b/x/merkledb/tracer.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/trie.go b/x/merkledb/trie.go index 0feeecdbfac2..bc2b4db81541 100644 --- a/x/merkledb/trie.go +++ b/x/merkledb/trie.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/trie_test.go b/x/merkledb/trie_test.go index 223822aa611e..f6dc0351f549 100644 --- a/x/merkledb/trie_test.go +++ b/x/merkledb/trie_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/value_node_db.go b/x/merkledb/value_node_db.go index 406c9a986dba..16cabe3d718f 100644 --- a/x/merkledb/value_node_db.go +++ b/x/merkledb/value_node_db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/value_node_db_test.go b/x/merkledb/value_node_db_test.go index 78dfe62b1e3b..224a4fe94ac1 100644 --- a/x/merkledb/value_node_db_test.go +++ b/x/merkledb/value_node_db_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/view.go b/x/merkledb/view.go index 301379d0a778..8f9e688efc26 100644 --- a/x/merkledb/view.go +++ b/x/merkledb/view.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/view_iterator.go b/x/merkledb/view_iterator.go index 2995cb6e8449..60d1b8909e76 100644 --- a/x/merkledb/view_iterator.go +++ b/x/merkledb/view_iterator.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/merkledb/view_iterator_test.go b/x/merkledb/view_iterator_test.go index 97d4e47ca11a..ba71c414c902 100644 --- a/x/merkledb/view_iterator_test.go +++ b/x/merkledb/view_iterator_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package merkledb diff --git a/x/sync/client.go b/x/sync/client.go index ad79e35f7e71..b753e48f9f9e 100644 --- a/x/sync/client.go +++ b/x/sync/client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/client_test.go b/x/sync/client_test.go index 8f4f9173b5d9..dd1767261296 100644 --- a/x/sync/client_test.go +++ b/x/sync/client_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/db.go b/x/sync/db.go index 5a0a5164c6a6..5ed9061b5889 100644 --- a/x/sync/db.go +++ b/x/sync/db.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/g_db/db_client.go b/x/sync/g_db/db_client.go index 376bff6aeab9..37b3339766ae 100644 --- a/x/sync/g_db/db_client.go +++ b/x/sync/g_db/db_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gdb diff --git a/x/sync/g_db/db_server.go b/x/sync/g_db/db_server.go index 820a130bb496..a65e8a4fe0de 100644 --- a/x/sync/g_db/db_server.go +++ b/x/sync/g_db/db_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package gdb diff --git a/x/sync/manager.go b/x/sync/manager.go index d094f33165cb..82f05eef08f9 100644 --- a/x/sync/manager.go +++ b/x/sync/manager.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/metrics.go b/x/sync/metrics.go index 881ca37282ef..fb27e6b45ffb 100644 --- a/x/sync/metrics.go +++ b/x/sync/metrics.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/network_client.go b/x/sync/network_client.go index efc3c6ef089e..22d7766f3f52 100644 --- a/x/sync/network_client.go +++ b/x/sync/network_client.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/network_server.go b/x/sync/network_server.go index e31e6d8f3ace..f8c311964e05 100644 --- a/x/sync/network_server.go +++ b/x/sync/network_server.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/network_server_test.go b/x/sync/network_server_test.go index a73aa3736979..66135c0025c6 100644 --- a/x/sync/network_server_test.go +++ b/x/sync/network_server_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/response_handler.go b/x/sync/response_handler.go index 71e0c5f64580..624a3221fc9c 100644 --- a/x/sync/response_handler.go +++ b/x/sync/response_handler.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/sync_test.go b/x/sync/sync_test.go index f970229aa2f5..0d659b3d84c3 100644 --- a/x/sync/sync_test.go +++ b/x/sync/sync_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/workheap.go b/x/sync/workheap.go index 76d438c92d17..b49a19372caf 100644 --- a/x/sync/workheap.go +++ b/x/sync/workheap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync diff --git a/x/sync/workheap_test.go b/x/sync/workheap_test.go index 826011dbdebd..d073ce5f9fdc 100644 --- a/x/sync/workheap_test.go +++ b/x/sync/workheap_test.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package sync From 935bfe45f95591a9b3710f5b53666a289ba6222b Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:59:38 -0500 Subject: [PATCH 227/267] [MerkleDB] Make intermediate node cache two layered (#2576) Co-authored-by: Dan Laine --- x/merkledb/db.go | 43 +++++++++++-------- x/merkledb/db_test.go | 17 ++++---- x/merkledb/intermediate_node_db.go | 53 ++++++++++++++++-------- x/merkledb/intermediate_node_db_test.go | 55 +++++++++++++++++-------- x/merkledb/proof.go | 16 ++++--- x/sync/client_test.go | 15 +++---- 6 files changed, 122 insertions(+), 77 deletions(-) diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 1f96c2a89d0c..5edcc809ae34 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -161,16 +161,19 @@ type Config struct { // // If 0 is specified, [runtime.NumCPU] will be used. RootGenConcurrency uint - // The number of bytes to write to disk when intermediate nodes are evicted - // from their cache and written to disk. - EvictionBatchSize uint + // The number of changes to the database that we store in memory in order to // serve change proofs. HistoryLength uint - // The number of bytes to cache nodes with values. + // The number of bytes used to cache nodes with values. ValueNodeCacheSize uint - // The number of bytes to cache nodes without values. + // The number of bytes used to cache nodes without values. IntermediateNodeCacheSize uint + // The number of bytes used to store nodes without values in memory before forcing them onto disk. + IntermediateWriteBufferSize uint + // The number of bytes to write to disk when intermediate nodes are evicted + // from the write buffer and written to disk. + IntermediateWriteBatchSize uint // If [Reg] is nil, metrics are collected locally but not exported through // Prometheus. // This may be useful for testing. @@ -256,11 +259,23 @@ func newDatabase( return make([]byte, 0, defaultBufferLength) }, } + iNodeDB, err := newIntermediateNodeDB( + db, + bufferPool, + metrics, + int(config.IntermediateNodeCacheSize), + int(config.IntermediateWriteBufferSize), + int(config.IntermediateWriteBatchSize), + BranchFactorToTokenSize[config.BranchFactor]) + if err != nil { + return nil, err + } + trieDB := &merkleDB{ metrics: metrics, baseDB: db, + intermediateNodeDB: iNodeDB, valueNodeDB: newValueNodeDB(db, bufferPool, metrics, int(config.ValueNodeCacheSize)), - intermediateNodeDB: newIntermediateNodeDB(db, bufferPool, metrics, int(config.IntermediateNodeCacheSize), int(config.EvictionBatchSize), BranchFactorToTokenSize[config.BranchFactor]), history: newTrieHistory(int(config.HistoryLength)), debugTracer: getTracerIfEnabled(config.TraceLevel, DebugTrace, config.Tracer), infoTracer: getTracerIfEnabled(config.TraceLevel, InfoTrace, config.Tracer), @@ -483,19 +498,11 @@ func (db *merkleDB) PrefetchPath(key []byte) error { func (db *merkleDB) prefetchPath(keyBytes []byte) error { return visitPathToKey(db, ToKey(keyBytes), func(n *node) error { - if !n.hasValue() { - // this value is already in the cache, so skip writing - // to avoid grabbing the cache write lock - if _, ok := db.intermediateNodeDB.nodeCache.Get(n.key); ok { - return nil - } - return db.intermediateNodeDB.nodeCache.Put(n.key, n) - } - // this value is already in the cache, so skip writing - if _, ok := db.valueNodeDB.nodeCache.Get(n.key); ok { - return nil + if n.hasValue() { + db.valueNodeDB.nodeCache.Put(n.key, n) + } else { + db.intermediateNodeDB.nodeCache.Put(n.key, n) } - db.valueNodeDB.nodeCache.Put(n.key, n) return nil }) } diff --git a/x/merkledb/db_test.go b/x/merkledb/db_test.go index 12bda7c03626..244858aeccc8 100644 --- a/x/merkledb/db_test.go +++ b/x/merkledb/db_test.go @@ -42,13 +42,14 @@ func newDB(ctx context.Context, db database.Database, config Config) (*merkleDB, func newDefaultConfig() Config { return Config{ - EvictionBatchSize: 10, - HistoryLength: defaultHistoryLength, - ValueNodeCacheSize: units.MiB, - IntermediateNodeCacheSize: units.MiB, - Reg: prometheus.NewRegistry(), - Tracer: trace.Noop, - BranchFactor: BranchFactor16, + IntermediateWriteBatchSize: 10, + HistoryLength: defaultHistoryLength, + ValueNodeCacheSize: units.MiB, + IntermediateNodeCacheSize: units.MiB, + IntermediateWriteBufferSize: units.KiB, + Reg: prometheus.NewRegistry(), + Tracer: trace.Noop, + BranchFactor: BranchFactor16, } } @@ -807,7 +808,7 @@ func TestMerkleDBClear(t *testing.T) { // Assert caches are empty. require.Zero(db.valueNodeDB.nodeCache.Len()) - require.Zero(db.intermediateNodeDB.nodeCache.currentSize) + require.Zero(db.intermediateNodeDB.writeBuffer.currentSize) // Assert history has only the clearing change. require.Len(db.history.lastChanges, 1) diff --git a/x/merkledb/intermediate_node_db.go b/x/merkledb/intermediate_node_db.go index 5039c618e7cb..fa31771d7b36 100644 --- a/x/merkledb/intermediate_node_db.go +++ b/x/merkledb/intermediate_node_db.go @@ -4,13 +4,18 @@ package merkledb import ( + "errors" "sync" + "github.com/ava-labs/avalanchego/cache" + "github.com/ava-labs/avalanchego/database" ) const defaultBufferLength = 256 +var errCacheSizeTooSmall = errors.New("cache size must be larger than or equal to write buffer size") + // Holds intermediate nodes. That is, those without values. // Changes to this database aren't written to [baseDB] until // they're evicted from the [nodeCache] or Flush is called. @@ -22,12 +27,16 @@ type intermediateNodeDB struct { // Keys written to [baseDB] are prefixed with [intermediateNodePrefix]. baseDB database.Database - // If a value is nil, the corresponding key isn't in the trie. + // The write buffer contains nodes that have been changed but have not been written to disk. // Note that a call to Put may cause a node to be evicted // from the cache, which will call [OnEviction]. // A non-nil error returned from Put is considered fatal. // Keys in [nodeCache] aren't prefixed with [intermediateNodePrefix]. - nodeCache onEvictCache[Key, *node] + writeBuffer onEvictCache[Key, *node] + + // If a value is nil, the corresponding key isn't in the trie. + nodeCache cache.Cacher[Key, *node] + // the number of bytes to evict during an eviction batch evictionBatchSize int metrics merkleMetrics @@ -38,29 +47,34 @@ func newIntermediateNodeDB( db database.Database, bufferPool *sync.Pool, metrics merkleMetrics, - size int, + cacheSize int, + writeBufferSize int, evictionBatchSize int, tokenSize int, -) *intermediateNodeDB { +) (*intermediateNodeDB, error) { + if cacheSize < writeBufferSize { + return nil, errCacheSizeTooSmall + } result := &intermediateNodeDB{ metrics: metrics, baseDB: db, bufferPool: bufferPool, evictionBatchSize: evictionBatchSize, tokenSize: tokenSize, + nodeCache: cache.NewSizedLRU(cacheSize, cacheEntrySize), } - result.nodeCache = newOnEvictCache( - size, + result.writeBuffer = newOnEvictCache( + writeBufferSize, cacheEntrySize, result.onEviction, ) - return result + + return result, nil } // A non-nil error is considered fatal and closes [db.baseDB]. func (db *intermediateNodeDB) onEviction(key Key, n *node) error { writeBatch := db.baseDB.NewBatch() - totalSize := cacheEntrySize(key, n) if err := db.addToBatch(writeBatch, key, n); err != nil { _ = db.baseDB.Close() @@ -73,7 +87,7 @@ func (db *intermediateNodeDB) onEviction(key Key, n *node) error { // node, because each time this method is called we do a disk write. // Evicts a total number of bytes, rather than a number of nodes for totalSize < db.evictionBatchSize { - key, n, exists := db.nodeCache.removeOldest() + key, n, exists := db.writeBuffer.removeOldest() if !exists { // The cache is empty. break @@ -136,24 +150,29 @@ func (db *intermediateNodeDB) constructDBKey(key Key) []byte { } func (db *intermediateNodeDB) Put(key Key, n *node) error { - return db.nodeCache.Put(key, n) + db.nodeCache.Put(key, n) + return db.writeBuffer.Put(key, n) } func (db *intermediateNodeDB) Flush() error { - return db.nodeCache.Flush() + db.nodeCache.Flush() + return db.writeBuffer.Flush() } func (db *intermediateNodeDB) Delete(key Key) error { - return db.nodeCache.Put(key, nil) + db.nodeCache.Put(key, nil) + return db.writeBuffer.Put(key, nil) } func (db *intermediateNodeDB) Clear() error { - // Reset the cache. Note we don't flush because that would cause us to + db.nodeCache.Flush() + + // Reset the buffer. Note we don't flush because that would cause us to // persist intermediate nodes we're about to delete. - db.nodeCache = newOnEvictCache( - db.nodeCache.maxSize, - db.nodeCache.size, - db.nodeCache.onEviction, + db.writeBuffer = newOnEvictCache( + db.writeBuffer.maxSize, + db.writeBuffer.size, + db.writeBuffer.onEviction, ) return database.AtomicClearPrefix(db.baseDB, db.baseDB, intermediateNodePrefix) } diff --git a/x/merkledb/intermediate_node_db_test.go b/x/merkledb/intermediate_node_db_test.go index 6b6012bccf7b..86bf67475096 100644 --- a/x/merkledb/intermediate_node_db_test.go +++ b/x/merkledb/intermediate_node_db_test.go @@ -28,19 +28,23 @@ func Test_IntermediateNodeDB(t *testing.T) { nodeSize := cacheEntrySize(n.key, n) // use exact multiple of node size so require.Equal(1, db.nodeCache.fifo.Len()) is correct later - cacheSize := nodeSize * 20 - evictionBatchSize := cacheSize + cacheSize := nodeSize * 100 + bufferSize := nodeSize * 20 + + evictionBatchSize := bufferSize baseDB := memdb.New() - db := newIntermediateNodeDB( + db, err := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, }, &mockMetrics{}, cacheSize, + bufferSize, evictionBatchSize, 4, ) + require.NoError(err) // Put a key-node pair node1Key := ToKey([]byte{0x01}) @@ -78,7 +82,7 @@ func Test_IntermediateNodeDB(t *testing.T) { node := newNode(Key{}) node.setValue(maybe.Some([]byte{byte(added)})) newExpectedSize := expectedSize + cacheEntrySize(key, node) - if newExpectedSize > cacheSize { + if newExpectedSize > bufferSize { // Don't trigger eviction. break } @@ -89,7 +93,7 @@ func Test_IntermediateNodeDB(t *testing.T) { } // Assert cache has expected number of elements - require.Equal(added, db.nodeCache.fifo.Len()) + require.Equal(added, db.writeBuffer.fifo.Len()) // Put one more element in the cache, which should trigger an eviction // of all but 2 elements. 2 elements remain rather than 1 element because of @@ -100,14 +104,14 @@ func Test_IntermediateNodeDB(t *testing.T) { require.NoError(db.Put(key, node)) // Assert cache has expected number of elements - require.Equal(1, db.nodeCache.fifo.Len()) - gotKey, _, ok := db.nodeCache.fifo.Oldest() + require.Equal(1, db.writeBuffer.fifo.Len()) + gotKey, _, ok := db.writeBuffer.fifo.Oldest() require.True(ok) require.Equal(ToKey([]byte{byte(added)}), gotKey) // Get a node from the base database // Use an early key that has been evicted from the cache - _, inCache := db.nodeCache.Get(node1Key) + _, inCache := db.writeBuffer.Get(node1Key) require.False(inCache) nodeRead, err := db.Get(node1Key) require.NoError(err) @@ -117,7 +121,7 @@ func Test_IntermediateNodeDB(t *testing.T) { require.NoError(db.Flush()) // Assert the cache is empty - require.Zero(db.nodeCache.fifo.Len()) + require.Zero(db.writeBuffer.fifo.Len()) // Assert the evicted cache elements were written to disk with prefix. it := baseDB.NewIteratorWithPrefix(intermediateNodePrefix) @@ -132,8 +136,9 @@ func Test_IntermediateNodeDB(t *testing.T) { } func FuzzIntermediateNodeDBConstructDBKey(f *testing.F) { + bufferSize := 200 cacheSize := 200 - evictionBatchSize := cacheSize + evictionBatchSize := bufferSize baseDB := memdb.New() f.Fuzz(func( @@ -143,16 +148,18 @@ func FuzzIntermediateNodeDBConstructDBKey(f *testing.F) { ) { require := require.New(t) for _, tokenSize := range validTokenSizes { - db := newIntermediateNodeDB( + db, err := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, }, &mockMetrics{}, cacheSize, + bufferSize, evictionBatchSize, tokenSize, ) + require.NoError(err) p := ToKey(key) uBitLength := tokenLength * uint(tokenSize) @@ -182,19 +189,23 @@ func FuzzIntermediateNodeDBConstructDBKey(f *testing.F) { func Test_IntermediateNodeDB_ConstructDBKey_DirtyBuffer(t *testing.T) { require := require.New(t) cacheSize := 200 - evictionBatchSize := cacheSize + bufferSize := 200 + evictionBatchSize := bufferSize baseDB := memdb.New() - db := newIntermediateNodeDB( + db, err := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, }, &mockMetrics{}, cacheSize, + bufferSize, evictionBatchSize, 4, ) + require.NoError(err) + db.bufferPool.Put([]byte{0xFF, 0xFF, 0xFF}) constructedKey := db.constructDBKey(ToKey([]byte{})) require.Len(constructedKey, 2) @@ -217,19 +228,23 @@ func Test_IntermediateNodeDB_ConstructDBKey_DirtyBuffer(t *testing.T) { func TestIntermediateNodeDBClear(t *testing.T) { require := require.New(t) cacheSize := 200 - evictionBatchSize := cacheSize + bufferSize := 200 + evictionBatchSize := bufferSize baseDB := memdb.New() - db := newIntermediateNodeDB( + db, err := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, }, &mockMetrics{}, cacheSize, + bufferSize, evictionBatchSize, 4, ) + require.NoError(err) + for _, b := range [][]byte{{1}, {2}, {3}} { require.NoError(db.Put(ToKey(b), newNode(ToKey(b)))) } @@ -240,7 +255,7 @@ func TestIntermediateNodeDBClear(t *testing.T) { defer iter.Release() require.False(iter.Next()) - require.Zero(db.nodeCache.currentSize) + require.Zero(db.writeBuffer.currentSize) } // Test that deleting the empty key and flushing works correctly. @@ -251,19 +266,23 @@ func TestIntermediateNodeDBClear(t *testing.T) { func TestIntermediateNodeDBDeleteEmptyKey(t *testing.T) { require := require.New(t) cacheSize := 200 - evictionBatchSize := cacheSize + bufferSize := 200 + evictionBatchSize := bufferSize baseDB := memdb.New() - db := newIntermediateNodeDB( + db, err := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, }, &mockMetrics{}, cacheSize, + bufferSize, evictionBatchSize, 4, ) + require.NoError(err) + emptyKey := ToKey([]byte{}) require.NoError(db.Put(emptyKey, newNode(emptyKey))) require.NoError(db.Flush()) diff --git a/x/merkledb/proof.go b/x/merkledb/proof.go index e863ca53c8e5..8ddd97ffa5f9 100644 --- a/x/merkledb/proof.go +++ b/x/merkledb/proof.go @@ -20,10 +20,7 @@ import ( pb "github.com/ava-labs/avalanchego/proto/pb/sync" ) -const ( - verificationEvictionBatchSize = 0 - verificationCacheSize = math.MaxInt -) +const verificationCacheSize = math.MaxUint16 var ( ErrInvalidProof = errors.New("proof obtained an invalid root ID") @@ -861,11 +858,12 @@ func getStandaloneView(ctx context.Context, ops []database.BatchOp, size int) (* ctx, memdb.New(), Config{ - EvictionBatchSize: verificationEvictionBatchSize, - Tracer: trace.Noop, - ValueNodeCacheSize: verificationCacheSize, - IntermediateNodeCacheSize: verificationCacheSize, - BranchFactor: tokenSizeToBranchFactor[size], + BranchFactor: tokenSizeToBranchFactor[size], + Tracer: trace.Noop, + ValueNodeCacheSize: verificationCacheSize, + IntermediateNodeCacheSize: verificationCacheSize, + IntermediateWriteBufferSize: verificationCacheSize, + IntermediateWriteBatchSize: verificationCacheSize, }, &mockMetrics{}, ) diff --git a/x/sync/client_test.go b/x/sync/client_test.go index dd1767261296..e81d1a44010c 100644 --- a/x/sync/client_test.go +++ b/x/sync/client_test.go @@ -32,13 +32,14 @@ import ( func newDefaultDBConfig() merkledb.Config { return merkledb.Config{ - EvictionBatchSize: 100, - HistoryLength: defaultRequestKeyLimit, - ValueNodeCacheSize: defaultRequestKeyLimit, - IntermediateNodeCacheSize: defaultRequestKeyLimit, - Reg: prometheus.NewRegistry(), - Tracer: trace.Noop, - BranchFactor: merkledb.BranchFactor16, + IntermediateWriteBatchSize: 100, + HistoryLength: defaultRequestKeyLimit, + ValueNodeCacheSize: defaultRequestKeyLimit, + IntermediateWriteBufferSize: defaultRequestKeyLimit, + IntermediateNodeCacheSize: defaultRequestKeyLimit, + Reg: prometheus.NewRegistry(), + Tracer: trace.Noop, + BranchFactor: merkledb.BranchFactor16, } } From 72dc44224e839ec0d905559d2d8bfdac9fef5848 Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:36:57 -0500 Subject: [PATCH 228/267] Fix merkledb rebuild iterator (#2581) --- x/merkledb/db.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/merkledb/db.go b/x/merkledb/db.go index 5edcc809ae34..a4af8058a440 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -336,7 +336,8 @@ func (db *merkleDB) rebuild(ctx context.Context, cacheSize int) error { ) currentOps := make([]database.BatchOp, 0, opsSizeLimit) valueIt := db.NewIterator() - defer valueIt.Release() + // ensure valueIt is captured and release gets called on the latest copy of valueIt + defer func() { valueIt.Release() }() for valueIt.Next() { if len(currentOps) >= opsSizeLimit { view, err := newView(db, db, ViewChanges{BatchOps: currentOps, ConsumeBytes: true}) From 7c82a5bc23c6e0006377ee2cf59a32a62c334ca5 Mon Sep 17 00:00:00 2001 From: David Boehm <91908103+dboehm-avalabs@users.noreply.github.com> Date: Thu, 4 Jan 2024 15:37:06 -0500 Subject: [PATCH 229/267] Fix intermediate node caching (#2585) Co-authored-by: Dan Laine --- x/merkledb/db.go | 29 ++++++++++++------------- x/merkledb/intermediate_node_db.go | 19 +++++++++------- x/merkledb/intermediate_node_db_test.go | 18 +++++---------- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/x/merkledb/db.go b/x/merkledb/db.go index a4af8058a440..021ebc12d7d8 100644 --- a/x/merkledb/db.go +++ b/x/merkledb/db.go @@ -259,23 +259,22 @@ func newDatabase( return make([]byte, 0, defaultBufferLength) }, } - iNodeDB, err := newIntermediateNodeDB( - db, - bufferPool, - metrics, - int(config.IntermediateNodeCacheSize), - int(config.IntermediateWriteBufferSize), - int(config.IntermediateWriteBatchSize), - BranchFactorToTokenSize[config.BranchFactor]) - if err != nil { - return nil, err - } trieDB := &merkleDB{ - metrics: metrics, - baseDB: db, - intermediateNodeDB: iNodeDB, - valueNodeDB: newValueNodeDB(db, bufferPool, metrics, int(config.ValueNodeCacheSize)), + metrics: metrics, + baseDB: db, + intermediateNodeDB: newIntermediateNodeDB( + db, + bufferPool, + metrics, + int(config.IntermediateNodeCacheSize), + int(config.IntermediateWriteBufferSize), + int(config.IntermediateWriteBatchSize), + BranchFactorToTokenSize[config.BranchFactor]), + valueNodeDB: newValueNodeDB(db, + bufferPool, + metrics, + int(config.ValueNodeCacheSize)), history: newTrieHistory(int(config.HistoryLength)), debugTracer: getTracerIfEnabled(config.TraceLevel, DebugTrace, config.Tracer), infoTracer: getTracerIfEnabled(config.TraceLevel, InfoTrace, config.Tracer), diff --git a/x/merkledb/intermediate_node_db.go b/x/merkledb/intermediate_node_db.go index fa31771d7b36..b0318e99064d 100644 --- a/x/merkledb/intermediate_node_db.go +++ b/x/merkledb/intermediate_node_db.go @@ -4,7 +4,6 @@ package merkledb import ( - "errors" "sync" "github.com/ava-labs/avalanchego/cache" @@ -14,8 +13,6 @@ import ( const defaultBufferLength = 256 -var errCacheSizeTooSmall = errors.New("cache size must be larger than or equal to write buffer size") - // Holds intermediate nodes. That is, those without values. // Changes to this database aren't written to [baseDB] until // they're evicted from the [nodeCache] or Flush is called. @@ -51,10 +48,7 @@ func newIntermediateNodeDB( writeBufferSize int, evictionBatchSize int, tokenSize int, -) (*intermediateNodeDB, error) { - if cacheSize < writeBufferSize { - return nil, errCacheSizeTooSmall - } +) *intermediateNodeDB { result := &intermediateNodeDB{ metrics: metrics, baseDB: db, @@ -69,7 +63,7 @@ func newIntermediateNodeDB( result.onEviction, ) - return result, nil + return result } // A non-nil error is considered fatal and closes [db.baseDB]. @@ -125,6 +119,15 @@ func (db *intermediateNodeDB) Get(key Key) (*node, error) { } db.metrics.IntermediateNodeCacheMiss() + if cachedValue, isCached := db.writeBuffer.Get(key); isCached { + db.metrics.IntermediateNodeCacheHit() + if cachedValue == nil { + return nil, database.ErrNotFound + } + return cachedValue, nil + } + db.metrics.IntermediateNodeCacheMiss() + dbKey := db.constructDBKey(key) db.metrics.DatabaseNodeRead() nodeBytes, err := db.baseDB.Get(dbKey) diff --git a/x/merkledb/intermediate_node_db_test.go b/x/merkledb/intermediate_node_db_test.go index 86bf67475096..26ad722ffa45 100644 --- a/x/merkledb/intermediate_node_db_test.go +++ b/x/merkledb/intermediate_node_db_test.go @@ -33,7 +33,7 @@ func Test_IntermediateNodeDB(t *testing.T) { evictionBatchSize := bufferSize baseDB := memdb.New() - db, err := newIntermediateNodeDB( + db := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, @@ -44,7 +44,6 @@ func Test_IntermediateNodeDB(t *testing.T) { evictionBatchSize, 4, ) - require.NoError(err) // Put a key-node pair node1Key := ToKey([]byte{0x01}) @@ -148,7 +147,7 @@ func FuzzIntermediateNodeDBConstructDBKey(f *testing.F) { ) { require := require.New(t) for _, tokenSize := range validTokenSizes { - db, err := newIntermediateNodeDB( + db := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, @@ -159,7 +158,6 @@ func FuzzIntermediateNodeDBConstructDBKey(f *testing.F) { evictionBatchSize, tokenSize, ) - require.NoError(err) p := ToKey(key) uBitLength := tokenLength * uint(tokenSize) @@ -192,7 +190,7 @@ func Test_IntermediateNodeDB_ConstructDBKey_DirtyBuffer(t *testing.T) { bufferSize := 200 evictionBatchSize := bufferSize baseDB := memdb.New() - db, err := newIntermediateNodeDB( + db := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, @@ -204,8 +202,6 @@ func Test_IntermediateNodeDB_ConstructDBKey_DirtyBuffer(t *testing.T) { 4, ) - require.NoError(err) - db.bufferPool.Put([]byte{0xFF, 0xFF, 0xFF}) constructedKey := db.constructDBKey(ToKey([]byte{})) require.Len(constructedKey, 2) @@ -231,7 +227,7 @@ func TestIntermediateNodeDBClear(t *testing.T) { bufferSize := 200 evictionBatchSize := bufferSize baseDB := memdb.New() - db, err := newIntermediateNodeDB( + db := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, @@ -243,8 +239,6 @@ func TestIntermediateNodeDBClear(t *testing.T) { 4, ) - require.NoError(err) - for _, b := range [][]byte{{1}, {2}, {3}} { require.NoError(db.Put(ToKey(b), newNode(ToKey(b)))) } @@ -269,7 +263,7 @@ func TestIntermediateNodeDBDeleteEmptyKey(t *testing.T) { bufferSize := 200 evictionBatchSize := bufferSize baseDB := memdb.New() - db, err := newIntermediateNodeDB( + db := newIntermediateNodeDB( baseDB, &sync.Pool{ New: func() interface{} { return make([]byte, 0) }, @@ -281,8 +275,6 @@ func TestIntermediateNodeDBDeleteEmptyKey(t *testing.T) { 4, ) - require.NoError(err) - emptyKey := ToKey([]byte{}) require.NoError(db.Put(emptyKey, newNode(emptyKey))) require.NoError(db.Flush()) From 71f920d8b5073b878d15f5ac8a0e68d13b74e8f3 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 4 Jan 2024 17:23:24 -0500 Subject: [PATCH 230/267] Remove codec length check after Durango (#2586) --- api/keystore/codec.go | 7 ++- chains/atomic/codec.go | 7 ++- codec/hierarchycodec/codec.go | 9 +-- codec/hierarchycodec/codec_test.go | 22 ++++++- codec/linearcodec/codec.go | 13 +++-- codec/linearcodec/codec_test.go | 22 ++++++- codec/reflectcodec/type_codec.go | 49 ++++++++++------ codec/test_codec.go | 57 +++++++++++++++++++ database/encdb/codec.go | 4 +- database/linkeddb/codec.go | 3 +- genesis/genesis.go | 9 ++- go.mod | 2 +- go.sum | 4 +- indexer/codec.go | 3 +- node/node.go | 16 +++++- snow/engine/avalanche/vertex/codec.go | 6 +- vms/avm/block/block_test.go | 18 ++++-- vms/avm/block/builder/builder_test.go | 9 ++- vms/avm/block/parser.go | 8 ++- vms/avm/config/config.go | 5 ++ vms/avm/environment_test.go | 10 +++- vms/avm/network/gossip_test.go | 14 +++-- vms/avm/network/network_test.go | 57 ++++++++++++------- vms/avm/state/state_test.go | 9 ++- vms/avm/static_service.go | 14 +++-- vms/avm/txs/base_tx_test.go | 10 +++- vms/avm/txs/create_asset_tx_test.go | 19 +++++-- vms/avm/txs/executor/executor_test.go | 16 +++++- .../txs/executor/semantic_verifier_test.go | 5 ++ .../txs/executor/syntactic_verifier_test.go | 46 ++++++++++----- vms/avm/txs/export_tx_test.go | 10 +++- vms/avm/txs/import_tx_test.go | 10 +++- vms/avm/txs/initial_state_test.go | 13 +++-- vms/avm/txs/operation_test.go | 3 +- vms/avm/txs/parser.go | 10 ++-- vms/avm/vm.go | 1 + vms/components/avax/asset_test.go | 3 +- vms/components/avax/transferables_test.go | 9 +-- vms/components/avax/utxo_fetching_test.go | 5 +- vms/components/avax/utxo_id_test.go | 3 +- vms/components/avax/utxo_state_test.go | 3 +- vms/components/avax/utxo_test.go | 3 +- vms/components/keystore/codec.go | 5 +- vms/components/message/codec.go | 5 +- vms/example/xsvm/tx/codec.go | 3 +- vms/nftfx/fx_test.go | 32 +++++------ vms/platformvm/block/builder/helpers_test.go | 2 +- vms/platformvm/block/codec.go | 43 +++++++++----- vms/platformvm/block/executor/helpers_test.go | 2 +- vms/platformvm/state/metadata_codec.go | 5 +- vms/platformvm/txs/codec.go | 32 ++++++++--- vms/platformvm/txs/executor/helpers_test.go | 2 +- vms/platformvm/vm.go | 3 +- vms/platformvm/warp/codec.go | 3 +- vms/platformvm/warp/payload/codec.go | 8 +-- vms/propertyfx/fx_test.go | 26 ++++----- vms/proposervm/block/codec.go | 3 +- vms/proposervm/state/codec.go | 3 +- vms/proposervm/summary/codec.go | 3 +- vms/secp256k1fx/credential_test.go | 3 +- vms/secp256k1fx/fx_test.go | 48 ++++++++-------- vms/secp256k1fx/transfer_input_test.go | 3 +- vms/secp256k1fx/transfer_output_test.go | 3 +- wallet/chain/x/constants.go | 15 +++-- 64 files changed, 544 insertions(+), 254 deletions(-) diff --git a/api/keystore/codec.go b/api/keystore/codec.go index 099bdbfa79e7..b925747c44ec 100644 --- a/api/keystore/codec.go +++ b/api/keystore/codec.go @@ -4,6 +4,8 @@ package keystore import ( + "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/utils/units" @@ -12,14 +14,13 @@ import ( const ( CodecVersion = 0 - maxPackerSize = 1 * units.GiB // max size, in bytes, of something being marshalled by Marshal() - maxSliceLength = linearcodec.DefaultMaxSliceLength + maxPackerSize = 1 * units.GiB // max size, in bytes, of something being marshalled by Marshal() ) var Codec codec.Manager func init() { - lc := linearcodec.NewCustomMaxLength(maxSliceLength) + lc := linearcodec.NewDefault(time.Time{}) Codec = codec.NewManager(maxPackerSize) if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { panic(err) diff --git a/chains/atomic/codec.go b/chains/atomic/codec.go index 6a947fb27841..290713b3c258 100644 --- a/chains/atomic/codec.go +++ b/chains/atomic/codec.go @@ -4,6 +4,9 @@ package atomic import ( + "math" + "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" ) @@ -14,8 +17,8 @@ const CodecVersion = 0 var Codec codec.Manager func init() { - lc := linearcodec.NewDefault() - Codec = codec.NewDefaultManager() + lc := linearcodec.NewDefault(time.Time{}) + Codec = codec.NewManager(math.MaxInt) if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { panic(err) } diff --git a/codec/hierarchycodec/codec.go b/codec/hierarchycodec/codec.go index 63bd9efa0443..db2ffed0425d 100644 --- a/codec/hierarchycodec/codec.go +++ b/codec/hierarchycodec/codec.go @@ -7,6 +7,7 @@ import ( "fmt" "reflect" "sync" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/reflectcodec" @@ -50,19 +51,19 @@ type hierarchyCodec struct { } // New returns a new, concurrency-safe codec -func New(tagNames []string, maxSliceLen uint32) Codec { +func New(durangoTime time.Time, tagNames []string, maxSliceLen uint32) Codec { hCodec := &hierarchyCodec{ currentGroupID: 0, nextTypeID: 0, registeredTypes: bimap.New[typeID, reflect.Type](), } - hCodec.Codec = reflectcodec.New(hCodec, tagNames, maxSliceLen) + hCodec.Codec = reflectcodec.New(hCodec, tagNames, durangoTime, maxSliceLen) return hCodec } // NewDefault returns a new codec with reasonable default values -func NewDefault() Codec { - return New([]string{reflectcodec.DefaultTagName}, defaultMaxSliceLength) +func NewDefault(durangoTime time.Time) Codec { + return New(durangoTime, []string{reflectcodec.DefaultTagName}, defaultMaxSliceLength) } // SkipRegistrations some number of type IDs diff --git a/codec/hierarchycodec/codec_test.go b/codec/hierarchycodec/codec_test.go index 72f3e30982db..8149cdcc65e2 100644 --- a/codec/hierarchycodec/codec_test.go +++ b/codec/hierarchycodec/codec_test.go @@ -5,25 +5,41 @@ package hierarchycodec import ( "testing" + "time" "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/utils/timer/mockable" ) func TestVectors(t *testing.T) { for _, test := range codec.Tests { - c := NewDefault() + c := NewDefault(mockable.MaxTime) test(c, t) } } func TestMultipleTags(t *testing.T) { for _, test := range codec.MultipleTagsTests { - c := New([]string{"tag1", "tag2"}, defaultMaxSliceLength) + c := New(mockable.MaxTime, []string{"tag1", "tag2"}, defaultMaxSliceLength) + test(c, t) + } +} + +func TestEnforceSliceLen(t *testing.T) { + for _, test := range codec.EnforceSliceLenTests { + c := NewDefault(mockable.MaxTime) + test(c, t) + } +} + +func TestIgnoreSliceLen(t *testing.T) { + for _, test := range codec.IgnoreSliceLenTests { + c := NewDefault(time.Time{}) test(c, t) } } func FuzzStructUnmarshalHierarchyCodec(f *testing.F) { - c := NewDefault() + c := NewDefault(mockable.MaxTime) codec.FuzzStructUnmarshal(c, f) } diff --git a/codec/linearcodec/codec.go b/codec/linearcodec/codec.go index 0bb0dbf27ed1..6ad36b8a197d 100644 --- a/codec/linearcodec/codec.go +++ b/codec/linearcodec/codec.go @@ -7,6 +7,7 @@ import ( "fmt" "reflect" "sync" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/reflectcodec" @@ -44,23 +45,23 @@ type linearCodec struct { // New returns a new, concurrency-safe codec; it allow to specify // both tagNames and maxSlicelenght -func New(tagNames []string, maxSliceLen uint32) Codec { +func New(durangoTime time.Time, tagNames []string, maxSliceLen uint32) Codec { hCodec := &linearCodec{ nextTypeID: 0, registeredTypes: bimap.New[uint32, reflect.Type](), } - hCodec.Codec = reflectcodec.New(hCodec, tagNames, maxSliceLen) + hCodec.Codec = reflectcodec.New(hCodec, tagNames, durangoTime, maxSliceLen) return hCodec } // NewDefault is a convenience constructor; it returns a new codec with reasonable default values -func NewDefault() Codec { - return New([]string{reflectcodec.DefaultTagName}, DefaultMaxSliceLength) +func NewDefault(durangoTime time.Time) Codec { + return New(durangoTime, []string{reflectcodec.DefaultTagName}, DefaultMaxSliceLength) } // NewCustomMaxLength is a convenience constructor; it returns a new codec with custom max length and default tags -func NewCustomMaxLength(maxSliceLen uint32) Codec { - return New([]string{reflectcodec.DefaultTagName}, maxSliceLen) +func NewCustomMaxLength(durangoTime time.Time, maxSliceLen uint32) Codec { + return New(durangoTime, []string{reflectcodec.DefaultTagName}, maxSliceLen) } // Skip some number of type IDs diff --git a/codec/linearcodec/codec_test.go b/codec/linearcodec/codec_test.go index 1e9b14852a72..3d2f3efff68a 100644 --- a/codec/linearcodec/codec_test.go +++ b/codec/linearcodec/codec_test.go @@ -5,25 +5,41 @@ package linearcodec import ( "testing" + "time" "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/utils/timer/mockable" ) func TestVectors(t *testing.T) { for _, test := range codec.Tests { - c := NewDefault() + c := NewDefault(mockable.MaxTime) test(c, t) } } func TestMultipleTags(t *testing.T) { for _, test := range codec.MultipleTagsTests { - c := New([]string{"tag1", "tag2"}, DefaultMaxSliceLength) + c := New(mockable.MaxTime, []string{"tag1", "tag2"}, DefaultMaxSliceLength) + test(c, t) + } +} + +func TestEnforceSliceLen(t *testing.T) { + for _, test := range codec.EnforceSliceLenTests { + c := NewDefault(mockable.MaxTime) + test(c, t) + } +} + +func TestIgnoreSliceLen(t *testing.T) { + for _, test := range codec.IgnoreSliceLenTests { + c := NewDefault(time.Time{}) test(c, t) } } func FuzzStructUnmarshalLinearCodec(f *testing.F) { - c := NewDefault() + c := NewDefault(mockable.MaxTime) codec.FuzzStructUnmarshal(c, f) } diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index 30a8d9dcc268..312927559280 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -9,6 +9,7 @@ import ( "fmt" "math" "reflect" + "time" "golang.org/x/exp/slices" @@ -72,14 +73,16 @@ type TypeCodec interface { // 7. nil slices are marshaled as empty slices type genericCodec struct { typer TypeCodec + durangoTime time.Time // Time after which [maxSliceLen] will be ignored maxSliceLen uint32 fielder StructFielder } // New returns a new, concurrency-safe codec -func New(typer TypeCodec, tagNames []string, maxSliceLen uint32) codec.Codec { +func New(typer TypeCodec, tagNames []string, durangoTime time.Time, maxSliceLen uint32) codec.Codec { return &genericCodec{ typer: typer, + durangoTime: durangoTime, maxSliceLen: maxSliceLen, fielder: NewStructFielder(tagNames), } @@ -361,7 +364,14 @@ func (c *genericCodec) marshal( return p.Err case reflect.Slice: numElts := value.Len() // # elements in the slice/array. 0 if this slice is nil. - if uint32(numElts) > c.maxSliceLen { + if numElts > math.MaxInt32 { + return fmt.Errorf("%w; slice length, %d, exceeds maximum length, %d", + codec.ErrMaxSliceLenExceeded, + numElts, + math.MaxInt32, + ) + } + if time.Now().Before(c.durangoTime) && uint32(numElts) > c.maxSliceLen { return fmt.Errorf("%w; slice length, %d, exceeds maximum length, %d", codec.ErrMaxSliceLenExceeded, numElts, @@ -391,19 +401,12 @@ func (c *genericCodec) marshal( } return nil case reflect.Array: - numElts := value.Len() if elemKind := value.Type().Kind(); elemKind == reflect.Uint8 { sliceVal := value.Convert(reflect.TypeOf([]byte{})) p.PackFixedBytes(sliceVal.Bytes()) return p.Err } - if uint32(numElts) > c.maxSliceLen { - return fmt.Errorf("%w; array length, %d, exceeds maximum length, %d", - codec.ErrMaxSliceLenExceeded, - numElts, - c.maxSliceLen, - ) - } + numElts := value.Len() for i := 0; i < numElts; i++ { // Process each element in the array if err := c.marshal(value.Index(i), p, typeStack); err != nil { return err @@ -424,7 +427,14 @@ func (c *genericCodec) marshal( case reflect.Map: keys := value.MapKeys() numElts := len(keys) - if uint32(numElts) > c.maxSliceLen { + if numElts > math.MaxInt32 { + return fmt.Errorf("%w; slice length, %d, exceeds maximum length, %d", + codec.ErrMaxSliceLenExceeded, + numElts, + math.MaxInt32, + ) + } + if time.Now().Before(c.durangoTime) && uint32(numElts) > c.maxSliceLen { return fmt.Errorf("%w; map length, %d, exceeds maximum length, %d", codec.ErrMaxSliceLenExceeded, numElts, @@ -586,18 +596,18 @@ func (c *genericCodec) unmarshal( if p.Err != nil { return fmt.Errorf("couldn't unmarshal slice: %w", p.Err) } - if numElts32 > c.maxSliceLen { + if numElts32 > math.MaxInt32 { return fmt.Errorf("%w; array length, %d, exceeds maximum length, %d", codec.ErrMaxSliceLenExceeded, numElts32, - c.maxSliceLen, + math.MaxInt32, ) } - if numElts32 > math.MaxInt32 { + if time.Now().Before(c.durangoTime) && numElts32 > c.maxSliceLen { return fmt.Errorf("%w; array length, %d, exceeds maximum length, %d", codec.ErrMaxSliceLenExceeded, numElts32, - math.MaxInt32, + c.maxSliceLen, ) } numElts := int(numElts32) @@ -694,7 +704,14 @@ func (c *genericCodec) unmarshal( if p.Err != nil { return fmt.Errorf("couldn't unmarshal map: %w", p.Err) } - if numElts32 > c.maxSliceLen { + if numElts32 > math.MaxInt32 { + return fmt.Errorf("%w; map length, %d, exceeds maximum length, %d", + codec.ErrMaxSliceLenExceeded, + numElts32, + math.MaxInt32, + ) + } + if time.Now().Before(c.durangoTime) && numElts32 > c.maxSliceLen { return fmt.Errorf("%w; map length, %d, exceeds maximum length, %d", codec.ErrMaxSliceLenExceeded, numElts32, diff --git a/codec/test_codec.go b/codec/test_codec.go index 931f9bd2e89d..d58e2d818f9e 100644 --- a/codec/test_codec.go +++ b/codec/test_codec.go @@ -8,6 +8,8 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/utils/wrappers" ) var ( @@ -47,6 +49,15 @@ var ( MultipleTagsTests = []func(c GeneralCodec, t testing.TB){ TestMultipleTags, } + + EnforceSliceLenTests = []func(c GeneralCodec, t testing.TB){ + TestCanNotMarshalLargeSlices, + TestCanNotUnmarshalLargeSlices, + } + + IgnoreSliceLenTests = []func(c GeneralCodec, t testing.TB){ + TestCanMarshalLargeSlices, + } ) // The below structs and interfaces exist @@ -1020,6 +1031,52 @@ func TestMap(codec GeneralCodec, t testing.TB) { require.Len(outerArrayBytes, outerArraySize) } +func TestCanNotMarshalLargeSlices(codec GeneralCodec, t testing.TB) { + require := require.New(t) + + data := make([]uint16, 1_000_000) + + manager := NewManager(math.MaxInt) + require.NoError(manager.RegisterCodec(0, codec)) + + _, err := manager.Marshal(0, data) + require.ErrorIs(err, ErrMaxSliceLenExceeded) +} + +func TestCanNotUnmarshalLargeSlices(codec GeneralCodec, t testing.TB) { + require := require.New(t) + + writer := wrappers.Packer{ + Bytes: make([]byte, 2+4+2_000_000), + } + writer.PackShort(0) + writer.PackInt(1_000_000) + + manager := NewManager(math.MaxInt) + require.NoError(manager.RegisterCodec(0, codec)) + + var data []uint16 + _, err := manager.Unmarshal(writer.Bytes, &data) + require.ErrorIs(err, ErrMaxSliceLenExceeded) +} + +func TestCanMarshalLargeSlices(codec GeneralCodec, t testing.TB) { + require := require.New(t) + + data := make([]uint16, 1_000_000) + + manager := NewManager(math.MaxInt) + require.NoError(manager.RegisterCodec(0, codec)) + + bytes, err := manager.Marshal(0, data) + require.NoError(err) + + var unmarshalledData []uint16 + _, err = manager.Unmarshal(bytes, &unmarshalledData) + require.NoError(err) + require.Equal(data, unmarshalledData) +} + func FuzzStructUnmarshal(codec GeneralCodec, f *testing.F) { manager := NewDefaultManager() // Register the types that may be unmarshaled into interfaces diff --git a/database/encdb/codec.go b/database/encdb/codec.go index b786bec66916..62223b4fdd2f 100644 --- a/database/encdb/codec.go +++ b/database/encdb/codec.go @@ -4,6 +4,8 @@ package encdb import ( + "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" ) @@ -13,7 +15,7 @@ const CodecVersion = 0 var Codec codec.Manager func init() { - lc := linearcodec.NewDefault() + lc := linearcodec.NewDefault(time.Time{}) Codec = codec.NewDefaultManager() if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { diff --git a/database/linkeddb/codec.go b/database/linkeddb/codec.go index 24c5398aa8a1..f1982e1c7cfd 100644 --- a/database/linkeddb/codec.go +++ b/database/linkeddb/codec.go @@ -5,6 +5,7 @@ package linkeddb import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -15,7 +16,7 @@ const CodecVersion = 0 var Codec codec.Manager func init() { - lc := linearcodec.NewCustomMaxLength(math.MaxUint32) + lc := linearcodec.NewDefault(time.Time{}) Codec = codec.NewManager(math.MaxInt32) if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { diff --git a/genesis/genesis.go b/genesis/genesis.go index 217713520fb0..6a61b80aa559 100644 --- a/genesis/genesis.go +++ b/genesis/genesis.go @@ -552,9 +552,12 @@ func VMGenesis(genesisBytes []byte, vmID ids.ID) (*pchaintxs.Tx, error) { } func AVAXAssetID(avmGenesisBytes []byte) (ids.ID, error) { - parser, err := xchaintxs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := xchaintxs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) if err != nil { return ids.Empty, err } diff --git a/go.mod b/go.mod index c1b6367a5223..7e333adf6682 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.10-rc.2 + github.com/ava-labs/coreth v0.12.10-rc.4 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index d83821fc4ceb..df800dfefb61 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.10-rc.2 h1:+2YK7PzStcLCHtsBb1VQjw6DyMl1sMZatReZAyIy7w8= -github.com/ava-labs/coreth v0.12.10-rc.2/go.mod h1:RIbv14KMyWSj4hB1danS+vEPCUsgArZUEo99SaP5nW8= +github.com/ava-labs/coreth v0.12.10-rc.4 h1:+Ll3cpi3tZbw37lTa+1a/VnPa7xZktpbAFiuKtDKnIE= +github.com/ava-labs/coreth v0.12.10-rc.4/go.mod h1:8pt5LW6MP/luIdhQA+gvs8LobKE8tP/5APXUiFbfb2c= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/indexer/codec.go b/indexer/codec.go index 6addc9e3ca19..afde47502ac3 100644 --- a/indexer/codec.go +++ b/indexer/codec.go @@ -5,6 +5,7 @@ package indexer import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -15,7 +16,7 @@ const CodecVersion = 0 var Codec codec.Manager func init() { - lc := linearcodec.NewCustomMaxLength(math.MaxUint32) + lc := linearcodec.NewDefault(time.Time{}) Codec = codec.NewManager(math.MaxInt) if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { diff --git a/node/node.go b/node/node.go index c5d75c2e1d59..45e2f6a506eb 100644 --- a/node/node.go +++ b/node/node.go @@ -78,7 +78,9 @@ import ( "github.com/ava-labs/avalanchego/vms/avm" "github.com/ava-labs/avalanchego/vms/nftfx" "github.com/ava-labs/avalanchego/vms/platformvm" + "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/propertyfx" "github.com/ava-labs/avalanchego/vms/registry" "github.com/ava-labs/avalanchego/vms/rpcchainvm/runtime" @@ -1075,6 +1077,17 @@ func (n *Node) initVMs() error { VMManager: n.VMManager, }) + durangoTime := version.GetDurangoTime(n.Config.NetworkID) + if err := txs.InitCodec(durangoTime); err != nil { + return err + } + if err := block.InitCodec(durangoTime); err != nil { + return err + } + if err := coreth.InitCodec(durangoTime); err != nil { + return err + } + // Register the VMs that Avalanche supports err := utils.Err( vmRegisterer.Register(context.TODO(), constants.PlatformVMID, &platformvm.Factory{ @@ -1106,7 +1119,7 @@ func (n *Node) initVMs() error { ApricotPhase5Time: version.GetApricotPhase5Time(n.Config.NetworkID), BanffTime: version.GetBanffTime(n.Config.NetworkID), CortinaTime: version.GetCortinaTime(n.Config.NetworkID), - DurangoTime: version.GetDurangoTime(n.Config.NetworkID), + DurangoTime: durangoTime, UseCurrentHeight: n.Config.UseCurrentHeight, }, }), @@ -1114,6 +1127,7 @@ func (n *Node) initVMs() error { Config: avmconfig.Config{ TxFee: n.Config.TxFee, CreateAssetTxFee: n.Config.CreateAssetTxFee, + DurangoTime: durangoTime, }, }), vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), diff --git a/snow/engine/avalanche/vertex/codec.go b/snow/engine/avalanche/vertex/codec.go index c6da27f1f57f..12f387d0d25d 100644 --- a/snow/engine/avalanche/vertex/codec.go +++ b/snow/engine/avalanche/vertex/codec.go @@ -4,6 +4,8 @@ package vertex import ( + "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/codec/reflectcodec" @@ -22,8 +24,8 @@ const ( var Codec codec.Manager func init() { - lc0 := linearcodec.New([]string{reflectcodec.DefaultTagName + "V0"}, maxSize) - lc1 := linearcodec.New([]string{reflectcodec.DefaultTagName + "V1"}, maxSize) + lc0 := linearcodec.New(time.Time{}, []string{reflectcodec.DefaultTagName + "V0"}, maxSize) + lc1 := linearcodec.New(time.Time{}, []string{reflectcodec.DefaultTagName + "V1"}, maxSize) Codec = codec.NewManager(maxSize) err := utils.Err( diff --git a/vms/avm/block/block_test.go b/vms/avm/block/block_test.go index db2e3b074b59..6100f1d6d987 100644 --- a/vms/avm/block/block_test.go +++ b/vms/avm/block/block_test.go @@ -28,9 +28,12 @@ var ( func TestInvalidBlock(t *testing.T) { require := require.New(t) - parser, err := NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) _, err = parser.ParseBlock(nil) @@ -41,9 +44,12 @@ func TestStandardBlocks(t *testing.T) { // check standard block can be built and parsed require := require.New(t) - parser, err := NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) blkTimestamp := time.Now() diff --git a/vms/avm/block/builder/builder_test.go b/vms/avm/block/builder/builder_test.go index 5ff59b8d66f8..185c93260eca 100644 --- a/vms/avm/block/builder/builder_test.go +++ b/vms/avm/block/builder/builder_test.go @@ -514,9 +514,12 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { _, ok := mempool.Get(txID) require.True(ok) - parser, err := block.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := block.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) backend := &txexecutor.Backend{ diff --git a/vms/avm/block/parser.go b/vms/avm/block/parser.go index bfae841093d1..f0c359a513b0 100644 --- a/vms/avm/block/parser.go +++ b/vms/avm/block/parser.go @@ -5,6 +5,7 @@ package block import ( "reflect" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/utils" @@ -30,8 +31,8 @@ type parser struct { txs.Parser } -func NewParser(fxs []fxs.Fx) (Parser, error) { - p, err := txs.NewParser(fxs) +func NewParser(durangoTime time.Time, fxs []fxs.Fx) (Parser, error) { + p, err := txs.NewParser(durangoTime, fxs) if err != nil { return nil, err } @@ -48,12 +49,13 @@ func NewParser(fxs []fxs.Fx) (Parser, error) { } func NewCustomParser( + durangoTime time.Time, typeToFxIndex map[reflect.Type]int, clock *mockable.Clock, log logging.Logger, fxs []fxs.Fx, ) (Parser, error) { - p, err := txs.NewCustomParser(typeToFxIndex, clock, log, fxs) + p, err := txs.NewCustomParser(durangoTime, typeToFxIndex, clock, log, fxs) if err != nil { return nil, err } diff --git a/vms/avm/config/config.go b/vms/avm/config/config.go index 08f6ab04240a..df6e4f7de2ae 100644 --- a/vms/avm/config/config.go +++ b/vms/avm/config/config.go @@ -3,6 +3,8 @@ package config +import "time" + // Struct collecting all the foundational parameters of the AVM type Config struct { // Fee that is burned by every non-asset creating transaction @@ -10,4 +12,7 @@ type Config struct { // Fee that must be burned by every asset creating transaction CreateAssetTxFee uint64 + + // Time of the Durango network upgrade + DurangoTime time.Time } diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index d572298dc5e5..236c20875796 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -7,6 +7,7 @@ import ( "context" "math/rand" "testing" + "time" stdjson "encoding/json" @@ -228,9 +229,12 @@ func setup(tb testing.TB, c *envConfig) *environment { func getCreateTxFromGenesisTest(tb testing.TB, genesisBytes []byte, assetName string) *txs.Tx { require := require.New(tb) - parser, err := txs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) cm := parser.GenesisCodec() diff --git a/vms/avm/network/gossip_test.go b/vms/avm/network/gossip_test.go index 725851e54606..8f9df5ac7c86 100644 --- a/vms/avm/network/gossip_test.go +++ b/vms/avm/network/gossip_test.go @@ -5,6 +5,7 @@ package network import ( "testing" + "time" "github.com/prometheus/client_golang/prometheus" @@ -33,9 +34,12 @@ func (v testVerifier) VerifyTx(*txs.Tx) error { func TestMarshaller(t *testing.T) { require := require.New(t) - parser, err := txs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) marhsaller := txParser{ @@ -62,7 +66,7 @@ func TestGossipMempoolAdd(t *testing.T) { baseMempool, err := mempool.New("", metrics, toEngine) require.NoError(err) - parser, err := txs.NewParser(nil) + parser, err := txs.NewParser(time.Time{}, nil) require.NoError(err) mempool, err := newGossipMempool( @@ -98,7 +102,7 @@ func TestGossipMempoolAddVerified(t *testing.T) { baseMempool, err := mempool.New("", metrics, toEngine) require.NoError(err) - parser, err := txs.NewParser(nil) + parser, err := txs.NewParser(time.Time{}, nil) require.NoError(err) mempool, err := newGossipMempool( diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index b2df09eec1b2..f5b45f8a6aae 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -59,9 +59,12 @@ func TestNetworkAppGossip(t *testing.T) { }, } - parser, err := txs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(t, err) require.NoError(t, testTx.Initialize(parser.Codec())) @@ -183,11 +186,14 @@ func TestNetworkAppGossip(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - parser, err := txs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - &nftfx.Fx{}, - &propertyfx.Fx{}, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + &nftfx.Fx{}, + &propertyfx.Fx{}, + }, + ) require.NoError(err) mempoolFunc := func(ctrl *gomock.Controller) mempool.Mempool { @@ -319,11 +325,14 @@ func TestNetworkIssueTx(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - parser, err := txs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - &nftfx.Fx{}, - &propertyfx.Fx{}, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + &nftfx.Fx{}, + &propertyfx.Fx{}, + }, + ) require.NoError(err) mempoolFunc := func(ctrl *gomock.Controller) mempool.Mempool { @@ -406,11 +415,14 @@ func TestNetworkIssueVerifiedTx(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - parser, err := txs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - &nftfx.Fx{}, - &propertyfx.Fx{}, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + &nftfx.Fx{}, + &propertyfx.Fx{}, + }, + ) require.NoError(err) mempoolFunc := func(ctrl *gomock.Controller) mempool.Mempool { @@ -449,9 +461,12 @@ func TestNetworkGossipTx(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - parser, err := txs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) appSender := common.NewMockSender(ctrl) diff --git a/vms/avm/state/state_test.go b/vms/avm/state/state_test.go index e0b3c8e1794b..758e55ffd7cd 100644 --- a/vms/avm/state/state_test.go +++ b/vms/avm/state/state_test.go @@ -38,9 +38,12 @@ var ( func init() { var err error - parser, err = block.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err = block.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) if err != nil { panic(err) } diff --git a/vms/avm/static_service.go b/vms/avm/static_service.go index 3599a3faa2de..8340bbb6a5df 100644 --- a/vms/avm/static_service.go +++ b/vms/avm/static_service.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "net/http" + "time" stdjson "encoding/json" @@ -77,11 +78,14 @@ type BuildGenesisReply struct { // BuildGenesis returns the UTXOs such that at least one address in [args.Addresses] is // referenced in the UTXO. func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, reply *BuildGenesisReply) error { - parser, err := txs.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - &nftfx.Fx{}, - &propertyfx.Fx{}, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + &nftfx.Fx{}, + &propertyfx.Fx{}, + }, + ) if err != nil { return err } diff --git a/vms/avm/txs/base_tx_test.go b/vms/avm/txs/base_tx_test.go index 4dcb82e38ce7..d7403e3420fc 100644 --- a/vms/avm/txs/base_tx_test.go +++ b/vms/avm/txs/base_tx_test.go @@ -5,6 +5,7 @@ package txs import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -125,9 +126,12 @@ func TestBaseTxSerialization(t *testing.T) { Memo: []byte{0x00, 0x01, 0x02, 0x03}, }}} - parser, err := NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) require.NoError(tx.Initialize(parser.Codec())) diff --git a/vms/avm/txs/create_asset_tx_test.go b/vms/avm/txs/create_asset_tx_test.go index f71ca13b4de1..9ef548eedea2 100644 --- a/vms/avm/txs/create_asset_tx_test.go +++ b/vms/avm/txs/create_asset_tx_test.go @@ -5,6 +5,7 @@ package txs import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -193,9 +194,12 @@ func TestCreateAssetTxSerialization(t *testing.T) { }, }} - parser, err := NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) require.NoError(tx.Initialize(parser.Codec())) @@ -362,9 +366,12 @@ func TestCreateAssetTxSerializationAgain(t *testing.T) { }) } - parser, err := NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) require.NoError(tx.Initialize(parser.Codec())) diff --git a/vms/avm/txs/executor/executor_test.go b/vms/avm/txs/executor/executor_test.go index ba5f13e836ef..66d210b40cb8 100644 --- a/vms/avm/txs/executor/executor_test.go +++ b/vms/avm/txs/executor/executor_test.go @@ -5,6 +5,7 @@ package executor import ( "testing" + "time" "github.com/prometheus/client_golang/prometheus" @@ -37,7 +38,10 @@ func TestBaseTxExecutor(t *testing.T) { require := require.New(t) secpFx := &secp256k1fx.Fx{} - parser, err := block.NewParser([]fxs.Fx{secpFx}) + parser, err := block.NewParser( + time.Time{}, + []fxs.Fx{secpFx}, + ) require.NoError(err) codec := parser.Codec() @@ -142,7 +146,10 @@ func TestCreateAssetTxExecutor(t *testing.T) { require := require.New(t) secpFx := &secp256k1fx.Fx{} - parser, err := block.NewParser([]fxs.Fx{secpFx}) + parser, err := block.NewParser( + time.Time{}, + []fxs.Fx{secpFx}, + ) require.NoError(err) codec := parser.Codec() @@ -285,7 +292,10 @@ func TestOperationTxExecutor(t *testing.T) { require := require.New(t) secpFx := &secp256k1fx.Fx{} - parser, err := block.NewParser([]fxs.Fx{secpFx}) + parser, err := block.NewParser( + time.Time{}, + []fxs.Fx{secpFx}, + ) require.NoError(err) codec := parser.Codec() diff --git a/vms/avm/txs/executor/semantic_verifier_test.go b/vms/avm/txs/executor/semantic_verifier_test.go index 4678d0548fb2..6579e29784d5 100644 --- a/vms/avm/txs/executor/semantic_verifier_test.go +++ b/vms/avm/txs/executor/semantic_verifier_test.go @@ -6,6 +6,7 @@ package executor import ( "reflect" "testing" + "time" "github.com/stretchr/testify/require" @@ -36,6 +37,7 @@ func TestSemanticVerifierBaseTx(t *testing.T) { typeToFxIndex := make(map[reflect.Type]int) secpFx := &secp256k1fx.Fx{} parser, err := txs.NewCustomParser( + time.Time{}, typeToFxIndex, new(mockable.Clock), logging.NoWarn{}, @@ -393,6 +395,7 @@ func TestSemanticVerifierExportTx(t *testing.T) { typeToFxIndex := make(map[reflect.Type]int) secpFx := &secp256k1fx.Fx{} parser, err := txs.NewCustomParser( + time.Time{}, typeToFxIndex, new(mockable.Clock), logging.NoWarn{}, @@ -761,6 +764,7 @@ func TestSemanticVerifierExportTxDifferentSubnet(t *testing.T) { typeToFxIndex := make(map[reflect.Type]int) secpFx := &secp256k1fx.Fx{} parser, err := txs.NewCustomParser( + time.Time{}, typeToFxIndex, new(mockable.Clock), logging.NoWarn{}, @@ -877,6 +881,7 @@ func TestSemanticVerifierImportTx(t *testing.T) { typeToFxIndex := make(map[reflect.Type]int) fx := &secp256k1fx.Fx{} parser, err := txs.NewCustomParser( + time.Time{}, typeToFxIndex, new(mockable.Clock), logging.NoWarn{}, diff --git a/vms/avm/txs/executor/syntactic_verifier_test.go b/vms/avm/txs/executor/syntactic_verifier_test.go index 21f2396148a0..108ac9e94a60 100644 --- a/vms/avm/txs/executor/syntactic_verifier_test.go +++ b/vms/avm/txs/executor/syntactic_verifier_test.go @@ -7,6 +7,7 @@ import ( "math" "strings" "testing" + "time" "github.com/stretchr/testify/require" @@ -36,9 +37,12 @@ func TestSyntacticVerifierBaseTx(t *testing.T) { ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} - parser, err := txs.NewParser([]fxs.Fx{ - fx, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + fx, + }, + ) require.NoError(t, err) feeAssetID := ids.GenerateTestID() @@ -406,9 +410,12 @@ func TestSyntacticVerifierCreateAssetTx(t *testing.T) { ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} - parser, err := txs.NewParser([]fxs.Fx{ - fx, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + fx, + }, + ) require.NoError(t, err) feeAssetID := ids.GenerateTestID() @@ -1013,9 +1020,12 @@ func TestSyntacticVerifierOperationTx(t *testing.T) { ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} - parser, err := txs.NewParser([]fxs.Fx{ - fx, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + fx, + }, + ) require.NoError(t, err) feeAssetID := ids.GenerateTestID() @@ -1500,9 +1510,12 @@ func TestSyntacticVerifierImportTx(t *testing.T) { ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} - parser, err := txs.NewParser([]fxs.Fx{ - fx, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + fx, + }, + ) require.NoError(t, err) feeAssetID := ids.GenerateTestID() @@ -1898,9 +1911,12 @@ func TestSyntacticVerifierExportTx(t *testing.T) { ctx := snowtest.Context(t, snowtest.XChainID) fx := &secp256k1fx.Fx{} - parser, err := txs.NewParser([]fxs.Fx{ - fx, - }) + parser, err := txs.NewParser( + time.Time{}, + []fxs.Fx{ + fx, + }, + ) require.NoError(t, err) feeAssetID := ids.GenerateTestID() diff --git a/vms/avm/txs/export_tx_test.go b/vms/avm/txs/export_tx_test.go index b56ae7003e5b..1d3ce2dee276 100644 --- a/vms/avm/txs/export_tx_test.go +++ b/vms/avm/txs/export_tx_test.go @@ -5,6 +5,7 @@ package txs import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -108,9 +109,12 @@ func TestExportTxSerialization(t *testing.T) { }, }} - parser, err := NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) require.NoError(tx.Initialize(parser.Codec())) diff --git a/vms/avm/txs/import_tx_test.go b/vms/avm/txs/import_tx_test.go index 4e4b95a16447..82dd0cfcd7b2 100644 --- a/vms/avm/txs/import_tx_test.go +++ b/vms/avm/txs/import_tx_test.go @@ -5,6 +5,7 @@ package txs import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -108,9 +109,12 @@ func TestImportTxSerialization(t *testing.T) { }}, }} - parser, err := NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - }) + parser, err := NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + }, + ) require.NoError(err) require.NoError(tx.Initialize(parser.Codec())) diff --git a/vms/avm/txs/initial_state_test.go b/vms/avm/txs/initial_state_test.go index 48c15ae196c4..5f61deb3e7c6 100644 --- a/vms/avm/txs/initial_state_test.go +++ b/vms/avm/txs/initial_state_test.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "testing" + "time" "github.com/stretchr/testify/require" @@ -23,7 +24,7 @@ var errTest = errors.New("non-nil error") func TestInitialStateVerifySerialization(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) require.NoError(c.RegisterType(&secp256k1fx.TransferOutput{})) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(CodecVersion, c)) @@ -80,7 +81,7 @@ func TestInitialStateVerifySerialization(t *testing.T) { func TestInitialStateVerifyNil(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(CodecVersion, c)) numFxs := 1 @@ -93,7 +94,7 @@ func TestInitialStateVerifyNil(t *testing.T) { func TestInitialStateVerifyUnknownFxID(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(CodecVersion, c)) numFxs := 1 @@ -108,7 +109,7 @@ func TestInitialStateVerifyUnknownFxID(t *testing.T) { func TestInitialStateVerifyNilOutput(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(CodecVersion, c)) numFxs := 1 @@ -124,7 +125,7 @@ func TestInitialStateVerifyNilOutput(t *testing.T) { func TestInitialStateVerifyInvalidOutput(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) require.NoError(c.RegisterType(&avax.TestState{})) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(CodecVersion, c)) @@ -141,7 +142,7 @@ func TestInitialStateVerifyInvalidOutput(t *testing.T) { func TestInitialStateVerifyUnsortedOutputs(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) require.NoError(c.RegisterType(&avax.TestTransferable{})) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(CodecVersion, c)) diff --git a/vms/avm/txs/operation_test.go b/vms/avm/txs/operation_test.go index ac9cf62530c6..3ca4676eb370 100644 --- a/vms/avm/txs/operation_test.go +++ b/vms/avm/txs/operation_test.go @@ -5,6 +5,7 @@ package txs import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -79,7 +80,7 @@ func TestOperationVerify(t *testing.T) { func TestOperationSorting(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) require.NoError(c.RegisterType(&testOperable{})) m := codec.NewDefaultManager() diff --git a/vms/avm/txs/parser.go b/vms/avm/txs/parser.go index 6ccd34e35bd6..979c71d8a7c8 100644 --- a/vms/avm/txs/parser.go +++ b/vms/avm/txs/parser.go @@ -7,10 +7,10 @@ import ( "fmt" "math" "reflect" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" - "github.com/ava-labs/avalanchego/codec/reflectcodec" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" @@ -40,8 +40,9 @@ type parser struct { gc linearcodec.Codec } -func NewParser(fxs []fxs.Fx) (Parser, error) { +func NewParser(durangoTime time.Time, fxs []fxs.Fx) (Parser, error) { return NewCustomParser( + durangoTime, make(map[reflect.Type]int), &mockable.Clock{}, logging.NoLog{}, @@ -50,13 +51,14 @@ func NewParser(fxs []fxs.Fx) (Parser, error) { } func NewCustomParser( + durangoTime time.Time, typeToFxIndex map[reflect.Type]int, clock *mockable.Clock, log logging.Logger, fxs []fxs.Fx, ) (Parser, error) { - gc := linearcodec.New([]string{reflectcodec.DefaultTagName}, 1<<20) - c := linearcodec.NewDefault() + gc := linearcodec.NewDefault(time.Time{}) + c := linearcodec.NewDefault(durangoTime) gcm := codec.NewManager(math.MaxInt32) cm := codec.NewDefaultManager() diff --git a/vms/avm/vm.go b/vms/avm/vm.go index fb42158034a7..59907c934e91 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -219,6 +219,7 @@ func (vm *VM) Initialize( vm.typeToFxIndex = map[reflect.Type]int{} vm.parser, err = block.NewCustomParser( + vm.DurangoTime, vm.typeToFxIndex, &vm.clock, ctx.Log, diff --git a/vms/components/avax/asset_test.go b/vms/components/avax/asset_test.go index ccb6f5549630..ad7628ce98b9 100644 --- a/vms/components/avax/asset_test.go +++ b/vms/components/avax/asset_test.go @@ -5,6 +5,7 @@ package avax import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -28,7 +29,7 @@ func TestAssetVerifyEmpty(t *testing.T) { func TestAssetID(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) manager := codec.NewDefaultManager() require.NoError(manager.RegisterCodec(codecVersion, c)) diff --git a/vms/components/avax/transferables_test.go b/vms/components/avax/transferables_test.go index f46d580e839a..755a0124eb7b 100644 --- a/vms/components/avax/transferables_test.go +++ b/vms/components/avax/transferables_test.go @@ -5,6 +5,7 @@ package avax import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -42,7 +43,7 @@ func TestTransferableOutputVerify(t *testing.T) { func TestTransferableOutputSorting(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) require.NoError(c.RegisterType(&TestTransferable{})) manager := codec.NewDefaultManager() require.NoError(manager.RegisterCodec(codecVersion, c)) @@ -84,7 +85,7 @@ func TestTransferableOutputSorting(t *testing.T) { func TestTransferableOutputSerialization(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) require.NoError(c.RegisterType(&secp256k1fx.TransferOutput{})) manager := codec.NewDefaultManager() require.NoError(manager.RegisterCodec(codecVersion, c)) @@ -175,7 +176,7 @@ func TestTransferableInputVerify(t *testing.T) { func TestTransferableInputSorting(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) require.NoError(c.RegisterType(&TestTransferable{})) ins := []*TransferableInput{ @@ -232,7 +233,7 @@ func TestTransferableInputSorting(t *testing.T) { func TestTransferableInputSerialization(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) require.NoError(c.RegisterType(&secp256k1fx.TransferInput{})) manager := codec.NewDefaultManager() require.NoError(manager.RegisterCodec(codecVersion, c)) diff --git a/vms/components/avax/utxo_fetching_test.go b/vms/components/avax/utxo_fetching_test.go index 25fe3fd91155..e36545c19cb7 100644 --- a/vms/components/avax/utxo_fetching_test.go +++ b/vms/components/avax/utxo_fetching_test.go @@ -5,6 +5,7 @@ package avax import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -39,7 +40,7 @@ func TestFetchUTXOs(t *testing.T) { }, } - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) manager := codec.NewDefaultManager() require.NoError(c.RegisterType(&secp256k1fx.TransferOutput{})) @@ -72,7 +73,7 @@ func TestGetPaginatedUTXOs(t *testing.T) { addr2 := ids.GenerateTestShortID() addrs := set.Of(addr0, addr1) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) manager := codec.NewDefaultManager() require.NoError(c.RegisterType(&secp256k1fx.TransferOutput{})) diff --git a/vms/components/avax/utxo_id_test.go b/vms/components/avax/utxo_id_test.go index 09887c0312e9..fed21d5ce986 100644 --- a/vms/components/avax/utxo_id_test.go +++ b/vms/components/avax/utxo_id_test.go @@ -6,6 +6,7 @@ package avax import ( "math" "testing" + "time" "github.com/stretchr/testify/require" @@ -23,7 +24,7 @@ func TestUTXOIDVerifyNil(t *testing.T) { func TestUTXOID(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) manager := codec.NewDefaultManager() require.NoError(manager.RegisterCodec(codecVersion, c)) diff --git a/vms/components/avax/utxo_state_test.go b/vms/components/avax/utxo_state_test.go index 09213bfa1bc6..fa4c530e011a 100644 --- a/vms/components/avax/utxo_state_test.go +++ b/vms/components/avax/utxo_state_test.go @@ -5,6 +5,7 @@ package avax import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -41,7 +42,7 @@ func TestUTXOState(t *testing.T) { } utxoID := utxo.InputID() - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) manager := codec.NewDefaultManager() require.NoError(c.RegisterType(&secp256k1fx.MintOutput{})) diff --git a/vms/components/avax/utxo_test.go b/vms/components/avax/utxo_test.go index 54f8360173a7..a79c8fcb6cd6 100644 --- a/vms/components/avax/utxo_test.go +++ b/vms/components/avax/utxo_test.go @@ -5,6 +5,7 @@ package avax import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -32,7 +33,7 @@ func TestUTXOVerifyEmpty(t *testing.T) { func TestUTXOSerialize(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) manager := codec.NewDefaultManager() require.NoError(c.RegisterType(&secp256k1fx.MintOutput{})) diff --git a/vms/components/keystore/codec.go b/vms/components/keystore/codec.go index 6cfa131ed183..15576b73e4ea 100644 --- a/vms/components/keystore/codec.go +++ b/vms/components/keystore/codec.go @@ -5,6 +5,7 @@ package keystore import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -19,9 +20,9 @@ var ( ) func init() { - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) Codec = codec.NewDefaultManager() - lc := linearcodec.NewCustomMaxLength(math.MaxUint32) + lc := linearcodec.NewDefault(time.Time{}) LegacyCodec = codec.NewManager(math.MaxInt32) err := utils.Err( diff --git a/vms/components/message/codec.go b/vms/components/message/codec.go index bb34ed490c4b..5614125b1cee 100644 --- a/vms/components/message/codec.go +++ b/vms/components/message/codec.go @@ -4,6 +4,8 @@ package message import ( + "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/utils" @@ -14,14 +16,13 @@ const ( CodecVersion = 0 maxMessageSize = 512 * units.KiB - maxSliceLen = maxMessageSize ) var Codec codec.Manager func init() { Codec = codec.NewManager(maxMessageSize) - lc := linearcodec.NewCustomMaxLength(maxSliceLen) + lc := linearcodec.NewDefault(time.Time{}) err := utils.Err( lc.RegisterType(&Tx{}), diff --git a/vms/example/xsvm/tx/codec.go b/vms/example/xsvm/tx/codec.go index c15150c4b37f..f61c7bf18098 100644 --- a/vms/example/xsvm/tx/codec.go +++ b/vms/example/xsvm/tx/codec.go @@ -5,6 +5,7 @@ package tx import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -16,7 +17,7 @@ const CodecVersion = 0 var Codec codec.Manager func init() { - c := linearcodec.NewCustomMaxLength(math.MaxInt32) + c := linearcodec.NewDefault(time.Time{}) Codec = codec.NewManager(math.MaxInt32) err := utils.Err( diff --git a/vms/nftfx/fx_test.go b/vms/nftfx/fx_test.go index 99a047b11328..1ed3426f5b11 100644 --- a/vms/nftfx/fx_test.go +++ b/vms/nftfx/fx_test.go @@ -39,7 +39,7 @@ var ( func TestFxInitialize(t *testing.T) { vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } fx := Fx{} @@ -56,7 +56,7 @@ func TestFxVerifyMintOperation(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -92,7 +92,7 @@ func TestFxVerifyMintOperationWrongTx(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -126,7 +126,7 @@ func TestFxVerifyMintOperationWrongNumberUTXOs(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -157,7 +157,7 @@ func TestFxVerifyMintOperationWrongCredential(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -189,7 +189,7 @@ func TestFxVerifyMintOperationInvalidUTXO(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -220,7 +220,7 @@ func TestFxVerifyMintOperationFailingVerification(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -258,7 +258,7 @@ func TestFxVerifyMintOperationInvalidGroupID(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -296,7 +296,7 @@ func TestFxVerifyTransferOperation(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -346,7 +346,7 @@ func TestFxVerifyTransferOperationWrongUTXO(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -387,7 +387,7 @@ func TestFxVerifyTransferOperationFailedVerify(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -435,7 +435,7 @@ func TestFxVerifyTransferOperationWrongGroupID(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -486,7 +486,7 @@ func TestFxVerifyTransferOperationWrongBytes(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -537,7 +537,7 @@ func TestFxVerifyTransferOperationTooSoon(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -589,7 +589,7 @@ func TestFxVerifyOperationUnknownOperation(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -625,7 +625,7 @@ func TestFxVerifyTransfer(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 7918411b3944..fa7339be6fdb 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -330,7 +330,7 @@ func defaultFx(t *testing.T, clk *mockable.Clock, log logging.Logger, isBootstra require := require.New(t) fxVMInt := &fxVMInt{ - registry: linearcodec.NewDefault(), + registry: linearcodec.NewDefault(time.Time{}), clk: clk, log: log, } diff --git a/vms/platformvm/block/codec.go b/vms/platformvm/block/codec.go index b7338ea98a03..33babbaf3a79 100644 --- a/vms/platformvm/block/codec.go +++ b/vms/platformvm/block/codec.go @@ -5,6 +5,7 @@ package block import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -15,20 +16,23 @@ import ( const CodecVersion = txs.CodecVersion -// GenesisCode allows blocks of larger than usual size to be parsed. -// While this gives flexibility in accommodating large genesis blocks -// it must not be used to parse new, unverified blocks which instead -// must be processed by Codec var ( - Codec codec.Manager + // GenesisCodec allows blocks of larger than usual size to be parsed. + // While this gives flexibility in accommodating large genesis blocks + // it must not be used to parse new, unverified blocks which instead + // must be processed by Codec GenesisCodec codec.Manager + + Codec codec.Manager ) -func init() { - c := linearcodec.NewDefault() - Codec = codec.NewDefaultManager() - gc := linearcodec.NewCustomMaxLength(math.MaxInt32) - GenesisCodec = codec.NewManager(math.MaxInt32) +// TODO: Remove after v1.11.x has activated +// +// Invariant: InitCodec, Codec, and GenesisCodec must not be accessed +// concurrently +func InitCodec(durangoTime time.Time) error { + c := linearcodec.NewDefault(durangoTime) + gc := linearcodec.NewDefault(time.Time{}) errs := wrappers.Errs{} for _, c := range []linearcodec.Codec{c, gc} { @@ -39,12 +43,25 @@ func init() { txs.RegisterDUnsignedTxsTypes(c), ) } + + newCodec := codec.NewDefaultManager() + newGenesisCodec := codec.NewManager(math.MaxInt32) errs.Add( - Codec.RegisterCodec(CodecVersion, c), - GenesisCodec.RegisterCodec(CodecVersion, gc), + newCodec.RegisterCodec(CodecVersion, c), + newGenesisCodec.RegisterCodec(CodecVersion, gc), ) if errs.Errored() { - panic(errs.Err) + return errs.Err + } + + Codec = newCodec + GenesisCodec = newGenesisCodec + return nil +} + +func init() { + if err := InitCodec(time.Time{}); err != nil { + panic(err) } } diff --git a/vms/platformvm/block/executor/helpers_test.go b/vms/platformvm/block/executor/helpers_test.go index 67ace707bd5a..5e7b5a3fce1e 100644 --- a/vms/platformvm/block/executor/helpers_test.go +++ b/vms/platformvm/block/executor/helpers_test.go @@ -345,7 +345,7 @@ func (fvi *fxVMInt) Logger() logging.Logger { func defaultFx(clk *mockable.Clock, log logging.Logger, isBootstrapped bool) fx.Fx { fxVMInt := &fxVMInt{ - registry: linearcodec.NewDefault(), + registry: linearcodec.NewDefault(time.Time{}), clk: clk, log: log, } diff --git a/vms/platformvm/state/metadata_codec.go b/vms/platformvm/state/metadata_codec.go index 400d23e29af2..65832ed77460 100644 --- a/vms/platformvm/state/metadata_codec.go +++ b/vms/platformvm/state/metadata_codec.go @@ -5,6 +5,7 @@ package state import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -22,8 +23,8 @@ const ( var MetadataCodec codec.Manager func init() { - c0 := linearcodec.New([]string{CodecVersion0Tag}, math.MaxInt32) - c1 := linearcodec.New([]string{CodecVersion0Tag, CodecVersion1Tag}, math.MaxInt32) + c0 := linearcodec.New(time.Time{}, []string{CodecVersion0Tag}, math.MaxInt32) + c1 := linearcodec.New(time.Time{}, []string{CodecVersion0Tag, CodecVersion1Tag}, math.MaxInt32) MetadataCodec = codec.NewManager(math.MaxInt32) err := utils.Err( diff --git a/vms/platformvm/txs/codec.go b/vms/platformvm/txs/codec.go index c0c300c4d79b..36fe2e5a8eb0 100644 --- a/vms/platformvm/txs/codec.go +++ b/vms/platformvm/txs/codec.go @@ -5,6 +5,7 @@ package txs import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -27,11 +28,13 @@ var ( GenesisCodec codec.Manager ) -func init() { - c := linearcodec.NewDefault() - Codec = codec.NewDefaultManager() - gc := linearcodec.NewCustomMaxLength(math.MaxInt32) - GenesisCodec = codec.NewManager(math.MaxInt32) +// TODO: Remove after v1.11.x has activated +// +// Invariant: InitCodec, Codec, and GenesisCodec must not be accessed +// concurrently +func InitCodec(durangoTime time.Time) error { + c := linearcodec.NewDefault(durangoTime) + gc := linearcodec.NewDefault(time.Time{}) errs := wrappers.Errs{} for _, c := range []linearcodec.Codec{c, gc} { @@ -46,12 +49,25 @@ func init() { errs.Add(RegisterDUnsignedTxsTypes(c)) } + + newCodec := codec.NewDefaultManager() + newGenesisCodec := codec.NewManager(math.MaxInt32) errs.Add( - Codec.RegisterCodec(CodecVersion, c), - GenesisCodec.RegisterCodec(CodecVersion, gc), + newCodec.RegisterCodec(CodecVersion, c), + newGenesisCodec.RegisterCodec(CodecVersion, gc), ) if errs.Errored() { - panic(errs.Err) + return errs.Err + } + + Codec = newCodec + GenesisCodec = newGenesisCodec + return nil +} + +func init() { + if err := InitCodec(time.Time{}); err != nil { + panic(err) } } diff --git a/vms/platformvm/txs/executor/helpers_test.go b/vms/platformvm/txs/executor/helpers_test.go index b18498fac1e1..1ea645efcfb8 100644 --- a/vms/platformvm/txs/executor/helpers_test.go +++ b/vms/platformvm/txs/executor/helpers_test.go @@ -318,7 +318,7 @@ func (fvi *fxVMInt) Logger() logging.Logger { func defaultFx(clk *mockable.Clock, log logging.Logger, isBootstrapped bool) fx.Fx { fxVMInt := &fxVMInt{ - registry: linearcodec.NewDefault(), + registry: linearcodec.NewDefault(time.Time{}), clk: clk, log: log, } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 341e5329666c..33053aef97f7 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -137,7 +137,8 @@ func (vm *VM) Initialize( vm.ctx = chainCtx vm.db = db - vm.codecRegistry = linearcodec.NewDefault() + // Note: this codec is never used to serialize anything + vm.codecRegistry = linearcodec.NewDefault(time.Time{}) vm.fx = &secp256k1fx.Fx{} if err := vm.fx.Initialize(vm); err != nil { return err diff --git a/vms/platformvm/warp/codec.go b/vms/platformvm/warp/codec.go index 78b194eb6291..6ef6e526bdc1 100644 --- a/vms/platformvm/warp/codec.go +++ b/vms/platformvm/warp/codec.go @@ -5,6 +5,7 @@ package warp import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -17,7 +18,7 @@ var Codec codec.Manager func init() { Codec = codec.NewManager(math.MaxInt) - lc := linearcodec.NewCustomMaxLength(math.MaxInt32) + lc := linearcodec.NewDefault(time.Time{}) err := utils.Err( lc.RegisterType(&BitSetSignature{}), diff --git a/vms/platformvm/warp/payload/codec.go b/vms/platformvm/warp/payload/codec.go index 906b86bc09ed..d188029abfed 100644 --- a/vms/platformvm/warp/payload/codec.go +++ b/vms/platformvm/warp/payload/codec.go @@ -4,6 +4,8 @@ package payload import ( + "time" + "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/utils" @@ -14,17 +16,13 @@ const ( CodecVersion = 0 MaxMessageSize = 24 * units.KiB - - // Note: Modifying this variable can have subtle implications on memory - // usage when parsing malformed payloads. - MaxSliceLen = 24 * 1024 ) var Codec codec.Manager func init() { Codec = codec.NewManager(MaxMessageSize) - lc := linearcodec.NewCustomMaxLength(MaxSliceLen) + lc := linearcodec.NewDefault(time.Time{}) err := utils.Err( lc.RegisterType(&Hash{}), diff --git a/vms/propertyfx/fx_test.go b/vms/propertyfx/fx_test.go index 10a96e6e5b0b..0cd995ba5282 100644 --- a/vms/propertyfx/fx_test.go +++ b/vms/propertyfx/fx_test.go @@ -39,7 +39,7 @@ var ( func TestFxInitialize(t *testing.T) { vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } fx := Fx{} @@ -56,7 +56,7 @@ func TestFxVerifyMintOperation(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -98,7 +98,7 @@ func TestFxVerifyMintOperationWrongTx(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -132,7 +132,7 @@ func TestFxVerifyMintOperationWrongNumberUTXOs(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -163,7 +163,7 @@ func TestFxVerifyMintOperationWrongCredential(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -195,7 +195,7 @@ func TestFxVerifyMintOperationInvalidUTXO(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -226,7 +226,7 @@ func TestFxVerifyMintOperationFailingVerification(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -264,7 +264,7 @@ func TestFxVerifyMintOperationInvalidGroupID(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -301,7 +301,7 @@ func TestFxVerifyTransferOperation(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -335,7 +335,7 @@ func TestFxVerifyTransferOperationWrongUTXO(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -364,7 +364,7 @@ func TestFxVerifyTransferOperationFailedVerify(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -399,7 +399,7 @@ func TestFxVerifyOperationUnknownOperation(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -431,7 +431,7 @@ func TestFxVerifyTransfer(t *testing.T) { require := require.New(t) vm := secp256k1fx.TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) diff --git a/vms/proposervm/block/codec.go b/vms/proposervm/block/codec.go index d3ccce4f1d43..ca2318002093 100644 --- a/vms/proposervm/block/codec.go +++ b/vms/proposervm/block/codec.go @@ -5,6 +5,7 @@ package block import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -16,7 +17,7 @@ const CodecVersion = 0 var Codec codec.Manager func init() { - lc := linearcodec.NewCustomMaxLength(math.MaxUint32) + lc := linearcodec.NewDefault(time.Time{}) // The maximum block size is enforced by the p2p message size limit. // See: [constants.DefaultMaxMessageSize] Codec = codec.NewManager(math.MaxInt) diff --git a/vms/proposervm/state/codec.go b/vms/proposervm/state/codec.go index 21d30d24da86..63727894e356 100644 --- a/vms/proposervm/state/codec.go +++ b/vms/proposervm/state/codec.go @@ -5,6 +5,7 @@ package state import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -15,7 +16,7 @@ const CodecVersion = 0 var Codec codec.Manager func init() { - lc := linearcodec.NewCustomMaxLength(math.MaxUint32) + lc := linearcodec.NewDefault(time.Time{}) Codec = codec.NewManager(math.MaxInt32) err := Codec.RegisterCodec(CodecVersion, lc) diff --git a/vms/proposervm/summary/codec.go b/vms/proposervm/summary/codec.go index 3eaa15e88683..41a9eb9a37d0 100644 --- a/vms/proposervm/summary/codec.go +++ b/vms/proposervm/summary/codec.go @@ -6,6 +6,7 @@ package summary import ( "errors" "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -20,7 +21,7 @@ var ( ) func init() { - lc := linearcodec.NewCustomMaxLength(math.MaxUint32) + lc := linearcodec.NewDefault(time.Time{}) Codec = codec.NewManager(math.MaxInt32) if err := Codec.RegisterCodec(CodecVersion, lc); err != nil { panic(err) diff --git a/vms/secp256k1fx/credential_test.go b/vms/secp256k1fx/credential_test.go index c08548e0bcc7..e69b98b286e7 100644 --- a/vms/secp256k1fx/credential_test.go +++ b/vms/secp256k1fx/credential_test.go @@ -5,6 +5,7 @@ package secp256k1fx import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -27,7 +28,7 @@ func TestCredentialVerifyNil(t *testing.T) { func TestCredentialSerialize(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(0, c)) diff --git a/vms/secp256k1fx/fx_test.go b/vms/secp256k1fx/fx_test.go index 388d7bc14d84..dcdf78385404 100644 --- a/vms/secp256k1fx/fx_test.go +++ b/vms/secp256k1fx/fx_test.go @@ -53,7 +53,7 @@ func init() { func TestFxInitialize(t *testing.T) { vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } fx := Fx{} @@ -69,7 +69,7 @@ func TestFxInitializeInvalid(t *testing.T) { func TestFxVerifyTransfer(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -107,7 +107,7 @@ func TestFxVerifyTransfer(t *testing.T) { func TestFxVerifyTransferNilTx(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -143,7 +143,7 @@ func TestFxVerifyTransferNilTx(t *testing.T) { func TestFxVerifyTransferNilOutput(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -170,7 +170,7 @@ func TestFxVerifyTransferNilOutput(t *testing.T) { func TestFxVerifyTransferNilInput(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -201,7 +201,7 @@ func TestFxVerifyTransferNilInput(t *testing.T) { func TestFxVerifyTransferNilCredential(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -233,7 +233,7 @@ func TestFxVerifyTransferNilCredential(t *testing.T) { func TestFxVerifyTransferInvalidOutput(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -270,7 +270,7 @@ func TestFxVerifyTransferInvalidOutput(t *testing.T) { func TestFxVerifyTransferWrongAmounts(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -307,7 +307,7 @@ func TestFxVerifyTransferWrongAmounts(t *testing.T) { func TestFxVerifyTransferTimelocked(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -344,7 +344,7 @@ func TestFxVerifyTransferTimelocked(t *testing.T) { func TestFxVerifyTransferTooManySigners(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -382,7 +382,7 @@ func TestFxVerifyTransferTooManySigners(t *testing.T) { func TestFxVerifyTransferTooFewSigners(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -417,7 +417,7 @@ func TestFxVerifyTransferTooFewSigners(t *testing.T) { func TestFxVerifyTransferMismatchedSigners(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -455,7 +455,7 @@ func TestFxVerifyTransferMismatchedSigners(t *testing.T) { func TestFxVerifyTransferInvalidSignature(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -495,7 +495,7 @@ func TestFxVerifyTransferInvalidSignature(t *testing.T) { func TestFxVerifyTransferWrongSigner(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -535,7 +535,7 @@ func TestFxVerifyTransferWrongSigner(t *testing.T) { func TestFxVerifyTransferSigIndexOOB(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -575,7 +575,7 @@ func TestFxVerifyTransferSigIndexOOB(t *testing.T) { func TestFxVerifyOperation(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -627,7 +627,7 @@ func TestFxVerifyOperation(t *testing.T) { func TestFxVerifyOperationUnknownTx(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -679,7 +679,7 @@ func TestFxVerifyOperationUnknownTx(t *testing.T) { func TestFxVerifyOperationUnknownOperation(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -709,7 +709,7 @@ func TestFxVerifyOperationUnknownOperation(t *testing.T) { func TestFxVerifyOperationUnknownCredential(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -757,7 +757,7 @@ func TestFxVerifyOperationUnknownCredential(t *testing.T) { func TestFxVerifyOperationWrongNumberOfUTXOs(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -810,7 +810,7 @@ func TestFxVerifyOperationWrongNumberOfUTXOs(t *testing.T) { func TestFxVerifyOperationUnknownUTXOType(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -855,7 +855,7 @@ func TestFxVerifyOperationUnknownUTXOType(t *testing.T) { func TestFxVerifyOperationInvalidOperationVerify(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -905,7 +905,7 @@ func TestFxVerifyOperationInvalidOperationVerify(t *testing.T) { func TestFxVerifyOperationMismatchedMintOutputs(t *testing.T) { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) @@ -952,7 +952,7 @@ func TestFxVerifyOperationMismatchedMintOutputs(t *testing.T) { func TestVerifyPermission(t *testing.T) { vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } fx := Fx{} diff --git a/vms/secp256k1fx/transfer_input_test.go b/vms/secp256k1fx/transfer_input_test.go index 4434584e1a9d..c155d848e559 100644 --- a/vms/secp256k1fx/transfer_input_test.go +++ b/vms/secp256k1fx/transfer_input_test.go @@ -5,6 +5,7 @@ package secp256k1fx import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -80,7 +81,7 @@ func TestTransferInputVerifyUnsorted(t *testing.T) { func TestTransferInputSerialize(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(0, c)) diff --git a/vms/secp256k1fx/transfer_output_test.go b/vms/secp256k1fx/transfer_output_test.go index b1d8a2170b5a..864fb85b9ff0 100644 --- a/vms/secp256k1fx/transfer_output_test.go +++ b/vms/secp256k1fx/transfer_output_test.go @@ -5,6 +5,7 @@ package secp256k1fx import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -135,7 +136,7 @@ func TestOutputVerifyDuplicated(t *testing.T) { func TestOutputSerialize(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(0, c)) diff --git a/wallet/chain/x/constants.go b/wallet/chain/x/constants.go index 44ff38393acc..47efbfc2ff6d 100644 --- a/wallet/chain/x/constants.go +++ b/wallet/chain/x/constants.go @@ -4,6 +4,8 @@ package x import ( + "time" + "github.com/ava-labs/avalanchego/vms/avm/block" "github.com/ava-labs/avalanchego/vms/avm/fxs" "github.com/ava-labs/avalanchego/vms/nftfx" @@ -22,11 +24,14 @@ var Parser block.Parser func init() { var err error - Parser, err = block.NewParser([]fxs.Fx{ - &secp256k1fx.Fx{}, - &nftfx.Fx{}, - &propertyfx.Fx{}, - }) + Parser, err = block.NewParser( + time.Time{}, + []fxs.Fx{ + &secp256k1fx.Fx{}, + &nftfx.Fx{}, + &propertyfx.Fx{}, + }, + ) if err != nil { panic(err) } From c74a08f3fefe1f02452924acd03acc18933e246a Mon Sep 17 00:00:00 2001 From: marun Date: Fri, 5 Jan 2024 13:37:03 -0500 Subject: [PATCH 231/267] `tmpnet`: Use AvalancheLocalChainConfig for cchain genesis (#2583) --- tests/fixture/tmpnet/genesis.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/fixture/tmpnet/genesis.go b/tests/fixture/tmpnet/genesis.go index a200efb3b065..a9c85fe8b441 100644 --- a/tests/fixture/tmpnet/genesis.go +++ b/tests/fixture/tmpnet/genesis.go @@ -148,9 +148,7 @@ func NewTestGenesis( // Define C-Chain genesis cChainGenesis := &core.Genesis{ - Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - }, + Config: params.AvalancheLocalChainConfig, Difficulty: big.NewInt(0), // Difficulty is a mandatory field GasLimit: defaultGasLimit, Alloc: cChainBalances, From 3096b61a6708da8bb7f13133e6713c1f14c7223d Mon Sep 17 00:00:00 2001 From: marun Date: Fri, 5 Jan 2024 14:48:05 -0500 Subject: [PATCH 232/267] `testing`: Ensure CheckBootstrapIsPossible is safe for teardown (#2582) --- tests/fixture/e2e/helpers.go | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index e57949106805..d4a8e3ade568 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -122,9 +122,7 @@ func Eventually(condition func() bool, waitFor time.Duration, tick time.Duration func AddEphemeralNode(network *tmpnet.Network, flags tmpnet.FlagsMap) *tmpnet.Node { require := require.New(ginkgo.GinkgoT()) - ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) - defer cancel() - node, err := network.AddEphemeralNode(ctx, ginkgo.GinkgoWriter, flags) + node, err := network.AddEphemeralNode(DefaultContext(), ginkgo.GinkgoWriter, flags) require.NoError(err) ginkgo.DeferCleanup(func() { @@ -188,16 +186,34 @@ func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { return common.WithBaseFee(baseFee) } -// Verify that a new node can bootstrap into the network. +// Verify that a new node can bootstrap into the network. This function is safe to call +// from `Teardown` by virtue of not depending on ginkgo.DeferCleanup. func CheckBootstrapIsPossible(network *tmpnet.Network) { + require := require.New(ginkgo.GinkgoT()) + if len(os.Getenv(SkipBootstrapChecksEnvName)) > 0 { tests.Outf("{{yellow}}Skipping bootstrap check due to the %s env var being set", SkipBootstrapChecksEnvName) return } ginkgo.By("checking if bootstrap is possible with the current network state") - node := AddEphemeralNode(network, tmpnet.FlagsMap{}) - WaitForHealthy(node) + ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() + + node, err := network.AddEphemeralNode(ctx, ginkgo.GinkgoWriter, tmpnet.FlagsMap{}) + // AddEphemeralNode will initiate node stop if an error is encountered during start, + // so no further cleanup effort is required if an error is seen here. + require.NoError(err) + + // Ensure the node is always stopped at the end of the check + defer func() { + ctx, cancel = context.WithTimeout(context.Background(), DefaultTimeout) + defer cancel() + require.NoError(node.Stop(ctx)) + }() + + // Check that the node becomes healthy within timeout + require.NoError(tmpnet.WaitForHealthy(ctx, node)) } // Start a temporary network with the provided avalanchego binary. From 4d6d25513e9f40f9f924c9fe402a4361671c22c8 Mon Sep 17 00:00:00 2001 From: marun Date: Fri, 5 Jan 2024 15:52:34 -0500 Subject: [PATCH 233/267] `tmpnet`: Separate network into orchestration and configuration (#2464) --- tests/e2e/README.md | 2 +- tests/fixture/e2e/env.go | 4 +- tests/fixture/e2e/helpers.go | 18 +- tests/fixture/tmpnet/README.md | 72 +-- tests/fixture/tmpnet/cmd/main.go | 29 +- tests/fixture/tmpnet/defaults.go | 21 +- tests/fixture/tmpnet/network.go | 714 ++++++++----------------- tests/fixture/tmpnet/network_config.go | 220 ++++++++ tests/fixture/tmpnet/network_test.go | 11 +- tests/fixture/tmpnet/node.go | 6 +- tests/upgrade/upgrade_test.go | 20 +- 11 files changed, 514 insertions(+), 603 deletions(-) create mode 100644 tests/fixture/tmpnet/network_config.go diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 41c724a15051..50ab608a3c4f 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -42,7 +42,7 @@ Define any flags/configurations in [`e2e.go`](./e2e.go). Create a new package to implement feature-specific tests, or add tests to an existing package. For example: ``` -. +tests └── e2e ├── README.md ├── e2e.go diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index ddd50580ade5..d87c0985edd6 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -69,7 +69,7 @@ func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { network = StartNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir) } - uris := tmpnet.GetNodeURIs(network.Nodes) + uris := network.GetNodeURIs() require.NotEmpty(uris, "network contains no nodes") tests.Outf("{{green}}network URIs: {{/}} %+v\n", uris) @@ -132,5 +132,5 @@ func (te *TestEnvironment) NewPrivateNetwork() *tmpnet.Network { privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName) te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute)) - return StartNetwork(sharedNetwork.AvalancheGoPath, privateNetworksDir) + return StartNetwork(sharedNetwork.DefaultRuntimeConfig.AvalancheGoPath, privateNetworksDir) } diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index d4a8e3ade568..706af72dde05 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -217,22 +217,14 @@ func CheckBootstrapIsPossible(network *tmpnet.Network) { } // Start a temporary network with the provided avalanchego binary. -func StartNetwork(avalancheGoExecPath string, networkDir string) *tmpnet.Network { +func StartNetwork(avalancheGoExecPath string, rootNetworkDir string) *tmpnet.Network { require := require.New(ginkgo.GinkgoT()) - network, err := tmpnet.StartNetwork( - DefaultContext(), - ginkgo.GinkgoWriter, - networkDir, - &tmpnet.Network{ - NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ - AvalancheGoPath: avalancheGoExecPath, - }, - }, - tmpnet.DefaultNodeCount, - tmpnet.DefaultPreFundedKeyCount, - ) + network, err := tmpnet.NewDefaultNetwork(ginkgo.GinkgoWriter, avalancheGoExecPath, tmpnet.DefaultNodeCount) require.NoError(err) + require.NoError(network.Create(rootNetworkDir)) + require.NoError(network.Start(DefaultContext(), ginkgo.GinkgoWriter)) + ginkgo.DeferCleanup(func() { tests.Outf("Shutting down network\n") ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout) diff --git a/tests/fixture/tmpnet/README.md b/tests/fixture/tmpnet/README.md index 90ec7f678b2f..abccbf52cf79 100644 --- a/tests/fixture/tmpnet/README.md +++ b/tests/fixture/tmpnet/README.md @@ -30,6 +30,7 @@ the following non-test files: | flags.go | FlagsMap | Simplifies configuration of avalanchego flags | | genesis.go | | Creates test genesis | | network.go | Network | Orchestrates and configures temporary networks | +| network_config.go | Network | Reads and writes network configuration | | node.go | Node | Orchestrates and configures nodes | | node_config.go | Node | Reads and writes node configuration | | node_process.go | NodeProcess | Orchestrates node processes | @@ -73,60 +74,25 @@ network. A temporary network can be managed in code: ```golang -network, _ := tmpnet.StartNetwork( - ctx, // Context used to limit duration of waiting for network health - ginkgo.GinkgoWriter, // Writer to report progress of network start - "", // Use default root dir (~/.tmpnet) - &tmpnet.Network{ - NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ - ExecPath: "/path/to/avalanchego", // Defining the avalanchego exec path is required - }, - }, - 5, // Number of initial validating nodes - 50, // Number of pre-funded keys to create +network, _ := tmpnet.NewDefaultNetwork( + ginkgo.GinkgoWriter, // Writer to report progress of initialization + "/path/to/avalanchego", // The path to the binary that nodes will execute + 5, // Number of initial validating nodes +) +_ = network.Create("") // Finalize network configuration and write to disk +_ = network.Start( // Start the nodes of the network and wait until they report healthy + ctx, // Context used to limit duration of waiting for network health + ginkgo.GinkgoWriter, // Writer to report progress of network start ) -uris := network.GetURIs() +uris := network.GetNodeURIs() // Use URIs to interact with the network // Stop all nodes in the network -network.Stop() +network.Stop(context.Background()) ``` -If non-default node behavior is required, the `Network` instance -supplied to `StartNetwork()` can be initialized with explicit node -configuration and by supplying a nodeCount argument of `0`: - -```golang -network, _ := tmpnet.StartNetwork( - ctx, - ginkgo.GinkgoWriter, - "", - &tmpnet.Network{ - NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ - ExecPath: "/path/to/avalanchego", - }, - Nodes: []*Node{ - { // node1 configuration is customized - Flags: FlagsMap{ // Any and all node flags can be configured here - config.DataDirKey: "/custom/path/to/node/data", - } - }, - }, - {}, // node2 uses default configuration - {}, // node3 uses default configuration - {}, // node4 uses default configuration - {}, // node5 uses default configuration - }, - 0, // Node count must be zero when setting node config - 50, -) -``` - -Further examples of code-based usage are located in the [e2e -tests](../../e2e/e2e_test.go). - ## Networking configuration By default, nodes in a temporary network will be started with staking and @@ -161,18 +127,18 @@ HOME ├── chains │ └── C │ └── config.json // C-Chain config for all nodes - ├── defaults.json // Default flags and configuration for network + ├── config.json // Common configuration (including defaults and pre-funded keys) ├── genesis.json // Genesis for all nodes └── network.env // Sets network dir env var to simplify network usage ``` -### Default flags and configuration +### Common networking configuration -The default avalanchego node flags (e.g. `--staking-port=`) and -default configuration like the avalanchego path are stored at -`[network-dir]/defaults.json`. The value for a given defaulted flag -will be set on initial and subsequently added nodes that do not supply -values for a given defaulted flag. +Network configuration such as default flags (e.g. `--log-level=`), +runtime defaults (e.g. avalanchego path) and pre-funded private keys +are stored at `[network-dir]/config.json`. A given default will only +be applied to a new node on its addition to the network if the node +does not explicitly set a given value. ### Genesis diff --git a/tests/fixture/tmpnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go index 45ed58cef7a5..1ab3f2648325 100644 --- a/tests/fixture/tmpnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -10,6 +10,7 @@ import ( "io/fs" "os" "path/filepath" + "time" "github.com/spf13/cobra" @@ -45,10 +46,9 @@ func main() { rootCmd.AddCommand(versionCmd) var ( - rootDir string - execPath string - nodeCount uint8 - preFundedKeyCount uint8 + rootDir string + execPath string + nodeCount uint8 ) startNetworkCmd := &cobra.Command{ Use: "start-network", @@ -60,15 +60,21 @@ func main() { // Root dir will be defaulted on start if not provided - network := &tmpnet.Network{ - NodeRuntimeConfig: tmpnet.NodeRuntimeConfig{ - AvalancheGoPath: execPath, - }, + network, err := tmpnet.NewDefaultNetwork(os.Stdout, execPath, int(nodeCount)) + if err != nil { + return err } - ctx, cancel := context.WithTimeout(context.Background(), tmpnet.DefaultNetworkTimeout) + + if err := network.Create(rootDir); err != nil { + return err + } + + // Extreme upper bound, should never take this long + networkStartTimeout := 2 * time.Minute + + ctx, cancel := context.WithTimeout(context.Background(), networkStartTimeout) defer cancel() - network, err := tmpnet.StartNetwork(ctx, os.Stdout, rootDir, network, int(nodeCount), int(preFundedKeyCount)) - if err != nil { + if err := network.Start(ctx, os.Stdout); err != nil { return err } @@ -94,7 +100,6 @@ func main() { startNetworkCmd.PersistentFlags().StringVar(&rootDir, "root-dir", os.Getenv(tmpnet.RootDirEnvName), "The path to the root directory for temporary networks") startNetworkCmd.PersistentFlags().StringVar(&execPath, "avalanchego-path", os.Getenv(tmpnet.AvalancheGoPathEnvName), "The path to an avalanchego binary") startNetworkCmd.PersistentFlags().Uint8Var(&nodeCount, "node-count", tmpnet.DefaultNodeCount, "Number of nodes the network should initially consist of") - startNetworkCmd.PersistentFlags().Uint8Var(&preFundedKeyCount, "pre-funded-key-count", tmpnet.DefaultPreFundedKeyCount, "Number of pre-funded keys the network should start with") rootCmd.AddCommand(startNetworkCmd) var networkDir string diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index 8ae303cf9af4..ce09def2582a 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -10,11 +10,6 @@ import ( ) const ( - // Constants defining the names of shell variables whose value can - // configure temporary network orchestration. - NetworkDirEnvName = "TMPNET_NETWORK_DIR" - RootDirEnvName = "TMPNET_ROOT_DIR" - DefaultNetworkTimeout = 2 * time.Minute // Minimum required to ensure connectivity-based health checks will pass @@ -48,12 +43,14 @@ func DefaultFlags() FlagsMap { } } -// C-Chain config for testing. -func DefaultCChainConfig() FlagsMap { - // Supply only non-default configuration to ensure that default - // values will be used. Available C-Chain configuration options are - // defined in the `github.com/ava-labs/coreth/evm` package. - return FlagsMap{ - "log-level": "trace", +// A set of chain configurations appropriate for testing. +func DefaultChainConfigs() map[string]FlagsMap { + return map[string]FlagsMap{ + // Supply only non-default configuration to ensure that default + // values will be used. Available C-Chain configuration options are + // defined in the `github.com/ava-labs/coreth/evm` package. + "C": { + "log-level": "trace", + }, } } diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 0c5818efa0ee..da18b59c0c58 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -5,7 +5,6 @@ package tmpnet import ( "context" - "encoding/json" "errors" "fmt" "io" @@ -24,114 +23,121 @@ import ( "github.com/ava-labs/avalanchego/utils/set" ) +// The Network type is defined in this file (orchestration) and +// network_config.go (reading/writing configuration). + const ( + // Constants defining the names of shell variables whose value can + // configure network orchestration. + NetworkDirEnvName = "TMPNET_NETWORK_DIR" + RootDirEnvName = "TMPNET_ROOT_DIR" + // This interval was chosen to avoid spamming node APIs during // startup, as smaller intervals (e.g. 50ms) seemed to noticeably // increase the time for a network's nodes to be seen as healthy. networkHealthCheckInterval = 200 * time.Millisecond - - defaultEphemeralDirName = "ephemeral" ) -var ( - errInvalidNodeCount = errors.New("failed to populate network config: non-zero node count is only valid for a network without nodes") - errInvalidKeyCount = errors.New("failed to populate network config: non-zero key count is only valid for a network without keys") - errNetworkDirNotSet = errors.New("network directory not set - has Create() been called?") - errInvalidNetworkDir = errors.New("failed to write network: invalid network directory") - errMissingBootstrapNodes = errors.New("failed to add node due to missing bootstrap nodes") -) +// Collects the configuration for running a temporary avalanchego network +type Network struct { + // Path where network configuration and data is stored + Dir string -// Default root dir for storing networks and their configuration. -func GetDefaultRootDir() (string, error) { - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } - return filepath.Join(homeDir, ".tmpnet", "networks"), nil -} + // Configuration common across nodes + Genesis *genesis.UnparsedConfig + ChainConfigs map[string]FlagsMap -// Find the next available network ID by attempting to create a -// directory numbered from 1000 until creation succeeds. Returns the -// network id and the full path of the created directory. -func FindNextNetworkID(rootDir string) (uint32, string, error) { - var ( - networkID uint32 = 1000 - dirPath string - ) - for { - _, reserved := constants.NetworkIDToNetworkName[networkID] - if reserved { - networkID++ - continue - } + // Default configuration to use when creating new nodes + DefaultFlags FlagsMap + DefaultRuntimeConfig NodeRuntimeConfig - dirPath = filepath.Join(rootDir, strconv.FormatUint(uint64(networkID), 10)) - err := os.Mkdir(dirPath, perms.ReadWriteExecute) - if err == nil { - return networkID, dirPath, nil - } + // Keys pre-funded in the genesis on both the X-Chain and the C-Chain + PreFundedKeys []*secp256k1.PrivateKey - if !errors.Is(err, fs.ErrExist) { - return 0, "", fmt.Errorf("failed to create network directory: %w", err) - } + // Nodes that constitute the network + Nodes []*Node +} - // Directory already exists, keep iterating - networkID++ +// Ensure a real and absolute network dir so that node +// configuration that embeds the network path will continue to +// work regardless of symlink and working directory changes. +func toCanonicalDir(dir string) (string, error) { + absDir, err := filepath.Abs(dir) + if err != nil { + return "", err } + return filepath.EvalSymlinks(absDir) } -// Defines the configuration required for a tempoary network -type Network struct { - NodeRuntimeConfig +// Initializes a new network with default configuration. +func NewDefaultNetwork(w io.Writer, avalancheGoPath string, nodeCount int) (*Network, error) { + if _, err := fmt.Fprintf(w, "Preparing configuration for new network with %s\n", avalancheGoPath); err != nil { + return nil, err + } - Genesis *genesis.UnparsedConfig - CChainConfig FlagsMap - DefaultFlags FlagsMap - PreFundedKeys []*secp256k1.PrivateKey + keys, err := NewPrivateKeys(DefaultPreFundedKeyCount) + if err != nil { + return nil, err + } - // Nodes comprising the network - Nodes []*Node + network := &Network{ + DefaultFlags: DefaultFlags(), + DefaultRuntimeConfig: NodeRuntimeConfig{ + AvalancheGoPath: avalancheGoPath, + }, + PreFundedKeys: keys, + ChainConfigs: DefaultChainConfigs(), + } - // Path where network configuration will be stored - Dir string + network.Nodes = make([]*Node, nodeCount) + for i := range network.Nodes { + network.Nodes[i] = NewNode("") + if err := network.EnsureNodeConfig(network.Nodes[i]); err != nil { + return nil, err + } + } + + return network, nil } -// Adds a backend-agnostic ephemeral node to the network -func (n *Network) AddEphemeralNode(ctx context.Context, w io.Writer, flags FlagsMap) (*Node, error) { - if flags == nil { - flags = FlagsMap{} +// Stops the nodes of the network configured in the provided directory. +func StopNetwork(ctx context.Context, dir string) error { + network, err := ReadNetwork(dir) + if err != nil { + return err } - return n.AddNode(ctx, w, &Node{ - Flags: flags, - }, true /* isEphemeral */) + return network.Stop(ctx) } -// Starts a new network stored under the provided root dir. Required -// configuration will be defaulted if not provided. -func StartNetwork( - ctx context.Context, - w io.Writer, - rootDir string, - network *Network, - nodeCount int, - keyCount int, -) (*Network, error) { - if _, err := fmt.Fprintf(w, "Preparing configuration for new temporary network with %s\n", network.AvalancheGoPath); err != nil { +// Reads a network from the provided directory. +func ReadNetwork(dir string) (*Network, error) { + canonicalDir, err := toCanonicalDir(dir) + if err != nil { return nil, err } + network := &Network{ + Dir: canonicalDir, + } + if err := network.Read(); err != nil { + return nil, fmt.Errorf("failed to read network: %w", err) + } + return network, nil +} +// Creates the network on disk, choosing its network id and generating its genesis in the process. +func (n *Network) Create(rootDir string) error { if len(rootDir) == 0 { // Use the default root dir var err error - rootDir, err = GetDefaultRootDir() + rootDir, err = getDefaultRootDir() if err != nil { - return nil, err + return err } } // Ensure creation of the root dir if err := os.MkdirAll(rootDir, perms.ReadWriteExecute); err != nil { - return nil, fmt.Errorf("failed to create root network dir: %w", err) + return fmt.Errorf("failed to create root network dir: %w", err) } // Determine the network path and ID @@ -139,107 +145,30 @@ func StartNetwork( networkDir string networkID uint32 ) - if network.Genesis != nil && network.Genesis.NetworkID > 0 { + if n.Genesis != nil && n.Genesis.NetworkID > 0 { // Use the network ID defined in the provided genesis - networkID = network.Genesis.NetworkID + networkID = n.Genesis.NetworkID } if networkID > 0 { // Use a directory with a random suffix var err error - networkDir, err = os.MkdirTemp(rootDir, fmt.Sprintf("%d.", network.Genesis.NetworkID)) + networkDir, err = os.MkdirTemp(rootDir, fmt.Sprintf("%d.", n.Genesis.NetworkID)) if err != nil { - return nil, fmt.Errorf("failed to create network dir: %w", err) + return fmt.Errorf("failed to create network dir: %w", err) } } else { // Find the next available network ID based on the contents of the root dir var err error - networkID, networkDir, err = FindNextNetworkID(rootDir) + networkID, networkDir, err = findNextNetworkID(rootDir) if err != nil { - return nil, err + return err } } - - // Setting the network dir before populating config ensures the - // nodes know where to write their configuration. - network.Dir = networkDir - - if err := network.PopulateNetworkConfig(networkID, nodeCount, keyCount); err != nil { - return nil, err - } - - if err := network.WriteAll(); err != nil { - return nil, err - } - if _, err := fmt.Fprintf(w, "Starting network %d @ %s\n", network.Genesis.NetworkID, network.Dir); err != nil { - return nil, err - } - if err := network.Start(w); err != nil { - return nil, err - } - if _, err := fmt.Fprintf(w, "Waiting for all nodes to report healthy...\n\n"); err != nil { - return nil, err - } - if err := network.WaitForHealthy(ctx, w); err != nil { - return nil, err - } - if _, err := fmt.Fprintf(w, "\nStarted network %d @ %s\n", network.Genesis.NetworkID, network.Dir); err != nil { - return nil, err - } - return network, nil -} - -// Read a network from the provided directory. -func ReadNetwork(dir string) (*Network, error) { - network := &Network{Dir: dir} - if err := network.ReadAll(); err != nil { - return nil, fmt.Errorf("failed to read network: %w", err) - } - return network, nil -} - -// Stop the nodes of the network configured in the provided directory. -func StopNetwork(ctx context.Context, dir string) error { - network, err := ReadNetwork(dir) + canonicalDir, err := toCanonicalDir(networkDir) if err != nil { return err } - return network.Stop(ctx) -} - -// Ensure the network has the configuration it needs to start. -func (n *Network) PopulateNetworkConfig(networkID uint32, nodeCount int, keyCount int) error { - if len(n.Nodes) > 0 && nodeCount > 0 { - return errInvalidNodeCount - } - if len(n.PreFundedKeys) > 0 && keyCount > 0 { - return errInvalidKeyCount - } - - if nodeCount > 0 { - // Add the specified number of nodes - nodes := make([]*Node, 0, nodeCount) - for i := 0; i < nodeCount; i++ { - nodes = append(nodes, NewNode("")) - } - n.Nodes = nodes - } - - // Ensure each node has keys and an associated node ID. This - // ensures the availability of node IDs and proofs of possession - // for genesis generation. - for _, node := range n.Nodes { - if err := node.EnsureKeys(); err != nil { - return err - } - } - - if keyCount > 0 { - keys, err := NewPrivateKeys(keyCount) - if err != nil { - return err - } - n.PreFundedKeys = keys - } + n.Dir = canonicalDir if n.Genesis == nil { genesis, err := NewTestGenesis(networkID, n.Nodes, n.PreFundedKeys) @@ -249,117 +178,81 @@ func (n *Network) PopulateNetworkConfig(networkID uint32, nodeCount int, keyCoun n.Genesis = genesis } - if n.CChainConfig == nil { - n.CChainConfig = DefaultCChainConfig() - } - - // Default flags need to be set in advance of node config - // population to ensure correct node configuration. - if n.DefaultFlags == nil { - n.DefaultFlags = DefaultFlags() - } - for _, node := range n.Nodes { // Ensure the node is configured for use with the network and // knows where to write its configuration. - if err := n.PopulateNodeConfig(node, n.Dir); err != nil { - return err + if err := n.EnsureNodeConfig(node); err != nil { + return nil } } - return nil + // Ensure configuration on disk is current + return n.Write() } -// Ensure the provided node has the configuration it needs to start. If the data dir is -// not set, it will be defaulted to [nodeParentDir]/[node ID]. Requires that the -// network has valid genesis data. -func (n *Network) PopulateNodeConfig(node *Node, nodeParentDir string) error { - flags := node.Flags - - // Set values common to all nodes - flags.SetDefaults(n.DefaultFlags) - flags.SetDefaults(FlagsMap{ - config.GenesisFileKey: n.GetGenesisPath(), - config.ChainConfigDirKey: n.GetChainConfigDir(), - }) - - // Convert the network id to a string to ensure consistency in JSON round-tripping. - flags[config.NetworkNameKey] = strconv.FormatUint(uint64(n.Genesis.NetworkID), 10) - - // Ensure keys are added if necessary - if err := node.EnsureKeys(); err != nil { +// Starts all nodes in the network +func (n *Network) Start(ctx context.Context, w io.Writer) error { + if _, err := fmt.Fprintf(w, "Starting network %d @ %s\n", n.Genesis.NetworkID, n.Dir); err != nil { return err } - // Ensure the node is configured with a runtime config - if node.RuntimeConfig == nil { - node.RuntimeConfig = &NodeRuntimeConfig{ - AvalancheGoPath: n.AvalancheGoPath, + // Configure the networking for each node and start + for _, node := range n.Nodes { + if err := n.StartNode(ctx, w, node); err != nil { + return err } } - // Ensure the node's data dir is configured - dataDir := node.getDataDir() - if len(dataDir) == 0 { - // NodeID will have been set by EnsureKeys - dataDir = filepath.Join(nodeParentDir, node.NodeID.String()) - flags[config.DataDirKey] = dataDir + if _, err := fmt.Fprintf(w, "Waiting for all nodes to report healthy...\n\n"); err != nil { + return err + } + if err := n.WaitForHealthy(ctx, w); err != nil { + return err + } + if _, err := fmt.Fprintf(w, "\nStarted network %d @ %s\n", n.Genesis.NetworkID, n.Dir); err != nil { + return err } return nil } -// Starts a network for the first time -func (n *Network) Start(w io.Writer) error { - if len(n.Dir) == 0 { - return errNetworkDirNotSet +func (n *Network) AddEphemeralNode(ctx context.Context, w io.Writer, flags FlagsMap) (*Node, error) { + node := NewNode("") + node.Flags = flags + node.IsEphemeral = true + if err := n.StartNode(ctx, w, node); err != nil { + return nil, err } + return node, nil +} - // Ensure configuration on disk is current - if err := n.WriteAll(); err != nil { +// Starts the provided node after configuring it for the network. +func (n *Network) StartNode(ctx context.Context, w io.Writer, node *Node) error { + if err := n.EnsureNodeConfig(node); err != nil { return err } - // Accumulate bootstrap nodes such that each subsequently started - // node bootstraps from the nodes previously started. - // - // e.g. - // 1st node: no bootstrap nodes - // 2nd node: 1st node - // 3rd node: 1st and 2nd nodes - // ... - // - bootstrapIDs := make([]string, 0, len(n.Nodes)) - bootstrapIPs := make([]string, 0, len(n.Nodes)) - - // Configure networking and start each node - for _, node := range n.Nodes { - // Update network configuration - node.SetNetworkingConfig(bootstrapIDs, bootstrapIPs) - - // Write configuration to disk in preparation for node start - if err := node.Write(); err != nil { - return err - } + bootstrapIPs, bootstrapIDs, err := n.getBootstrapIPsAndIDs(node) + if err != nil { + return err + } + node.SetNetworkingConfig(bootstrapIDs, bootstrapIPs) - // Start waits for the process context to be written which - // indicates that the node will be accepting connections on - // its staking port. The network will start faster with this - // synchronization due to the avoidance of exponential backoff - // if a node tries to connect to a beacon that is not ready. - if err := node.Start(w); err != nil { - return err - } + if err := node.Write(); err != nil { + return err + } - // Collect bootstrap nodes for subsequently started nodes to use - bootstrapIDs = append(bootstrapIDs, node.NodeID.String()) - bootstrapIPs = append(bootstrapIPs, node.StakingAddress) + if err := node.Start(w); err != nil { + // Attempt to stop an unhealthy node to provide some assurance to the caller + // that an error condition will not result in a lingering process. + err = errors.Join(err, node.Stop(ctx)) + return err } return nil } -// Wait until all nodes in the network are healthy. +// Waits until all nodes in the network are healthy. func (n *Network) WaitForHealthy(ctx context.Context, w io.Writer) error { ticker := time.NewTicker(networkHealthCheckInterval) defer ticker.Stop() @@ -394,303 +287,150 @@ func (n *Network) WaitForHealthy(ctx context.Context, w io.Writer) error { return nil } -// Retrieve API URIs for all running primary validator nodes. URIs for -// ephemeral nodes are not returned. -func (n *Network) GetURIs() []NodeURI { - uris := make([]NodeURI, 0, len(n.Nodes)) - for _, node := range n.Nodes { - // Only append URIs that are not empty. A node may have an - // empty URI if it was not running at the time - // node.ReadProcessContext() was called. - if len(node.URI) > 0 { - uris = append(uris, NodeURI{ - NodeID: node.NodeID, - URI: node.URI, - }) - } +// Stops all nodes in the network. +func (n *Network) Stop(ctx context.Context) error { + // Target all nodes, including the ephemeral ones + nodes, err := ReadNodes(n.Dir, true /* includeEphemeral */) + if err != nil { + return err } - return uris -} -// Stop all nodes in the network. -func (n *Network) Stop(ctx context.Context) error { var errs []error - // Assume the nodes are loaded and the pids are current - for _, node := range n.Nodes { - if err := node.Stop(ctx); err != nil { + + // Initiate stop on all nodes + for _, node := range nodes { + if err := node.InitiateStop(); err != nil { errs = append(errs, fmt.Errorf("failed to stop node %s: %w", node.NodeID, err)) } } - if len(errs) > 0 { - return fmt.Errorf("failed to stop network:\n%w", errors.Join(errs...)) - } - return nil -} - -func (n *Network) GetGenesisPath() string { - return filepath.Join(n.Dir, "genesis.json") -} - -func (n *Network) ReadGenesis() error { - bytes, err := os.ReadFile(n.GetGenesisPath()) - if err != nil { - return fmt.Errorf("failed to read genesis: %w", err) - } - genesis := genesis.UnparsedConfig{} - if err := json.Unmarshal(bytes, &genesis); err != nil { - return fmt.Errorf("failed to unmarshal genesis: %w", err) - } - n.Genesis = &genesis - return nil -} -func (n *Network) WriteGenesis() error { - bytes, err := DefaultJSONMarshal(n.Genesis) - if err != nil { - return fmt.Errorf("failed to marshal genesis: %w", err) - } - if err := os.WriteFile(n.GetGenesisPath(), bytes, perms.ReadWrite); err != nil { - return fmt.Errorf("failed to write genesis: %w", err) + // Wait for stop to complete on all nodes + for _, node := range nodes { + if err := node.WaitForStopped(ctx); err != nil { + errs = append(errs, fmt.Errorf("failed to wait for node %s to stop: %w", node.NodeID, err)) + } } - return nil -} -func (n *Network) GetChainConfigDir() string { - return filepath.Join(n.Dir, "chains") -} - -func (n *Network) GetCChainConfigPath() string { - return filepath.Join(n.GetChainConfigDir(), "C", "config.json") -} - -func (n *Network) ReadCChainConfig() error { - chainConfig, err := ReadFlagsMap(n.GetCChainConfigPath(), "C-Chain config") - if err != nil { - return err + if len(errs) > 0 { + return fmt.Errorf("failed to stop network:\n%w", errors.Join(errs...)) } - n.CChainConfig = *chainConfig return nil } -func (n *Network) WriteCChainConfig() error { - path := n.GetCChainConfigPath() - dir := filepath.Dir(path) - if err := os.MkdirAll(dir, perms.ReadWriteExecute); err != nil { - return fmt.Errorf("failed to create C-Chain config dir: %w", err) - } - return n.CChainConfig.Write(path, "C-Chain config") -} - -// Used to marshal/unmarshal persistent network defaults. -type networkDefaults struct { - Flags FlagsMap - AvalancheGoPath string - PreFundedKeys []*secp256k1.PrivateKey -} - -func (n *Network) GetDefaultsPath() string { - return filepath.Join(n.Dir, "defaults.json") -} +// Ensures the provided node has the configuration it needs to start. If the data dir is not +// set, it will be defaulted to [nodeParentDir]/[node ID]. For a not-yet-created network, +// no action will be taken. +// TODO(marun) Reword or refactor to account for the differing behavior pre- vs post-start +func (n *Network) EnsureNodeConfig(node *Node) error { + flags := node.Flags -func (n *Network) ReadDefaults() error { - bytes, err := os.ReadFile(n.GetDefaultsPath()) - if err != nil { - return fmt.Errorf("failed to read defaults: %w", err) - } - defaults := networkDefaults{} - if err := json.Unmarshal(bytes, &defaults); err != nil { - return fmt.Errorf("failed to unmarshal defaults: %w", err) + // Set the network name if available + if n.Genesis != nil && n.Genesis.NetworkID > 0 { + // Convert the network id to a string to ensure consistency in JSON round-tripping. + flags[config.NetworkNameKey] = strconv.FormatUint(uint64(n.Genesis.NetworkID), 10) } - n.DefaultFlags = defaults.Flags - n.AvalancheGoPath = defaults.AvalancheGoPath - n.PreFundedKeys = defaults.PreFundedKeys - return nil -} -func (n *Network) WriteDefaults() error { - defaults := networkDefaults{ - Flags: n.DefaultFlags, - AvalancheGoPath: n.AvalancheGoPath, - PreFundedKeys: n.PreFundedKeys, - } - bytes, err := DefaultJSONMarshal(defaults) - if err != nil { - return fmt.Errorf("failed to marshal defaults: %w", err) - } - if err := os.WriteFile(n.GetDefaultsPath(), bytes, perms.ReadWrite); err != nil { - return fmt.Errorf("failed to write defaults: %w", err) + if err := node.EnsureKeys(); err != nil { + return err } - return nil -} - -func (n *Network) EnvFilePath() string { - return filepath.Join(n.Dir, "network.env") -} -func (n *Network) EnvFileContents() string { - return fmt.Sprintf("export %s=%s", NetworkDirEnvName, n.Dir) -} + flags.SetDefaults(n.DefaultFlags) -// Write an env file that sets the network dir env when sourced. -func (n *Network) WriteEnvFile() error { - if err := os.WriteFile(n.EnvFilePath(), []byte(n.EnvFileContents()), perms.ReadWrite); err != nil { - return fmt.Errorf("failed to write network env file: %w", err) + // Set fields including the network path + if len(n.Dir) > 0 { + node.Flags.SetDefaults(FlagsMap{ + config.GenesisFileKey: n.getGenesisPath(), + config.ChainConfigDirKey: n.getChainConfigDir(), + }) + + // Ensure the node's data dir is configured + dataDir := node.getDataDir() + if len(dataDir) == 0 { + // NodeID will have been set by EnsureKeys + dataDir = filepath.Join(n.Dir, node.NodeID.String()) + flags[config.DataDirKey] = dataDir + } } - return nil -} -func (n *Network) WriteNodes() error { - for _, node := range n.Nodes { - if err := node.Write(); err != nil { - return err + // Ensure the node runtime is configured + if node.RuntimeConfig == nil { + node.RuntimeConfig = &NodeRuntimeConfig{ + AvalancheGoPath: n.DefaultRuntimeConfig.AvalancheGoPath, } } - return nil -} -// Write network configuration to disk. -func (n *Network) WriteAll() error { - if len(n.Dir) == 0 { - return errInvalidNetworkDir - } - if err := n.WriteGenesis(); err != nil { - return err - } - if err := n.WriteCChainConfig(); err != nil { - return err - } - if err := n.WriteDefaults(); err != nil { - return err - } - if err := n.WriteEnvFile(); err != nil { - return err - } - return n.WriteNodes() + return nil } -// Read network configuration from disk. -func (n *Network) ReadConfig() error { - if err := n.ReadGenesis(); err != nil { - return err - } - if err := n.ReadCChainConfig(); err != nil { - return err - } - return n.ReadDefaults() +func (n *Network) GetNodeURIs() []NodeURI { + return GetNodeURIs(n.Nodes) } -// Read node configuration and process context from disk. -func (n *Network) ReadNodes() error { - nodes := []*Node{} - - // Node configuration / process context is stored in child directories - entries, err := os.ReadDir(n.Dir) +// Retrieves bootstrap IPs and IDs for all nodes except the skipped one (this supports +// collecting the bootstrap details for restarting a node). +func (n *Network) getBootstrapIPsAndIDs(skippedNode *Node) ([]string, []string, error) { + // Collect staking addresses of non-ephemeral nodes for use in bootstrapping a node + nodes, err := ReadNodes(n.Dir, false /* includeEphemeral */) if err != nil { - return fmt.Errorf("failed to read network path: %w", err) + return nil, nil, fmt.Errorf("failed to read network's nodes: %w", err) } - for _, entry := range entries { - if !entry.IsDir() { + var ( + bootstrapIPs = make([]string, 0, len(nodes)) + bootstrapIDs = make([]string, 0, len(nodes)) + ) + for _, node := range nodes { + if skippedNode != nil && node.NodeID == skippedNode.NodeID { continue } - nodeDir := filepath.Join(n.Dir, entry.Name()) - node, err := ReadNode(nodeDir) - if errors.Is(err, os.ErrNotExist) { - // If no config file exists, assume this is not the path of a node + if len(node.StakingAddress) == 0 { + // Node is not running continue - } else if err != nil { - return err } - nodes = append(nodes, node) + bootstrapIPs = append(bootstrapIPs, node.StakingAddress) + bootstrapIDs = append(bootstrapIDs, node.NodeID.String()) } - n.Nodes = nodes - - return nil -} - -// Read network and node configuration from disk. -func (n *Network) ReadAll() error { - if err := n.ReadConfig(); err != nil { - return err - } - return n.ReadNodes() + return bootstrapIPs, bootstrapIDs, nil } -func (n *Network) AddNode(ctx context.Context, w io.Writer, node *Node, isEphemeral bool) (*Node, error) { - // Assume network configuration has been written to disk and is current in memory - - if node == nil { - // Set an empty data dir so that PopulateNodeConfig will know - // to set the default of `[network dir]/[node id]`. - node = NewNode("") - } - - // Default to a data dir of [network-dir]/[node-ID] - nodeParentDir := n.Dir - if isEphemeral { - // For an ephemeral node, default to a data dir of [network-dir]/[ephemeral-dir]/[node-ID] - // to provide a clear separation between nodes that are expected to expose stable API - // endpoints and those that will live for only a short time (e.g. a node started by a test - // and stopped on teardown). - // - // The data for an ephemeral node is still stored in the file tree rooted at the network - // dir to ensure that recursively archiving the network dir in CI will collect all node - // data used for a test run. - nodeParentDir = filepath.Join(n.Dir, defaultEphemeralDirName) - } - - if err := n.PopulateNodeConfig(node, nodeParentDir); err != nil { - return nil, err - } - - bootstrapIPs, bootstrapIDs, err := n.GetBootstrapIPsAndIDs() - if err != nil { - return nil, err - } - node.SetNetworkingConfig(bootstrapIDs, bootstrapIPs) - - if err := node.Write(); err != nil { - return nil, err - } - - err = node.Start(w) +// Retrieves the default root dir for storing networks and their +// configuration. +func getDefaultRootDir() (string, error) { + homeDir, err := os.UserHomeDir() if err != nil { - // Attempt to stop an unhealthy node to provide some assurance to the caller - // that an error condition will not result in a lingering process. - stopErr := node.Stop(ctx) - if stopErr != nil { - err = errors.Join(err, stopErr) - } - return nil, err + return "", err } - - return node, nil + return filepath.Join(homeDir, ".tmpnet", "networks"), nil } -func (n *Network) GetBootstrapIPsAndIDs() ([]string, []string, error) { - // Collect staking addresses of running nodes for use in bootstrapping a node - if err := n.ReadNodes(); err != nil { - return nil, nil, fmt.Errorf("failed to read network nodes: %w", err) - } +// Finds the next available network ID by attempting to create a +// directory numbered from 1000 until creation succeeds. Returns the +// network id and the full path of the created directory. +func findNextNetworkID(rootDir string) (uint32, string, error) { var ( - bootstrapIPs = make([]string, 0, len(n.Nodes)) - bootstrapIDs = make([]string, 0, len(n.Nodes)) + networkID uint32 = 1000 + dirPath string ) - for _, node := range n.Nodes { - if len(node.StakingAddress) == 0 { - // Node is not running + for { + _, reserved := constants.NetworkIDToNetworkName[networkID] + if reserved { + networkID++ continue } - bootstrapIPs = append(bootstrapIPs, node.StakingAddress) - bootstrapIDs = append(bootstrapIDs, node.NodeID.String()) - } + dirPath = filepath.Join(rootDir, strconv.FormatUint(uint64(networkID), 10)) + err := os.Mkdir(dirPath, perms.ReadWriteExecute) + if err == nil { + return networkID, dirPath, nil + } - if len(bootstrapIDs) == 0 { - return nil, nil, errMissingBootstrapNodes - } + if !errors.Is(err, fs.ErrExist) { + return 0, "", fmt.Errorf("failed to create network directory: %w", err) + } - return bootstrapIPs, bootstrapIDs, nil + // Directory already exists, keep iterating + networkID++ + } } diff --git a/tests/fixture/tmpnet/network_config.go b/tests/fixture/tmpnet/network_config.go new file mode 100644 index 000000000000..967a2b1b4ee3 --- /dev/null +++ b/tests/fixture/tmpnet/network_config.go @@ -0,0 +1,220 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package tmpnet + +import ( + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/perms" +) + +// The Network type is defined in this file (reading/writing configuration) and network.go +// (orchestration). + +var errMissingNetworkDir = errors.New("failed to write network: missing network directory") + +// Read network and node configuration from disk. +func (n *Network) Read() error { + if err := n.readNetwork(); err != nil { + return err + } + return n.readNodes() +} + +// Write network configuration to disk. +func (n *Network) Write() error { + if len(n.Dir) == 0 { + return errMissingNetworkDir + } + if err := n.writeGenesis(); err != nil { + return err + } + if err := n.writeChainConfigs(); err != nil { + return err + } + if err := n.writeNetworkConfig(); err != nil { + return err + } + if err := n.writeEnvFile(); err != nil { + return err + } + return n.writeNodes() +} + +// Read network configuration from disk. +func (n *Network) readNetwork() error { + if err := n.readGenesis(); err != nil { + return err + } + if err := n.readChainConfigs(); err != nil { + return err + } + return n.readConfig() +} + +// Read the non-ephemeral nodes associated with the network from disk. +func (n *Network) readNodes() error { + nodes, err := ReadNodes(n.Dir, false /* includeEphemeral */) + if err != nil { + return err + } + n.Nodes = nodes + return nil +} + +func (n *Network) writeNodes() error { + for _, node := range n.Nodes { + if err := node.Write(); err != nil { + return err + } + } + return nil +} + +func (n *Network) getGenesisPath() string { + return filepath.Join(n.Dir, "genesis.json") +} + +func (n *Network) readGenesis() error { + bytes, err := os.ReadFile(n.getGenesisPath()) + if err != nil { + return fmt.Errorf("failed to read genesis: %w", err) + } + genesis := genesis.UnparsedConfig{} + if err := json.Unmarshal(bytes, &genesis); err != nil { + return fmt.Errorf("failed to unmarshal genesis: %w", err) + } + n.Genesis = &genesis + return nil +} + +func (n *Network) writeGenesis() error { + bytes, err := DefaultJSONMarshal(n.Genesis) + if err != nil { + return fmt.Errorf("failed to marshal genesis: %w", err) + } + if err := os.WriteFile(n.getGenesisPath(), bytes, perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write genesis: %w", err) + } + return nil +} + +func (n *Network) getChainConfigDir() string { + return filepath.Join(n.Dir, "chains") +} + +func (n *Network) readChainConfigs() error { + baseChainConfigDir := n.getChainConfigDir() + entries, err := os.ReadDir(baseChainConfigDir) + if err != nil { + return fmt.Errorf("failed to read chain config dir: %w", err) + } + + // Clear the map of data that may end up stale (e.g. if a given + // chain is in the map but no longer exists on disk) + n.ChainConfigs = map[string]FlagsMap{} + + for _, entry := range entries { + if !entry.IsDir() { + // Chain config files are expected to be nested under a + // directory with the name of the chain alias. + continue + } + chainAlias := entry.Name() + configPath := filepath.Join(baseChainConfigDir, chainAlias, defaultConfigFilename) + if _, err := os.Stat(configPath); os.IsNotExist(err) { + // No config file present + continue + } + chainConfig, err := ReadFlagsMap(configPath, fmt.Sprintf("%s chain config", chainAlias)) + if err != nil { + return err + } + n.ChainConfigs[chainAlias] = *chainConfig + } + + return nil +} + +func (n *Network) writeChainConfigs() error { + baseChainConfigDir := n.getChainConfigDir() + + for chainAlias, chainConfig := range n.ChainConfigs { + // Create the directory + chainConfigDir := filepath.Join(baseChainConfigDir, chainAlias) + if err := os.MkdirAll(chainConfigDir, perms.ReadWriteExecute); err != nil { + return fmt.Errorf("failed to create %s chain config dir: %w", chainAlias, err) + } + + // Write the file + path := filepath.Join(chainConfigDir, defaultConfigFilename) + if err := chainConfig.Write(path, fmt.Sprintf("%s chain config", chainAlias)); err != nil { + return err + } + } + + // TODO(marun) Ensure the removal of chain aliases that aren't present in the map + + return nil +} + +func (n *Network) getConfigPath() string { + return filepath.Join(n.Dir, defaultConfigFilename) +} + +func (n *Network) readConfig() error { + bytes, err := os.ReadFile(n.getConfigPath()) + if err != nil { + return fmt.Errorf("failed to read network config: %w", err) + } + if err := json.Unmarshal(bytes, n); err != nil { + return fmt.Errorf("failed to unmarshal network config: %w", err) + } + return nil +} + +// The subset of network fields to store in the network config file. +type serializedNetworkConfig struct { + DefaultFlags FlagsMap + DefaultRuntimeConfig NodeRuntimeConfig + PreFundedKeys []*secp256k1.PrivateKey +} + +func (n *Network) writeNetworkConfig() error { + config := &serializedNetworkConfig{ + DefaultFlags: n.DefaultFlags, + DefaultRuntimeConfig: n.DefaultRuntimeConfig, + PreFundedKeys: n.PreFundedKeys, + } + bytes, err := DefaultJSONMarshal(config) + if err != nil { + return fmt.Errorf("failed to marshal network config: %w", err) + } + if err := os.WriteFile(n.getConfigPath(), bytes, perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write network config: %w", err) + } + return nil +} + +func (n *Network) EnvFilePath() string { + return filepath.Join(n.Dir, "network.env") +} + +func (n *Network) EnvFileContents() string { + return fmt.Sprintf("export %s=%s", NetworkDirEnvName, n.Dir) +} + +// Write an env file that sets the network dir env when sourced. +func (n *Network) writeEnvFile() error { + if err := os.WriteFile(n.EnvFilePath(), []byte(n.EnvFileContents()), perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write network env file: %w", err) + } + return nil +} diff --git a/tests/fixture/tmpnet/network_test.go b/tests/fixture/tmpnet/network_test.go index a797ff873a25..3cbbb8ffcae8 100644 --- a/tests/fixture/tmpnet/network_test.go +++ b/tests/fixture/tmpnet/network_test.go @@ -4,6 +4,7 @@ package tmpnet import ( + "bytes" "testing" "github.com/stretchr/testify/require" @@ -14,14 +15,14 @@ func TestNetworkSerialization(t *testing.T) { tmpDir := t.TempDir() - network := &Network{Dir: tmpDir} - require.NoError(network.PopulateNetworkConfig(1337, 1, 1)) - require.NoError(network.WriteAll()) + network, err := NewDefaultNetwork(&bytes.Buffer{}, "/path/to/avalanche/go", 1) + require.NoError(err) + require.NoError(network.Create(tmpDir)) // Ensure node runtime is initialized - require.NoError(network.ReadNodes()) + require.NoError(network.readNodes()) - loadedNetwork, err := ReadNetwork(tmpDir) + loadedNetwork, err := ReadNetwork(network.Dir) require.NoError(err) for _, key := range loadedNetwork.PreFundedKeys { // Address() enables comparison with the original network by diff --git a/tests/fixture/tmpnet/node.go b/tests/fixture/tmpnet/node.go index f0f800802046..8638985dd5b2 100644 --- a/tests/fixture/tmpnet/node.go +++ b/tests/fixture/tmpnet/node.go @@ -89,7 +89,7 @@ func ReadNode(dataDir string) (*Node, error) { } // Reads nodes from the specified network directory. -func ReadNodes(networkDir string) ([]*Node, error) { +func ReadNodes(networkDir string, includeEphemeral bool) ([]*Node, error) { nodes := []*Node{} // Node configuration is stored in child directories @@ -111,6 +111,10 @@ func ReadNodes(networkDir string) ([]*Node, error) { return nil, err } + if !includeEphemeral && node.IsEphemeral { + continue + } + nodes = append(nodes, node) } diff --git a/tests/upgrade/upgrade_test.go b/tests/upgrade/upgrade_test.go index 9f56c79ad910..37c2fd259e66 100644 --- a/tests/upgrade/upgrade_test.go +++ b/tests/upgrade/upgrade_test.go @@ -6,7 +6,6 @@ package upgrade import ( "flag" "fmt" - "strings" "testing" "github.com/onsi/ginkgo/v2" @@ -15,7 +14,6 @@ import ( "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/tests/fixture/e2e" ) @@ -55,21 +53,9 @@ var _ = ginkgo.Describe("[Upgrade]", func() { ginkgo.By(fmt.Sprintf("restarting node %q with %q binary", node.NodeID, avalancheGoExecPathToUpgradeTo)) require.NoError(node.Stop(e2e.DefaultContext())) - // A node must start with sufficient bootstrap nodes to represent a quorum. Since the node's current - // bootstrap configuration may not satisfy this requirement (i.e. if on network start the node was one of - // the first validators), updating the node to bootstrap from all running validators maximizes the - // chances of a successful start. - // - // TODO(marun) Refactor node start to do this automatically - bootstrapIPs, bootstrapIDs, err := network.GetBootstrapIPsAndIDs() - require.NoError(err) - require.NotEmpty(bootstrapIDs) - node.Flags[config.BootstrapIDsKey] = strings.Join(bootstrapIDs, ",") - node.Flags[config.BootstrapIPsKey] = strings.Join(bootstrapIPs, ",") - node.RuntimeConfig.AvalancheGoPath = avalancheGoExecPath - require.NoError(node.Write()) - - require.NoError(node.Start(ginkgo.GinkgoWriter)) + node.RuntimeConfig.AvalancheGoPath = avalancheGoExecPathToUpgradeTo + + require.NoError(network.StartNode(e2e.DefaultContext(), ginkgo.GinkgoWriter, node)) ginkgo.By(fmt.Sprintf("waiting for node %q to report healthy after restart", node.NodeID)) e2e.WaitForHealthy(node) From 73c4c0ff9817cb13fdb8b205939596af0c416f1f Mon Sep 17 00:00:00 2001 From: Dan Laine Date: Sun, 7 Jan 2024 11:22:37 -0500 Subject: [PATCH 234/267] Update uintsize implementation (#2590) --- x/merkledb/codec.go | 13 +++++-------- x/merkledb/codec_test.go | 21 +++++++++++++++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/x/merkledb/codec.go b/x/merkledb/codec.go index 02eb5fc3ad5a..eae205631192 100644 --- a/x/merkledb/codec.go +++ b/x/merkledb/codec.go @@ -9,6 +9,7 @@ import ( "errors" "io" "math" + "math/bits" "sync" "golang.org/x/exp/maps" @@ -101,14 +102,10 @@ func (c *codecImpl) childSize(index byte, childEntry *child) int { // based on the current implementation of codecImpl.encodeUint which uses binary.PutUvarint func (*codecImpl) uintSize(value uint64) int { - // binary.PutUvarint repeatedly divides by 128 until the value is under 128, - // so count the number of times that will occur - i := 0 - for value >= 0x80 { - value >>= 7 - i++ - } - return i + 1 + if value == 0 { + return 1 + } + return (bits.Len64(value) + 6) / 7 } func (c *codecImpl) keySize(p Key) int { diff --git a/x/merkledb/codec_test.go b/x/merkledb/codec_test.go index 5972cbb43b9d..455b75e1bed1 100644 --- a/x/merkledb/codec_test.go +++ b/x/merkledb/codec_test.go @@ -247,9 +247,22 @@ func TestCodecDecodeKeyLengthOverflowRegression(t *testing.T) { func TestUintSize(t *testing.T) { c := codec.(*codecImpl) - for i := uint64(0); i < math.MaxInt16; i++ { - expectedSize := c.uintSize(i) - actualSize := binary.PutUvarint(make([]byte, binary.MaxVarintLen64), i) - require.Equal(t, expectedSize, actualSize, i) + + // Test lower bound + expectedSize := c.uintSize(0) + actualSize := binary.PutUvarint(make([]byte, binary.MaxVarintLen64), 0) + require.Equal(t, expectedSize, actualSize) + + // Test upper bound + expectedSize = c.uintSize(math.MaxUint64) + actualSize = binary.PutUvarint(make([]byte, binary.MaxVarintLen64), math.MaxUint64) + require.Equal(t, expectedSize, actualSize) + + // Test powers of 2 + for power := 0; power < 64; power++ { + n := uint64(1) << uint(power) + expectedSize := c.uintSize(n) + actualSize := binary.PutUvarint(make([]byte, binary.MaxVarintLen64), n) + require.Equal(t, expectedSize, actualSize, power) } } From bba8e75b5bec7c7a0c8d6b00930f9872131b301d Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 7 Jan 2024 22:24:14 -0500 Subject: [PATCH 235/267] Optimize bloom filter (#2588) --- go.mod | 3 +- go.sum | 2 - network/p2p/gossip/bloom.go | 79 ++----- network/p2p/gossip/bloom_test.go | 7 +- network/p2p/gossip/handler.go | 14 +- proto/pb/sdk/sdk.pb.go | 38 ++-- proto/sdk/sdk.proto | 4 +- pubsub/bloom/filter.go | 51 +++++ .../bloom/filter_test.go | 8 +- {utils => pubsub}/bloom/map_filter.go | 0 pubsub/connection.go | 4 +- pubsub/filter_param.go | 2 +- pubsub/filter_test.go | 2 +- utils/bloom/bloom_filter.go | 77 ------- utils/bloom/filter.go | 151 +++++++++++++ utils/bloom/filter_test.go | 100 +++++++++ utils/bloom/hasher.go | 31 +++ utils/bloom/hasher_test.go | 34 +++ utils/bloom/optimal.go | 115 ++++++++++ utils/bloom/optimal_test.go | 203 ++++++++++++++++++ utils/bloom/read_filter.go | 48 +++++ utils/bloom/read_filter_test.go | 112 ++++++++++ vms/avm/network/config.go | 2 +- vms/avm/network/gossip.go | 2 +- vms/platformvm/network/config.go | 2 +- vms/platformvm/network/gossip.go | 2 +- 26 files changed, 907 insertions(+), 186 deletions(-) create mode 100644 pubsub/bloom/filter.go rename utils/bloom/bloom_filter_test.go => pubsub/bloom/filter_test.go (81%) rename {utils => pubsub}/bloom/map_filter.go (100%) delete mode 100644 utils/bloom/bloom_filter.go create mode 100644 utils/bloom/filter.go create mode 100644 utils/bloom/filter_test.go create mode 100644 utils/bloom/hasher.go create mode 100644 utils/bloom/hasher_test.go create mode 100644 utils/bloom/optimal.go create mode 100644 utils/bloom/optimal_test.go create mode 100644 utils/bloom/read_filter.go create mode 100644 utils/bloom/read_filter_test.go diff --git a/go.mod b/go.mod index 7e333adf6682..f557f64cca62 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,6 @@ require ( github.com/gorilla/rpc v1.2.0 github.com/gorilla/websocket v1.4.2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 - github.com/holiman/bloomfilter/v2 v2.0.3 github.com/huin/goupnp v1.0.3 github.com/jackpal/gateway v1.0.6 github.com/jackpal/go-nat-pmp v1.0.2 @@ -39,7 +38,6 @@ require ( github.com/prometheus/client_model v0.3.0 github.com/rs/cors v1.7.0 github.com/shirou/gopsutil v3.21.11+incompatible - github.com/spaolacci/murmur3 v1.1.0 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.0.0 github.com/spf13/pflag v1.0.5 @@ -110,6 +108,7 @@ require ( github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect diff --git a/go.sum b/go.sum index df800dfefb61..743661fe7ee6 100644 --- a/go.sum +++ b/go.sum @@ -554,8 +554,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= diff --git a/network/p2p/gossip/bloom.go b/network/p2p/gossip/bloom.go index 12fca6bfcad4..9553c22c3692 100644 --- a/network/p2p/gossip/bloom.go +++ b/network/p2p/gossip/bloom.go @@ -5,27 +5,25 @@ package gossip import ( "crypto/rand" - "encoding/binary" - "hash" - - bloomfilter "github.com/holiman/bloomfilter/v2" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/bloom" ) -var _ hash.Hash64 = (*hasher)(nil) - // NewBloomFilter returns a new instance of a bloom filter with at most // [maxExpectedElements] elements anticipated at any moment, and a false // positive probability of [falsePositiveProbability]. +// +// Invariant: The returned bloom filter is not safe to reset concurrently with +// other operations. However, it is otherwise safe to access concurrently. func NewBloomFilter( - maxExpectedElements uint64, + maxExpectedElements int, falsePositiveProbability float64, ) (*BloomFilter, error) { - bloom, err := bloomfilter.NewOptimal( + bloom, err := bloom.New(bloom.OptimalParameters( maxExpectedElements, falsePositiveProbability, - ) + )) if err != nil { return nil, err } @@ -38,7 +36,7 @@ func NewBloomFilter( } type BloomFilter struct { - bloom *bloomfilter.Filter + bloom *bloom.Filter // salt is provided to eventually unblock collisions in Bloom. It's possible // that conflicting Gossipable items collide in the bloom filter, so a salt // is generated to eventually resolve collisions. @@ -47,28 +45,21 @@ type BloomFilter struct { func (b *BloomFilter) Add(gossipable Gossipable) { h := gossipable.GossipID() - salted := &hasher{ - hash: h[:], - salt: b.salt, - } - b.bloom.Add(salted) + bloom.Add(b.bloom, h[:], b.salt[:]) } func (b *BloomFilter) Has(gossipable Gossipable) bool { h := gossipable.GossipID() - salted := &hasher{ - hash: h[:], - salt: b.salt, - } - return b.bloom.Contains(salted) + return bloom.Contains(b.bloom, h[:], b.salt[:]) } +// TODO: Remove error from the return func (b *BloomFilter) Marshal() ([]byte, []byte, error) { - bloomBytes, err := b.bloom.MarshalBinary() + bloomBytes := b.bloom.Marshal() // salt must be copied here to ensure the bytes aren't overwritten if salt // is later modified. salt := b.salt - return bloomBytes, salt[:], err + return bloomBytes, salt[:], nil } // ResetBloomFilterIfNeeded resets a bloom filter if it breaches a target false @@ -77,11 +68,15 @@ func ResetBloomFilterIfNeeded( bloomFilter *BloomFilter, falsePositiveProbability float64, ) (bool, error) { - if bloomFilter.bloom.FalsePosititveProbability() < falsePositiveProbability { + numHashes, numEntries := bloomFilter.bloom.Parameters() + // TODO: Precalculate maxCount, as it is independent of the current state + // of the bloom filter. + maxCount := bloom.EstimateCount(numHashes, numEntries, falsePositiveProbability) + if bloomFilter.bloom.Count() < maxCount { return false, nil } - newBloom, err := bloomfilter.New(bloomFilter.bloom.M(), bloomFilter.bloom.K()) + newBloom, err := bloom.New(numHashes, numEntries) if err != nil { return false, err } @@ -100,39 +95,3 @@ func randomSalt() (ids.ID, error) { _, err := rand.Read(salt[:]) return salt, err } - -type hasher struct { - hash []byte - salt ids.ID -} - -func (h *hasher) Write(p []byte) (n int, err error) { - h.hash = append(h.hash, p...) - return len(p), nil -} - -func (h *hasher) Sum(b []byte) []byte { - h.hash = append(h.hash, b...) - return h.hash -} - -func (h *hasher) Reset() { - h.hash = ids.Empty[:] -} - -func (*hasher) BlockSize() int { - return ids.IDLen -} - -func (h *hasher) Sum64() uint64 { - salted := ids.ID{} - for i := 0; i < len(h.hash) && i < ids.IDLen; i++ { - salted[i] = h.hash[i] ^ h.salt[i] - } - - return binary.BigEndian.Uint64(salted[:]) -} - -func (h *hasher) Size() int { - return len(h.hash) -} diff --git a/network/p2p/gossip/bloom_test.go b/network/p2p/gossip/bloom_test.go index 9eb06a6a2458..097fbecb608e 100644 --- a/network/p2p/gossip/bloom_test.go +++ b/network/p2p/gossip/bloom_test.go @@ -6,13 +6,12 @@ package gossip import ( "testing" - bloomfilter "github.com/holiman/bloomfilter/v2" - "github.com/stretchr/testify/require" "golang.org/x/exp/slices" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/bloom" ) func TestBloomFilterRefresh(t *testing.T) { @@ -48,7 +47,7 @@ func TestBloomFilterRefresh(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - b, err := bloomfilter.New(10, 1) + b, err := bloom.New(1, 10) require.NoError(err) bloom := BloomFilter{ bloom: b, @@ -69,8 +68,6 @@ func TestBloomFilterRefresh(t *testing.T) { require.Equal(initialSaltBytes, saltBytes) } - require.Equal(uint64(len(tt.expected)), bloom.bloom.N()) - for _, expected := range tt.expected { require.True(bloom.Has(expected)) } diff --git a/network/p2p/gossip/handler.go b/network/p2p/gossip/handler.go index 380b67ad2dc3..15ef1fe16684 100644 --- a/network/p2p/gossip/handler.go +++ b/network/p2p/gossip/handler.go @@ -8,8 +8,6 @@ import ( "fmt" "time" - bloomfilter "github.com/holiman/bloomfilter/v2" - "go.uber.org/zap" "google.golang.org/protobuf/proto" @@ -17,6 +15,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/proto/pb/sdk" + "github.com/ava-labs/avalanchego/utils/bloom" "github.com/ava-labs/avalanchego/utils/logging" ) @@ -62,19 +61,18 @@ func (h Handler[T]) AppRequest(_ context.Context, _ ids.NodeID, _ time.Time, req return nil, err } - filter := &BloomFilter{ - bloom: &bloomfilter.Filter{}, - salt: salt, - } - if err := filter.bloom.UnmarshalBinary(request.Filter); err != nil { + filter, err := bloom.Parse(request.Filter) + if err != nil { return nil, err } responseSize := 0 gossipBytes := make([][]byte, 0) h.set.Iterate(func(gossipable T) bool { + gossipID := gossipable.GossipID() + // filter out what the requesting peer already knows about - if filter.Has(gossipable) { + if bloom.Contains(filter, gossipID[:], salt[:]) { return true } diff --git a/proto/pb/sdk/sdk.pb.go b/proto/pb/sdk/sdk.pb.go index b828c4026d96..b90c23450270 100644 --- a/proto/pb/sdk/sdk.pb.go +++ b/proto/pb/sdk/sdk.pb.go @@ -25,8 +25,8 @@ type PullGossipRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Filter []byte `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` Salt []byte `protobuf:"bytes,2,opt,name=salt,proto3" json:"salt,omitempty"` + Filter []byte `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"` } func (x *PullGossipRequest) Reset() { @@ -61,16 +61,16 @@ func (*PullGossipRequest) Descriptor() ([]byte, []int) { return file_sdk_sdk_proto_rawDescGZIP(), []int{0} } -func (x *PullGossipRequest) GetFilter() []byte { +func (x *PullGossipRequest) GetSalt() []byte { if x != nil { - return x.Filter + return x.Salt } return nil } -func (x *PullGossipRequest) GetSalt() []byte { +func (x *PullGossipRequest) GetFilter() []byte { if x != nil { - return x.Salt + return x.Filter } return nil } @@ -173,20 +173,20 @@ var File_sdk_sdk_proto protoreflect.FileDescriptor var file_sdk_sdk_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x73, 0x64, 0x6b, 0x2f, 0x73, 0x64, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x03, 0x73, 0x64, 0x6b, 0x22, 0x3f, 0x0a, 0x11, 0x50, 0x75, 0x6c, 0x6c, 0x47, 0x6f, 0x73, 0x73, - 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x73, 0x61, 0x6c, 0x74, 0x22, 0x2c, 0x0a, 0x12, 0x50, 0x75, 0x6c, 0x6c, 0x47, 0x6f, 0x73, - 0x73, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, - 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, - 0x73, 0x69, 0x70, 0x22, 0x24, 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x47, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, - 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x64, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x03, 0x73, 0x64, 0x6b, 0x22, 0x45, 0x0a, 0x11, 0x50, 0x75, 0x6c, 0x6c, 0x47, 0x6f, 0x73, 0x73, + 0x69, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x61, 0x6c, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x12, 0x16, 0x0a, + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x2c, 0x0a, 0x12, 0x50, + 0x75, 0x6c, 0x6c, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x22, 0x24, 0x0a, 0x0a, 0x50, 0x75, 0x73, + 0x68, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, + 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x42, + 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, + 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, + 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x64, 0x6b, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/sdk/sdk.proto b/proto/sdk/sdk.proto index 6841cfb8b020..f42912391fe7 100644 --- a/proto/sdk/sdk.proto +++ b/proto/sdk/sdk.proto @@ -5,8 +5,10 @@ package sdk; option go_package = "github.com/ava-labs/avalanchego/proto/pb/sdk"; message PullGossipRequest { - bytes filter = 1; + // TODO: Remove reservation after v1.11.x activates. + reserved 1; bytes salt = 2; + bytes filter = 3; } message PullGossipResponse { diff --git a/pubsub/bloom/filter.go b/pubsub/bloom/filter.go new file mode 100644 index 000000000000..b0d023b51f19 --- /dev/null +++ b/pubsub/bloom/filter.go @@ -0,0 +1,51 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "errors" + + "github.com/ava-labs/avalanchego/utils/bloom" +) + +const bytesPerHash = 8 + +var ( + _ Filter = (*filter)(nil) + + errMaxBytes = errors.New("too large") +) + +type Filter interface { + // Add adds to filter, assumed thread safe + Add(...[]byte) + + // Check checks filter, assumed thread safe + Check([]byte) bool +} + +func New(maxN int, p float64, maxBytes int) (Filter, error) { + numHashes, numEntries := bloom.OptimalParameters(maxN, p) + if neededBytes := 1 + numHashes*bytesPerHash + numEntries; neededBytes > maxBytes { + return nil, errMaxBytes + } + f, err := bloom.New(numHashes, numEntries) + return &filter{ + filter: f, + }, err +} + +type filter struct { + filter *bloom.Filter +} + +func (f *filter) Add(bl ...[]byte) { + for _, b := range bl { + bloom.Add(f.filter, b, nil) + } +} + +func (f *filter) Check(b []byte) bool { + return bloom.Contains(f.filter, b, nil) +} diff --git a/utils/bloom/bloom_filter_test.go b/pubsub/bloom/filter_test.go similarity index 81% rename from utils/bloom/bloom_filter_test.go rename to pubsub/bloom/filter_test.go index c28443d99912..3b2c4b71a59d 100644 --- a/utils/bloom/bloom_filter_test.go +++ b/pubsub/bloom/filter_test.go @@ -13,10 +13,10 @@ import ( func TestNew(t *testing.T) { var ( - require = require.New(t) - maxN uint64 = 10000 - p = 0.1 - maxBytes uint64 = 1 * units.MiB // 1 MiB + require = require.New(t) + maxN = 10000 + p = 0.1 + maxBytes = 1 * units.MiB // 1 MiB ) f, err := New(maxN, p, maxBytes) require.NoError(err) diff --git a/utils/bloom/map_filter.go b/pubsub/bloom/map_filter.go similarity index 100% rename from utils/bloom/map_filter.go rename to pubsub/bloom/map_filter.go diff --git a/pubsub/connection.go b/pubsub/connection.go index f5f471c64c08..901a33a25da3 100644 --- a/pubsub/connection.go +++ b/pubsub/connection.go @@ -14,7 +14,7 @@ import ( "go.uber.org/zap" - "github.com/ava-labs/avalanchego/utils/bloom" + "github.com/ava-labs/avalanchego/pubsub/bloom" ) var ( @@ -190,7 +190,7 @@ func (c *connection) handleNewBloom(cmd *NewBloom) error { if !cmd.IsParamsValid() { return ErrInvalidFilterParam } - filter, err := bloom.New(uint64(cmd.MaxElements), float64(cmd.CollisionProb), MaxBytes) + filter, err := bloom.New(int(cmd.MaxElements), float64(cmd.CollisionProb), MaxBytes) if err != nil { return fmt.Errorf("bloom filter creation failed %w", err) } diff --git a/pubsub/filter_param.go b/pubsub/filter_param.go index 1a1306c8d10d..5fd80a2ad706 100644 --- a/pubsub/filter_param.go +++ b/pubsub/filter_param.go @@ -6,7 +6,7 @@ package pubsub import ( "sync" - "github.com/ava-labs/avalanchego/utils/bloom" + "github.com/ava-labs/avalanchego/pubsub/bloom" "github.com/ava-labs/avalanchego/utils/set" ) diff --git a/pubsub/filter_test.go b/pubsub/filter_test.go index d32c3e87bdfd..3b47a38e0237 100644 --- a/pubsub/filter_test.go +++ b/pubsub/filter_test.go @@ -10,7 +10,7 @@ import ( "github.com/ava-labs/avalanchego/api" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/bloom" + "github.com/ava-labs/avalanchego/pubsub/bloom" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/formatting/address" ) diff --git a/utils/bloom/bloom_filter.go b/utils/bloom/bloom_filter.go deleted file mode 100644 index c4a0ff4c4ae8..000000000000 --- a/utils/bloom/bloom_filter.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package bloom - -import ( - "errors" - "sync" - - "github.com/spaolacci/murmur3" - - streakKnife "github.com/holiman/bloomfilter/v2" -) - -var errMaxBytes = errors.New("too large") - -type Filter interface { - // Add adds to filter, assumed thread safe - Add(...[]byte) - - // Check checks filter, assumed thread safe - Check([]byte) bool -} - -func New(maxN uint64, p float64, maxBytes uint64) (Filter, error) { - neededBytes := bytesSteakKnifeFilter(maxN, p) - if neededBytes > maxBytes { - return nil, errMaxBytes - } - return newSteakKnifeFilter(maxN, p) -} - -type steakKnifeFilter struct { - lock sync.RWMutex - filter *streakKnife.Filter -} - -func bytesSteakKnifeFilter(maxN uint64, p float64) uint64 { - m := streakKnife.OptimalM(maxN, p) - k := streakKnife.OptimalK(m, maxN) - - // This is pulled from bloomFilter.newBits and bloomfilter.newRandKeys. The - // calculation is the size of the bitset which would be created from this - // filter. - mSize := (m + 63) / 64 - totalSize := mSize + k - - return totalSize * 8 // 8 == sizeof(uint64)) -} - -func newSteakKnifeFilter(maxN uint64, p float64) (Filter, error) { - m := streakKnife.OptimalM(maxN, p) - k := streakKnife.OptimalK(m, maxN) - - filter, err := streakKnife.New(m, k) - return &steakKnifeFilter{filter: filter}, err -} - -func (f *steakKnifeFilter) Add(bl ...[]byte) { - f.lock.Lock() - defer f.lock.Unlock() - - for _, b := range bl { - h := murmur3.New64() - _, _ = h.Write(b) - f.filter.Add(h) - } -} - -func (f *steakKnifeFilter) Check(b []byte) bool { - f.lock.RLock() - defer f.lock.RUnlock() - - h := murmur3.New64() - _, _ = h.Write(b) - return f.filter.Contains(h) -} diff --git a/utils/bloom/filter.go b/utils/bloom/filter.go new file mode 100644 index 000000000000..569de80f1d1b --- /dev/null +++ b/utils/bloom/filter.go @@ -0,0 +1,151 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "crypto/rand" + "encoding/binary" + "errors" + "fmt" + "math/bits" + "sync" +) + +const ( + minHashes = 1 + maxHashes = 16 // Supports a false positive probability of 2^-16 when using optimal size values + minEntries = 1 + + bitsPerByte = 8 + bytesPerUint64 = 8 + hashRotation = 17 +) + +var ( + errInvalidNumHashes = errors.New("invalid num hashes") + errTooFewHashes = errors.New("too few hashes") + errTooManyHashes = errors.New("too many hashes") + errTooFewEntries = errors.New("too few entries") +) + +type Filter struct { + // numBits is always equal to [bitsPerByte * len(entries)] + numBits uint64 + + lock sync.RWMutex + hashSeeds []uint64 + entries []byte + count int +} + +// New creates a new Filter with the specified number of hashes and bytes for +// entries. The returned bloom filter is safe for concurrent usage. +func New(numHashes, numEntries int) (*Filter, error) { + if numEntries < minEntries { + return nil, errTooFewEntries + } + + hashSeeds, err := newHashSeeds(numHashes) + if err != nil { + return nil, err + } + + return &Filter{ + numBits: uint64(numEntries * bitsPerByte), + hashSeeds: hashSeeds, + entries: make([]byte, numEntries), + count: 0, + }, nil +} + +// Parameters returns the [numHashes] and [numEntries] that were used when +// creating this filter. +func (f *Filter) Parameters() (int, int) { + return len(f.hashSeeds), len(f.entries) +} + +func (f *Filter) Add(hash uint64) { + f.lock.Lock() + defer f.lock.Unlock() + + for _, seed := range f.hashSeeds { + hash = bits.RotateLeft64(hash, hashRotation) ^ seed + index := hash % f.numBits + byteIndex := index / bitsPerByte + bitIndex := index % bitsPerByte + f.entries[byteIndex] |= 1 << bitIndex + } + f.count++ +} + +// Count returns the number of elements that have been added to the bloom +// filter. +func (f *Filter) Count() int { + f.lock.RLock() + defer f.lock.RUnlock() + + return f.count +} + +func (f *Filter) Contains(hash uint64) bool { + f.lock.RLock() + defer f.lock.RUnlock() + + return contains(f.hashSeeds, f.entries, hash) +} + +func (f *Filter) Marshal() []byte { + f.lock.RLock() + defer f.lock.RUnlock() + + return marshal(f.hashSeeds, f.entries) +} + +func newHashSeeds(count int) ([]uint64, error) { + switch { + case count < minHashes: + return nil, fmt.Errorf("%w: %d < %d", errTooFewHashes, count, minHashes) + case count > maxHashes: + return nil, fmt.Errorf("%w: %d > %d", errTooManyHashes, count, maxHashes) + } + + bytes := make([]byte, count*bytesPerUint64) + if _, err := rand.Reader.Read(bytes); err != nil { + return nil, err + } + + seeds := make([]uint64, count) + for i := range seeds { + seeds[i] = binary.BigEndian.Uint64(bytes[i*bytesPerUint64:]) + } + return seeds, nil +} + +func contains(hashSeeds []uint64, entries []byte, hash uint64) bool { + var ( + numBits = bitsPerByte * uint64(len(entries)) + accumulator byte = 1 + ) + for seedIndex := 0; seedIndex < len(hashSeeds) && accumulator != 0; seedIndex++ { + hash = bits.RotateLeft64(hash, hashRotation) ^ hashSeeds[seedIndex] + index := hash % numBits + byteIndex := index / bitsPerByte + bitIndex := index % bitsPerByte + accumulator &= entries[byteIndex] >> bitIndex + } + return accumulator != 0 +} + +func marshal(hashSeeds []uint64, entries []byte) []byte { + numHashes := len(hashSeeds) + entriesOffset := 1 + numHashes*bytesPerUint64 + + bytes := make([]byte, entriesOffset+len(entries)) + bytes[0] = byte(numHashes) + for i, seed := range hashSeeds { + binary.BigEndian.PutUint64(bytes[1+i*bytesPerUint64:], seed) + } + copy(bytes[entriesOffset:], entries) + return bytes +} diff --git a/utils/bloom/filter_test.go b/utils/bloom/filter_test.go new file mode 100644 index 000000000000..94e4b29d9bce --- /dev/null +++ b/utils/bloom/filter_test.go @@ -0,0 +1,100 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "math/rand" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/utils/units" +) + +func TestNewErrors(t *testing.T) { + tests := []struct { + numHashes int + numEntries int + err error + }{ + { + numHashes: 0, + numEntries: 1, + err: errTooFewHashes, + }, + { + numHashes: 17, + numEntries: 1, + err: errTooManyHashes, + }, + { + numHashes: 8, + numEntries: 0, + err: errTooFewEntries, + }, + } + for _, test := range tests { + t.Run(test.err.Error(), func(t *testing.T) { + _, err := New(test.numHashes, test.numEntries) + require.ErrorIs(t, err, test.err) + }) + } +} + +func TestNormalUsage(t *testing.T) { + require := require.New(t) + + toAdd := make([]uint64, 1024) + for i := range toAdd { + toAdd[i] = rand.Uint64() //#nosec G404 + } + + initialNumHashes, initialNumBytes := OptimalParameters(1024, 0.01) + filter, err := New(initialNumHashes, initialNumBytes) + require.NoError(err) + + for i, elem := range toAdd { + filter.Add(elem) + for _, elem := range toAdd[:i] { + require.True(filter.Contains(elem)) + } + } + + require.Equal(len(toAdd), filter.Count()) + + numHashes, numEntries := filter.Parameters() + require.Equal(initialNumHashes, numHashes) + require.Equal(initialNumBytes, numEntries) + + filterBytes := filter.Marshal() + parsedFilter, err := Parse(filterBytes) + require.NoError(err) + + for _, elem := range toAdd { + require.True(parsedFilter.Contains(elem)) + } + + parsedFilterBytes := parsedFilter.Marshal() + require.Equal(filterBytes, parsedFilterBytes) +} + +func BenchmarkAdd(b *testing.B) { + f, err := New(8, 16*units.KiB) + require.NoError(b, err) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + f.Add(1) + } +} + +func BenchmarkMarshal(b *testing.B) { + f, err := New(OptimalParameters(10_000, .01)) + require.NoError(b, err) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + f.Marshal() + } +} diff --git a/utils/bloom/hasher.go b/utils/bloom/hasher.go new file mode 100644 index 000000000000..d5e3f5a6f5ec --- /dev/null +++ b/utils/bloom/hasher.go @@ -0,0 +1,31 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "crypto/sha256" + "encoding/binary" +) + +func Add(f *Filter, key, salt []byte) { + f.Add(Hash(key, salt)) +} + +func Contains(c Checker, key, salt []byte) bool { + return c.Contains(Hash(key, salt)) +} + +type Checker interface { + Contains(hash uint64) bool +} + +func Hash(key, salt []byte) uint64 { + hash := sha256.New() + // sha256.Write never returns errors + _, _ = hash.Write(key) + _, _ = hash.Write(salt) + + output := make([]byte, 0, sha256.Size) + return binary.BigEndian.Uint64(hash.Sum(output)) +} diff --git a/utils/bloom/hasher_test.go b/utils/bloom/hasher_test.go new file mode 100644 index 000000000000..b262f1dbb5dc --- /dev/null +++ b/utils/bloom/hasher_test.go @@ -0,0 +1,34 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/units" +) + +func TestCollisionResistance(t *testing.T) { + require := require.New(t) + + f, err := New(8, 16*units.KiB) + require.NoError(err) + + Add(f, []byte("hello world?"), []byte("so salty")) + collision := Contains(f, []byte("hello world!"), []byte("so salty")) + require.False(collision) +} + +func BenchmarkHash(b *testing.B) { + key := ids.GenerateTestID() + salt := ids.GenerateTestID() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + Hash(key[:], salt[:]) + } +} diff --git a/utils/bloom/optimal.go b/utils/bloom/optimal.go new file mode 100644 index 000000000000..fc434ca57987 --- /dev/null +++ b/utils/bloom/optimal.go @@ -0,0 +1,115 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "math" + + safemath "github.com/ava-labs/avalanchego/utils/math" +) + +const ln2Squared = math.Ln2 * math.Ln2 + +// OptimalParameters calculates the optimal [numHashes] and [numEntries] that +// should be allocated for a bloom filter which will contain [count] and target +// [falsePositiveProbability]. +func OptimalParameters(count int, falsePositiveProbability float64) (int, int) { + numEntries := OptimalEntries(count, falsePositiveProbability) + numHashes := OptimalHashes(numEntries, count) + return numHashes, numEntries +} + +// OptimalHashes calculates the number of hashes which will minimize the false +// positive probability of a bloom filter with [numEntries] after [count] +// additions. +// +// It is guaranteed to return a value in the range [minHashes, maxHashes]. +// +// ref: https://en.wikipedia.org/wiki/Bloom_filter +func OptimalHashes(numEntries, count int) int { + switch { + case numEntries < minEntries: + return minHashes + case count <= 0: + return maxHashes + } + + numHashes := math.Ceil(float64(numEntries) * bitsPerByte * math.Ln2 / float64(count)) + // Converting a floating-point value to an int produces an undefined value + // if the floating-point value cannot be represented as an int. To avoid + // this undefined behavior, we explicitly check against MaxInt here. + // + // ref: https://go.dev/ref/spec#Conversions + if numHashes >= maxHashes { + return maxHashes + } + return safemath.Max(int(numHashes), minHashes) +} + +// OptimalEntries calculates the optimal number of entries to use when creating +// a new Bloom filter when targenting a size of [count] with +// [falsePositiveProbability] assuming that the optimal number of hashes is +// used. +// +// It is guaranteed to return a value in the range [minEntries, MaxInt]. +// +// ref: https://en.wikipedia.org/wiki/Bloom_filter +func OptimalEntries(count int, falsePositiveProbability float64) int { + switch { + case count <= 0: + return minEntries + case falsePositiveProbability >= 1: + return minEntries + case falsePositiveProbability <= 0: + return math.MaxInt + } + + entriesInBits := -float64(count) * math.Log(falsePositiveProbability) / ln2Squared + entries := (entriesInBits + bitsPerByte - 1) / bitsPerByte + // Converting a floating-point value to an int produces an undefined value + // if the floating-point value cannot be represented as an int. To avoid + // this undefined behavior, we explicitly check against MaxInt here. + // + // ref: https://go.dev/ref/spec#Conversions + if entries >= math.MaxInt { + return math.MaxInt + } + return safemath.Max(int(entries), minEntries) +} + +// EstimateCount estimates the number of additions a bloom filter with +// [numHashes] and [numEntries] must have to reach [falsePositiveProbability]. +// This is derived by inversing a lower-bound on the probability of false +// positives. For values where numBits >> numHashes, the predicted probability +// is fairly accurate. +// +// It is guaranteed to return a value in the range [0, MaxInt]. +// +// ref: https://tsapps.nist.gov/publication/get_pdf.cfm?pub_id=903775 +func EstimateCount(numHashes, numEntries int, falsePositiveProbability float64) int { + switch { + case numHashes < minHashes: + return 0 + case numEntries < minEntries: + return 0 + case falsePositiveProbability <= 0: + return 0 + case falsePositiveProbability >= 1: + return math.MaxInt + } + + invNumHashes := 1 / float64(numHashes) + numBits := float64(numEntries * 8) + exp := 1 - math.Pow(falsePositiveProbability, invNumHashes) + count := math.Ceil(-math.Log(exp) * numBits * invNumHashes) + // Converting a floating-point value to an int produces an undefined value + // if the floating-point value cannot be represented as an int. To avoid + // this undefined behavior, we explicitly check against MaxInt here. + // + // ref: https://go.dev/ref/spec#Conversions + if count >= math.MaxInt { + return math.MaxInt + } + return int(count) +} diff --git a/utils/bloom/optimal_test.go b/utils/bloom/optimal_test.go new file mode 100644 index 000000000000..b52356d5b307 --- /dev/null +++ b/utils/bloom/optimal_test.go @@ -0,0 +1,203 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "fmt" + "math" + "testing" + + "github.com/stretchr/testify/require" +) + +const largestFloat64LessThan1 float64 = 1 - 1e-16 + +func TestOptimalHashes(t *testing.T) { + tests := []struct { + numEntries int + count int + expectedHashes int + }{ + { // invalid params + numEntries: 0, + count: 1024, + expectedHashes: minHashes, + }, + { // invalid params + numEntries: 1024, + count: 0, + expectedHashes: maxHashes, + }, + { + numEntries: math.MaxInt, + count: 1, + expectedHashes: maxHashes, + }, + { + numEntries: 1, + count: math.MaxInt, + expectedHashes: minHashes, + }, + { + numEntries: 1024, + count: 1024, + expectedHashes: 6, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d_%d", test.numEntries, test.count), func(t *testing.T) { + hashes := OptimalHashes(test.numEntries, test.count) + require.Equal(t, test.expectedHashes, hashes) + }) + } +} + +func TestOptimalEntries(t *testing.T) { + tests := []struct { + count int + falsePositiveProbability float64 + expectedEntries int + }{ + { // invalid params + count: 0, + falsePositiveProbability: .5, + expectedEntries: minEntries, + }, + { // invalid params + count: 1, + falsePositiveProbability: 0, + expectedEntries: math.MaxInt, + }, + { // invalid params + count: 1, + falsePositiveProbability: 1, + expectedEntries: minEntries, + }, + { + count: math.MaxInt, + falsePositiveProbability: math.SmallestNonzeroFloat64, + expectedEntries: math.MaxInt, + }, + { + count: 1024, + falsePositiveProbability: largestFloat64LessThan1, + expectedEntries: minEntries, + }, + { + count: 1024, + falsePositiveProbability: .01, + expectedEntries: 1227, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d_%f", test.count, test.falsePositiveProbability), func(t *testing.T) { + entries := OptimalEntries(test.count, test.falsePositiveProbability) + require.Equal(t, test.expectedEntries, entries) + }) + } +} + +func TestEstimateEntries(t *testing.T) { + tests := []struct { + numHashes int + numEntries int + falsePositiveProbability float64 + expectedEntries int + }{ + { // invalid params + numHashes: 0, + numEntries: 2_048, + falsePositiveProbability: .5, + expectedEntries: 0, + }, + { // invalid params + numHashes: 1, + numEntries: 0, + falsePositiveProbability: .5, + expectedEntries: 0, + }, + { // invalid params + numHashes: 1, + numEntries: 1, + falsePositiveProbability: 2, + expectedEntries: math.MaxInt, + }, + { // invalid params + numHashes: 1, + numEntries: 1, + falsePositiveProbability: -1, + expectedEntries: 0, + }, + { + numHashes: 8, + numEntries: 2_048, + falsePositiveProbability: 0, + expectedEntries: 0, + }, + { // params from OptimalParameters(10_000, .01) + numHashes: 7, + numEntries: 11_982, + falsePositiveProbability: .01, + expectedEntries: 9_993, + }, + { // params from OptimalParameters(100_000, .001) + numHashes: 10, + numEntries: 179_720, + falsePositiveProbability: .001, + expectedEntries: 100_000, + }, + { // params from OptimalParameters(10_000, .01) + numHashes: 7, + numEntries: 11_982, + falsePositiveProbability: .05, + expectedEntries: 14_449, + }, + { // params from OptimalParameters(10_000, .01) + numHashes: 7, + numEntries: 11_982, + falsePositiveProbability: 1, + expectedEntries: math.MaxInt, + }, + { // params from OptimalParameters(10_000, .01) + numHashes: 7, + numEntries: 11_982, + falsePositiveProbability: math.SmallestNonzeroFloat64, + expectedEntries: 0, + }, + { // params from OptimalParameters(10_000, .01) + numHashes: 7, + numEntries: 11_982, + falsePositiveProbability: largestFloat64LessThan1, + expectedEntries: math.MaxInt, + }, + } + for _, test := range tests { + t.Run(fmt.Sprintf("%d_%d_%f", test.numHashes, test.numEntries, test.falsePositiveProbability), func(t *testing.T) { + entries := EstimateCount(test.numHashes, test.numEntries, test.falsePositiveProbability) + require.Equal(t, test.expectedEntries, entries) + }) + } +} + +func FuzzOptimalHashes(f *testing.F) { + f.Fuzz(func(t *testing.T, numEntries, count int) { + hashes := OptimalHashes(numEntries, count) + require.GreaterOrEqual(t, hashes, minHashes) + require.LessOrEqual(t, hashes, maxHashes) + }) +} + +func FuzzOptimalEntries(f *testing.F) { + f.Fuzz(func(t *testing.T, count int, falsePositiveProbability float64) { + entries := OptimalEntries(count, falsePositiveProbability) + require.GreaterOrEqual(t, entries, minEntries) + }) +} + +func FuzzEstimateEntries(f *testing.F) { + f.Fuzz(func(t *testing.T, numHashes, numEntries int, falsePositiveProbability float64) { + entries := EstimateCount(numHashes, numEntries, falsePositiveProbability) + require.GreaterOrEqual(t, entries, 0) + }) +} diff --git a/utils/bloom/read_filter.go b/utils/bloom/read_filter.go new file mode 100644 index 000000000000..8c32e143b1c4 --- /dev/null +++ b/utils/bloom/read_filter.go @@ -0,0 +1,48 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "encoding/binary" + "fmt" +) + +type ReadFilter struct { + hashSeeds []uint64 + entries []byte +} + +// Parse [bytes] into a read-only bloom filter. +func Parse(bytes []byte) (*ReadFilter, error) { + if len(bytes) == 0 { + return nil, errInvalidNumHashes + } + numHashes := bytes[0] + entriesOffset := 1 + int(numHashes)*bytesPerUint64 + switch { + case numHashes < minHashes: + return nil, fmt.Errorf("%w: %d < %d", errTooFewHashes, numHashes, minHashes) + case numHashes > maxHashes: + return nil, fmt.Errorf("%w: %d > %d", errTooManyHashes, numHashes, maxHashes) + case len(bytes) < entriesOffset+minEntries: // numEntries = len(bytes) - entriesOffset + return nil, errTooFewEntries + } + + f := &ReadFilter{ + hashSeeds: make([]uint64, numHashes), + entries: bytes[entriesOffset:], + } + for i := range f.hashSeeds { + f.hashSeeds[i] = binary.BigEndian.Uint64(bytes[1+i*bytesPerUint64:]) + } + return f, nil +} + +func (f *ReadFilter) Contains(hash uint64) bool { + return contains(f.hashSeeds, f.entries, hash) +} + +func (f *ReadFilter) Marshal() []byte { + return marshal(f.hashSeeds, f.entries) +} diff --git a/utils/bloom/read_filter_test.go b/utils/bloom/read_filter_test.go new file mode 100644 index 000000000000..8ea83db092ca --- /dev/null +++ b/utils/bloom/read_filter_test.go @@ -0,0 +1,112 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bloom + +import ( + "math" + "testing" + + "github.com/stretchr/testify/require" +) + +func NewMaliciousFilter(numHashes, numEntries int) *Filter { + f := &Filter{ + numBits: uint64(numEntries * bitsPerByte), + hashSeeds: make([]uint64, numHashes), + entries: make([]byte, numEntries), + count: 0, + } + for i := range f.entries { + f.entries[i] = math.MaxUint8 + } + return f +} + +func TestParseErrors(t *testing.T) { + tests := []struct { + bytes []byte + err error + }{ + { + bytes: nil, + err: errInvalidNumHashes, + }, + { + bytes: NewMaliciousFilter(0, 1).Marshal(), + err: errTooFewHashes, + }, + { + bytes: NewMaliciousFilter(17, 1).Marshal(), + err: errTooManyHashes, + }, + { + bytes: NewMaliciousFilter(1, 0).Marshal(), + err: errTooFewEntries, + }, + { + bytes: []byte{ + 0x01, // num hashes = 1 + }, + err: errTooFewEntries, + }, + } + for _, test := range tests { + t.Run(test.err.Error(), func(t *testing.T) { + _, err := Parse(test.bytes) + require.ErrorIs(t, err, test.err) + }) + } +} + +func BenchmarkParse(b *testing.B) { + f, err := New(OptimalParameters(10_000, .01)) + require.NoError(b, err) + bytes := f.Marshal() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _ = Parse(bytes) + } +} + +func BenchmarkContains(b *testing.B) { + f := NewMaliciousFilter(maxHashes, 1) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + f.Contains(1) + } +} + +func FuzzParseThenMarshal(f *testing.F) { + f.Fuzz(func(t *testing.T, bytes []byte) { + f, err := Parse(bytes) + if err != nil { + return + } + + marshalledBytes := marshal(f.hashSeeds, f.entries) + require.Equal(t, bytes, marshalledBytes) + }) +} + +func FuzzMarshalThenParse(f *testing.F) { + f.Fuzz(func(t *testing.T, numHashes int, entries []byte) { + require := require.New(t) + + hashSeeds, err := newHashSeeds(numHashes) + if err != nil { + return + } + if len(entries) < minEntries { + return + } + + marshalledBytes := marshal(hashSeeds, entries) + rf, err := Parse(marshalledBytes) + require.NoError(err) + require.Equal(hashSeeds, rf.hashSeeds) + require.Equal(entries, rf.entries) + }) +} diff --git a/vms/avm/network/config.go b/vms/avm/network/config.go index 8f54a20baf8a..8536504d8383 100644 --- a/vms/avm/network/config.go +++ b/vms/avm/network/config.go @@ -45,7 +45,7 @@ type Config struct { // ExpectedBloomFilterElements is the number of elements to expect when // creating a new bloom filter. The larger this number is, the larger the // bloom filter will be. - ExpectedBloomFilterElements uint64 `json:"expected-bloom-filter-elements"` + ExpectedBloomFilterElements int `json:"expected-bloom-filter-elements"` // ExpectedBloomFilterFalsePositiveProbability is the expected probability // of a false positive after having inserted ExpectedBloomFilterElements // into a bloom filter. The smaller this number is, the larger the bloom diff --git a/vms/avm/network/gossip.go b/vms/avm/network/gossip.go index ef3b53d039ec..c36195ff8870 100644 --- a/vms/avm/network/gossip.go +++ b/vms/avm/network/gossip.go @@ -64,7 +64,7 @@ func newGossipMempool( log logging.Logger, txVerifier TxVerifier, parser txs.Parser, - maxExpectedElements uint64, + maxExpectedElements int, falsePositiveProbability, maxFalsePositiveProbability float64, ) (*gossipMempool, error) { diff --git a/vms/platformvm/network/config.go b/vms/platformvm/network/config.go index 8f54a20baf8a..8536504d8383 100644 --- a/vms/platformvm/network/config.go +++ b/vms/platformvm/network/config.go @@ -45,7 +45,7 @@ type Config struct { // ExpectedBloomFilterElements is the number of elements to expect when // creating a new bloom filter. The larger this number is, the larger the // bloom filter will be. - ExpectedBloomFilterElements uint64 `json:"expected-bloom-filter-elements"` + ExpectedBloomFilterElements int `json:"expected-bloom-filter-elements"` // ExpectedBloomFilterFalsePositiveProbability is the expected probability // of a false positive after having inserted ExpectedBloomFilterElements // into a bloom filter. The smaller this number is, the larger the bloom diff --git a/vms/platformvm/network/gossip.go b/vms/platformvm/network/gossip.go index b2f409c75626..0bfc705bfd5a 100644 --- a/vms/platformvm/network/gossip.go +++ b/vms/platformvm/network/gossip.go @@ -61,7 +61,7 @@ func newGossipMempool( mempool mempool.Mempool, log logging.Logger, txVerifier TxVerifier, - maxExpectedElements uint64, + maxExpectedElements int, falsePositiveProbability float64, maxFalsePositiveProbability float64, ) (*gossipMempool, error) { From 718e306433d571fa7ebc7d99850ed993c7791d42 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 9 Jan 2024 13:07:16 -0500 Subject: [PATCH 236/267] Remove TLS key gen from networking tests (#2596) --- network/certs_test.go | 39 +++++++++++++++++++++++++++++-- network/test_cert_1.crt | 27 +++++++++++++++++++++ network/test_cert_2.crt | 27 +++++++++++++++++++++ network/test_cert_3.crt | 27 +++++++++++++++++++++ network/test_key_1.key | 52 +++++++++++++++++++++++++++++++++++++++++ network/test_key_2.key | 52 +++++++++++++++++++++++++++++++++++++++++ network/test_key_3.key | 52 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 274 insertions(+), 2 deletions(-) create mode 100644 network/test_cert_1.crt create mode 100644 network/test_cert_2.crt create mode 100644 network/test_cert_3.crt create mode 100644 network/test_key_1.key create mode 100644 network/test_key_2.key create mode 100644 network/test_key_3.key diff --git a/network/certs_test.go b/network/certs_test.go index 483d6ea4eeee..7b59e11d800c 100644 --- a/network/certs_test.go +++ b/network/certs_test.go @@ -8,6 +8,8 @@ import ( "sync" "testing" + _ "embed" + "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" @@ -16,11 +18,42 @@ import ( ) var ( + //go:embed test_cert_1.crt + testCertBytes1 []byte + //go:embed test_key_1.key + testKeyBytes1 []byte + //go:embed test_cert_2.crt + testCertBytes2 []byte + //go:embed test_key_2.key + testKeyBytes2 []byte + //go:embed test_cert_3.crt + testCertBytes3 []byte + //go:embed test_key_3.key + testKeyBytes3 []byte + certLock sync.Mutex tlsCerts []*tls.Certificate tlsConfigs []*tls.Config ) +func init() { + cert1, err := staking.LoadTLSCertFromBytes(testKeyBytes1, testCertBytes1) + if err != nil { + panic(err) + } + cert2, err := staking.LoadTLSCertFromBytes(testKeyBytes2, testCertBytes2) + if err != nil { + panic(err) + } + cert3, err := staking.LoadTLSCertFromBytes(testKeyBytes3, testCertBytes3) + if err != nil { + panic(err) + } + tlsCerts = []*tls.Certificate{ + cert1, cert2, cert3, + } +} + func getTLS(t *testing.T, index int) (ids.NodeID, *tls.Certificate, *tls.Config) { certLock.Lock() defer certLock.Unlock() @@ -28,9 +61,11 @@ func getTLS(t *testing.T, index int) (ids.NodeID, *tls.Certificate, *tls.Config) for len(tlsCerts) <= index { cert, err := staking.NewTLSCert() require.NoError(t, err) - tlsConfig := peer.TLSConfig(*cert, nil) - tlsCerts = append(tlsCerts, cert) + } + for len(tlsConfigs) <= index { + cert := tlsCerts[len(tlsConfigs)] + tlsConfig := peer.TLSConfig(*cert, nil) tlsConfigs = append(tlsConfigs, tlsConfig) } diff --git a/network/test_cert_1.crt b/network/test_cert_1.crt new file mode 100644 index 000000000000..2f2b95e658ad --- /dev/null +++ b/network/test_cert_1.crt @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEnTCCAoWgAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw +MFoYDzIxMjQwMTA5MTQ0NTU4WjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAqCOUESK8b5N894dVCSIs4mTfNTdhaL5cnw3ZXSbZlfquBRJOxhqHXutG +An9++OTWvevrssaXBxGT4oOT3N11dm4iKh7ewi3to+1Sfqq71blCVZtBDOeWpZx0 +WwhPO37Us26fCR7T2gStiTHY9qE0QV/9p15OCAFsRb94JuhF0OR0d6tRm0yQ6b7Y +NRzpaBw4MBxZD9h84+QDdhsTyxI0xk/NnbG74pykjsau0/YA9mNqHHSnL4DyD5qu +IKqRfD5HQHemx66I3jEXUB/GxTHhxz5uskIpS9AV3oclvVi14BjSEWgNkJX+nMi+ +tjuSKouAFpzJZzZme2DvmyAecxbNVBdajOTe2QRiG7HKh1OdMZabd2dUNv5S9/gd +bI53s4R++z/H4llsBfk6B2+/DmqDRauh4Mz9HTf0Pud7Nz2b7r77PnPTjHExgN3R +i+Yo6LskRCQTzzTVwW/RY+rNVux9UE6ZPLarDbXnSyetKMUS7qlz8NUerWjtkC6i +om570LfTGs3GxIqVgoGg0mXuji+EoG+XpYR3PRaeo8cAmfEu7T+SxgSfJAv7DyZv ++a2VTZcOPDI1KTLrM8Xovy17t5rd9cy1/75vxnKLiGDEhzWJmNl4IvIYbtihWWl5 +ksdFYbe9Dpvuh/wBCGoK+kmCirUM1DiizWn5TxJeS1qYI8I2sYMCAwEAAaMgMB4w +DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB +AABzczRjzfhlmV+bFDzAs7nszQlZREcoRuWe5qHy7VKLvZvIAaYlcApB34hH7nDq +T/8fS8g8rC+Tzw0iCPF21Z4AzSe76V6EU4VGWWe8l00nDszfvavE5BF24z8dCuVC +1gScC1tvG6FPT23koZ0BVmyueCIa7sdqFlDz8rrRpLWfUcLj38gxwWM2JVBHQUvV +j87lzpTNH+2nPiwrKISqUPFi4YvbWKe8T4bY2Elw7THiNLZGfgqOXVkeIVi4fs97 +Tc5uscZ4OpSTlrfJqMJEV8cMRvrDmhD/VWbJvnk7lyELPoHx6MUinBswBT51yvmY +bZh4AZ43GSvSyo/V7p9scytQP3zM1MeHpsFa0RHwGVFp2BmO1abvydAxX0NMWasv +WUzXCKliXsVD/qUeCU/CFnaBqpzBvm4AFBgwHzprwzP9Be/mz/TjTcsfrmoiyxlr +QjXNk9TnP9d+aeOJsRz+JSYyHETACO5PkCg+XCDyEOf+kQAzVb9Dp0oWaCovXciU +A5z0DSDzyKVBOQo0syb5NFsLZ2DeJemNbP+3kCNzBBASQ4VWAvRbLjPh3Oe8A5PZ +xezCvzRE05O6tYkz5C5hcKbpAjfP8G8RV6ERjLBICBfb7XI7T0hixhiNHlIKknkJ +F82B/zDt+qBFARw8A/qr44RF+vy3Ql4IS2ZcflAv2pTO +-----END CERTIFICATE----- diff --git a/network/test_cert_2.crt b/network/test_cert_2.crt new file mode 100644 index 000000000000..283e286be446 --- /dev/null +++ b/network/test_cert_2.crt @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEnTCCAoWgAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw +MFoYDzIxMjQwMTA5MTQ0NTQ3WjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEArT7afarml6cvCmAySAO8GQka1mcQIMACyEWy6KsqiccX+DoGh5ECyQSa +WFKWKGdQ32dAWGVlSkmmgJ1jtW749hSguysav3EPMaxe/ad5CV1MwyyccGS9U99M +z0UVuFEXVjN5W6UlcULp1oJDj07NzZP6ByRiDvnjzgeYb3jHwjqOBNwex1jLW6vp +oWD03zTanVQXZaaGcEISCI2CgDP3uXfd0NQpoGVpf9gMi0cdGu8gpqbLqBjzjzr8 +GDBQYGaWKFnlqe6X9nBUad/qNE3Zeb3ehSg+M2ecQzTZFWirfa6cGTtovu04RMML +9OLflQy3rTRST2HQ6z0gpVCP3V2Mg/LmAuWyhOLVYNkhEwkRHvddzFksRzQ+ghpP +cGfvI0dwxQV0CbEMVjd9zVEA6dOrMLI3st2922hqF23Al1+Hwcu1G/T3ybfSTwjd +YZ23IgkQF4r+RIXevzgOBBXfEwE8XERW2zNwUG5Sv5dxx+FgDjX0EGbrzgY6OeKT +D1SP/7WQLjwmGgwyNJYkAklvEKwU+dlGD5NpgvJ9fg8R1wUhp2HhSZ1l1OUVmRYw +YqUm7dTLK1CJU2BH2sRyZcUkwstjvgi688zfHNttGYmAnx6wGS12jWf+W4df+QNI +Ng6AdcJ5Ee0z0JAbTpZW/zX3CTSroow7igHnd4AwvKEVQFcyO/MCAwEAAaMgMB4w +DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB +ACePaZvjw2KiheheWNjzOv2B+7uLVe7oEbThEUQypEmTFK8wKaHwI4BGdBGEOr/N +LZ1M2wAYgwzMTEDJE+GEB2ZHIdH9cH5lu7ITsOMVcBSJttEJVhhEtbMwVJ9JC62j +AsW4VmHFpEik+xvinxedKczXOa21YJo4sv2TiFWFaSHqPeRo7HA1dxQYOwiLsS6e +JKIupMrn8IZz2YN5gFhbvQTBp2J3u6kxMIzN0a+BPARR4fwMn5lVMVvye/+8Kwtw +dZHSN1FYUcFqHagmhNlNkAOaGQklSFWtsVVQxQCFS2bxEImLj5kG16fCAsQoRC0J +ZS2OaRncrtB0r0Qu1JB5XJP9FLflSb57KIxBNVrl+iWdWikgBFE6cMthMwgLfQ99 +k8AMp6KrCjcxqegN+P30ct/JwahKPq2+SwtdHG3yrZ2TJEjhOtersrTnRK9zqm9v +lqS7JsiztjgqnhMs2eTdXygfEe0AoZihGTaaLYj37A9+2RECkuijkjBghG2NBnv6 +264lTghZyZcZgZNCgYglYC1bhifEorJpYf6TOOcDAi5UH8R7vi4x70vI6sIDrhga +d9E63EVe11QdIjceceMlNm42UTrhl0epMbL6FIzU+d91qBgd9qT6YqoYPFZSiYFy +2hArgLxH2fxTXatCAit5g1MEk0w1MiHVrPZ8lTU3U/ET +-----END CERTIFICATE----- diff --git a/network/test_cert_3.crt b/network/test_cert_3.crt new file mode 100644 index 000000000000..c0977191ec7b --- /dev/null +++ b/network/test_cert_3.crt @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEnTCCAoWgAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw +MFoYDzIxMjQwMTA5MTQ0NTM0WjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA5aV76ivIZ1iWmW0OzGMCrmFQBnej9JntQ1jP9yiacKu7j5Z/bD/eqoyc +jRwoSiesErfnThAGy7H80glVw/XmC0fYNPVDPyzAEdNk46M3yEI8hAKI6aSkl1s1 +KVAHpQuNcG+3xIB39OOMx0XuycZ6gqzyMmjqeT0cThNDXTwGbodMVDAf0q220QAq +zB/lz0sjHPXlYh25LJ1yPtl+vlcfGrP+q+2ODR9rnI79PE7AZB4Xc6wUIca5XXkH +PS7zQ1Ida1xrf446MYCVuazLFhpzq8/nhkxNMzxdZsJaWavL+xkpjGxAySvj0jlu +QFGsmsxOIU/XgJD/VRqqyISXpl2wg0l8mpsU9fV7bEW1y6MIc7AARRgbbEPiDz8m +/O8mjEW3C16untLHB7LzPCCitTssGR65Shkj+Lw+aM4X5ZI+Xm8eHTRCek8T5Cl3 +Sm2UFkLk2mun6cwoyWWhwi6+EfW6ks0c7qSHtJTP8DgLrWxYmBuD9PKSHclpa4/5 +toj52YnT6fIBJWz5ggIdntRCaH8+0eWvwuvDsdPUL7JQFjJmfQOdMenlNqW2aEvx ++JZiYLJBWj9cjpI33P5CAfFEVM3IFlDHmMHRTQ/kKLcfvSDfuofEBoMt4tjf01Um +dfi8kFKWl9ba9I7CoQ13U4J1wkk6KxatZP7eGCmKRoq8w+Y38NsCAwEAAaMgMB4w +DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB +AKsvbN5/r4YPguetl+jIhqpr4TZM8GNZRGTqkKC8clRspBeihJqkNQWsnZiFkJTH +NhNAx+7tlJHqeGdojc2XjBAkc+//qYqXKHgihsO54bVG9oN9IPO+mpPumRRhGneH +jTUE/hLFqwA4ZPw5L1HtJ0m1yqg/HXf4aBXcVQ/YO8YN17ZgLpueYt+Chi1pP/Ku +TzHuoKuHst2T6uuZQZxcD+XJoXwdOt7mfPTh5y9/Psjn+qx833DNWSwF3O/lEghA +2yOb+5CFta2LLUHH894oj5SvgJ/5cvn4+NbyDCUv5ebvE98BMh72PLNRuIRV0gfO +XalMIZ+9Jm2TGXD0dWt9GeZ5z3h+nCEB6s3x0sqluaWG3lTUx+4T/aIxdGuvPFi6 +7DWm7TG7yxFGfbECyyXXL+B/gyHhE1Q93nE3wK9flSG+ljqFJS+8wytht52XhgwE +lV1AwHgxkbkFzNIwB0s7etR9+wBcQvFKqeCZrDeG1twKNcY1dv1D/OCUlBYJvL/X +YADeT2ZjFzHhWhv6TLVEAtqytT1o4qXh6VWeIrwfMG0VcQSiJyNxwO/aW5BOTM44 +EelDzvSjo/pRxqN/m44Iuf0Ran86DO7LmjNYh/04FN3oaL9cFIaT9BWXt/Xx2Fdw ++dg5bPSJ62ExVnnNRlY9lQECkSoRZK2epcICs+3YmmGX +-----END CERTIFICATE----- diff --git a/network/test_key_1.key b/network/test_key_1.key new file mode 100644 index 000000000000..c49775114d66 --- /dev/null +++ b/network/test_key_1.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCoI5QRIrxvk3z3 +h1UJIiziZN81N2FovlyfDdldJtmV+q4FEk7GGode60YCf3745Na96+uyxpcHEZPi +g5Pc3XV2biIqHt7CLe2j7VJ+qrvVuUJVm0EM55alnHRbCE87ftSzbp8JHtPaBK2J +Mdj2oTRBX/2nXk4IAWxFv3gm6EXQ5HR3q1GbTJDpvtg1HOloHDgwHFkP2Hzj5AN2 +GxPLEjTGT82dsbvinKSOxq7T9gD2Y2ocdKcvgPIPmq4gqpF8PkdAd6bHrojeMRdQ +H8bFMeHHPm6yQilL0BXehyW9WLXgGNIRaA2Qlf6cyL62O5Iqi4AWnMlnNmZ7YO+b +IB5zFs1UF1qM5N7ZBGIbscqHU50xlpt3Z1Q2/lL3+B1sjnezhH77P8fiWWwF+ToH +b78OaoNFq6HgzP0dN/Q+53s3PZvuvvs+c9OMcTGA3dGL5ijouyREJBPPNNXBb9Fj +6s1W7H1QTpk8tqsNtedLJ60oxRLuqXPw1R6taO2QLqKibnvQt9MazcbEipWCgaDS +Ze6OL4Sgb5elhHc9Fp6jxwCZ8S7tP5LGBJ8kC/sPJm/5rZVNlw48MjUpMuszxei/ +LXu3mt31zLX/vm/GcouIYMSHNYmY2Xgi8hhu2KFZaXmSx0Vht70Om+6H/AEIagr6 +SYKKtQzUOKLNaflPEl5LWpgjwjaxgwIDAQABAoICAHGe8U0PGyWPFlCzLDyq0of+ +wHNWxEWi9jYphqyTN1BJgVU+BOuMO9RhywKfI6+P/KmFBtbdqmuFblkQr1f+c4Uf +cYjjKYcwwDkZg7jDKYGI2pG9A51z1nJ9oodtuxUqZRQH+gKQyXq31Ik0nTg0wXo4 +ItH6QWLZi1AqzkgEiEFcUHQZ2mDGwdqjM7nYmsXW5AVm8qxpkCP0Dn6+V4bP+8fT +X9BjreK6Fd3B15y2zfmyPp+SGPRZ/7mZvnemq/+4mi+va43enPEBXY6wmoLhbYBV +6ToeyYdIy65/x3oHu4f/Xd2TYi9FnTRX18CPyvtjH6CoPNW5hlFztRcwAkOlsgQ7 +sZ+9FGAnRvz1lrBg80DeCHeSKVkDHmMQSINhPcPnlMJpxn6iiZjdvz/Bd+9RRqZl +xUI/lV3/Wueh8SeCQlFOj3fHBZEaq6QoC/VmmaeIiLEm1hj+ymuFxwOtA6AKWLb3 +59XnEkONeTfv9d2eQ7NOPU86n/zhWHUKodmBUEaxLDaUwRkS1Adb4rLuRwrMfn3a +2KkknYWzvyrlk8lDqKAMeQneFmpresGAXeIn0vt434eaGcK4a/IZ8PebuhZxGq1Z +bVbxVm0AsLmd9X3htR6MOiZswnVmA3JCw1AMKZpLMDRSbjV0uYuhBJQsN4Y/kyOK +l52JtymFNvbuRF+836+RAoIBAQDZ9wyihmgsEPLl7PHzfYo4pnTs1puoT5PS7GjO +iVm7UtOKaawsJxKX3cxzSFVXONs9hbPPzmsQEL3Xz+lUsgrSeXReF00KLRbfE2LM +dv9hlJVMQXEKnEkFYNNgETyZIJE3ZDDqdd2PDzNM8aKHlvLYREiETCwVn7r4x5QE +jIHC0gUjRJHqUgSdAMa+qvranPLxVV9mpJmL2RXjjb/OtJosFef9h5augSNI9tPS +EDLm4wMjyXr25Vu20/cusmTlOhCzi2d23hNHx8nPE0nCEVtZ2rnnWyH/ozqRnpXX +EPh0IeZQmebBhHWzkjIPaOa05Ua5rkVAQau8/FUUubjXytyZAoIBAQDFerIQwodP +V46WVC0LtSq4ju88x1vgDfT0NFE3H6hIX7Mc91zt0NGOhzv4crfjnoj+romNfQwD +0ymtudnnoaGPFBRrRF8T+26jfFpes7Ve5q/PpY78zJH1ZLwyKKX4dzgeY0Aj9FbO +q4dzh21oD7wyknRm0NTqOvgLAuxoBFZ4FTgudKNDzGymgIaQVT1+h0226og289WT +iptkpOZ/HcxQts2U3j3a87pJB0IFjIrBTtVqIyphdwRVDa929WGDITUPHa3aqykx +Ma/zvXvocAlIDITVwxXlS16DkSS+5jdN/CUj5h0O6FefGaJmk6/bFQIeXM4fRhRF +M0cs1mxXkNR7AoIBAQCFxYftn4wDr4tD7f44sE3Kou6UBMqXq+9PvmQ8jjOSMi0+ +f8h5eKmCp0+5WSV3WJ/FzG8lFMzEmWHKOAI+Rt85ee0fajGQE0g8NMuoLUhjfSt8 +F5XnKy/tqxVPmoSUflZhpo4W96u5B1021f4oNU5pyM6w04ci5lt8IBEKEan6Bae9 +k3HyW9AVA8r2bj1zOmwoDXt1pYPPPraeZ/rWRCVy9SbihPrHst4TA9nQzLxQ0/az +Wg6rxOxa8xB7imU+AjsJ1n7zhyxSG54SBwZ3outr5D/AbEAbgvSJNslDq1iw/bU6 +tpnXHxKV2R38MyeU0jpr7zb1Tti2Li+RfsKhPhHRAoIBAHfbpXH4r6mfaeKiCokd +l2VXE6tfEMtnjTIfAuAjLb9nnk3JcTTCVj5cpDCCaEwV7+4sPz6KFB3KL3TK5Y/q +ESXHOTF12QNGyvsdQbhS+JU2DKVKRgP3oetADd2fwESTD5OaB9cKuRlNELQ1EVlk +m4RSUaYJwAC+c8gzKQtk/pp5vpSrpGBFFfjk70dxBRbjxm5r4OsBibK4IOKwF1o1 +2sluek6NqRtYbMtgRVka2SjE0VFPMKzhUNbSrJnWCy5MnGilSdz7n8/E6ZdVfXwx +a+C4AHPBqWt3GFFgad4X2p9Rl7U3OJHQwUXGiEQcBVNCZ/vHti9TGIB7xApZxn5L +YDsCggEBAJ8RhrfEzm2YkyODFKFwgOszHQ3TNSvbC4+yLOUMSdzdKIyroOq0t53A +PSs046TINd+EDs9Pi6E69C+RYLim1NYMHeHFMzmKnQPXPwJVnYYUKInbIMURcuE9 +8FNBSKg3SUGz31SwG4bRIkJluMUp5oSAEUxWaxbUzLYkZex2uxnUGSd6TjddWKk1 ++SuoiZ3+W6yPWWh7TDKAR/oukBCmLIJI7dXSwv2DhagRpppdoMfqcnsCAgs/omB8 +Ku4y/jEkGbxLgo3Qd6U1o/QZlZG+9Q0iaxQS4dIpMxA3LwrL5txy00bm3JeWMB4H +MUZqfFgfj8ESxFBEeToOwr3Jq46vOwQ= +-----END PRIVATE KEY----- diff --git a/network/test_key_2.key b/network/test_key_2.key new file mode 100644 index 000000000000..bcc0a192b2b4 --- /dev/null +++ b/network/test_key_2.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCtPtp9quaXpy8K +YDJIA7wZCRrWZxAgwALIRbLoqyqJxxf4OgaHkQLJBJpYUpYoZ1DfZ0BYZWVKSaaA +nWO1bvj2FKC7Kxq/cQ8xrF79p3kJXUzDLJxwZL1T30zPRRW4URdWM3lbpSVxQunW +gkOPTs3Nk/oHJGIO+ePOB5hveMfCOo4E3B7HWMtbq+mhYPTfNNqdVBdlpoZwQhII +jYKAM/e5d93Q1CmgZWl/2AyLRx0a7yCmpsuoGPOPOvwYMFBgZpYoWeWp7pf2cFRp +3+o0Tdl5vd6FKD4zZ5xDNNkVaKt9rpwZO2i+7ThEwwv04t+VDLetNFJPYdDrPSCl +UI/dXYyD8uYC5bKE4tVg2SETCREe913MWSxHND6CGk9wZ+8jR3DFBXQJsQxWN33N +UQDp06swsjey3b3baGoXbcCXX4fBy7Ub9PfJt9JPCN1hnbciCRAXiv5Ehd6/OA4E +Fd8TATxcRFbbM3BQblK/l3HH4WAONfQQZuvOBjo54pMPVI//tZAuPCYaDDI0liQC +SW8QrBT52UYPk2mC8n1+DxHXBSGnYeFJnWXU5RWZFjBipSbt1MsrUIlTYEfaxHJl +xSTCy2O+CLrzzN8c220ZiYCfHrAZLXaNZ/5bh1/5A0g2DoB1wnkR7TPQkBtOllb/ +NfcJNKuijDuKAed3gDC8oRVAVzI78wIDAQABAoICAQCIgPu7BMuINoyUClPT9k1h +FJF22eIVS/VlQ7XCKgvsX1j9lwrKCnI9XUkXyorR7wYD4OEMRWhX7kwpDtoffP7h +NkOm9kGvEjA8nWqDRk/SFxeCuUXSMS4URd/JeM+yWQKgQxKeKTOlWGnTQPRmmFsE +XlIlCn/Q+QiLr+RmAK601VpNbfs6azZgVsZRB4opzQVr7XQ5/cnz7bszzfxDc67/ +DflSr7jUztMfjmXj3/aI4F3DsazKGE7gTkOP85GBQ5OQ27Rf/sTxwnRgr7Nj3us6 +R2ZrWNgZvMudEKjze3OUJd6M6wiPV258j4p+O7ybPlgDOzSXo6TvlUyBtUaFz04E +5S7bgimNUxEjFzTxkn9W/FTUeauvJcgDk+JmMZ+I9dFdMIuyksndywN9KdXBVxZH +1ZtO1P6JeFpxF7zQUmkH+/6RZd9PbQGlpNI06nAj98LVwqSDCO1aejLqoXYs9zqG +DOU4JdRm3qK0eshIghkvVOWIYhqKPkskQfbTFY+hasg82cGGFyzxqOsSiuW+CVIy +3iF3WyfKgvLMABoK/38zutsMT+/mOtA7rjErh1NJuwwWkkglmuwQMDqaWdOASs+v +MK8JjSi6zDpnbp70Prw5pUlHvvsD1iYWo7SOcpFos+U5zw1jHJJvnAatzcXWixuu +Xzbn2BtCqSFigW7waMy14QKCAQEAx/Nwy2xH9lVGfz8aO2CB0FGL9Ra3Jcv4HFJT +nw6/yvVLvRAwr87+/c+qbIzwLKbQXV/4vmNsqPrIJiazY+Tk739DjcW8YaMbejfr +ASPHtYbeF0FmVbxBHNZ/JSDSYUXdFZ7JlBiDSs3zhPlFBZYG2tU3JJZCR8+9J/Ss +JEIwL9UlapMznMwljFkLbvZ2oFstKkfdY61WxROOIwuGaKr0yRnNvMMp135JiB/O +dwh/NfROt4JzQ5O4ipMg6Wc73+OvBsOSQHYZQHl9NOaK1uomu5bUY7H8pLwGU7sw +LmPRzrGiu8dB+UUEyFkNI2xzwkjet+0UGupDyOfsCMf9hlzWmwKCAQEA3c8FeHkl +Il4GEB0VEw1NtC5x6i+s3NiPOlUmH+nOHgdaI7/BfljfTokQBGo+GkXkJ36yTEMh +L9Vtya3HtW4VEHNfPMjntPztn4XQvMZdSpu/k8rM44m+CB0DDLhFfwRr2cyUAwHz +xebXw8KhceqaWRp6ygJGx5Sk0gr7s7nhmIByjdx4tddEH/MahLklGdV7Vnp+yb3o +zNLVx/aDueknArgUb/zvZRcYWuNoGs9ac4pl0m6jan/x0ZcdBF0SU2bI6ltvF3WT +qwcvVnbJbBwq5PRuL4ZUqrqmXBbBAkpLJTx+kfPKD4bgcZTBnV2TxDbzze9CeieT +YCtg4u+khW7ZiQKCAQBrMIEuPD0TvEFPo8dvP1w4Dg9Gc0f5li/LFwNHCIQezIMu +togzJ3ehHvuQt7llZoPbGsDhZ7FvoQk9EpAmpCVqksHnNbK4cNUhHur3sHO2R7e1 +pdSzb3lEeWStxbuic+6CUZ5kqwNvTZsXlP3Acd344EZwcbDUiHQyAENsKKNmcRBe +4szPaM1UQMQVV0De1CIRQXdYoSsb+VDATsReRg9140Rcxg8fO881jz+CpmZzySWN +0PvzpTRP7XG+Th5V9tv0d1FnByigXMCXZGPXtKzQ8ZmoXFlBAp8tsfKxW8e005uW +qMogVDStJrgZXmFsLN5goVKe3yk5gcMSLgwmRIyzAoIBAQCoE6CkmsAd27uiaDc4 ++aLA/1TIzZmiu+NEo5NBKY1LyexvHHZGBJgqTcg6YDtw8zchCmuXSGMUeRk5cxrb +C3Cgx5wKVn7l8acqc18qPPIigATavBkn7o92XG2cLOJUjogfQVuDL+6GLxeeupRV +2x1cmakj/DegMq32j+YNWbRuOB8WClPaDyYLQ877dcR8X/2XGTmMLAEFfFoMrWtB +7D/oWo76EWNiae7FqH6RmkCDPwNLQxVHtW4LkQOm89PYKRHkLKbw0uKz/bzMOzUE +XA/Q8Lux/YuY19kJ/SACWUO6Eq4icObTfzQCPWO9mFRJog57JWttXyHZBOXk8Qzt +I4NpAoIBACurK0zJxaGUdTjmzaVipauyOZYFBsbzvCWsdSNodtZ/mw6n/qkj2N33 +vNCRLrsQAkDKATzWrscRg+xvl5/wIa4B3s8TZNIp3hL7bvI/NoR5bi5M0vcjdXEd +DeKeZsSBzEs5zivM3aWEF5MSR2zpJPNYyD0PnT6EvZOkMoq6LM3FJcouS1ChePLQ +wHEY5ZMqPODOcQ+EixNXl6FGdywaJYxKnG4liG9zdJ0lGNIivTA7gyM+JCbG4fs8 +73uGsbCpts5Y2xKFp3uK8HjWKbOCR3dE4mOZM8M/NlsUGNjSydXZMIJYWR8nvVmo +i3mHicYaTQxj0ruIz7JHOtFNVGi1sME= +-----END PRIVATE KEY----- diff --git a/network/test_key_3.key b/network/test_key_3.key new file mode 100644 index 000000000000..2cef238b67a9 --- /dev/null +++ b/network/test_key_3.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDlpXvqK8hnWJaZ +bQ7MYwKuYVAGd6P0me1DWM/3KJpwq7uPln9sP96qjJyNHChKJ6wSt+dOEAbLsfzS +CVXD9eYLR9g09UM/LMAR02TjozfIQjyEAojppKSXWzUpUAelC41wb7fEgHf044zH +Re7JxnqCrPIyaOp5PRxOE0NdPAZuh0xUMB/SrbbRACrMH+XPSyMc9eViHbksnXI+ +2X6+Vx8as/6r7Y4NH2ucjv08TsBkHhdzrBQhxrldeQc9LvNDUh1rXGt/jjoxgJW5 +rMsWGnOrz+eGTE0zPF1mwlpZq8v7GSmMbEDJK+PSOW5AUayazE4hT9eAkP9VGqrI +hJemXbCDSXyamxT19XtsRbXLowhzsABFGBtsQ+IPPyb87yaMRbcLXq6e0scHsvM8 +IKK1OywZHrlKGSP4vD5ozhflkj5ebx4dNEJ6TxPkKXdKbZQWQuTaa6fpzCjJZaHC +Lr4R9bqSzRzupIe0lM/wOAutbFiYG4P08pIdyWlrj/m2iPnZidPp8gElbPmCAh2e +1EJofz7R5a/C68Ox09QvslAWMmZ9A50x6eU2pbZoS/H4lmJgskFaP1yOkjfc/kIB +8URUzcgWUMeYwdFND+Qotx+9IN+6h8QGgy3i2N/TVSZ1+LyQUpaX1tr0jsKhDXdT +gnXCSTorFq1k/t4YKYpGirzD5jfw2wIDAQABAoICAQC/Rt32h29NvTj7JB5OWS2z +h3R7Xo2ev9Mi5EecSyKQNEpuZ+FMjcpubd47nrdkRLULhkhP+gNfCKpXW9Um+psY +zEemnJ7dcO2uK1B+VsWwtJLpNZ9KVIuPUjXuai1j6EJv423Ca2r++8WXeYVSZVJH +o7u8By09vIvl8B+M+eE1kNYfzVHETlLWtHfxO6RTy/a8OYhM+ArzwVSWStxJuBE9 +Ua0PETffcEtWxLbi04lmGrZX7315QKfG1ncUHBYc/blpYjpbrWCFON/9HpKtn2y3 +L91dPBKVWXNGkx1kUTb+t8+mmchAh6Ejyhgt1Jma+g8dqf4KpTs3bJXRnLcfqCvL +Kq+wCUGv7iVWlTmhlzLpneajLDdBxGfbkAgwPFOyZoJNrnh6hU60TPc1IV6YSLlB +GsxesK9QWUrg3BAN4iKD3FvDt0qeUPbPztxEZi1OzSYQDZUQBrBL+WHuD9NxeAYe +2yx1OlPMo73gK5GW/MHBCz77+NX2kVURlTvYW4TsmInCRvOTsVNkRPUJtiHYT7Ss +Y8SzS5F/u9sfjFAVowGgwtNfq8Rm6Q1QdPZltiUNBgiTekFNQEy7WhzVg6MlT5Ca +BRqUhN3+CFwxLZ9rSQL6gxfAHk9umb0ee4JU9JgcYjtb5AtyE6DmmcSZPSejjxit +HwZ/g5MDK7kk5fKMcnL7kQKCAQEA895z7T0c6y3rhWfEUMDdTlsPgAoxYNf+jXyJ +aQmtfnDP9tf8BdPpobfHp29e7JRaGGa9QWPaaemBPHXMmD+IegG9/E+PQdHQwFSG +OpI13uCBULt8a+MMUbTCg1V4uXqf2j1BUo9SFQ6aXh/Rg1gVBgsq1M6eyvel93io +0X+/cinsDEpB5HENZwBuRb0SP0RfCgQR9Yh+jIy2TwJDDNw3sG1TvIo9aK7blSwB +z/gwSDx1UUa2KReD4ChYcqgLFUj3F/uF2f20P/JuaUn7tU3HoCsbG0C+Cci/XSJ9 +gu8xYl64Vg16bO3CflqjucPTFXgyBOt0lIug77YYa9CgCUJvEwKCAQEA8RHqGghV +meDnRXvPmAEwtoT7IKBe+eYjGN6wc2o+QZzjeUFkyfOtaB8rqriUXqvihD2GD6XQ +O/cSNCqp5g6yUhBLo3b9BmCsQsvxkhMpwB/hdi5aYjn+CFQVD4rAso9yGwRBWoA0 +gQdGMKenOUhU/PtVKyTTUuY7rFD8RhYq0ZLqEgO7chn8QXCNPo7MfE/qF9vQBosP +ktiS0FG442PJp2B/lYKK6N2w77ZeCoLhQowaNN0/N36kX/n4bjBE2XFLNpSuHtlg +C7bV/RMR5i/3yB0eRVUDVlqC077qlC1w0tCNZvvi6kbWwIu/4pQTdcA8mAz5B7Lc +OwOMbA2GT4OIGQKCAQABoyS0Gwzup0hFhQTUZfcWZ5YbDfZ25/xVhtiFVANOLgO3 +bIvMnjebVliIzz6b6AMS1t2+aqU0wNSVS1UsUIDiENDtuLsFfhsgr3CXRBQIgwlb +OWcEcmnKwqPrrc85r5ETLgYaP8wVSBvRNfV6JEU/3SNUem6mfjMnDjBT97+ZTJ7B +Fl6K4hds8ZvL7BELS7I3pv9X3qq61tcCgMlidLgK/zDouyTeZw4iWkFI3Cm20nEX +MppWfEnuX1b4rhgk9HB0QMQNSp7DLyV+n3iJJxSIBsIP1Mdx2V8viOO+1UxHlMs4 +CK8hvBbqMkGXJbFtG3l6fvoxZR6XfWl8j9IDPebxAoIBAF07cnBy/LgwdQE4awb8 +ntxX/c+WdmTrjnNV3KQmWMGDba49jj9UkKIOPBMgo7EhhM9kA+8VT72BRncKcP7a +fDikuLwVjrHivXxv55N4+dKmAcp1DtuiVg7ehe6m2PO16olsUeIwZx3ntEuo61GK +GeRlR4ESEvCivj1cbNSmShUXXpNtAheU2Sxt3RJuo8MIHR7xEjkVmwZN4CnVEU5Q +D3M+LNmjzRlWc9GhlCk4iOn1yUTctFBAGE5OHLhwzo/R8ya+xcCEjVK6eXQQ5gFC +V+/64vQpdsr04lgGJC7+i/3cTnOfwxicIP4CjkmQvx3xJP4hNka189qW+r3nVSR3 +WDECggEAAQCCqF4J8C2keY+o/kYQBq0tHhrC28HgiVQuCGc4XruYQtDh4di/I72F +RsvgVHS29ApAlh29i29ws7K2bU6WIc+JR3nmwAHUtiJmxRZhn/c722AvRXF5YMH/ +u46bEURHF5sGz8vr5chX/R4LiF579xyNsB9KC3mPqdjW/L6ACQdrBJVAS9cwplO0 +D+YWxmCE1Ps2tQtz6ZN+LUC7WO6M24k8KW2y4Scue0/23uCllWFgS3/vxDdQDZWn ++7AvMYPh4Wrfdd0t0cU+c9rirFYVz+uo/QBUIZOIw64AvIUjZpHTbhcjz1mAqcgJ +eAOQk+OFUTNKeI9uJwoNYOguHsxt2w== +-----END PRIVATE KEY----- From b25c2472dbf1c23eda92d9adffd12cf6596d2ff8 Mon Sep 17 00:00:00 2001 From: Patrick O'Grady Date: Wed, 10 Jan 2024 12:08:00 +0100 Subject: [PATCH 237/267] [utils/bloom] Optionally Update Bloom Filter Size on Reset (#2591) Co-authored-by: Stephen Buttolph --- go.mod | 3 +- go.sum | 6 +- network/p2p/gossip/bloom.go | 64 ++++++++++++++-------- network/p2p/gossip/bloom_test.go | 55 ++++++++++++++----- network/p2p/gossip/gossip.go | 6 +- network/p2p/gossip/gossip_test.go | 6 +- network/p2p/gossip/gossipable.go | 2 +- network/p2p/gossip/test_gossip.go | 2 +- utils/bloom/filter.go | 6 -- utils/bloom/filter_test.go | 4 -- vms/avm/network/gossip.go | 34 ++++++------ vms/avm/network/network_test.go | 3 + vms/avm/txs/mempool/mempool.go | 10 ++++ vms/avm/txs/mempool/mock_mempool.go | 14 +++++ vms/platformvm/network/gossip.go | 30 +++++----- vms/platformvm/network/gossip_test.go | 1 + vms/platformvm/network/network_test.go | 2 + vms/platformvm/txs/mempool/mempool.go | 10 ++++ vms/platformvm/txs/mempool/mock_mempool.go | 14 +++++ 19 files changed, 177 insertions(+), 95 deletions(-) diff --git a/go.mod b/go.mod index f557f64cca62..5f2bea429f7b 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.10-rc.4 + github.com/ava-labs/coreth v0.12.10-rc.5 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -107,7 +107,6 @@ require ( github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect diff --git a/go.sum b/go.sum index 743661fe7ee6..489a6ee12e1d 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.10-rc.4 h1:+Ll3cpi3tZbw37lTa+1a/VnPa7xZktpbAFiuKtDKnIE= -github.com/ava-labs/coreth v0.12.10-rc.4/go.mod h1:8pt5LW6MP/luIdhQA+gvs8LobKE8tP/5APXUiFbfb2c= +github.com/ava-labs/coreth v0.12.10-rc.5 h1:FMVvXHssvMQ3Eade7i85Wsx9tuD3kUOFMG8ktHeDTp8= +github.com/ava-labs/coreth v0.12.10-rc.5/go.mod h1:a58HbIBc9jscGc3aL8e7JuG8RfhBBOm63waq1q0YM+U= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -353,8 +353,6 @@ github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuW github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= diff --git a/network/p2p/gossip/bloom.go b/network/p2p/gossip/bloom.go index 9553c22c3692..5c477826c9b6 100644 --- a/network/p2p/gossip/bloom.go +++ b/network/p2p/gossip/bloom.go @@ -8,35 +8,48 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/bloom" + "github.com/ava-labs/avalanchego/utils/math" ) -// NewBloomFilter returns a new instance of a bloom filter with at most -// [maxExpectedElements] elements anticipated at any moment, and a false -// positive probability of [falsePositiveProbability]. +// NewBloomFilter returns a new instance of a bloom filter with at least [minTargetElements] elements +// anticipated at any moment, and a false positive probability of [targetFalsePositiveProbability]. If the +// false positive probability exceeds [resetFalsePositiveProbability], the bloom filter will be reset. // // Invariant: The returned bloom filter is not safe to reset concurrently with // other operations. However, it is otherwise safe to access concurrently. func NewBloomFilter( - maxExpectedElements int, - falsePositiveProbability float64, + minTargetElements int, + targetFalsePositiveProbability, + resetFalsePositiveProbability float64, ) (*BloomFilter, error) { - bloom, err := bloom.New(bloom.OptimalParameters( - maxExpectedElements, - falsePositiveProbability, - )) + numHashes, numEntries := bloom.OptimalParameters( + minTargetElements, + targetFalsePositiveProbability, + ) + b, err := bloom.New(numHashes, numEntries) if err != nil { return nil, err } salt, err := randomSalt() return &BloomFilter{ - bloom: bloom, - salt: salt, + minTargetElements: minTargetElements, + targetFalsePositiveProbability: targetFalsePositiveProbability, + resetFalsePositiveProbability: resetFalsePositiveProbability, + + maxCount: bloom.EstimateCount(numHashes, numEntries, resetFalsePositiveProbability), + bloom: b, + salt: salt, }, err } type BloomFilter struct { - bloom *bloom.Filter + minTargetElements int + targetFalsePositiveProbability float64 + resetFalsePositiveProbability float64 + + maxCount int + bloom *bloom.Filter // salt is provided to eventually unblock collisions in Bloom. It's possible // that conflicting Gossipable items collide in the bloom filter, so a salt // is generated to eventually resolve collisions. @@ -53,29 +66,32 @@ func (b *BloomFilter) Has(gossipable Gossipable) bool { return bloom.Contains(b.bloom, h[:], b.salt[:]) } -// TODO: Remove error from the return -func (b *BloomFilter) Marshal() ([]byte, []byte, error) { +func (b *BloomFilter) Marshal() ([]byte, []byte) { bloomBytes := b.bloom.Marshal() // salt must be copied here to ensure the bytes aren't overwritten if salt // is later modified. salt := b.salt - return bloomBytes, salt[:], nil + return bloomBytes, salt[:] } -// ResetBloomFilterIfNeeded resets a bloom filter if it breaches a target false -// positive probability. Returns true if the bloom filter was reset. +// ResetBloomFilterIfNeeded resets a bloom filter if it breaches [targetFalsePositiveProbability]. +// +// If [targetElements] exceeds [minTargetElements], the size of the bloom filter will grow to maintain +// the same [targetFalsePositiveProbability]. +// +// Returns true if the bloom filter was reset. func ResetBloomFilterIfNeeded( bloomFilter *BloomFilter, - falsePositiveProbability float64, + targetElements int, ) (bool, error) { - numHashes, numEntries := bloomFilter.bloom.Parameters() - // TODO: Precalculate maxCount, as it is independent of the current state - // of the bloom filter. - maxCount := bloom.EstimateCount(numHashes, numEntries, falsePositiveProbability) - if bloomFilter.bloom.Count() < maxCount { + if bloomFilter.bloom.Count() <= bloomFilter.maxCount { return false, nil } + numHashes, numEntries := bloom.OptimalParameters( + math.Max(bloomFilter.minTargetElements, targetElements), + bloomFilter.targetFalsePositiveProbability, + ) newBloom, err := bloom.New(numHashes, numEntries) if err != nil { return false, err @@ -84,7 +100,7 @@ func ResetBloomFilterIfNeeded( if err != nil { return false, err } - + bloomFilter.maxCount = bloom.EstimateCount(numHashes, numEntries, bloomFilter.resetFalsePositiveProbability) bloomFilter.bloom = newBloom bloomFilter.salt = salt return true, nil diff --git a/network/p2p/gossip/bloom_test.go b/network/p2p/gossip/bloom_test.go index 097fbecb608e..128ea97824c0 100644 --- a/network/p2p/gossip/bloom_test.go +++ b/network/p2p/gossip/bloom_test.go @@ -16,30 +16,44 @@ import ( func TestBloomFilterRefresh(t *testing.T) { tests := []struct { - name string - falsePositiveProbability float64 - add []*testTx - expected []*testTx + name string + minTargetElements int + targetFalsePositiveProbability float64 + resetFalsePositiveProbability float64 + reset bool + add []*testTx + expected []*testTx }{ { - name: "no refresh", - falsePositiveProbability: 1, + name: "no refresh", + minTargetElements: 1, + targetFalsePositiveProbability: 0.01, + resetFalsePositiveProbability: 1, + reset: false, // maxCount = 9223372036854775807 add: []*testTx{ {id: ids.ID{0}}, + {id: ids.ID{1}}, + {id: ids.ID{2}}, }, expected: []*testTx{ {id: ids.ID{0}}, + {id: ids.ID{1}}, + {id: ids.ID{2}}, }, }, { - name: "refresh", - falsePositiveProbability: 0.1, + name: "refresh", + minTargetElements: 1, + targetFalsePositiveProbability: 0.01, + resetFalsePositiveProbability: 0.0000000000000001, // maxCount = 1 + reset: true, add: []*testTx{ {id: ids.ID{0}}, {id: ids.ID{1}}, + {id: ids.ID{2}}, }, expected: []*testTx{ - {id: ids.ID{1}}, + {id: ids.ID{2}}, }, }, } @@ -47,27 +61,38 @@ func TestBloomFilterRefresh(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { require := require.New(t) - b, err := bloom.New(1, 10) + numHashes, numEntries := bloom.OptimalParameters( + tt.minTargetElements, + tt.targetFalsePositiveProbability, + ) + b, err := bloom.New(numHashes, numEntries) require.NoError(err) bloom := BloomFilter{ - bloom: b, + bloom: b, + maxCount: bloom.EstimateCount(numHashes, numEntries, tt.resetFalsePositiveProbability), + minTargetElements: tt.minTargetElements, + targetFalsePositiveProbability: tt.targetFalsePositiveProbability, + resetFalsePositiveProbability: tt.resetFalsePositiveProbability, } + var didReset bool for _, item := range tt.add { - bloomBytes, saltBytes, err := bloom.Marshal() - require.NoError(err) - + bloomBytes, saltBytes := bloom.Marshal() initialBloomBytes := slices.Clone(bloomBytes) initialSaltBytes := slices.Clone(saltBytes) - _, err = ResetBloomFilterIfNeeded(&bloom, tt.falsePositiveProbability) + reset, err := ResetBloomFilterIfNeeded(&bloom, len(tt.add)) require.NoError(err) + if reset { + didReset = reset + } bloom.Add(item) require.Equal(initialBloomBytes, bloomBytes) require.Equal(initialSaltBytes, saltBytes) } + require.Equal(tt.reset, didReset) for _, expected := range tt.expected { require.True(bloom.Has(expected)) } diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index dfeb50d201a1..97e90e6e99af 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -151,11 +151,7 @@ type PullGossiper[T Gossipable] struct { } func (p *PullGossiper[_]) Gossip(ctx context.Context) error { - bloom, salt, err := p.set.GetFilter() - if err != nil { - return err - } - + bloom, salt := p.set.GetFilter() request := &sdk.PullGossipRequest{ Filter: bloom, Salt: salt, diff --git a/network/p2p/gossip/gossip_test.go b/network/p2p/gossip/gossip_test.go index 94387ebd9420..1c0941bd7eba 100644 --- a/network/p2p/gossip/gossip_test.go +++ b/network/p2p/gossip/gossip_test.go @@ -111,7 +111,7 @@ func TestGossiperGossip(t *testing.T) { responseNetwork, err := p2p.NewNetwork(logging.NoLog{}, responseSender, prometheus.NewRegistry(), "") require.NoError(err) - responseBloom, err := NewBloomFilter(1000, 0.01) + responseBloom, err := NewBloomFilter(1000, 0.01, 0.05) require.NoError(err) responseSet := &testSet{ txs: make(map[ids.ID]*testTx), @@ -143,7 +143,7 @@ func TestGossiperGossip(t *testing.T) { require.NoError(err) require.NoError(requestNetwork.Connected(context.Background(), ids.EmptyNodeID, nil)) - bloom, err := NewBloomFilter(1000, 0.01) + bloom, err := NewBloomFilter(1000, 0.01, 0.05) require.NoError(err) requestSet := &testSet{ txs: make(map[ids.ID]*testTx), @@ -365,7 +365,7 @@ func TestPushGossipE2E(t *testing.T) { knownTx := &testTx{id: ids.GenerateTestID()} log := logging.NoLog{} - bloom, err := NewBloomFilter(100, 0.01) + bloom, err := NewBloomFilter(100, 0.01, 0.05) require.NoError(err) set := &testSet{ txs: make(map[ids.ID]*testTx), diff --git a/network/p2p/gossip/gossipable.go b/network/p2p/gossip/gossipable.go index a204c465720d..238c62b4641c 100644 --- a/network/p2p/gossip/gossipable.go +++ b/network/p2p/gossip/gossipable.go @@ -25,5 +25,5 @@ type Set[T Gossipable] interface { Iterate(f func(gossipable T) bool) // GetFilter returns the byte representation of bloom filter and its // corresponding salt. - GetFilter() (bloom []byte, salt []byte, err error) + GetFilter() (bloom []byte, salt []byte) } diff --git a/network/p2p/gossip/test_gossip.go b/network/p2p/gossip/test_gossip.go index f903693c8054..03098399462e 100644 --- a/network/p2p/gossip/test_gossip.go +++ b/network/p2p/gossip/test_gossip.go @@ -64,6 +64,6 @@ func (t *testSet) Iterate(f func(gossipable *testTx) bool) { } } -func (t *testSet) GetFilter() ([]byte, []byte, error) { +func (t *testSet) GetFilter() ([]byte, []byte) { return t.bloom.Marshal() } diff --git a/utils/bloom/filter.go b/utils/bloom/filter.go index 569de80f1d1b..761ebfad12e1 100644 --- a/utils/bloom/filter.go +++ b/utils/bloom/filter.go @@ -59,12 +59,6 @@ func New(numHashes, numEntries int) (*Filter, error) { }, nil } -// Parameters returns the [numHashes] and [numEntries] that were used when -// creating this filter. -func (f *Filter) Parameters() (int, int) { - return len(f.hashSeeds), len(f.entries) -} - func (f *Filter) Add(hash uint64) { f.lock.Lock() defer f.lock.Unlock() diff --git a/utils/bloom/filter_test.go b/utils/bloom/filter_test.go index 94e4b29d9bce..856797f8ab50 100644 --- a/utils/bloom/filter_test.go +++ b/utils/bloom/filter_test.go @@ -63,10 +63,6 @@ func TestNormalUsage(t *testing.T) { require.Equal(len(toAdd), filter.Count()) - numHashes, numEntries := filter.Parameters() - require.Equal(initialNumHashes, numHashes) - require.Equal(initialNumBytes, numEntries) - filterBytes := filter.Marshal() parsedFilter, err := Parse(filterBytes) require.NoError(err) diff --git a/vms/avm/network/gossip.go b/vms/avm/network/gossip.go index c36195ff8870..adfe9aa6831f 100644 --- a/vms/avm/network/gossip.go +++ b/vms/avm/network/gossip.go @@ -23,6 +23,10 @@ var ( _ gossip.Marshaller[*txs.Tx] = (*txParser)(nil) ) +// bloomChurnMultiplier is the number used to multiply the size of the mempool +// to determine how large of a bloom filter to create. +const bloomChurnMultiplier = 3 + // txGossipHandler is the handler called when serving gossip messages type txGossipHandler struct { p2p.NoOpHandler @@ -64,27 +68,25 @@ func newGossipMempool( log logging.Logger, txVerifier TxVerifier, parser txs.Parser, - maxExpectedElements int, - falsePositiveProbability, - maxFalsePositiveProbability float64, + minTargetElements int, + targetFalsePositiveProbability, + resetFalsePositiveProbability float64, ) (*gossipMempool, error) { - bloom, err := gossip.NewBloomFilter(maxExpectedElements, falsePositiveProbability) + bloom, err := gossip.NewBloomFilter(minTargetElements, targetFalsePositiveProbability, resetFalsePositiveProbability) return &gossipMempool{ - Mempool: mempool, - log: log, - txVerifier: txVerifier, - parser: parser, - maxFalsePositiveProbability: maxFalsePositiveProbability, - bloom: bloom, + Mempool: mempool, + log: log, + txVerifier: txVerifier, + parser: parser, + bloom: bloom, }, err } type gossipMempool struct { mempool.Mempool - log logging.Logger - txVerifier TxVerifier - parser txs.Parser - maxFalsePositiveProbability float64 + log logging.Logger + txVerifier TxVerifier + parser txs.Parser lock sync.RWMutex bloom *gossip.BloomFilter @@ -127,7 +129,7 @@ func (g *gossipMempool) AddVerified(tx *txs.Tx) error { defer g.lock.Unlock() g.bloom.Add(tx) - reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, g.maxFalsePositiveProbability) + reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, g.Mempool.Len()*bloomChurnMultiplier) if err != nil { return err } @@ -148,7 +150,7 @@ func (g *gossipMempool) Iterate(f func(*txs.Tx) bool) { g.Mempool.Iterate(f) } -func (g *gossipMempool) GetFilter() (bloom []byte, salt []byte, err error) { +func (g *gossipMempool) GetFilter() (bloom []byte, salt []byte) { g.lock.RLock() defer g.lock.RUnlock() diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index f5b45f8a6aae..da66dff9b2ac 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -165,6 +165,7 @@ func TestNetworkAppGossip(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().Len().Return(0) mempool.EXPECT().RequestBuildBlock() return mempool }, @@ -303,6 +304,7 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().Len().Return(0) mempool.EXPECT().RequestBuildBlock() return mempool }, @@ -398,6 +400,7 @@ func TestNetworkIssueVerifiedTx(t *testing.T) { mempoolFunc: func(ctrl *gomock.Controller) mempool.Mempool { mempool := mempool.NewMockMempool(ctrl) mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().Len().Return(0) mempool.EXPECT().RequestBuildBlock() return mempool }, diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index d5030cbce648..4ac275a21305 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -63,6 +63,9 @@ type Mempool interface { // unissued. This allows previously dropped txs to be possibly reissued. MarkDropped(txID ids.ID, reason error) GetDropReason(txID ids.ID) error + + // Len returns the number of txs in the mempool. + Len() int } type mempool struct { @@ -233,3 +236,10 @@ func (m *mempool) GetDropReason(txID ids.ID) error { err, _ := m.droppedTxIDs.Get(txID) return err } + +func (m *mempool) Len() int { + m.lock.RLock() + defer m.lock.RUnlock() + + return m.unissuedTxs.Len() +} diff --git a/vms/avm/txs/mempool/mock_mempool.go b/vms/avm/txs/mempool/mock_mempool.go index b94d2db095bf..c82758bac51f 100644 --- a/vms/avm/txs/mempool/mock_mempool.go +++ b/vms/avm/txs/mempool/mock_mempool.go @@ -90,6 +90,20 @@ func (mr *MockMempoolMockRecorder) Iterate(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockMempool)(nil).Iterate), arg0) } +// Len mocks base method. +func (m *MockMempool) Len() int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Len") + ret0, _ := ret[0].(int) + return ret0 +} + +// Len indicates an expected call of Len. +func (mr *MockMempoolMockRecorder) Len() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Len", reflect.TypeOf((*MockMempool)(nil).Len)) +} + // MarkDropped mocks base method. func (m *MockMempool) MarkDropped(arg0 ids.ID, arg1 error) { m.ctrl.T.Helper() diff --git a/vms/platformvm/network/gossip.go b/vms/platformvm/network/gossip.go index 0bfc705bfd5a..fa40567430f7 100644 --- a/vms/platformvm/network/gossip.go +++ b/vms/platformvm/network/gossip.go @@ -23,6 +23,10 @@ var ( _ gossip.Gossipable = (*txs.Tx)(nil) ) +// bloomChurnMultiplier is the number used to multiply the size of the mempool +// to determine how large of a bloom filter to create. +const bloomChurnMultiplier = 3 + // txGossipHandler is the handler called when serving gossip messages type txGossipHandler struct { p2p.NoOpHandler @@ -61,25 +65,23 @@ func newGossipMempool( mempool mempool.Mempool, log logging.Logger, txVerifier TxVerifier, - maxExpectedElements int, - falsePositiveProbability float64, - maxFalsePositiveProbability float64, + minTargetElements int, + targetFalsePositiveProbability, + resetFalsePositiveProbability float64, ) (*gossipMempool, error) { - bloom, err := gossip.NewBloomFilter(maxExpectedElements, falsePositiveProbability) + bloom, err := gossip.NewBloomFilter(minTargetElements, targetFalsePositiveProbability, resetFalsePositiveProbability) return &gossipMempool{ - Mempool: mempool, - log: log, - txVerifier: txVerifier, - bloom: bloom, - maxFalsePositiveProbability: maxFalsePositiveProbability, + Mempool: mempool, + log: log, + txVerifier: txVerifier, + bloom: bloom, }, err } type gossipMempool struct { mempool.Mempool - log logging.Logger - txVerifier TxVerifier - maxFalsePositiveProbability float64 + log logging.Logger + txVerifier TxVerifier lock sync.RWMutex bloom *gossip.BloomFilter @@ -113,7 +115,7 @@ func (g *gossipMempool) Add(tx *txs.Tx) error { defer g.lock.Unlock() g.bloom.Add(tx) - reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, g.maxFalsePositiveProbability) + reset, err := gossip.ResetBloomFilterIfNeeded(g.bloom, g.Mempool.Len()*bloomChurnMultiplier) if err != nil { return err } @@ -130,7 +132,7 @@ func (g *gossipMempool) Add(tx *txs.Tx) error { return nil } -func (g *gossipMempool) GetFilter() (bloom []byte, salt []byte, err error) { +func (g *gossipMempool) GetFilter() (bloom []byte, salt []byte) { g.lock.RLock() defer g.lock.RUnlock() diff --git a/vms/platformvm/network/gossip_test.go b/vms/platformvm/network/gossip_test.go index a51c86872297..dcfca4ed2eed 100644 --- a/vms/platformvm/network/gossip_test.go +++ b/vms/platformvm/network/gossip_test.go @@ -130,6 +130,7 @@ func TestGossipAddBloomFilter(t *testing.T) { mempool.EXPECT().Get(txID).Return(nil, false) mempool.EXPECT().GetDropReason(txID).Return(nil) mempool.EXPECT().Add(tx).Return(nil) + mempool.EXPECT().Len().Return(0) mempool.EXPECT().RequestBuildBlock(false) gossipMempool, err := newGossipMempool( diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go index 5bb735395767..181fbc163cea 100644 --- a/vms/platformvm/network/network_test.go +++ b/vms/platformvm/network/network_test.go @@ -124,6 +124,7 @@ func TestNetworkAppGossip(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().Len().Return(0) mempool.EXPECT().RequestBuildBlock(false) return mempool }, @@ -300,6 +301,7 @@ func TestNetworkIssueTx(t *testing.T) { mempool.EXPECT().Get(gomock.Any()).Return(nil, false) mempool.EXPECT().GetDropReason(gomock.Any()).Return(nil) mempool.EXPECT().Add(gomock.Any()).Return(nil) + mempool.EXPECT().Len().Return(0) mempool.EXPECT().RequestBuildBlock(false) return mempool }, diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index 3f202cc3940d..34ee9c283745 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -67,6 +67,9 @@ type Mempool interface { // possibly reissued. MarkDropped(txID ids.ID, reason error) GetDropReason(txID ids.ID) error + + // Len returns the number of txs in the mempool. + Len() int } // Transactions from clients that have not yet been put into blocks and added to @@ -246,3 +249,10 @@ func (m *mempool) RequestBuildBlock(emptyBlockPermitted bool) { default: } } + +func (m *mempool) Len() int { + m.lock.RLock() + defer m.lock.RUnlock() + + return m.unissuedTxs.Len() +} diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index 0cfd9b141def..d88f0592571a 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -90,6 +90,20 @@ func (mr *MockMempoolMockRecorder) Iterate(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockMempool)(nil).Iterate), arg0) } +// Len mocks base method. +func (m *MockMempool) Len() int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Len") + ret0, _ := ret[0].(int) + return ret0 +} + +// Len indicates an expected call of Len. +func (mr *MockMempoolMockRecorder) Len() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Len", reflect.TypeOf((*MockMempool)(nil).Len)) +} + // MarkDropped mocks base method. func (m *MockMempool) MarkDropped(arg0 ids.ID, arg1 error) { m.ctrl.T.Helper() From 310b77e221b8d0c5fcee3254900079b1987466f5 Mon Sep 17 00:00:00 2001 From: Patrick O'Grady Date: Wed, 10 Jan 2024 16:29:17 +0100 Subject: [PATCH 238/267] [ci] Increase Fuzz Time in Periodic Runs (#2599) --- .github/workflows/fuzz.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index b0ede2b349b7..fdca7ab41b8b 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -22,4 +22,4 @@ jobs: check-latest: true - name: Run fuzz tests shell: bash - run: ./scripts/build_fuzz.sh 30 # Run each fuzz test 30 seconds + run: ./scripts/build_fuzz.sh 180 # Run each fuzz test 180 seconds From 9b4a01ca5f96ee3f9b07da80c373d8010684aaa6 Mon Sep 17 00:00:00 2001 From: marun Date: Thu, 11 Jan 2024 13:50:02 +0100 Subject: [PATCH 239/267] `tmpnet`: Save metrics snapshot to disk before node shutdown (#2601) --- tests/fixture/tmpnet/network.go | 2 +- tests/fixture/tmpnet/node.go | 31 +++++++++++++++++++++++++++-- tests/fixture/tmpnet/node_config.go | 14 +++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index da18b59c0c58..3352f7dcb1cf 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -299,7 +299,7 @@ func (n *Network) Stop(ctx context.Context) error { // Initiate stop on all nodes for _, node := range nodes { - if err := node.InitiateStop(); err != nil { + if err := node.InitiateStop(ctx); err != nil { errs = append(errs, fmt.Errorf("failed to stop node %s: %w", node.NodeID, err)) } } diff --git a/tests/fixture/tmpnet/node.go b/tests/fixture/tmpnet/node.go index 8638985dd5b2..d1f97c7ead9c 100644 --- a/tests/fixture/tmpnet/node.go +++ b/tests/fixture/tmpnet/node.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "net/http" "os" "path/filepath" "strings" @@ -141,7 +142,10 @@ func (n *Node) Start(w io.Writer) error { return n.getRuntime().Start(w) } -func (n *Node) InitiateStop() error { +func (n *Node) InitiateStop(ctx context.Context) error { + if err := n.SaveMetricsSnapshot(ctx); err != nil { + return err + } return n.getRuntime().InitiateStop() } @@ -157,9 +161,32 @@ func (n *Node) getDataDir() string { return cast.ToString(n.Flags[config.DataDirKey]) } +// Writes the current state of the metrics endpoint to disk +func (n *Node) SaveMetricsSnapshot(ctx context.Context) error { + if len(n.URI) == 0 { + // No URI to request metrics from + return nil + } + uri := n.URI + "/ext/metrics" + req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil) + if err != nil { + return err + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + return n.writeMetricsSnapshot(body) +} + // Initiates node shutdown and waits for the node to stop. func (n *Node) Stop(ctx context.Context) error { - if err := n.InitiateStop(); err != nil { + if err := n.InitiateStop(ctx); err != nil { return err } return n.WaitForStopped(ctx) diff --git a/tests/fixture/tmpnet/node_config.go b/tests/fixture/tmpnet/node_config.go index 15000ae279fb..3ebbc01b6c32 100644 --- a/tests/fixture/tmpnet/node_config.go +++ b/tests/fixture/tmpnet/node_config.go @@ -8,6 +8,8 @@ import ( "fmt" "os" "path/filepath" + "strings" + "time" "github.com/ava-labs/avalanchego/utils/perms" ) @@ -98,3 +100,15 @@ func (n *Node) Write() error { } return n.writeConfig() } + +func (n *Node) writeMetricsSnapshot(data []byte) error { + metricsDir := filepath.Join(n.getDataDir(), "metrics") + if err := os.MkdirAll(metricsDir, perms.ReadWriteExecute); err != nil { + return fmt.Errorf("failed to create metrics dir: %w", err) + } + // Create a compatible filesystem from the current timestamp + ts := time.Now().UTC().Format(time.RFC3339) + ts = strings.ReplaceAll(strings.ReplaceAll(ts, ":", ""), "-", "") + metricsPath := filepath.Join(metricsDir, ts) + return os.WriteFile(metricsPath, data, perms.ReadWrite) +} From d3595e5cec301c08891cb864f03d372cd338ad3e Mon Sep 17 00:00:00 2001 From: hugo-syn <61210734+hugo-syn@users.noreply.github.com> Date: Thu, 11 Jan 2024 20:25:06 +0100 Subject: [PATCH 240/267] chore: Fix typo s/useage/usage (#2602) --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index a7c232d7674b..743df32d471d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -36,7 +36,7 @@ The plugin version is unchanged at `30` and is compatible with versions `v1.10.1 ### Fixes - Fixed `duplicated operation on provided value` error when executing atomic operations after state syncing the C-chain -- Removed useage of atomic trie after commitment +- Removed usage of atomic trie after commitment - Fixed atomic trie root overwrite during state sync - Prevented closure of `stdout` and `stderr` when shutting down the logger From 31e5b3e6655e2e2a1e5c1653ab8ea48e228bba3e Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 11 Jan 2024 17:22:59 -0500 Subject: [PATCH 241/267] Deprecate `SnowRogueCommitThresholdKey` and `SnowVirtuousCommitThresholdKey` (#2600) --- config/config.go | 23 ++++++++++++----------- config/flags.go | 6 ++++-- config/keys.go | 1 + snow/consensus/snowball/parameters.go | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/config/config.go b/config/config.go index 0c53f46837a4..297d46255077 100644 --- a/config/config.go +++ b/config/config.go @@ -79,6 +79,9 @@ var ( ConsensusGossipOnAcceptValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, ConsensusGossipOnAcceptNonValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, ConsensusGossipOnAcceptPeerSizeKey: acceptedFrontierGossipDeprecationMsg, + + SnowRogueCommitThresholdKey: fmt.Sprintf("use --%s instead", SnowCommitThresholdKey), + SnowVirtuousCommitThresholdKey: fmt.Sprintf("use --%s instead", SnowCommitThresholdKey), } errConflictingACPOpinion = errors.New("supporting and objecting to the same ACP") @@ -106,17 +109,11 @@ var ( func getConsensusConfig(v *viper.Viper) snowball.Parameters { p := snowball.Parameters{ - K: v.GetInt(SnowSampleSizeKey), - AlphaPreference: v.GetInt(SnowPreferenceQuorumSizeKey), - AlphaConfidence: v.GetInt(SnowConfidenceQuorumSizeKey), - // During the X-chain linearization we require BetaVirtuous and - // BetaRogue to be equal. Therefore we use the more conservative - // BetaRogue value for both BetaVirtuous and BetaRogue. - // - // TODO: After the X-chain linearization use the - // SnowVirtuousCommitThresholdKey as before. - BetaVirtuous: v.GetInt(SnowRogueCommitThresholdKey), - BetaRogue: v.GetInt(SnowRogueCommitThresholdKey), + K: v.GetInt(SnowSampleSizeKey), + AlphaPreference: v.GetInt(SnowPreferenceQuorumSizeKey), + AlphaConfidence: v.GetInt(SnowConfidenceQuorumSizeKey), + BetaVirtuous: v.GetInt(SnowCommitThresholdKey), + BetaRogue: v.GetInt(SnowCommitThresholdKey), ConcurrentRepolls: v.GetInt(SnowConcurrentRepollsKey), OptimalProcessing: v.GetInt(SnowOptimalProcessingKey), MaxOutstandingItems: v.GetInt(SnowMaxProcessingKey), @@ -126,6 +123,10 @@ func getConsensusConfig(v *viper.Viper) snowball.Parameters { p.AlphaPreference = v.GetInt(SnowQuorumSizeKey) p.AlphaConfidence = p.AlphaPreference } + if v.IsSet(SnowRogueCommitThresholdKey) { + p.BetaVirtuous = v.GetInt(SnowRogueCommitThresholdKey) + p.BetaRogue = v.GetInt(SnowRogueCommitThresholdKey) + } return p } diff --git a/config/flags.go b/config/flags.go index acf965aea3a2..d8b013edc4a6 100644 --- a/config/flags.go +++ b/config/flags.go @@ -306,10 +306,12 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.Int(SnowQuorumSizeKey, snowball.DefaultParameters.AlphaConfidence, "Threshold of nodes required to update this node's preference and increase its confidence in a network poll") fs.Int(SnowPreferenceQuorumSizeKey, snowball.DefaultParameters.AlphaPreference, fmt.Sprintf("Threshold of nodes required to update this node's preference in a network poll. Ignored if %s is provided", SnowQuorumSizeKey)) fs.Int(SnowConfidenceQuorumSizeKey, snowball.DefaultParameters.AlphaConfidence, fmt.Sprintf("Threshold of nodes required to increase this node's confidence in a network poll. Ignored if %s is provided", SnowQuorumSizeKey)) - // TODO: Replace this temporary flag description after the X-chain - // linearization with "Beta value to use for virtuous transactions" + + fs.Int(SnowCommitThresholdKey, snowball.DefaultParameters.BetaRogue, "Beta value to use for transactions") + // TODO: Remove these once enough time has passed with SnowCommitThresholdKey fs.Int(SnowVirtuousCommitThresholdKey, snowball.DefaultParameters.BetaVirtuous, "This flag is temporarily ignored due to the X-chain linearization") fs.Int(SnowRogueCommitThresholdKey, snowball.DefaultParameters.BetaRogue, "Beta value to use for rogue transactions") + fs.Int(SnowConcurrentRepollsKey, snowball.DefaultParameters.ConcurrentRepolls, "Minimum number of concurrent polls for finalizing consensus") fs.Int(SnowOptimalProcessingKey, snowball.DefaultParameters.OptimalProcessing, "Optimal number of processing containers in consensus") fs.Int(SnowMaxProcessingKey, snowball.DefaultParameters.MaxOutstandingItems, "Maximum number of processing items to be considered healthy") diff --git a/config/keys.go b/config/keys.go index 45ccdf0a9d83..cdd90bf2b7f8 100644 --- a/config/keys.go +++ b/config/keys.go @@ -130,6 +130,7 @@ const ( SnowConfidenceQuorumSizeKey = "snow-confidence-quorum-size" SnowVirtuousCommitThresholdKey = "snow-virtuous-commit-threshold" SnowRogueCommitThresholdKey = "snow-rogue-commit-threshold" + SnowCommitThresholdKey = "snow-commit-threshold" SnowConcurrentRepollsKey = "snow-concurrent-repolls" SnowOptimalProcessingKey = "snow-optimal-processing" SnowMaxProcessingKey = "snow-max-processing" diff --git a/snow/consensus/snowball/parameters.go b/snow/consensus/snowball/parameters.go index 640b8702817e..bf458fbf9f40 100644 --- a/snow/consensus/snowball/parameters.go +++ b/snow/consensus/snowball/parameters.go @@ -39,7 +39,7 @@ var ( K: 20, AlphaPreference: 15, AlphaConfidence: 15, - BetaVirtuous: 15, + BetaVirtuous: 20, BetaRogue: 20, ConcurrentRepolls: 4, OptimalProcessing: 10, From 74e6afcfeb47d293bcd5680b5dd18e505c4da65f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 11 Jan 2024 18:10:43 -0500 Subject: [PATCH 242/267] Fix networking invalid field log (#2604) --- network/peer/peer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/peer/peer.go b/network/peer/peer.go index 5b6f38c6f19f..013b9d8ec3ea 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -1079,7 +1079,7 @@ func (p *peer) handlePeerList(msg *p2p.PeerList) { if ipLen := len(claimedIPPort.IpAddr); ipLen != net.IPv6len { p.Log.Debug("message with invalid field", zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.HandshakeOp), + zap.Stringer("messageOp", message.PeerListOp), zap.String("field", "IP"), zap.Int("ipLen", ipLen), ) From 62fe36de319852be10604f81e6d0d06d7ee417cc Mon Sep 17 00:00:00 2001 From: hugo-syn <61210734+hugo-syn@users.noreply.github.com> Date: Fri, 12 Jan 2024 18:56:43 +0100 Subject: [PATCH 243/267] chore: Fix typo s/seperate/separate/ (#2605) --- proto/pb/vm/vm_grpc.pb.go | 4 ++-- proto/vm/vm.proto | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/proto/pb/vm/vm_grpc.pb.go b/proto/pb/vm/vm_grpc.pb.go index 5250af11f86f..917e04d25e96 100644 --- a/proto/pb/vm/vm_grpc.pb.go +++ b/proto/pb/vm/vm_grpc.pb.go @@ -73,7 +73,7 @@ type VMClient interface { // Creates the HTTP handlers for custom VM network calls. // // Note: RPC Chain VM Factory will start a new instance of the VM in a - // seperate process which will populate the static handlers. After this + // separate process which will populate the static handlers. After this // process is created other processes will be created to populate blockchains, // but they will not have the static handlers be called again. CreateStaticHandlers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateStaticHandlersResponse, error) @@ -464,7 +464,7 @@ type VMServer interface { // Creates the HTTP handlers for custom VM network calls. // // Note: RPC Chain VM Factory will start a new instance of the VM in a - // seperate process which will populate the static handlers. After this + // separate process which will populate the static handlers. After this // process is created other processes will be created to populate blockchains, // but they will not have the static handlers be called again. CreateStaticHandlers(context.Context, *emptypb.Empty) (*CreateStaticHandlersResponse, error) diff --git a/proto/vm/vm.proto b/proto/vm/vm.proto index fb93455105df..ff50de1eb6cb 100644 --- a/proto/vm/vm.proto +++ b/proto/vm/vm.proto @@ -24,7 +24,7 @@ service VM { // Creates the HTTP handlers for custom VM network calls. // // Note: RPC Chain VM Factory will start a new instance of the VM in a - // seperate process which will populate the static handlers. After this + // separate process which will populate the static handlers. After this // process is created other processes will be created to populate blockchains, // but they will not have the static handlers be called again. rpc CreateStaticHandlers(google.protobuf.Empty) returns (CreateStaticHandlersResponse); From a6ee97878fe831148bfa044e063f39d092955c42 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 13 Jan 2024 17:27:22 -0500 Subject: [PATCH 244/267] Support dynamic port peerlist gossip (#2603) --- .github/workflows/ci.yml | 21 +++--- app/app.go | 101 +------------------------ config/config.go | 68 +++-------------- config/flags.go | 5 +- nat/nat.go | 4 +- network/dialer_test.go | 10 +-- network/network.go | 15 +++- network/peer/peer.go | 27 +++++++ network/peer/peer_test.go | 4 +- network/peer/test_peer.go | 2 +- network/test_network.go | 4 +- node/config.go | 13 +--- node/node.go | 153 +++++++++++++++++++++++++++++++++----- 13 files changed, 214 insertions(+), 213 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9e0501d677f..b08cb01068d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -109,16 +109,17 @@ jobs: - name: Build AvalancheGo Binary shell: bash run: ./scripts/build.sh - - name: Run e2e tests - shell: bash - run: ./scripts/tests.upgrade.sh - - name: Upload tmpnet network dir - uses: actions/upload-artifact@v3 - if: always() - with: - name: upgrade-tmpnet-data - path: ${{ env.tmpnet_data_path }} - if-no-files-found: error + # TODO: re-activate this test after there is a compatible tag to use + # - name: Run e2e tests + # shell: bash + # run: ./scripts/tests.upgrade.sh + # - name: Upload tmpnet network dir + # uses: actions/upload-artifact@v3 + # if: always() + # with: + # name: upgrade-tmpnet-data + # path: ${{ env.tmpnet_data_path }} + # if-no-files-found: error Lint: runs-on: ubuntu-latest steps: diff --git a/app/app.go b/app/app.go index c2da07b416a8..26043ff449da 100644 --- a/app/app.go +++ b/app/app.go @@ -14,30 +14,20 @@ import ( "golang.org/x/sync/errgroup" - "github.com/ava-labs/avalanchego/nat" "github.com/ava-labs/avalanchego/node" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/utils/ulimit" ) -const ( - Header = ` _____ .__ .__ +const Header = ` _____ .__ .__ / _ \___ _______ | | _____ ____ ____ | |__ ____ ,_ o / /_\ \ \/ /\__ \ | | \__ \ / \_/ ___\| | \_/ __ \ / //\, / | \ / / __ \| |__/ __ \| | \ \___| Y \ ___/ \>> | \____|__ /\_/ (____ /____(____ /___| /\___ >___| /\___ > \\ \/ \/ \/ \/ \/ \/ \/` -) - -var ( - stakingPortName = fmt.Sprintf("%s-staking", constants.AppName) - httpPortName = fmt.Sprintf("%s-http", constants.AppName) - _ App = (*app)(nil) -) +var _ App = (*app)(nil) type App interface { // Start kicks off the application and returns immediately. @@ -88,7 +78,6 @@ func New(config node.Config) (App, error) { } return &app{ - config: config, node: n, log: log, logFactory: logFactory, @@ -133,7 +122,6 @@ func Run(app App) int { // app is a wrapper around a node that runs in this process type app struct { - config node.Config node *node.Node log logging.Logger logFactory logging.Factory @@ -144,88 +132,6 @@ type app struct { // Does not block until the node is done. Errors returned from this method // are not logged. func (a *app) Start() error { - // Track if sybil control is enforced - if !a.config.SybilProtectionEnabled { - a.log.Warn("sybil control is not enforced") - } - - // TODO move this to config - // SupportsNAT() for NoRouter is false. - // Which means we tried to perform a NAT activity but we were not successful. - if a.config.AttemptedNATTraversal && !a.config.Nat.SupportsNAT() { - a.log.Warn("UPnP and NAT-PMP router attach failed, " + - "you may not be listening publicly. " + - "Please confirm the settings in your router") - } - - if ip := a.config.IPPort.IPPort().IP; ip.IsLoopback() || ip.IsPrivate() { - a.log.Warn("P2P IP is private, you will not be publicly discoverable", - zap.Stringer("ip", ip), - ) - } - - // An empty host is treated as a wildcard to match all addresses, so it is - // considered public. - hostIsPublic := a.config.HTTPHost == "" - if !hostIsPublic { - ip, err := ips.Lookup(a.config.HTTPHost) - if err != nil { - a.log.Fatal("failed to lookup HTTP host", - zap.String("host", a.config.HTTPHost), - zap.Error(err), - ) - a.logFactory.Close() - return err - } - hostIsPublic = !ip.IsLoopback() && !ip.IsPrivate() - - a.log.Debug("finished HTTP host lookup", - zap.String("host", a.config.HTTPHost), - zap.Stringer("ip", ip), - zap.Bool("isPublic", hostIsPublic), - ) - } - - mapper := nat.NewPortMapper(a.log, a.config.Nat) - - // Open staking port we want for NAT traversal to have the external port - // (config.IP.Port) to connect to our internal listening port - // (config.InternalStakingPort) which should be the same in most cases. - if port := a.config.IPPort.IPPort().Port; port != 0 { - mapper.Map( - port, - port, - stakingPortName, - a.config.IPPort, - a.config.IPResolutionFreq, - ) - } - - // Don't open the HTTP port if the HTTP server is private - if hostIsPublic { - a.log.Warn("HTTP server is binding to a potentially public host. "+ - "You may be vulnerable to a DoS attack if your HTTP port is publicly accessible", - zap.String("host", a.config.HTTPHost), - ) - - // For NAT traversal we want to route from the external port - // (config.ExternalHTTPPort) to our internal port (config.HTTPPort). - if a.config.HTTPPort != 0 { - mapper.Map( - a.config.HTTPPort, - a.config.HTTPPort, - httpPortName, - nil, - a.config.IPResolutionFreq, - ) - } - } - - // Regularly update our public IP. - // Note that if the node config said to not dynamically resolve and - // update our public IP, [p.config.IPUdater] is a no-op implementation. - go a.config.IPUpdater.Dispatch(a.log) - // [p.ExitCode] will block until [p.exitWG.Done] is called a.exitWG.Add(1) go func() { @@ -238,9 +144,6 @@ func (a *app) Start() error { a.exitWG.Done() }() defer func() { - mapper.UnmapAllPorts() - a.config.IPUpdater.Stop() - // If [p.node.Dispatch()] panics, then we should log the panic and // then re-raise the panic. This is why the above defer is broken // into two parts. diff --git a/config/config.go b/config/config.go index 297d46255077..e4ae0816c043 100644 --- a/config/config.go +++ b/config/config.go @@ -4,7 +4,6 @@ package config import ( - "context" "crypto/tls" "encoding/base64" "encoding/json" @@ -12,7 +11,6 @@ import ( "fmt" "io/fs" "math" - "net" "os" "path/filepath" "strings" @@ -25,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/ipcs" - "github.com/ava-labs/avalanchego/nat" "github.com/ava-labs/avalanchego/network" "github.com/ava-labs/avalanchego/network/dialer" "github.com/ava-labs/avalanchego/network/throttling" @@ -40,7 +37,6 @@ import ( "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/dynamicip" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/password" @@ -58,7 +54,6 @@ const ( chainConfigFileName = "config" chainUpgradeFileName = "upgrade" subnetConfigFileExt = ".json" - ipResolutionTimeout = 30 * time.Second ipcDeprecationMsg = "IPC API is deprecated" keystoreDeprecationMsg = "keystore API is deprecated" @@ -617,64 +612,19 @@ func getBootstrapConfig(v *viper.Viper, networkID uint32) (node.BootstrapConfig, } func getIPConfig(v *viper.Viper) (node.IPConfig, error) { - ipResolutionService := v.GetString(PublicIPResolutionServiceKey) - ipResolutionFreq := v.GetDuration(PublicIPResolutionFreqKey) - if ipResolutionFreq <= 0 { - return node.IPConfig{}, fmt.Errorf("%q must be > 0", PublicIPResolutionFreqKey) - } - - stakingPort := uint16(v.GetUint(StakingPortKey)) - publicIP := v.GetString(PublicIPKey) - if publicIP != "" && ipResolutionService != "" { - return node.IPConfig{}, fmt.Errorf("only one of --%s and --%s can be given", PublicIPKey, PublicIPResolutionServiceKey) - } - - // Define default configuration ipConfig := node.IPConfig{ - IPUpdater: dynamicip.NewNoUpdater(), - IPResolutionFreq: ipResolutionFreq, - Nat: nat.NewNoRouter(), - ListenHost: v.GetString(StakingHostKey), - } - - if publicIP != "" { - // User specified a specific public IP to use. - ip := net.ParseIP(publicIP) - if ip == nil { - return node.IPConfig{}, fmt.Errorf("invalid IP Address %s", publicIP) - } - ipConfig.IPPort = ips.NewDynamicIPPort(ip, stakingPort) - return ipConfig, nil + PublicIP: v.GetString(PublicIPKey), + PublicIPResolutionService: v.GetString(PublicIPResolutionServiceKey), + PublicIPResolutionFreq: v.GetDuration(PublicIPResolutionFreqKey), + ListenHost: v.GetString(StakingHostKey), + ListenPort: uint16(v.GetUint(StakingPortKey)), } - if ipResolutionService != "" { - // User specified to use dynamic IP resolution. - resolver, err := dynamicip.NewResolver(ipResolutionService) - if err != nil { - return node.IPConfig{}, fmt.Errorf("couldn't create IP resolver: %w", err) - } - - // Use that to resolve our public IP. - ctx, cancel := context.WithTimeout(context.Background(), ipResolutionTimeout) - defer cancel() - ip, err := resolver.Resolve(ctx) - if err != nil { - return node.IPConfig{}, fmt.Errorf("couldn't resolve public IP: %w", err) - } - ipConfig.IPPort = ips.NewDynamicIPPort(ip, stakingPort) - ipConfig.IPUpdater = dynamicip.NewUpdater(ipConfig.IPPort, resolver, ipResolutionFreq) - return ipConfig, nil + if ipConfig.PublicIPResolutionFreq <= 0 { + return node.IPConfig{}, fmt.Errorf("%q must be > 0", PublicIPResolutionFreqKey) } - - // User didn't specify a public IP to use, and they didn't specify a public IP resolution - // service to use. Try to resolve public IP with NAT traversal. - nat := nat.GetRouter() - ip, err := nat.ExternalIP() - if err != nil { - return node.IPConfig{}, fmt.Errorf("public IP / IP resolution service not given and failed to resolve IP with NAT: %w", err) + if ipConfig.PublicIP != "" && ipConfig.PublicIPResolutionService != "" { + return node.IPConfig{}, fmt.Errorf("only one of --%s and --%s can be given", PublicIPKey, PublicIPResolutionServiceKey) } - ipConfig.IPPort = ips.NewDynamicIPPort(ip, stakingPort) - ipConfig.Nat = nat - ipConfig.AttemptedNATTraversal = true return ipConfig, nil } diff --git a/config/flags.go b/config/flags.go index d8b013edc4a6..e98f132da6a5 100644 --- a/config/flags.go +++ b/config/flags.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/trace" "github.com/ava-labs/avalanchego/utils/compression" "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/dynamicip" "github.com/ava-labs/avalanchego/utils/ulimit" "github.com/ava-labs/avalanchego/utils/units" ) @@ -133,9 +134,9 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.Duration(NetworkPeerListGossipFreqKey, constants.DefaultNetworkPeerListGossipFreq, "Frequency to gossip peers to other nodes") // Public IP Resolution - fs.String(PublicIPKey, "", "Public IP of this node for P2P communication. If empty, try to discover with NAT") + fs.String(PublicIPKey, "", "Public IP of this node for P2P communication") fs.Duration(PublicIPResolutionFreqKey, 5*time.Minute, "Frequency at which this node resolves/updates its public IP and renew NAT mappings, if applicable") - fs.String(PublicIPResolutionServiceKey, "", fmt.Sprintf("Only acceptable values are 'ifconfigco', 'opendns' or 'ifconfigme'. When provided, the node will use that service to periodically resolve/update its public IP. Ignored if %s is set", PublicIPKey)) + fs.String(PublicIPResolutionServiceKey, "", fmt.Sprintf("Only acceptable values are %q, %q or %q. When provided, the node will use that service to periodically resolve/update its public IP", dynamicip.OpenDNSName, dynamicip.IFConfigCoName, dynamicip.IFConfigMeName)) // Inbound Connection Throttling fs.Duration(NetworkInboundConnUpgradeThrottlerCooldownKey, constants.DefaultInboundConnUpgradeThrottlerCooldown, "Upgrade an inbound connection from a given IP at most once per this duration. If 0, don't rate-limit inbound connection upgrades") diff --git a/nat/nat.go b/nat/nat.go index 20af4fe27ea9..a6e37078e7a6 100644 --- a/nat/nat.go +++ b/nat/nat.go @@ -53,8 +53,8 @@ type Mapper struct { } // NewPortMapper returns an initialized mapper -func NewPortMapper(log logging.Logger, r Router) Mapper { - return Mapper{ +func NewPortMapper(log logging.Logger, r Router) *Mapper { + return &Mapper{ log: log, r: r, closer: make(chan struct{}), diff --git a/network/dialer_test.go b/network/dialer_test.go index ecc506ba2927..7a60d056d66d 100644 --- a/network/dialer_test.go +++ b/network/dialer_test.go @@ -33,7 +33,7 @@ func (d *testDialer) NewListener() (ips.DynamicIPPort, *testListener) { // Uses a private IP to easily enable testing AllowPrivateIPs ip := ips.NewDynamicIPPort( net.IPv4(10, 0, 0, 0), - uint16(len(d.listeners)), + uint16(len(d.listeners)+1), ) staticIP := ip.IPPort() listener := newTestListener(staticIP) @@ -55,22 +55,22 @@ func (d *testDialer) Dial(ctx context.Context, ip ips.IPPort) (net.Conn, error) Conn: serverConn, localAddr: &net.TCPAddr{ IP: net.IPv6loopback, - Port: 0, + Port: 1, }, remoteAddr: &net.TCPAddr{ IP: net.IPv6loopback, - Port: 1, + Port: 2, }, } client := &testConn{ Conn: clientConn, localAddr: &net.TCPAddr{ IP: net.IPv6loopback, - Port: 2, + Port: 3, }, remoteAddr: &net.TCPAddr{ IP: net.IPv6loopback, - Port: 3, + Port: 4, }, } select { diff --git a/network/network.go b/network/network.go index 2dc6b2bbfdcb..2d178cb93488 100644 --- a/network/network.go +++ b/network/network.go @@ -1068,6 +1068,10 @@ func (n *network) peerIPStatus(nodeID ids.NodeID, ip *ips.ClaimedIPPort) (*ips.C // there is a randomized exponential backoff to avoid spamming connection // attempts. func (n *network) dial(nodeID ids.NodeID, ip *trackedIP) { + n.peerConfig.Log.Verbo("attempting to dial node", + zap.Stringer("nodeID", nodeID), + zap.Stringer("ip", ip.ip), + ) go func() { n.metrics.numTracked.Inc() defer n.metrics.numTracked.Dec() @@ -1141,7 +1145,7 @@ func (n *network) dial(nodeID ids.NodeID, ip *trackedIP) { n.peerConfig.Log.Verbo("skipping connection dial", zap.String("reason", "outbound connections to private IPs are prohibited"), zap.Stringer("nodeID", nodeID), - zap.Stringer("peerIP", ip.ip.IP), + zap.Stringer("peerIP", ip.ip), zap.Duration("delay", ip.delay), ) continue @@ -1151,7 +1155,8 @@ func (n *network) dial(nodeID ids.NodeID, ip *trackedIP) { if err != nil { n.peerConfig.Log.Verbo( "failed to reach peer, attempting again", - zap.Stringer("peerIP", ip.ip.IP), + zap.Stringer("nodeID", nodeID), + zap.Stringer("peerIP", ip.ip), zap.Duration("delay", ip.delay), ) continue @@ -1159,14 +1164,16 @@ func (n *network) dial(nodeID ids.NodeID, ip *trackedIP) { n.peerConfig.Log.Verbo("starting to upgrade connection", zap.String("direction", "outbound"), - zap.Stringer("peerIP", ip.ip.IP), + zap.Stringer("nodeID", nodeID), + zap.Stringer("peerIP", ip.ip), ) err = n.upgrade(conn, n.clientUpgrader) if err != nil { n.peerConfig.Log.Verbo( "failed to upgrade, attempting again", - zap.Stringer("peerIP", ip.ip.IP), + zap.Stringer("nodeID", nodeID), + zap.Stringer("peerIP", ip.ip), zap.Duration("delay", ip.delay), ) continue diff --git a/network/peer/peer.go b/network/peer/peer.go index 013b9d8ec3ea..16b5d3ab3090 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -500,6 +500,13 @@ func (p *peer) writeMessages() { ) return } + if mySignedIP.Port == 0 { + p.Log.Error("signed IP has invalid port", + zap.Stringer("nodeID", p.id), + zap.Uint16("port", mySignedIP.Port), + ) + return + } myVersion := p.VersionCompatibility.Version() legacyApplication := &version.Application{ @@ -996,6 +1003,16 @@ func (p *peer) handleHandshake(msg *p2p.Handshake) { p.StartClose() return } + if msg.IpPort == 0 { + p.Log.Debug("message with invalid field", + zap.Stringer("nodeID", p.id), + zap.Stringer("messageOp", message.HandshakeOp), + zap.String("field", "Port"), + zap.Uint32("port", msg.IpPort), + ) + p.StartClose() + return + } p.ip = &SignedIP{ UnsignedIP: UnsignedIP{ @@ -1086,6 +1103,16 @@ func (p *peer) handlePeerList(msg *p2p.PeerList) { p.StartClose() return } + if claimedIPPort.IpPort == 0 { + p.Log.Debug("message with invalid field", + zap.Stringer("nodeID", p.id), + zap.Stringer("messageOp", message.PeerListOp), + zap.String("field", "Port"), + zap.Uint32("port", claimedIPPort.IpPort), + ) + // TODO: After v1.11.x is activated, close the peer here. + continue + } txID, err := ids.ToID(claimedIPPort.TxId) if err != nil { diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index 77dd47e73f2c..797a9634a863 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -112,7 +112,7 @@ func makeRawTestPeers(t *testing.T, trackedSubnets set.Set[ids.ID]) (*rawTestPee peerConfig0 := sharedConfig peerConfig1 := sharedConfig - ip0 := ips.NewDynamicIPPort(net.IPv6loopback, 0) + ip0 := ips.NewDynamicIPPort(net.IPv6loopback, 1) tls0 := tlsCert0.PrivateKey.(crypto.Signer) peerConfig0.IPSigner = NewIPSigner(ip0, tls0) @@ -122,7 +122,7 @@ func makeRawTestPeers(t *testing.T, trackedSubnets set.Set[ids.ID]) (*rawTestPee inboundMsgChan0 <- msg }) - ip1 := ips.NewDynamicIPPort(net.IPv6loopback, 1) + ip1 := ips.NewDynamicIPPort(net.IPv6loopback, 2) tls1 := tlsCert1.PrivateKey.(crypto.Signer) peerConfig1.IPSigner = NewIPSigner(ip1, tls1) diff --git a/network/peer/test_peer.go b/network/peer/test_peer.go index 74627930c952..7bd58344ab86 100644 --- a/network/peer/test_peer.go +++ b/network/peer/test_peer.go @@ -102,7 +102,7 @@ func StartTestPeer( return nil, err } - signerIP := ips.NewDynamicIPPort(net.IPv6zero, 0) + signerIP := ips.NewDynamicIPPort(net.IPv6zero, 1) tls := tlsCert.PrivateKey.(crypto.Signer) peer := Start( diff --git a/network/test_network.go b/network/test_network.go index e1c76e92774a..0811875b4c43 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -66,7 +66,7 @@ func (l *noopListener) Close() error { func (*noopListener) Addr() net.Addr { return &net.TCPAddr{ IP: net.IPv4zero, - Port: 0, + Port: 1, } } @@ -225,7 +225,7 @@ func NewTestNetwork( networkConfig.ResourceTracker.DiskTracker(), ) - networkConfig.MyIPPort = ips.NewDynamicIPPort(net.IPv4zero, 0) + networkConfig.MyIPPort = ips.NewDynamicIPPort(net.IPv4zero, 1) networkConfig.GossipTracker, err = peer.NewGossipTracker(metrics, "") if err != nil { diff --git a/node/config.go b/node/config.go index 768f23cab3e9..a26ec4806fc6 100644 --- a/node/config.go +++ b/node/config.go @@ -11,7 +11,6 @@ import ( "github.com/ava-labs/avalanchego/chains" "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/nat" "github.com/ava-labs/avalanchego/network" "github.com/ava-labs/avalanchego/snow/networking/benchlist" "github.com/ava-labs/avalanchego/snow/networking/router" @@ -19,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/subnets" "github.com/ava-labs/avalanchego/trace" "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/dynamicip" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/profiler" @@ -74,19 +72,16 @@ type APIConfig struct { } type IPConfig struct { - IPPort ips.DynamicIPPort `json:"ip"` - IPUpdater dynamicip.Updater `json:"-"` - IPResolutionFreq time.Duration `json:"ipResolutionFrequency"` - // True if we attempted NAT traversal - AttemptedNATTraversal bool `json:"attemptedNATTraversal"` - // Tries to perform network address translation - Nat nat.Router `json:"-"` + PublicIP string `json:"publicIP"` + PublicIPResolutionService string `json:"publicIPResolutionService"` + PublicIPResolutionFreq time.Duration `json:"publicIPResolutionFreq"` // The host portion of the address to listen on. The port to // listen on will be sourced from IPPort. // // - If empty, listen on all interfaces (both ipv4 and ipv6). // - If populated, listen only on the specified address. ListenHost string `json:"listenHost"` + ListenPort uint16 `json:"listenPort"` } type StakingConfig struct { diff --git a/node/node.go b/node/node.go index 45e2f6a506eb..8fce5df75550 100644 --- a/node/node.go +++ b/node/node.go @@ -48,6 +48,7 @@ import ( "github.com/ava-labs/avalanchego/indexer" "github.com/ava-labs/avalanchego/ipcs" "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/nat" "github.com/ava-labs/avalanchego/network" "github.com/ava-labs/avalanchego/network/dialer" "github.com/ava-labs/avalanchego/network/peer" @@ -64,6 +65,7 @@ import ( "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/dynamicip" "github.com/ava-labs/avalanchego/utils/filesystem" "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/ips" @@ -91,6 +93,13 @@ import ( platformconfig "github.com/ava-labs/avalanchego/vms/platformvm/config" ) +const ( + stakingPortName = constants.AppName + "-staking" + httpPortName = constants.AppName + "-http" + + ipResolutionTimeout = 30 * time.Second +) + var ( genesisHashKey = []byte("genesisID") ungracefulShutdown = []byte("ungracefulShutdown") @@ -156,7 +165,7 @@ func New( } n.initMetrics() - + n.initNAT() if err := n.initAPIServer(); err != nil { // Start the API Server return nil, fmt.Errorf("couldn't initialize API server: %w", err) } @@ -193,6 +202,7 @@ func New( n.vdrs = validators.NewManager() if !n.Config.SybilProtectionEnabled { + logger.Warn("sybil control is not enforced") n.vdrs = newOverriddenManager(constants.PrimaryNetworkID, n.vdrs) } if err := n.initResourceManager(n.MetricsRegisterer); err != nil { @@ -266,6 +276,10 @@ type Node struct { // Storage for this node DB database.Database + router nat.Router + portMapper *nat.Mapper + ipUpdater dynamicip.Updater + // Profiles the process. Nil if continuous profiling is disabled. profiler profiler.ContinuousProfiler @@ -380,8 +394,6 @@ type Node struct { // Initialize the networking layer. // Assumes [n.vdrs], [n.CPUTracker], and [n.CPUTargeter] have been initialized. func (n *Node) initNetworking() error { - currentIPPort := n.Config.IPPort.IPPort() - // Providing either loopback address - `::1` for ipv6 and `127.0.0.1` for ipv4 - as the listen // host will avoid the need for a firewall exception on recent MacOS: // @@ -399,8 +411,7 @@ func (n *Node) initNetworking() error { // // 1: https://apple.stackexchange.com/questions/393715/do-you-want-the-application-main-to-accept-incoming-network-connections-pop // 2: https://github.com/golang/go/issues/56998 - listenAddress := net.JoinHostPort(n.Config.ListenHost, strconv.FormatUint(uint64(currentIPPort.Port), 10)) - + listenAddress := net.JoinHostPort(n.Config.ListenHost, strconv.FormatUint(uint64(n.Config.ListenPort), 10)) listener, err := net.Listen(constants.NetworkType, listenAddress) if err != nil { return err @@ -408,23 +419,67 @@ func (n *Node) initNetworking() error { // Wrap listener so it will only accept a certain number of incoming connections per second listener = throttling.NewThrottledListener(listener, n.Config.NetworkConfig.ThrottlerConfig.MaxInboundConnsPerSec) - ipPort, err := ips.ToIPPort(listener.Addr().String()) + // Record the bound address to enable inclusion in process context file. + n.stakingAddress = listener.Addr().String() + ipPort, err := ips.ToIPPort(n.stakingAddress) if err != nil { - n.Log.Info("initializing networking", - zap.Stringer("currentNodeIP", currentIPPort), - ) - } else { - ipPort = ips.IPPort{ - IP: currentIPPort.IP, - Port: ipPort.Port, + return err + } + + var dynamicIP ips.DynamicIPPort + switch { + case n.Config.PublicIP != "": + // Use the specified public IP. + ipPort.IP = net.ParseIP(n.Config.PublicIP) + if ipPort.IP == nil { + return fmt.Errorf("invalid IP Address: %s", n.Config.PublicIP) } - n.Log.Info("initializing networking", - zap.Stringer("currentNodeIP", ipPort), + dynamicIP = ips.NewDynamicIPPort(ipPort.IP, ipPort.Port) + n.ipUpdater = dynamicip.NewNoUpdater() + case n.Config.PublicIPResolutionService != "": + // Use dynamic IP resolution. + resolver, err := dynamicip.NewResolver(n.Config.PublicIPResolutionService) + if err != nil { + return fmt.Errorf("couldn't create IP resolver: %w", err) + } + + // Use that to resolve our public IP. + ctx, cancel := context.WithTimeout(context.Background(), ipResolutionTimeout) + ipPort.IP, err = resolver.Resolve(ctx) + cancel() + if err != nil { + return fmt.Errorf("couldn't resolve public IP: %w", err) + } + dynamicIP = ips.NewDynamicIPPort(ipPort.IP, ipPort.Port) + n.ipUpdater = dynamicip.NewUpdater(dynamicIP, resolver, n.Config.PublicIPResolutionFreq) + default: + ipPort.IP, err = n.router.ExternalIP() + if err != nil { + return fmt.Errorf("public IP / IP resolution service not given and failed to resolve IP with NAT: %w", err) + } + dynamicIP = ips.NewDynamicIPPort(ipPort.IP, ipPort.Port) + n.ipUpdater = dynamicip.NewNoUpdater() + } + + if ipPort.IP.IsLoopback() || ipPort.IP.IsPrivate() { + n.Log.Warn("P2P IP is private, you will not be publicly discoverable", + zap.Stringer("ip", ipPort), ) } - // Record the bound address to enable inclusion in process context file. - n.stakingAddress = listener.Addr().String() + // Regularly update our public IP and port mappings. + n.portMapper.Map( + ipPort.Port, + ipPort.Port, + stakingPortName, + dynamicIP, + n.Config.PublicIPResolutionFreq, + ) + go n.ipUpdater.Dispatch(n.Log) + + n.Log.Info("initializing networking", + zap.Stringer("ip", ipPort), + ) tlsKey, ok := n.Config.StakingTLSCert.PrivateKey.(crypto.Signer) if !ok { @@ -543,7 +598,7 @@ func (n *Node) initNetworking() error { // add node configs to network config n.Config.NetworkConfig.Namespace = n.networkNamespace n.Config.NetworkConfig.MyNodeID = n.ID - n.Config.NetworkConfig.MyIPPort = n.Config.IPPort + n.Config.NetworkConfig.MyIPPort = dynamicIP n.Config.NetworkConfig.NetworkID = n.Config.NetworkID n.Config.NetworkConfig.Validators = n.vdrs n.Config.NetworkConfig.Beacons = n.bootstrappers @@ -861,16 +916,76 @@ func (n *Node) initMetrics() { n.MetricsGatherer = metrics.NewMultiGatherer() } +func (n *Node) initNAT() { + n.Log.Info("initializing NAT") + + if n.Config.PublicIP == "" && n.Config.PublicIPResolutionService == "" { + n.router = nat.GetRouter() + if !n.router.SupportsNAT() { + n.Log.Warn("UPnP and NAT-PMP router attach failed, " + + "you may not be listening publicly. " + + "Please confirm the settings in your router") + } + } else { + n.router = nat.NewNoRouter() + } + + n.portMapper = nat.NewPortMapper(n.Log, n.router) +} + // initAPIServer initializes the server that handles HTTP calls func (n *Node) initAPIServer() error { n.Log.Info("initializing API server") + // An empty host is treated as a wildcard to match all addresses, so it is + // considered public. + hostIsPublic := n.Config.HTTPHost == "" + if !hostIsPublic { + ip, err := ips.Lookup(n.Config.HTTPHost) + if err != nil { + n.Log.Fatal("failed to lookup HTTP host", + zap.String("host", n.Config.HTTPHost), + zap.Error(err), + ) + return err + } + hostIsPublic = !ip.IsLoopback() && !ip.IsPrivate() + + n.Log.Debug("finished HTTP host lookup", + zap.String("host", n.Config.HTTPHost), + zap.Stringer("ip", ip), + zap.Bool("isPublic", hostIsPublic), + ) + } + listenAddress := net.JoinHostPort(n.Config.HTTPHost, strconv.FormatUint(uint64(n.Config.HTTPPort), 10)) listener, err := net.Listen("tcp", listenAddress) if err != nil { return err } + addr := listener.Addr().String() + ipPort, err := ips.ToIPPort(addr) + if err != nil { + return err + } + + // Don't open the HTTP port if the HTTP server is private + if hostIsPublic { + n.Log.Warn("HTTP server is binding to a potentially public host. "+ + "You may be vulnerable to a DoS attack if your HTTP port is publicly accessible", + zap.String("host", n.Config.HTTPHost), + ) + + n.portMapper.Map( + ipPort.Port, + ipPort.Port, + httpPortName, + nil, + n.Config.PublicIPResolutionFreq, + ) + } + protocol := "http" if n.Config.HTTPSEnabled { cert, err := tls.X509KeyPair(n.Config.HTTPSCert, n.Config.HTTPSKey) @@ -1585,6 +1700,8 @@ func (n *Node) shutdown() { zap.Error(err), ) } + n.portMapper.UnmapAllPorts() + n.ipUpdater.Stop() if err := n.indexer.Close(); err != nil { n.Log.Debug("error closing tx indexer", zap.Error(err), From 864dbec3964dd4e0cc9080f19f1b5d1efa773685 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 14 Jan 2024 02:03:09 -0500 Subject: [PATCH 245/267] Replace `PeerListAck` with `GetPeerList` (#2580) --- config/config.go | 6 + config/flags.go | 2 + config/keys.go | 2 + genesis/bootstrappers.go | 9 +- message/messages_test.go | 87 ++- message/mock_outbound_message_builder.go | 40 +- message/ops.go | 22 +- message/outbound_msg_builder.go | 61 +- network/README.md | 69 +- network/certs_test.go | 24 + network/config.go | 12 +- network/ip_tracker.go | 364 +++++++++ network/ip_tracker_test.go | 690 +++++++++++++++++ network/network.go | 491 ++++-------- network/network_test.go | 92 +-- network/peer/gossip_tracker.go | 323 -------- network/peer/gossip_tracker_callback.go | 56 -- network/peer/gossip_tracker_metrics.go | 40 - network/peer/gossip_tracker_test.go | 620 --------------- network/peer/network.go | 25 +- network/peer/peer.go | 223 ++++-- network/peer/test_network.go | 16 +- network/test_network.go | 10 +- node/node.go | 13 - proto/p2p/p2p.proto | 45 +- proto/pb/p2p/p2p.pb.go | 943 ++++++++++++----------- utils/bloom/read_filter.go | 17 + utils/constants/networking.go | 2 + utils/ips/claimed_ip_port.go | 44 +- utils/ips/ip_port.go | 5 +- 30 files changed, 2142 insertions(+), 2211 deletions(-) create mode 100644 network/ip_tracker.go create mode 100644 network/ip_tracker_test.go delete mode 100644 network/peer/gossip_tracker.go delete mode 100644 network/peer/gossip_tracker_callback.go delete mode 100644 network/peer/gossip_tracker_metrics.go delete mode 100644 network/peer/gossip_tracker_test.go diff --git a/config/config.go b/config/config.go index e4ae0816c043..5de3e70777b4 100644 --- a/config/config.go +++ b/config/config.go @@ -427,6 +427,8 @@ func getNetworkConfig( PeerListNonValidatorGossipSize: v.GetUint32(NetworkPeerListNonValidatorGossipSizeKey), PeerListPeersGossipSize: v.GetUint32(NetworkPeerListPeersGossipSizeKey), PeerListGossipFreq: v.GetDuration(NetworkPeerListGossipFreqKey), + PeerListPullGossipFreq: v.GetDuration(NetworkPeerListPullGossipFreqKey), + PeerListBloomResetFreq: v.GetDuration(NetworkPeerListBloomResetFreqKey), }, DelayConfig: network.DelayConfig{ @@ -462,6 +464,10 @@ func getNetworkConfig( return network.Config{}, fmt.Errorf("%q must be >= 0", NetworkOutboundConnectionTimeoutKey) case config.PeerListGossipFreq < 0: return network.Config{}, fmt.Errorf("%s must be >= 0", NetworkPeerListGossipFreqKey) + case config.PeerListPullGossipFreq < 0: + return network.Config{}, fmt.Errorf("%s must be >= 0", NetworkPeerListPullGossipFreqKey) + case config.PeerListBloomResetFreq < 0: + return network.Config{}, fmt.Errorf("%s must be >= 0", NetworkPeerListBloomResetFreqKey) case config.ThrottlerConfig.InboundMsgThrottlerConfig.CPUThrottlerConfig.MaxRecheckDelay < constants.MinInboundThrottlerMaxRecheckDelay: return network.Config{}, fmt.Errorf("%s must be >= %d", InboundThrottlerCPUMaxRecheckDelayKey, constants.MinInboundThrottlerMaxRecheckDelay) case config.ThrottlerConfig.InboundMsgThrottlerConfig.DiskThrottlerConfig.MaxRecheckDelay < constants.MinInboundThrottlerMaxRecheckDelay: diff --git a/config/flags.go b/config/flags.go index e98f132da6a5..6f85fedfd33c 100644 --- a/config/flags.go +++ b/config/flags.go @@ -132,6 +132,8 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.Uint(NetworkPeerListNonValidatorGossipSizeKey, constants.DefaultNetworkPeerListNonValidatorGossipSize, "Number of non-validators that the node will gossip peer list to") fs.Uint(NetworkPeerListPeersGossipSizeKey, constants.DefaultNetworkPeerListPeersGossipSize, "Number of total peers (including non-validators and validators) that the node will gossip peer list to") fs.Duration(NetworkPeerListGossipFreqKey, constants.DefaultNetworkPeerListGossipFreq, "Frequency to gossip peers to other nodes") + fs.Duration(NetworkPeerListPullGossipFreqKey, constants.DefaultNetworkPeerListPullGossipFreq, "Frequency to request peers from other nodes") + fs.Duration(NetworkPeerListBloomResetFreqKey, constants.DefaultNetworkPeerListBloomResetFreq, "Frequency to recalculate the bloom filter used to request new peers from other nodes") // Public IP Resolution fs.String(PublicIPKey, "", "Public IP of this node for P2P communication") diff --git a/config/keys.go b/config/keys.go index cdd90bf2b7f8..b2ccc16fc63d 100644 --- a/config/keys.go +++ b/config/keys.go @@ -94,6 +94,8 @@ const ( NetworkPeerListNonValidatorGossipSizeKey = "network-peer-list-non-validator-gossip-size" NetworkPeerListPeersGossipSizeKey = "network-peer-list-peers-gossip-size" NetworkPeerListGossipFreqKey = "network-peer-list-gossip-frequency" + NetworkPeerListPullGossipFreqKey = "network-peer-list-pull-gossip-frequency" + NetworkPeerListBloomResetFreqKey = "network-peer-list-bloom-reset-frequency" NetworkInitialReconnectDelayKey = "network-initial-reconnect-delay" NetworkReadHandshakeTimeoutKey = "network-read-handshake-timeout" NetworkPingTimeoutKey = "network-ping-timeout" diff --git a/genesis/bootstrappers.go b/genesis/bootstrappers.go index cac90bb50301..b3e3a2a24f0c 100644 --- a/genesis/bootstrappers.go +++ b/genesis/bootstrappers.go @@ -36,10 +36,15 @@ type Bootstrapper struct { IP ips.IPDesc `json:"ip"` } +// GetBootstrappers returns all default bootstrappers for the provided network. +func GetBootstrappers(networkID uint32) []Bootstrapper { + networkName := constants.NetworkIDToNetworkName[networkID] + return bootstrappersPerNetwork[networkName] +} + // SampleBootstrappers returns the some beacons this node should connect to func SampleBootstrappers(networkID uint32, count int) []Bootstrapper { - networkName := constants.NetworkIDToNetworkName[networkID] - bootstrappers := bootstrappersPerNetwork[networkName] + bootstrappers := GetBootstrappers(networkID) count = math.Min(count, len(bootstrappers)) s := sampler.NewUniform() diff --git a/message/messages_test.go b/message/messages_test.go index e164e8993007..b259cefa341e 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -142,12 +142,63 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, + { + desc: "get_peer_list message with no compression", + op: GetPeerListOp, + msg: &p2p.Message{ + Message: &p2p.Message_GetPeerList{ + GetPeerList: &p2p.GetPeerList{ + KnownPeers: &p2p.BloomFilter{ + Filter: make([]byte, 2048), + Salt: make([]byte, 32), + }, + }, + }, + }, + compressionType: compression.TypeNone, + bypassThrottling: false, + bytesSaved: false, + }, + { + desc: "get_peer_list message with gzip compression", + op: GetPeerListOp, + msg: &p2p.Message{ + Message: &p2p.Message_GetPeerList{ + GetPeerList: &p2p.GetPeerList{ + KnownPeers: &p2p.BloomFilter{ + Filter: make([]byte, 2048), + Salt: make([]byte, 32), + }, + }, + }, + }, + compressionType: compression.TypeGzip, + bypassThrottling: false, + bytesSaved: true, + }, + { + desc: "get_peer_list message with zstd compression", + op: GetPeerListOp, + msg: &p2p.Message{ + Message: &p2p.Message_GetPeerList{ + GetPeerList: &p2p.GetPeerList{ + KnownPeers: &p2p.BloomFilter{ + Filter: make([]byte, 2048), + Salt: make([]byte, 32), + }, + }, + }, + }, + compressionType: compression.TypeZstd, + bypassThrottling: false, + bytesSaved: true, + }, { desc: "peer_list message with no compression", op: PeerListOp, msg: &p2p.Message{ - Message: &p2p.Message_PeerList{ - PeerList: &p2p.PeerList{ + Message: &p2p.Message_PeerList_{ + PeerList_: &p2p.PeerList{ ClaimedIpPorts: []*p2p.ClaimedIpPort{ { X509Certificate: testTLSCert.Certificate[0], @@ -168,8 +219,8 @@ func TestMessage(t *testing.T) { desc: "peer_list message with gzip compression", op: PeerListOp, msg: &p2p.Message{ - Message: &p2p.Message_PeerList{ - PeerList: &p2p.PeerList{ + Message: &p2p.Message_PeerList_{ + PeerList_: &p2p.PeerList{ ClaimedIpPorts: []*p2p.ClaimedIpPort{ { X509Certificate: testTLSCert.Certificate[0], @@ -190,8 +241,8 @@ func TestMessage(t *testing.T) { desc: "peer_list message with zstd compression", op: PeerListOp, msg: &p2p.Message{ - Message: &p2p.Message_PeerList{ - PeerList: &p2p.PeerList{ + Message: &p2p.Message_PeerList_{ + PeerList_: &p2p.PeerList{ ClaimedIpPorts: []*p2p.ClaimedIpPort{ { X509Certificate: testTLSCert.Certificate[0], @@ -208,25 +259,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: true, }, - { - desc: "peer_list_ack message with no compression", - op: PeerListAckOp, - msg: &p2p.Message{ - Message: &p2p.Message_PeerListAck{ - PeerListAck: &p2p.PeerListAck{ - PeerAcks: []*p2p.PeerAck{ - { - TxId: testID[:], - Timestamp: 1, - }, - }, - }, - }, - }, - compressionType: compression.TypeNone, - bypassThrottling: false, - bytesSaved: false, - }, { desc: "get_state_summary_frontier message with no compression", op: GetStateSummaryFrontierOp, @@ -836,8 +868,9 @@ func TestMessage(t *testing.T) { require.Equal(tv.bypassThrottling, encodedMsg.BypassThrottling()) require.Equal(tv.op, encodedMsg.Op()) - bytesSaved := encodedMsg.BytesSavedCompression() - require.Equal(tv.bytesSaved, bytesSaved > 0) + if bytesSaved := encodedMsg.BytesSavedCompression(); tv.bytesSaved { + require.Greater(bytesSaved, 0) + } parsedMsg, err := mb.parseInbound(encodedMsg.Bytes(), ids.EmptyNodeID, func() {}) require.NoError(err) diff --git a/message/mock_outbound_message_builder.go b/message/mock_outbound_message_builder.go index 50af02669546..21cb518976ae 100644 --- a/message/mock_outbound_message_builder.go +++ b/message/mock_outbound_message_builder.go @@ -232,6 +232,21 @@ func (mr *MockOutboundMsgBuilderMockRecorder) GetAncestors(arg0, arg1, arg2, arg return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAncestors", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAncestors), arg0, arg1, arg2, arg3, arg4) } +// GetPeerList mocks base method. +func (m *MockOutboundMsgBuilder) GetPeerList(arg0, arg1 []byte) (OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPeerList", arg0, arg1) + ret0, _ := ret[0].(OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPeerList indicates an expected call of GetPeerList. +func (mr *MockOutboundMsgBuilderMockRecorder) GetPeerList(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPeerList", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetPeerList), arg0, arg1) +} + // GetStateSummaryFrontier mocks base method. func (m *MockOutboundMsgBuilder) GetStateSummaryFrontier(arg0 ids.ID, arg1 uint32, arg2 time.Duration) (OutboundMessage, error) { m.ctrl.T.Helper() @@ -248,22 +263,22 @@ func (mr *MockOutboundMsgBuilderMockRecorder) GetStateSummaryFrontier(arg0, arg1 } // Handshake mocks base method. -func (m *MockOutboundMsgBuilder) Handshake(arg0 uint32, arg1 uint64, arg2 ips.IPPort, arg3, arg4 string, arg5, arg6, arg7 uint32, arg8 uint64, arg9 []byte, arg10 []ids.ID, arg11, arg12 []uint32) (OutboundMessage, error) { +func (m *MockOutboundMsgBuilder) Handshake(arg0 uint32, arg1 uint64, arg2 ips.IPPort, arg3, arg4 string, arg5, arg6, arg7 uint32, arg8 uint64, arg9 []byte, arg10 []ids.ID, arg11, arg12 []uint32, arg13, arg14 []byte) (OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Handshake", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) + ret := m.ctrl.Call(m, "Handshake", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14) ret0, _ := ret[0].(OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Handshake indicates an expected call of Handshake. -func (mr *MockOutboundMsgBuilderMockRecorder) Handshake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Handshake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Handshake), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Handshake), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14) } // PeerList mocks base method. -func (m *MockOutboundMsgBuilder) PeerList(arg0 []ips.ClaimedIPPort, arg1 bool) (OutboundMessage, error) { +func (m *MockOutboundMsgBuilder) PeerList(arg0 []*ips.ClaimedIPPort, arg1 bool) (OutboundMessage, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PeerList", arg0, arg1) ret0, _ := ret[0].(OutboundMessage) @@ -277,21 +292,6 @@ func (mr *MockOutboundMsgBuilderMockRecorder) PeerList(arg0, arg1 interface{}) * return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerList", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).PeerList), arg0, arg1) } -// PeerListAck mocks base method. -func (m *MockOutboundMsgBuilder) PeerListAck(arg0 []*p2p.PeerAck) (OutboundMessage, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PeerListAck", arg0) - ret0, _ := ret[0].(OutboundMessage) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// PeerListAck indicates an expected call of PeerListAck. -func (mr *MockOutboundMsgBuilderMockRecorder) PeerListAck(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerListAck", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).PeerListAck), arg0) -} - // Ping mocks base method. func (m *MockOutboundMsgBuilder) Ping(arg0 uint32, arg1 []*p2p.SubnetUptime) (OutboundMessage, error) { m.ctrl.T.Helper() diff --git a/message/ops.go b/message/ops.go index 2f496713e419..0c58eb60690b 100644 --- a/message/ops.go +++ b/message/ops.go @@ -22,8 +22,8 @@ const ( PingOp Op = iota PongOp HandshakeOp + GetPeerListOp PeerListOp - PeerListAckOp // State sync: GetStateSummaryFrontierOp GetStateSummaryFrontierFailedOp @@ -72,8 +72,8 @@ var ( PingOp, PongOp, HandshakeOp, + GetPeerListOp, PeerListOp, - PeerListAckOp, } // List of all consensus request message types @@ -211,10 +211,10 @@ func (op Op) String() string { return "pong" case HandshakeOp: return "handshake" + case GetPeerListOp: + return "get_peerlist" case PeerListOp: return "peerlist" - case PeerListAckOp: - return "peerlist_ack" // State sync case GetStateSummaryFrontierOp: return "get_state_summary_frontier" @@ -305,10 +305,10 @@ func Unwrap(m *p2p.Message) (fmt.Stringer, error) { return msg.Pong, nil case *p2p.Message_Handshake: return msg.Handshake, nil - case *p2p.Message_PeerList: - return msg.PeerList, nil - case *p2p.Message_PeerListAck: - return msg.PeerListAck, nil + case *p2p.Message_GetPeerList: + return msg.GetPeerList, nil + case *p2p.Message_PeerList_: + return msg.PeerList_, nil // State sync: case *p2p.Message_GetStateSummaryFrontier: return msg.GetStateSummaryFrontier, nil @@ -364,10 +364,10 @@ func ToOp(m *p2p.Message) (Op, error) { return PongOp, nil case *p2p.Message_Handshake: return HandshakeOp, nil - case *p2p.Message_PeerList: + case *p2p.Message_GetPeerList: + return GetPeerListOp, nil + case *p2p.Message_PeerList_: return PeerListOp, nil - case *p2p.Message_PeerListAck: - return PeerListAckOp, nil case *p2p.Message_GetStateSummaryFrontier: return GetStateSummaryFrontierOp, nil case *p2p.Message_StateSummaryFrontier_: diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index f50f5cf6ae5d..150c9f4f3a65 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -32,15 +32,18 @@ type OutboundMsgBuilder interface { trackedSubnets []ids.ID, supportedACPs []uint32, objectedACPs []uint32, + knownPeersFilter []byte, + knownPeersSalt []byte, ) (OutboundMessage, error) - PeerList( - peers []ips.ClaimedIPPort, - bypassThrottling bool, + GetPeerList( + knownPeersFilter []byte, + knownPeersSalt []byte, ) (OutboundMessage, error) - PeerListAck( - peerAcks []*p2p.PeerAck, + PeerList( + peers []*ips.ClaimedIPPort, + bypassThrottling bool, ) (OutboundMessage, error) Ping( @@ -244,6 +247,8 @@ func (b *outMsgBuilder) Handshake( trackedSubnets []ids.ID, supportedACPs []uint32, objectedACPs []uint32, + knownPeersFilter []byte, + knownPeersSalt []byte, ) (OutboundMessage, error) { subnetIDBytes := make([][]byte, len(trackedSubnets)) encodeIDs(trackedSubnets, subnetIDBytes) @@ -267,6 +272,10 @@ func (b *outMsgBuilder) Handshake( }, SupportedAcps: supportedACPs, ObjectedAcps: objectedACPs, + KnownPeers: &p2p.BloomFilter{ + Filter: knownPeersFilter, + Salt: knownPeersSalt, + }, }, }, }, @@ -275,7 +284,27 @@ func (b *outMsgBuilder) Handshake( ) } -func (b *outMsgBuilder) PeerList(peers []ips.ClaimedIPPort, bypassThrottling bool) (OutboundMessage, error) { +func (b *outMsgBuilder) GetPeerList( + knownPeersFilter []byte, + knownPeersSalt []byte, +) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_GetPeerList{ + GetPeerList: &p2p.GetPeerList{ + KnownPeers: &p2p.BloomFilter{ + Filter: knownPeersFilter, + Salt: knownPeersSalt, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) PeerList(peers []*ips.ClaimedIPPort, bypassThrottling bool) (OutboundMessage, error) { claimIPPorts := make([]*p2p.ClaimedIpPort, len(peers)) for i, p := range peers { claimIPPorts[i] = &p2p.ClaimedIpPort{ @@ -284,13 +313,13 @@ func (b *outMsgBuilder) PeerList(peers []ips.ClaimedIPPort, bypassThrottling boo IpPort: uint32(p.IPPort.Port), Timestamp: p.Timestamp, Signature: p.Signature, - TxId: p.TxID[:], + TxId: ids.Empty[:], } } return b.builder.createOutbound( &p2p.Message{ - Message: &p2p.Message_PeerList{ - PeerList: &p2p.PeerList{ + Message: &p2p.Message_PeerList_{ + PeerList_: &p2p.PeerList{ ClaimedIpPorts: claimIPPorts, }, }, @@ -300,20 +329,6 @@ func (b *outMsgBuilder) PeerList(peers []ips.ClaimedIPPort, bypassThrottling boo ) } -func (b *outMsgBuilder) PeerListAck(peerAcks []*p2p.PeerAck) (OutboundMessage, error) { - return b.builder.createOutbound( - &p2p.Message{ - Message: &p2p.Message_PeerListAck{ - PeerListAck: &p2p.PeerListAck{ - PeerAcks: peerAcks, - }, - }, - }, - compression.TypeNone, - false, - ) -} - func (b *outMsgBuilder) GetStateSummaryFrontier( chainID ids.ID, requestID uint32, diff --git a/network/README.md b/network/README.md index 5e66e2e25f4f..303d1f56ab82 100644 --- a/network/README.md +++ b/network/README.md @@ -46,7 +46,7 @@ When starting an Avalanche node, a node needs to be able to initiate some proces In Avalanche, nodes connect to an initial set of bootstrapper nodes known as **beacons** (this is user-configurable). Once connected to a set of beacons, a node is able to discover other nodes in the network. Over time, a node eventually discovers other peers in the network through `PeerList` messages it receives through: - The handshake initiated between two peers when attempting to connect to a peer (see [Connecting](#connecting)). -- Periodic `PeerList` gossip messages that every peer sends to the peers it's connected to (see [Connected](#connected)). +- Responses to periodically sent `GetPeerList` messages requesting a `PeerList` of unknown peers (see [Connected](#connected)). #### Connecting @@ -79,7 +79,6 @@ Note right of Peer: LGTM! Note over Node,Peer: PeerList message Peer->>Node: Peer-X, Peer-Y, Peer-Z Note over Node,Peer: Handshake Complete -Node->>Peer: ACK Peer-X, Peer-Y, Peer-Z ``` Once the node attempting to join the network receives this `PeerList` message, the handshake is complete and the node is now connected to the peer. The node attempts to connect to the new peers discovered in the `PeerList` message. Each connection results in another peer handshake, which results in the node incrementally discovering more and more peers in the network as more and more `PeerList` messages are exchanged. @@ -92,71 +91,53 @@ Some peers aren't discovered through the `PeerList` messages exchanged through p sequenceDiagram Node ->> Peer-1: Handshake - v1.9.5 Peer-1 ->> Node: PeerList - Peer-2 -Node ->> Peer-1: ACK - Peer-2 Note left of Node: Node is connected to Peer-1 and now tries to connect to Peer-2. Node ->> Peer-2: Handshake - v1.9.5 Peer-2 ->> Node: PeerList - Peer-1 -Node ->> Peer-2: ACK - Peer-1 Note left of Node: Peer-3 was never sampled, so we haven't connected yet! Node --> Peer-3: No connection ``` -To guarantee that a node can discover all peers, each node periodically gossips a sample of the peers it knows about to other peers. +To guarantee that a node can discover all peers, each node periodically sends a `GetPeerList` message to a random peer. ##### PeerList Gossip ###### Messages -A `PeerList` is the message that is used to communicate the presence of peers in the network. Each `PeerList` message contains networking-level metadata about the peer that provides the necessary information to connect to it, alongside the corresponding transaction id that added that peer to the validator set. Transaction ids are unique hashes that only add a single validator, so it is guaranteed that there is a 1:1 mapping between a validator and its associated transaction id. +A `GetPeerList` message requests that the peer sends a `PeerList` message. `GetPeerList` messages contain a bloom filter of already known peers to reduce useless bandwidth on `PeerList` messages. The bloom filter reduces bandwidth by enabling the `PeerList` message to only include peers that aren't already known. -`PeerListAck` messages are sent in response to `PeerList` messages to allow a peer to confirm which peers it will actually attempt to connect to. Because nodes only gossip peers they believe another peer doesn't already know about to optimize bandwidth, `PeerListAck` messages are important to confirm that a peer will attempt to connect to someone. Without this, a node might gossip a peer to another peer and assume a connection between the two is being established, and not re-gossip the peer in future gossip cycles. If the connection was never actually wanted by the peer being gossiped to due to a transient reason, that peer would never be able to re-discover the gossiped peer and could be isolated from a subset of the network. +A `PeerList` is the message that is used to communicate the presence of peers in the network. Each `PeerList` message contains signed networking-level metadata about a peer that provides the necessary information to connect to it. -Once a `PeerListAck` message is received from a peer, the node that sent the original `PeerList` message marks the corresponding acknowledged validators as already having been transmitted to the peer, so that it's excluded from subsequent iterations of `PeerList` gossip. +Once peer metadata is received, the node will add that data to its bloom filter to prevent learning about it again. ###### Gossip Handshake messages provide a node with some knowledge of peers in the network, but offers no guarantee that learning about a subset of peers from each peer the node connects with will result in the node learning about every peer in the network. -In order to provide a probabilistic guarantee that all peers in the network will eventually learn of one another, each node periodically gossips a sample of the peers that they're aware of to a sample of the peers that they're connected to. Over time, this probabilistically guarantees that every peer will eventually learn of every other peer. +To provide an eventual guarantee that all peers learn of one another, each node periodically requests peers from a random peer. -To optimize bandwidth usage, each node tracks which peers are guaranteed to know of which peers. A node learns this information by tracking both inbound and outbound `PeerList` gossip. +To optimize bandwidth, each node tracks the most recent IPs of validators. The validator's nodeID and timestamp are inserted into a bloom filter which is used to select only necessary IPs to gossip. -- Inbound - - If a node ever receives `PeerList` from a peer, that peer _must_ have known about the peers in that `PeerList` message in order to have gossiped them. -- Outbound - - If a node sends a `PeerList` to a peer and the peer replies with an `PeerListAck` message, then all peers in the `PeerListAck` must be known by the peer. +As the number of entries increases in the bloom filter, the probability of a false positive increases. False positives can cause recent IPs not to be gossiped when they otherwise should be, slowing down the rate of `PeerList` gossip. To prevent the bloom filter from having too many false positives, a new bloom filter is periodically generated and the number of entries a validator is allowed to have in the bloom filter is capped. Generating the new bloom filter both removes stale entries and modifies the hash functions to avoid persistent hash collisions. -To efficiently track which peers know of which peers, the peers that each peer is aware of is represented in a [bit set](https://en.wikipedia.org/wiki/Bit_array). A peer is represented by either a `0` if it isn't known by the peer yet, or a `1` if it is known by the peer. - -A node follows the following steps for every cycle of `PeerList` gossip: - -1. Get a sample of peers in the network that the node is connected to -2. For each peer: - 1. Figure out which peers the node hasn't gossiped to them yet. - 2. Take a random sample of these unknown peers. - 3. Send a message describing these peers to the peer. +A node follows the following steps for of `PeerList` gossip: ```mermaid sequenceDiagram -Note left of Node: Initialize gossip bit set for Peer-123 -Note left of Node: Peer-123: [0, 0, 0] -Node->>Peer-123: PeerList - Peer-1 -Peer-123->>Node: PeerListAck - Peer-1 -Note left of Node: Peer-123: [1, 0, 0] -Node->>Peer-123: PeerList - Peer-3 -Peer-123->>Node: PeerListAck - Peer-3 -Note left of Node: Peer-123: [1, 0, 1] -Node->>Peer-123: PeerList - Peer-2 -Peer-123->>Node: PeerListAck - Peer-2 -Note left of Node: Peer-123: [1, 1, 1] -Note left of Node: No more gossip left to send to Peer-123! +Note left of Node: Initialize bloom filter +Note left of Node: Bloom: [0, 0, 0] +Node->>Peer-123: GetPeerList [0, 0, 0] +Note right of Peer-123: Any peers can be sent. +Peer-123->>Node: PeerList - Peer-1 +Note left of Node: Bloom: [1, 0, 0] +Node->>Peer-123: GetPeerList [1, 0, 0] +Note right of Peer-123: Either Peer-2 or Peer-3 can be sent. +Peer-123->>Node: PeerList - Peer-3 +Note left of Node: Bloom: [1, 0, 1] +Node->>Peer-123: GetPeerList [1, 0, 1] +Note right of Peer-123: Only Peer-2 can be sent. +Peer-123->>Node: PeerList - Peer-2 +Note left of Node: Bloom: [1, 1, 1] +Node->>Peer-123: GetPeerList [1, 1, 1] +Note right of Peer-123: There are no more peers left to send! ``` - -Because network state is generally expected to be stable (i.e nodes are not continuously flickering online/offline), as more and more gossip messages are exchanged nodes eventually realize that the peers that they are connected to have learned about every other peer. - -A node eventually stops gossiping peers when there's no more new peers to gossip about. `PeerList` gossip only resumes once: - -1. a new peer joins -2. a peer disconnects and reconnects -3. a new validator joins the network -4. a validator's IP is updated diff --git a/network/certs_test.go b/network/certs_test.go index 7b59e11d800c..d172d68650fc 100644 --- a/network/certs_test.go +++ b/network/certs_test.go @@ -5,6 +5,7 @@ package network import ( "crypto/tls" + "net" "sync" "testing" @@ -15,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/utils/ips" ) var ( @@ -31,6 +33,9 @@ var ( //go:embed test_key_3.key testKeyBytes3 []byte + ip *ips.ClaimedIPPort + otherIP *ips.ClaimedIPPort + certLock sync.Mutex tlsCerts []*tls.Certificate tlsConfigs []*tls.Config @@ -52,6 +57,25 @@ func init() { tlsCerts = []*tls.Certificate{ cert1, cert2, cert3, } + + ip = ips.NewClaimedIPPort( + staking.CertificateFromX509(cert1.Leaf), + ips.IPPort{ + IP: net.IPv4(127, 0, 0, 1), + Port: 9651, + }, + 1, // timestamp + nil, // signature + ) + otherIP = ips.NewClaimedIPPort( + staking.CertificateFromX509(cert2.Leaf), + ips.IPPort{ + IP: net.IPv4(127, 0, 0, 1), + Port: 9651, + }, + 1, // timestamp + nil, // signature + ) } func getTLS(t *testing.T, index int) (ids.NodeID, *tls.Certificate, *tls.Config) { diff --git a/network/config.go b/network/config.go index eda7257fa62c..5cb014741f56 100644 --- a/network/config.go +++ b/network/config.go @@ -10,7 +10,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/network/dialer" - "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/network/throttling" "github.com/ava-labs/avalanchego/snow/networking/tracker" "github.com/ava-labs/avalanchego/snow/uptime" @@ -73,6 +72,14 @@ type PeerListGossipConfig struct { // PeerListGossipFreq is the frequency that this node will attempt to gossip // signed IPs to its peers. PeerListGossipFreq time.Duration `json:"peerListGossipFreq"` + + // PeerListPullGossipFreq is the frequency that this node will attempt to + // request signed IPs from its peers. + PeerListPullGossipFreq time.Duration `json:"peerListPullGossipFreq"` + + // PeerListBloomResetFreq is how frequently this node will recalculate the + // IP tracker's bloom filter. + PeerListBloomResetFreq time.Duration `json:"peerListBloomResetFreq"` } type TimeoutConfig struct { @@ -182,7 +189,4 @@ type Config struct { // Specifies how much disk usage each peer can cause before // we rate-limit them. DiskTargeter tracker.Targeter `json:"-"` - - // Tracks which validators have been sent to which peers - GossipTracker peer.GossipTracker `json:"-"` } diff --git a/network/ip_tracker.go b/network/ip_tracker.go new file mode 100644 index 000000000000..7bc6cb293810 --- /dev/null +++ b/network/ip_tracker.go @@ -0,0 +1,364 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "crypto/rand" + "sync" + + "go.uber.org/zap" + + "golang.org/x/exp/maps" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/bloom" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/ips" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/sampler" + "github.com/ava-labs/avalanchego/utils/set" +) + +const ( + saltSize = 32 + minCountEstimate = 128 + targetFalsePositiveProbability = .001 + maxFalsePositiveProbability = .01 + // By setting maxIPEntriesPerValidator > 1, we allow validators to update + // their IP at least once per bloom filter reset. + maxIPEntriesPerValidator = 2 +) + +var _ validators.SetCallbackListener = (*ipTracker)(nil) + +func newIPTracker(log logging.Logger) (*ipTracker, error) { + tracker := &ipTracker{ + log: log, + connected: make(map[ids.NodeID]*ips.ClaimedIPPort), + mostRecentValidatorIPs: make(map[ids.NodeID]*ips.ClaimedIPPort), + gossipableIndicies: make(map[ids.NodeID]int), + bloomAdditions: make(map[ids.NodeID]int), + } + return tracker, tracker.resetBloom() +} + +type ipTracker struct { + log logging.Logger + + lock sync.RWMutex + // Manually tracked nodes are always treated like validators + manuallyTracked set.Set[ids.NodeID] + // Connected tracks the currently connected peers, including validators and + // non-validators. The IP is not necessarily the same IP as in + // mostRecentIPs. + connected map[ids.NodeID]*ips.ClaimedIPPort + mostRecentValidatorIPs map[ids.NodeID]*ips.ClaimedIPPort + validators set.Set[ids.NodeID] + + // An IP is marked as gossipable if: + // - The node is a validator + // - The node is connected + // - The IP the node connected with is its latest IP + gossipableIndicies map[ids.NodeID]int + gossipableIPs []*ips.ClaimedIPPort + + // The bloom filter contains the most recent validator IPs to avoid + // unnecessary IP gossip. + bloom *bloom.Filter + // To prevent validators from causing the bloom filter to have too many + // false positives, we limit each validator to maxIPEntriesPerValidator in + // the bloom filter. + bloomAdditions map[ids.NodeID]int // Number of IPs added to the bloom + bloomSalt []byte + maxBloomCount int +} + +func (i *ipTracker) ManuallyTrack(nodeID ids.NodeID) { + i.lock.Lock() + defer i.lock.Unlock() + + // We treat manually tracked nodes as if they were validators. + if !i.validators.Contains(nodeID) { + i.onValidatorAdded(nodeID) + } + // Now that the node is marked as a validator, freeze it's validation + // status. Future calls to OnValidatorAdded or OnValidatorRemoved will be + // treated as noops. + i.manuallyTracked.Add(nodeID) +} + +func (i *ipTracker) WantsConnection(nodeID ids.NodeID) bool { + i.lock.RLock() + defer i.lock.RUnlock() + + return i.validators.Contains(nodeID) +} + +func (i *ipTracker) ShouldVerifyIP(ip *ips.ClaimedIPPort) bool { + i.lock.RLock() + defer i.lock.RUnlock() + + if !i.validators.Contains(ip.NodeID) { + return false + } + + prevIP, ok := i.mostRecentValidatorIPs[ip.NodeID] + return !ok || // This would be the first IP + prevIP.Timestamp < ip.Timestamp // This would be a newer IP +} + +// AddIP returns true if the addition of the provided IP updated the most +// recently known IP of a validator. +func (i *ipTracker) AddIP(ip *ips.ClaimedIPPort) bool { + i.lock.Lock() + defer i.lock.Unlock() + + if !i.validators.Contains(ip.NodeID) { + return false + } + + prevIP, ok := i.mostRecentValidatorIPs[ip.NodeID] + if !ok { + // This is the first IP we've heard from the validator, so it is the + // most recent. + i.updateMostRecentValidatorIP(ip) + // Because we didn't previously have an IP, we know we aren't currently + // connected to them. + return true + } + + if prevIP.Timestamp >= ip.Timestamp { + // This IP is not newer than the previously known IP. + return false + } + + i.updateMostRecentValidatorIP(ip) + i.removeGossipableIP(ip.NodeID) + return true +} + +func (i *ipTracker) GetIP(nodeID ids.NodeID) (*ips.ClaimedIPPort, bool) { + i.lock.RLock() + defer i.lock.RUnlock() + + ip, ok := i.mostRecentValidatorIPs[nodeID] + return ip, ok +} + +func (i *ipTracker) Connected(ip *ips.ClaimedIPPort) { + i.lock.Lock() + defer i.lock.Unlock() + + i.connected[ip.NodeID] = ip + if !i.validators.Contains(ip.NodeID) { + return + } + + prevIP, ok := i.mostRecentValidatorIPs[ip.NodeID] + if !ok { + // This is the first IP we've heard from the validator, so it is the + // most recent. + i.updateMostRecentValidatorIP(ip) + i.addGossipableIP(ip) + return + } + + if prevIP.Timestamp > ip.Timestamp { + // There is a more up-to-date IP than the one that was used to connect. + return + } + + if prevIP.Timestamp < ip.Timestamp { + i.updateMostRecentValidatorIP(ip) + } + i.addGossipableIP(ip) +} + +func (i *ipTracker) Disconnected(nodeID ids.NodeID) { + i.lock.Lock() + defer i.lock.Unlock() + + delete(i.connected, nodeID) + i.removeGossipableIP(nodeID) +} + +func (i *ipTracker) OnValidatorAdded(nodeID ids.NodeID, _ *bls.PublicKey, _ ids.ID, _ uint64) { + i.lock.Lock() + defer i.lock.Unlock() + + i.onValidatorAdded(nodeID) +} + +func (i *ipTracker) onValidatorAdded(nodeID ids.NodeID) { + if i.manuallyTracked.Contains(nodeID) { + return + } + + i.validators.Add(nodeID) + ip, connected := i.connected[nodeID] + if !connected { + return + } + + // Because we only track validator IPs, the from the connection is + // guaranteed to be the most up-to-date IP that we know. + i.updateMostRecentValidatorIP(ip) + i.addGossipableIP(ip) +} + +func (*ipTracker) OnValidatorWeightChanged(ids.NodeID, uint64, uint64) {} + +func (i *ipTracker) OnValidatorRemoved(nodeID ids.NodeID, _ uint64) { + i.lock.Lock() + defer i.lock.Unlock() + + if i.manuallyTracked.Contains(nodeID) { + return + } + + delete(i.mostRecentValidatorIPs, nodeID) + i.validators.Remove(nodeID) + i.removeGossipableIP(nodeID) +} + +func (i *ipTracker) updateMostRecentValidatorIP(ip *ips.ClaimedIPPort) { + i.mostRecentValidatorIPs[ip.NodeID] = ip + oldCount := i.bloomAdditions[ip.NodeID] + if oldCount >= maxIPEntriesPerValidator { + return + } + + // If the validator set is growing rapidly, we should increase the size of + // the bloom filter. + if count := i.bloom.Count(); count >= i.maxBloomCount { + if err := i.resetBloom(); err != nil { + i.log.Error("failed to reset validator tracker bloom filter", + zap.Int("maxCount", i.maxBloomCount), + zap.Int("currentCount", count), + zap.Error(err), + ) + } else { + i.log.Info("reset validator tracker bloom filter", + zap.Int("currentCount", count), + ) + } + return + } + + i.bloomAdditions[ip.NodeID] = oldCount + 1 + bloom.Add(i.bloom, ip.GossipID[:], i.bloomSalt) +} + +func (i *ipTracker) addGossipableIP(ip *ips.ClaimedIPPort) { + i.gossipableIndicies[ip.NodeID] = len(i.gossipableIPs) + i.gossipableIPs = append(i.gossipableIPs, ip) +} + +func (i *ipTracker) removeGossipableIP(nodeID ids.NodeID) { + indexToRemove, wasGossipable := i.gossipableIndicies[nodeID] + if !wasGossipable { + return + } + + newNumGossipable := len(i.gossipableIPs) - 1 + if newNumGossipable != indexToRemove { + replacementIP := i.gossipableIPs[newNumGossipable] + i.gossipableIndicies[replacementIP.NodeID] = indexToRemove + i.gossipableIPs[indexToRemove] = replacementIP + } + + delete(i.gossipableIndicies, nodeID) + i.gossipableIPs[newNumGossipable] = nil + i.gossipableIPs = i.gossipableIPs[:newNumGossipable] +} + +// GetGossipableIPs returns the latest IPs of connected validators. The returned +// IPs will not contain [exceptNodeID] or any IPs contained in [exceptIPs]. If +// the number of eligible IPs to return low, it's possible that every IP will be +// iterated over while handling this call. +func (i *ipTracker) GetGossipableIPs( + exceptNodeID ids.NodeID, + exceptIPs *bloom.ReadFilter, + salt []byte, + maxNumIPs int, +) []*ips.ClaimedIPPort { + var ( + uniform = sampler.NewUniform() + ips = make([]*ips.ClaimedIPPort, 0, maxNumIPs) + ) + + i.lock.RLock() + defer i.lock.RUnlock() + + uniform.Initialize(uint64(len(i.gossipableIPs))) + for len(ips) < maxNumIPs { + index, err := uniform.Next() + if err != nil { + return ips + } + + ip := i.gossipableIPs[index] + if ip.NodeID == exceptNodeID { + continue + } + + if !bloom.Contains(exceptIPs, ip.GossipID[:], salt) { + ips = append(ips, ip) + } + } + return ips +} + +// ResetBloom prunes the current bloom filter. This must be called periodically +// to ensure that validators that change their IPs are updated correctly and +// that validators that left the validator set are removed. +func (i *ipTracker) ResetBloom() error { + i.lock.Lock() + defer i.lock.Unlock() + + return i.resetBloom() +} + +// Bloom returns the binary representation of the bloom filter along with the +// random salt. +func (i *ipTracker) Bloom() ([]byte, []byte) { + i.lock.RLock() + defer i.lock.RUnlock() + + return i.bloom.Marshal(), i.bloomSalt +} + +// resetBloom creates a new bloom filter with a reasonable size for the current +// validator set size. This function additionally populates the new bloom filter +// with the current most recently known IPs of validators. +func (i *ipTracker) resetBloom() error { + newSalt := make([]byte, saltSize) + _, err := rand.Reader.Read(newSalt) + if err != nil { + return err + } + + count := math.Max(maxIPEntriesPerValidator*i.validators.Len(), minCountEstimate) + numHashes, numEntries := bloom.OptimalParameters( + count, + targetFalsePositiveProbability, + ) + newFilter, err := bloom.New(numHashes, numEntries) + if err != nil { + return err + } + + i.bloom = newFilter + maps.Clear(i.bloomAdditions) + i.bloomSalt = newSalt + i.maxBloomCount = bloom.EstimateCount(numHashes, numEntries, maxFalsePositiveProbability) + + for nodeID, ip := range i.mostRecentValidatorIPs { + bloom.Add(newFilter, ip.GossipID[:], newSalt) + i.bloomAdditions[nodeID] = 1 + } + return nil +} diff --git a/network/ip_tracker_test.go b/network/ip_tracker_test.go new file mode 100644 index 000000000000..882c0a47ce8c --- /dev/null +++ b/network/ip_tracker_test.go @@ -0,0 +1,690 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/bloom" + "github.com/ava-labs/avalanchego/utils/ips" + "github.com/ava-labs/avalanchego/utils/logging" +) + +func newTestIPTracker(t *testing.T) *ipTracker { + tracker, err := newIPTracker(logging.NoLog{}) + require.NoError(t, err) + return tracker +} + +func newerTestIP(ip *ips.ClaimedIPPort) *ips.ClaimedIPPort { + return ips.NewClaimedIPPort( + ip.Cert, + ip.IPPort, + ip.Timestamp+1, + ip.Signature, + ) +} + +func requireEqual(t *testing.T, expected, actual *ipTracker) { + require := require.New(t) + require.Equal(expected.manuallyTracked, actual.manuallyTracked) + require.Equal(expected.connected, actual.connected) + require.Equal(expected.mostRecentValidatorIPs, actual.mostRecentValidatorIPs) + require.Equal(expected.validators, actual.validators) + require.Equal(expected.gossipableIndicies, actual.gossipableIndicies) + require.Equal(expected.gossipableIPs, actual.gossipableIPs) + require.Equal(expected.bloomAdditions, actual.bloomAdditions) + require.Equal(expected.maxBloomCount, actual.maxBloomCount) +} + +func TestIPTracker_ManuallyTrack(t *testing.T) { + tests := []struct { + name string + initialState *ipTracker + nodeID ids.NodeID + expectedState *ipTracker + }{ + { + name: "non-connected non-validator", + initialState: newTestIPTracker(t), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.validators.Add(ip.NodeID) + tracker.manuallyTracked.Add(ip.NodeID) + return tracker + }(), + }, + { + name: "connected non-validator", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.Connected(ip) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.Connected(ip) + tracker.mostRecentValidatorIPs[ip.NodeID] = ip + tracker.bloomAdditions[ip.NodeID] = 1 + tracker.gossipableIndicies[ip.NodeID] = 0 + tracker.gossipableIPs = []*ips.ClaimedIPPort{ + ip, + } + tracker.validators.Add(ip.NodeID) + tracker.manuallyTracked.Add(ip.NodeID) + return tracker + }(), + }, + { + name: "non-connected validator", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.manuallyTracked.Add(ip.NodeID) + return tracker + }(), + }, + { + name: "connected validator", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.Connected(ip) + tracker.onValidatorAdded(ip.NodeID) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.Connected(ip) + tracker.onValidatorAdded(ip.NodeID) + tracker.manuallyTracked.Add(ip.NodeID) + return tracker + }(), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.initialState.ManuallyTrack(test.nodeID) + requireEqual(t, test.expectedState, test.initialState) + }) + } +} + +func TestIPTracker_AddIP(t *testing.T) { + newerIP := newerTestIP(ip) + tests := []struct { + name string + initialState *ipTracker + ip *ips.ClaimedIPPort + expectedUpdated bool + expectedState *ipTracker + }{ + { + name: "non-validator", + initialState: newTestIPTracker(t), + ip: ip, + expectedUpdated: false, + expectedState: newTestIPTracker(t), + }, + { + name: "first known IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + return tracker + }(), + ip: ip, + expectedUpdated: true, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.mostRecentValidatorIPs[ip.NodeID] = ip + tracker.bloomAdditions[ip.NodeID] = 1 + return tracker + }(), + }, + { + name: "older IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(newerIP.NodeID) + require.True(t, tracker.AddIP(newerIP)) + return tracker + }(), + ip: ip, + expectedUpdated: false, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(newerIP.NodeID) + require.True(t, tracker.AddIP(newerIP)) + return tracker + }(), + }, + { + name: "same IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + return tracker + }(), + ip: ip, + expectedUpdated: false, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + return tracker + }(), + }, + { + name: "disconnected newer IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + return tracker + }(), + ip: newerIP, + expectedUpdated: true, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + tracker.mostRecentValidatorIPs[newerIP.NodeID] = newerIP + tracker.bloomAdditions[newerIP.NodeID] = 2 + return tracker + }(), + }, + { + name: "connected newer IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + return tracker + }(), + ip: newerIP, + expectedUpdated: true, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + tracker.mostRecentValidatorIPs[newerIP.NodeID] = newerIP + tracker.bloomAdditions[newerIP.NodeID] = 2 + delete(tracker.gossipableIndicies, newerIP.NodeID) + tracker.gossipableIPs = tracker.gossipableIPs[:0] + return tracker + }(), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + updated := test.initialState.AddIP(test.ip) + require.Equal(t, test.expectedUpdated, updated) + requireEqual(t, test.expectedState, test.initialState) + }) + } +} + +func TestIPTracker_Connected(t *testing.T) { + newerIP := newerTestIP(ip) + tests := []struct { + name string + initialState *ipTracker + ip *ips.ClaimedIPPort + expectedState *ipTracker + }{ + { + name: "non-validator", + initialState: newTestIPTracker(t), + ip: ip, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.connected[ip.NodeID] = ip + return tracker + }(), + }, + { + name: "first known IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + return tracker + }(), + ip: ip, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.connected[ip.NodeID] = ip + tracker.mostRecentValidatorIPs[ip.NodeID] = ip + tracker.bloomAdditions[ip.NodeID] = 1 + tracker.gossipableIndicies[ip.NodeID] = 0 + tracker.gossipableIPs = []*ips.ClaimedIPPort{ + ip, + } + return tracker + }(), + }, + { + name: "connected with older IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(newerIP.NodeID) + require.True(t, tracker.AddIP(newerIP)) + return tracker + }(), + ip: ip, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(newerIP.NodeID) + require.True(t, tracker.AddIP(newerIP)) + tracker.connected[ip.NodeID] = ip + return tracker + }(), + }, + { + name: "connected with newer IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + return tracker + }(), + ip: newerIP, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + tracker.connected[newerIP.NodeID] = newerIP + tracker.mostRecentValidatorIPs[newerIP.NodeID] = newerIP + tracker.bloomAdditions[newerIP.NodeID] = 2 + tracker.gossipableIndicies[newerIP.NodeID] = 0 + tracker.gossipableIPs = []*ips.ClaimedIPPort{ + newerIP, + } + return tracker + }(), + }, + { + name: "connected with same IP", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + return tracker + }(), + ip: ip, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + tracker.connected[ip.NodeID] = ip + tracker.gossipableIndicies[ip.NodeID] = 0 + tracker.gossipableIPs = []*ips.ClaimedIPPort{ + ip, + } + return tracker + }(), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.initialState.Connected(test.ip) + requireEqual(t, test.expectedState, test.initialState) + }) + } +} + +func TestIPTracker_Disconnected(t *testing.T) { + tests := []struct { + name string + initialState *ipTracker + nodeID ids.NodeID + expectedState *ipTracker + }{ + { + name: "not gossipable", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.Connected(ip) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: newTestIPTracker(t), + }, + { + name: "latest gossipable", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + delete(tracker.connected, ip.NodeID) + delete(tracker.gossipableIndicies, ip.NodeID) + tracker.gossipableIPs = tracker.gossipableIPs[:0] + return tracker + }(), + }, + { + name: "non-latest gossipable", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + tracker.onValidatorAdded(otherIP.NodeID) + tracker.Connected(otherIP) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + tracker.onValidatorAdded(otherIP.NodeID) + tracker.Connected(otherIP) + delete(tracker.connected, ip.NodeID) + tracker.gossipableIndicies = map[ids.NodeID]int{ + otherIP.NodeID: 0, + } + tracker.gossipableIPs = []*ips.ClaimedIPPort{ + otherIP, + } + return tracker + }(), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.initialState.Disconnected(test.nodeID) + requireEqual(t, test.expectedState, test.initialState) + }) + } +} + +func TestIPTracker_OnValidatorAdded(t *testing.T) { + tests := []struct { + name string + initialState *ipTracker + nodeID ids.NodeID + expectedState *ipTracker + }{ + { + name: "manually tracked", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.ManuallyTrack(ip.NodeID) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.ManuallyTrack(ip.NodeID) + return tracker + }(), + }, + { + name: "disconnected", + initialState: newTestIPTracker(t), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.validators.Add(ip.NodeID) + return tracker + }(), + }, + { + name: "connected", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.Connected(ip) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.Connected(ip) + tracker.validators.Add(ip.NodeID) + tracker.mostRecentValidatorIPs[ip.NodeID] = ip + tracker.bloomAdditions[ip.NodeID] = 1 + tracker.gossipableIndicies[ip.NodeID] = 0 + tracker.gossipableIPs = []*ips.ClaimedIPPort{ + ip, + } + return tracker + }(), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.initialState.OnValidatorAdded(test.nodeID, nil, ids.Empty, 0) + requireEqual(t, test.expectedState, test.initialState) + }) + } +} + +func TestIPTracker_OnValidatorRemoved(t *testing.T) { + tests := []struct { + name string + initialState *ipTracker + nodeID ids.NodeID + expectedState *ipTracker + }{ + { + name: "manually tracked", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.ManuallyTrack(ip.NodeID) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.ManuallyTrack(ip.NodeID) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + return tracker + }(), + }, + { + name: "not gossipable", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(t, tracker.AddIP(ip)) + delete(tracker.mostRecentValidatorIPs, ip.NodeID) + tracker.validators.Remove(ip.NodeID) + return tracker + }(), + }, + { + name: "latest gossipable", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + delete(tracker.mostRecentValidatorIPs, ip.NodeID) + tracker.validators.Remove(ip.NodeID) + delete(tracker.gossipableIndicies, ip.NodeID) + tracker.gossipableIPs = tracker.gossipableIPs[:0] + return tracker + }(), + }, + { + name: "non-latest gossipable", + initialState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + tracker.onValidatorAdded(otherIP.NodeID) + tracker.Connected(otherIP) + return tracker + }(), + nodeID: ip.NodeID, + expectedState: func() *ipTracker { + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + tracker.Connected(ip) + tracker.onValidatorAdded(otherIP.NodeID) + tracker.Connected(otherIP) + delete(tracker.mostRecentValidatorIPs, ip.NodeID) + tracker.validators.Remove(ip.NodeID) + tracker.gossipableIndicies = map[ids.NodeID]int{ + otherIP.NodeID: 0, + } + tracker.gossipableIPs = []*ips.ClaimedIPPort{ + otherIP, + } + return tracker + }(), + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.initialState.OnValidatorRemoved(test.nodeID, 0) + requireEqual(t, test.expectedState, test.initialState) + }) + } +} + +func TestIPTracker_GetGossipableIPs(t *testing.T) { + require := require.New(t) + + tracker := newTestIPTracker(t) + tracker.Connected(ip) + tracker.Connected(otherIP) + tracker.onValidatorAdded(ip.NodeID) + tracker.onValidatorAdded(otherIP.NodeID) + + gossipableIPs := tracker.GetGossipableIPs(ids.EmptyNodeID, bloom.EmptyFilter, nil, 2) + require.ElementsMatch([]*ips.ClaimedIPPort{ip, otherIP}, gossipableIPs) + + gossipableIPs = tracker.GetGossipableIPs(ip.NodeID, bloom.EmptyFilter, nil, 2) + require.Equal([]*ips.ClaimedIPPort{otherIP}, gossipableIPs) + + gossipableIPs = tracker.GetGossipableIPs(ids.EmptyNodeID, bloom.FullFilter, nil, 2) + require.Empty(gossipableIPs) + + filter, err := bloom.New(8, 1024) + require.NoError(err) + bloom.Add(filter, ip.GossipID[:], nil) + + readFilter, err := bloom.Parse(filter.Marshal()) + require.NoError(err) + + gossipableIPs = tracker.GetGossipableIPs(ip.NodeID, readFilter, nil, 2) + require.Equal([]*ips.ClaimedIPPort{otherIP}, gossipableIPs) +} + +func TestIPTracker_BloomFiltersEverything(t *testing.T) { + require := require.New(t) + + tracker := newTestIPTracker(t) + tracker.Connected(ip) + tracker.Connected(otherIP) + tracker.onValidatorAdded(ip.NodeID) + tracker.onValidatorAdded(otherIP.NodeID) + + bloomBytes, salt := tracker.Bloom() + readFilter, err := bloom.Parse(bloomBytes) + require.NoError(err) + + gossipableIPs := tracker.GetGossipableIPs(ids.EmptyNodeID, readFilter, salt, 2) + require.Empty(gossipableIPs) + + require.NoError(tracker.ResetBloom()) +} + +func TestIPTracker_BloomGrowsWithValidatorSet(t *testing.T) { + require := require.New(t) + + tracker := newTestIPTracker(t) + initialMaxBloomCount := tracker.maxBloomCount + for i := 0; i < 2048; i++ { + tracker.onValidatorAdded(ids.GenerateTestNodeID()) + } + + require.NoError(tracker.ResetBloom()) + require.Greater(tracker.maxBloomCount, initialMaxBloomCount) +} + +func TestIPTracker_BloomResetsDynamically(t *testing.T) { + require := require.New(t) + + tracker := newTestIPTracker(t) + tracker.Connected(ip) + tracker.onValidatorAdded(ip.NodeID) + tracker.OnValidatorRemoved(ip.NodeID, 0) + tracker.maxBloomCount = 1 + tracker.Connected(otherIP) + tracker.onValidatorAdded(otherIP.NodeID) + + bloomBytes, salt := tracker.Bloom() + readFilter, err := bloom.Parse(bloomBytes) + require.NoError(err) + + require.False(bloom.Contains(readFilter, ip.GossipID[:], salt)) + require.True(bloom.Contains(readFilter, otherIP.GossipID[:], salt)) +} + +func TestIPTracker_PreventBloomFilterAddition(t *testing.T) { + require := require.New(t) + + newerIP := newerTestIP(ip) + newestIP := newerTestIP(newerIP) + + tracker := newTestIPTracker(t) + tracker.onValidatorAdded(ip.NodeID) + require.True(tracker.AddIP(ip)) + require.True(tracker.AddIP(newerIP)) + require.True(tracker.AddIP(newestIP)) + require.Equal(maxIPEntriesPerValidator, tracker.bloomAdditions[ip.NodeID]) +} + +func TestIPTracker_ShouldVerifyIP(t *testing.T) { + require := require.New(t) + + newerIP := newerTestIP(ip) + + tracker := newTestIPTracker(t) + require.False(tracker.ShouldVerifyIP(ip)) + tracker.onValidatorAdded(ip.NodeID) + require.True(tracker.ShouldVerifyIP(ip)) + require.True(tracker.AddIP(ip)) + require.False(tracker.ShouldVerifyIP(ip)) + require.True(tracker.ShouldVerifyIP(newerIP)) +} diff --git a/network/network.go b/network/network.go index 2d178cb93488..374038883ba7 100644 --- a/network/network.go +++ b/network/network.go @@ -20,22 +20,20 @@ import ( "go.uber.org/zap" - "golang.org/x/exp/maps" - "github.com/ava-labs/avalanchego/api/health" + "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/message" "github.com/ava-labs/avalanchego/network/dialer" "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/network/throttling" - "github.com/ava-labs/avalanchego/proto/pb/p2p" "github.com/ava-labs/avalanchego/snow/networking/router" "github.com/ava-labs/avalanchego/snow/networking/sender" "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/utils/bloom" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/utils/sampler" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/avalanchego/version" @@ -79,12 +77,6 @@ type Network interface { // or the network is closed. Dispatch() error - // WantsConnection returns true if this node is willing to attempt to - // connect to the provided nodeID. If the node is attempting to connect to - // the minimum number of peers, then it should only connect if the peer is a - // validator or beacon. - WantsConnection(ids.NodeID) bool - // Attempt to connect to this IP. The network will never stop attempting to // connect to this ID. ManuallyTrack(nodeID ids.NodeID, ip ips.IPPort) @@ -151,13 +143,8 @@ type network struct { sendFailRateCalculator safemath.Averager // Tracks which peers know about which peers - gossipTracker peer.GossipTracker - peersLock sync.RWMutex - // peerIPs contains the most up to date set of signed IPs for nodes we are - // currently connected or attempting to connect to. - // Note: The txID provided inside of a claimed IP is not verified and should - // not be accessed from this map. - peerIPs map[ids.NodeID]*ips.ClaimedIPPort + ipTracker *ipTracker + peersLock sync.RWMutex // trackedIPs contains the set of IPs that we are currently attempting to // connect to. An entry is added to this set when we first start attempting // to connect to the peer. An entry is deleted from this set once we have @@ -167,10 +154,6 @@ type network struct { connectedPeers peer.Set closing bool - // Tracks special peers that the network should always track - manuallyTrackedIDsLock sync.RWMutex - manuallyTrackedIDs set.Set[ids.NodeID] - // router is notified about all peer [Connected] and [Disconnected] events // as well as all non-handshake peer messages. // @@ -254,6 +237,18 @@ func NewNetwork( return nil, fmt.Errorf("initializing network metrics failed with: %w", err) } + ipTracker, err := newIPTracker(log) + if err != nil { + return nil, fmt.Errorf("initializing ip tracker failed with: %w", err) + } + config.Validators.RegisterCallbackListener(constants.PrimaryNetworkID, ipTracker) + + // Track all default bootstrappers to ensure their current IPs are gossiped + // like validator IPs. + for _, bootstrapper := range genesis.GetBootstrappers(config.NetworkID) { + ipTracker.ManuallyTrack(bootstrapper.ID) + } + peerConfig := &peer.Config{ ReadBufferSize: config.PeerReadBufferSize, WriteBufferSize: config.PeerWriteBufferSize, @@ -300,9 +295,8 @@ func NewNetwork( time.Now(), )), - peerIPs: make(map[ids.NodeID]*ips.ClaimedIPPort), trackedIPs: make(map[ids.NodeID]*trackedIP), - gossipTracker: config.GossipTracker, + ipTracker: ipTracker, connectingPeers: peer.NewSet(), connectedPeers: peer.NewSet(), router: router, @@ -424,32 +418,6 @@ func (n *network) Connected(nodeID ids.NodeID) { return } - peerIP := peer.IP() - newIP := &ips.ClaimedIPPort{ - Cert: peer.Cert(), - IPPort: peerIP.IPPort, - Timestamp: peerIP.Timestamp, - Signature: peerIP.Signature, - } - prevIP, ok := n.peerIPs[nodeID] - if !ok { - // If the IP wasn't previously tracked, then we never could have - // gossiped it. This means we don't need to reset the validator's - // tracked set. - n.peerIPs[nodeID] = newIP - } else if prevIP.Timestamp < newIP.Timestamp { - // The previous IP was stale, so we should gossip the newer IP. - n.peerIPs[nodeID] = newIP - - if !prevIP.IPPort.Equal(newIP.IPPort) { - // This IP is actually different, so we should gossip it. - n.peerConfig.Log.Debug("resetting gossip due to ip change", - zap.Stringer("nodeID", nodeID), - ) - _ = n.gossipTracker.ResetValidator(nodeID) - } - } - if tracked, ok := n.trackedIPs[nodeID]; ok { tracked.stopTracking() delete(n.trackedIPs, nodeID) @@ -458,6 +426,15 @@ func (n *network) Connected(nodeID ids.NodeID) { n.connectedPeers.Add(peer) n.peersLock.Unlock() + peerIP := peer.IP() + newIP := ips.NewClaimedIPPort( + peer.Cert(), + peerIP.IPPort, + peerIP.Timestamp, + peerIP.Signature, + ) + n.ipTracker.Connected(newIP) + n.metrics.markConnected(peer) peerVersion := peer.Version() @@ -475,177 +452,15 @@ func (n *network) AllowConnection(nodeID ids.NodeID) bool { if !n.config.RequireValidatorToConnect { return true } - _, isValidator := n.config.Validators.GetValidator(constants.PrimaryNetworkID, n.config.MyNodeID) - return isValidator || n.WantsConnection(nodeID) -} - -func (n *network) Track(peerID ids.NodeID, claimedIPPorts []*ips.ClaimedIPPort) ([]*p2p.PeerAck, error) { - // Perform all signature verification and hashing before grabbing the peer - // lock. - // Note: Avoiding signature verification when the IP isn't needed is a - // **significant** performance optimization. - // Note: To avoid signature verification when the IP isn't needed, we - // optimistically filter out IPs. This can result in us not tracking an IP - // that we otherwise would have. This case can only happen if the node - // became a validator between the time we verified the signature and when we - // processed the IP; which should be very rare. - ipAuths, err := n.authenticateIPs(claimedIPPorts) - if err != nil { - n.peerConfig.Log.Debug("authenticating claimed IPs failed", - zap.Stringer("nodeID", peerID), - zap.Error(err), - ) - return nil, err - } - - // Information for them to update about us - ipLen := len(claimedIPPorts) - newestTimestamp := make(map[ids.ID]uint64, ipLen) - // Information for us to update about them - txIDsWithUpToDateIP := make([]ids.ID, 0, ipLen) - - // Atomically modify peer data - n.peersLock.Lock() - defer n.peersLock.Unlock() - for i, ip := range claimedIPPorts { - ipAuth := ipAuths[i] - nodeID := ipAuth.nodeID - // Invariant: [ip] is only used to modify local node state if - // [verifiedIP] is true. - // Note: modifying peer-level state is allowed regardless of - // [verifiedIP]. - verifiedIP := ipAuth.verified - - // Re-fetch latest info for a [nodeID] in case it changed since we last - // held [peersLock]. - prevIP, previouslyTracked, shouldUpdateOurIP, shouldDial := n.peerIPStatus(nodeID, ip) - tracked, isTracked := n.trackedIPs[nodeID] - - // Evaluate if the gossiped IP is useful to us or to the peer that - // shared it with us. - switch { - case previouslyTracked && prevIP.Timestamp > ip.Timestamp: - // Our previous IP was more up to date. We should tell the peer - // not to gossip their IP to us. We should still gossip our IP to - // them. - newestTimestamp[ip.TxID] = prevIP.Timestamp - - n.metrics.numUselessPeerListBytes.Add(float64(ip.BytesLen())) - case previouslyTracked && prevIP.Timestamp == ip.Timestamp: - // Our previous IP was equally fresh. We should tell the peer - // not to gossip this IP to us. We should not gossip our IP to them. - newestTimestamp[ip.TxID] = prevIP.Timestamp - txIDsWithUpToDateIP = append(txIDsWithUpToDateIP, ip.TxID) - - n.metrics.numUselessPeerListBytes.Add(float64(ip.BytesLen())) - case verifiedIP && shouldUpdateOurIP: - // This IP is more up to date. We should tell the peer not to gossip - // this IP to us. We should not gossip our IP to them. - newestTimestamp[ip.TxID] = ip.Timestamp - txIDsWithUpToDateIP = append(txIDsWithUpToDateIP, ip.TxID) - - // In the future, we should gossip this IP rather than the old IP. - n.peerIPs[nodeID] = ip - - // If the new IP is equal to the old IP, there is no reason to - // refresh the references to it. This can happen when a node - // restarts but does not change their IP. - if prevIP.IPPort.Equal(ip.IPPort) { - continue - } - - // We should gossip this new IP to all our peers. - n.peerConfig.Log.Debug("resetting gossip due to ip change", - zap.Stringer("nodeID", nodeID), - ) - _ = n.gossipTracker.ResetValidator(nodeID) - - // We should update any existing outbound connection attempts. - if isTracked { - // Stop tracking the old IP and start tracking the new one. - tracked := tracked.trackNewIP(ip.IPPort) - n.trackedIPs[nodeID] = tracked - n.dial(nodeID, tracked) - } - case verifiedIP && shouldDial: - // Invariant: [isTracked] is false here. - - // This is the first we've heard of this IP and we want to connect - // to it. We should tell the peer not to gossip this IP to us again. - newestTimestamp[ip.TxID] = ip.Timestamp - // We should not gossip this IP back to them. - txIDsWithUpToDateIP = append(txIDsWithUpToDateIP, ip.TxID) - - // We don't need to reset gossip about this validator because - // we've never gossiped it before. - n.peerIPs[nodeID] = ip - - tracked := newTrackedIP(ip.IPPort) - n.trackedIPs[nodeID] = tracked - n.dial(nodeID, tracked) - default: - // This IP isn't desired - n.metrics.numUselessPeerListBytes.Add(float64(ip.BytesLen())) - } - } - - txIDsToAck := maps.Keys(newestTimestamp) - txIDsToAck, ok := n.gossipTracker.AddKnown(peerID, txIDsWithUpToDateIP, txIDsToAck) - if !ok { - n.peerConfig.Log.Error("failed to update known peers", - zap.Stringer("nodeID", peerID), - ) - return nil, nil - } - - peerAcks := make([]*p2p.PeerAck, len(txIDsToAck)) - for i, txID := range txIDsToAck { - txID := txID - peerAcks[i] = &p2p.PeerAck{ - TxId: txID[:], - // By responding with the highest timestamp, not just the timestamp - // the peer provided us, we may be able to avoid some unnecessary - // gossip in the case that the peer is about to update this - // validator's IP. - Timestamp: newestTimestamp[txID], - } - } - return peerAcks, nil + _, iAmAValidator := n.config.Validators.GetValidator(constants.PrimaryNetworkID, n.config.MyNodeID) + return iAmAValidator || n.ipTracker.WantsConnection(nodeID) } -func (n *network) MarkTracked(peerID ids.NodeID, ips []*p2p.PeerAck) error { - txIDs := make([]ids.ID, 0, len(ips)) - - n.peersLock.RLock() - defer n.peersLock.RUnlock() - - for _, ip := range ips { - txID, err := ids.ToID(ip.TxId) - if err != nil { +func (n *network) Track(claimedIPPorts []*ips.ClaimedIPPort) error { + for _, ip := range claimedIPPorts { + if err := n.track(ip); err != nil { return err } - - // If [txID]'s corresponding nodeID isn't known, then they must no - // longer be a validator. Therefore we wouldn't gossip their IP anyways. - nodeID, ok := n.gossipTracker.GetNodeID(txID) - if !ok { - continue - } - - // If the peer returns a lower timestamp than I currently have, then I - // have updated the IP since I sent the PeerList message this is in - // response to. That means that I should re-gossip this node's IP to the - // peer. - myIP, previouslyTracked := n.peerIPs[nodeID] - if previouslyTracked && myIP.Timestamp <= ip.Timestamp { - txIDs = append(txIDs, txID) - } - } - - if _, ok := n.gossipTracker.AddKnown(peerID, txIDs, nil); !ok { - n.peerConfig.Log.Error("failed to update known peers", - zap.Stringer("nodeID", peerID), - ) } return nil } @@ -656,13 +471,6 @@ func (n *network) MarkTracked(peerID ids.NodeID, ips []*p2p.PeerAck) error { // call. Note that this is from the perspective of a single peer object, because // a peer with the same ID can reconnect to this network instance. func (n *network) Disconnected(nodeID ids.NodeID) { - if !n.gossipTracker.StopTrackingPeer(nodeID) { - n.peerConfig.Log.Error( - "stopped non-existent peer tracker", - zap.Stringer("nodeID", nodeID), - ) - } - n.peersLock.RLock() _, connecting := n.connectingPeers.GetByID(nodeID) peer, connected := n.connectedPeers.GetByID(nodeID) @@ -676,57 +484,17 @@ func (n *network) Disconnected(nodeID ids.NodeID) { } } -func (n *network) Peers(peerID ids.NodeID) ([]ips.ClaimedIPPort, error) { - // Only select validators that we haven't already sent to this peer - unknownValidators, ok := n.gossipTracker.GetUnknown(peerID) - if !ok { - n.peerConfig.Log.Debug( - "unable to find peer to gossip to", - zap.Stringer("nodeID", peerID), - ) - return nil, nil - } - - // We select a random sample of validators to gossip to avoid starving out a - // validator from being gossiped for an extended period of time. - s := sampler.NewUniform() - s.Initialize(uint64(len(unknownValidators))) - - // Calculate the unknown information we need to send to this peer. - validatorIPs := make([]ips.ClaimedIPPort, 0, int(n.config.PeerListNumValidatorIPs)) - for i := 0; i < len(unknownValidators) && len(validatorIPs) < int(n.config.PeerListNumValidatorIPs); i++ { - drawn, err := s.Next() - if err != nil { - return nil, err - } - - validator := unknownValidators[drawn] - n.peersLock.RLock() - _, isConnected := n.connectedPeers.GetByID(validator.NodeID) - peerIP := n.peerIPs[validator.NodeID] - n.peersLock.RUnlock() - if !isConnected { - n.peerConfig.Log.Verbo( - "unable to find validator in connected peers", - zap.Stringer("nodeID", validator.NodeID), - ) - continue - } - - // Note: peerIP isn't used directly here because the TxID may be - // incorrect. - validatorIPs = append(validatorIPs, - ips.ClaimedIPPort{ - Cert: peerIP.Cert, - IPPort: peerIP.IPPort, - Timestamp: peerIP.Timestamp, - Signature: peerIP.Signature, - TxID: validator.TxID, - }, - ) - } +func (n *network) KnownPeers() ([]byte, []byte) { + return n.ipTracker.Bloom() +} - return validatorIPs, nil +func (n *network) Peers(except ids.NodeID, knownPeers *bloom.ReadFilter, salt []byte) []*ips.ClaimedIPPort { + return n.ipTracker.GetGossipableIPs( + except, + knownPeers, + salt, + int(n.config.PeerListNumValidatorIPs), + ) } // Dispatch starts accepting connections from other nodes attempting to connect @@ -806,21 +574,8 @@ func (n *network) Dispatch() error { return errs.Err } -func (n *network) WantsConnection(nodeID ids.NodeID) bool { - if _, ok := n.config.Validators.GetValidator(constants.PrimaryNetworkID, nodeID); ok { - return true - } - - n.manuallyTrackedIDsLock.RLock() - defer n.manuallyTrackedIDsLock.RUnlock() - - return n.manuallyTrackedIDs.Contains(nodeID) -} - func (n *network) ManuallyTrack(nodeID ids.NodeID, ip ips.IPPort) { - n.manuallyTrackedIDsLock.Lock() - n.manuallyTrackedIDs.Add(nodeID) - n.manuallyTrackedIDsLock.Unlock() + n.ipTracker.ManuallyTrack(nodeID) n.peersLock.Lock() defer n.peersLock.Unlock() @@ -841,6 +596,58 @@ func (n *network) ManuallyTrack(nodeID ids.NodeID, ip ips.IPPort) { } } +func (n *network) track(ip *ips.ClaimedIPPort) error { + // To avoid signature verification when the IP isn't needed, we + // optimistically filter out IPs. This can result in us not tracking an IP + // that we otherwise would have. This case can only happen if the node + // became a validator between the time we verified the signature and when we + // processed the IP; which should be very rare. + // + // Note: Avoiding signature verification when the IP isn't needed is a + // **significant** performance optimization. + if !n.ipTracker.ShouldVerifyIP(ip) { + n.metrics.numUselessPeerListBytes.Add(float64(ip.Size())) + return nil + } + + // Perform all signature verification and hashing before grabbing the peer + // lock. + signedIP := peer.SignedIP{ + UnsignedIP: peer.UnsignedIP{ + IPPort: ip.IPPort, + Timestamp: ip.Timestamp, + }, + Signature: ip.Signature, + } + if err := signedIP.Verify(ip.Cert); err != nil { + return err + } + + n.peersLock.Lock() + defer n.peersLock.Unlock() + + if !n.ipTracker.AddIP(ip) { + return nil + } + + if _, connected := n.connectedPeers.GetByID(ip.NodeID); connected { + // If I'm currently connected to [nodeID] then I'll attempt to dial them + // when we disconnect. + return nil + } + + tracked, isTracked := n.trackedIPs[ip.NodeID] + if isTracked { + // Stop tracking the old IP and start tracking the new one. + tracked = tracked.trackNewIP(ip.IPPort) + } else { + tracked = newTrackedIP(ip.IPPort) + } + n.trackedIPs[ip.NodeID] = tracked + n.dial(ip.NodeID, tracked) + return nil +} + // getPeers returns a slice of connected peers from a set of [nodeIDs]. // // - [nodeIDs] the IDs of the peers that should be returned if they are @@ -965,13 +772,12 @@ func (n *network) disconnectedFromConnecting(nodeID ids.NodeID) { // The peer that is disconnecting from us didn't finish the handshake tracked, ok := n.trackedIPs[nodeID] if ok { - if n.WantsConnection(nodeID) { + if n.ipTracker.WantsConnection(nodeID) { tracked := tracked.trackNewIP(tracked.ip) n.trackedIPs[nodeID] = tracked n.dial(nodeID, tracked) } else { tracked.stopTracking() - delete(n.peerIPs, nodeID) delete(n.trackedIPs, nodeID) } } @@ -980,6 +786,7 @@ func (n *network) disconnectedFromConnecting(nodeID ids.NodeID) { } func (n *network) disconnectedFromConnected(peer peer.Peer, nodeID ids.NodeID) { + n.ipTracker.Disconnected(nodeID) n.router.Disconnected(nodeID) n.peersLock.Lock() @@ -988,66 +795,15 @@ func (n *network) disconnectedFromConnected(peer peer.Peer, nodeID ids.NodeID) { n.connectedPeers.Remove(nodeID) // The peer that is disconnecting from us finished the handshake - if n.WantsConnection(nodeID) { - prevIP := n.peerIPs[nodeID] - tracked := newTrackedIP(prevIP.IPPort) + if ip, wantsConnection := n.ipTracker.GetIP(nodeID); wantsConnection { + tracked := newTrackedIP(ip.IPPort) n.trackedIPs[nodeID] = tracked n.dial(nodeID, tracked) - } else { - delete(n.peerIPs, nodeID) } n.metrics.markDisconnected(peer) } -// ipAuth is a helper struct used to convey information about an -// [*ips.ClaimedIPPort]. -type ipAuth struct { - nodeID ids.NodeID - verified bool -} - -func (n *network) authenticateIPs(ips []*ips.ClaimedIPPort) ([]*ipAuth, error) { - ipAuths := make([]*ipAuth, len(ips)) - for i, ip := range ips { - nodeID := ids.NodeIDFromCert(ip.Cert) - n.peersLock.RLock() - _, _, shouldUpdateOurIP, shouldDial := n.peerIPStatus(nodeID, ip) - n.peersLock.RUnlock() - if !shouldUpdateOurIP && !shouldDial { - ipAuths[i] = &ipAuth{ - nodeID: nodeID, - } - continue - } - - // Verify signature if needed - signedIP := peer.SignedIP{ - UnsignedIP: peer.UnsignedIP{ - IPPort: ip.IPPort, - Timestamp: ip.Timestamp, - }, - Signature: ip.Signature, - } - if err := signedIP.Verify(ip.Cert); err != nil { - return nil, err - } - ipAuths[i] = &ipAuth{ - nodeID: nodeID, - verified: true, - } - } - return ipAuths, nil -} - -// peerIPStatus assumes the caller holds [peersLock] -func (n *network) peerIPStatus(nodeID ids.NodeID, ip *ips.ClaimedIPPort) (*ips.ClaimedIPPort, bool, bool, bool) { - prevIP, previouslyTracked := n.peerIPs[nodeID] - shouldUpdateOurIP := previouslyTracked && prevIP.Timestamp < ip.Timestamp - shouldDial := !previouslyTracked && n.WantsConnection(nodeID) - return prevIP, previouslyTracked, shouldUpdateOurIP, shouldDial -} - // dial will spin up a new goroutine and attempt to establish a connection with // [nodeID] at [ip]. // @@ -1094,13 +850,12 @@ func (n *network) dial(nodeID ids.NodeID, ip *trackedIP) { // trackedIPs and this goroutine. This prevents a memory leak when // the tracked nodeID leaves the validator set and is never able to // be connected to. - if !n.WantsConnection(nodeID) { + if !n.ipTracker.WantsConnection(nodeID) { // Typically [n.trackedIPs[nodeID]] will already equal [ip], but // the reference to [ip] is refreshed to avoid any potential // race conditions before removing the entry. if ip, exists := n.trackedIPs[nodeID]; exists { ip.stopTracking() - delete(n.peerIPs, nodeID) delete(n.trackedIPs, nodeID) } n.peersLock.Unlock() @@ -1277,13 +1032,6 @@ func (n *network) upgrade(conn net.Conn, upgrader peer.Upgrader) error { zap.Stringer("nodeID", nodeID), ) - if !n.gossipTracker.StartTrackingPeer(nodeID) { - n.peerConfig.Log.Error( - "started duplicate peer tracker", - zap.Stringer("nodeID", nodeID), - ) - } - // peer.Start requires there is only ever one peer instance running with the // same [peerConfig.InboundMsgThrottler]. This is guaranteed by the above // de-duplications for [connectingPeers] and [connectedPeers]. @@ -1332,7 +1080,6 @@ func (n *network) StartClose() { for nodeID, tracked := range n.trackedIPs { tracked.stopTracking() - delete(n.peerIPs, nodeID) delete(n.trackedIPs, nodeID) } @@ -1404,10 +1151,13 @@ func (n *network) NodeUptime(subnetID ids.ID) (UptimeResult, error) { } func (n *network) runTimers() { - gossipPeerlists := time.NewTicker(n.config.PeerListGossipFreq) + pushGossipPeerlists := time.NewTicker(n.config.PeerListGossipFreq) + pullGossipPeerlists := time.NewTicker(n.config.PeerListPullGossipFreq) + resetPeerListBloom := time.NewTicker(n.config.PeerListBloomResetFreq) updateUptimes := time.NewTicker(n.config.UptimeMetricFreq) defer func() { - gossipPeerlists.Stop() + pushGossipPeerlists.Stop() + resetPeerListBloom.Stop() updateUptimes.Stop() }() @@ -1415,8 +1165,18 @@ func (n *network) runTimers() { select { case <-n.onCloseCtx.Done(): return - case <-gossipPeerlists.C: - n.gossipPeerLists() + case <-pushGossipPeerlists.C: + n.pushGossipPeerLists() + case <-pullGossipPeerlists.C: + n.pullGossipPeerLists() + case <-resetPeerListBloom.C: + if err := n.ipTracker.ResetBloom(); err != nil { + n.peerConfig.Log.Error("failed to reset ip tracker bloom filter", + zap.Error(err), + ) + } else { + n.peerConfig.Log.Debug("reset ip tracker bloom filter") + } case <-updateUptimes.C: primaryUptime, err := n.NodeUptime(constants.PrimaryNetworkID) if err != nil { @@ -1443,8 +1203,8 @@ func (n *network) runTimers() { } } -// gossipPeerLists gossips validators to peers in the network -func (n *network) gossipPeerLists() { +// pushGossipPeerLists gossips validators to peers in the network +func (n *network) pushGossipPeerLists() { peers := n.samplePeers( constants.PrimaryNetworkID, int(n.config.PeerListValidatorGossipSize), @@ -1458,6 +1218,21 @@ func (n *network) gossipPeerLists() { } } +// pullGossipPeerLists requests validators from peers in the network +func (n *network) pullGossipPeerLists() { + peers := n.samplePeers( + constants.PrimaryNetworkID, + 1, // numValidatorsToSample + 0, // numNonValidatorsToSample + 0, // numPeersToSample + subnets.NoOpAllower, + ) + + for _, p := range peers { + p.StartSendGetPeerList() + } +} + func (n *network) getLastReceived() (time.Time, bool) { lastReceived := atomic.LoadInt64(&n.peerConfig.LastReceived) if lastReceived == 0 { diff --git a/network/network_test.go b/network/network_test.go index 916b527da82b..90c063a99bb7 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -54,6 +54,8 @@ var ( PeerListNonValidatorGossipSize: 100, PeerListPeersGossipSize: 100, PeerListGossipFreq: time.Second, + PeerListPullGossipFreq: time.Second, + PeerListBloomResetFreq: constants.DefaultNetworkPeerListBloomResetFreq, } defaultTimeoutConfig = TimeoutConfig{ PingPongTimeout: 30 * time.Second, @@ -215,27 +217,16 @@ func newFullyConnectedTestNetwork(t *testing.T, handlers []router.InboundHandler msgCreator := newMessageCreator(t) registry := prometheus.NewRegistry() - g, err := peer.NewGossipTracker(registry, "foobar") - require.NoError(err) - - log := logging.NoLog{} - gossipTrackerCallback := peer.GossipTrackerCallback{ - Log: log, - GossipTracker: g, - } - beacons := validators.NewManager() require.NoError(beacons.AddStaker(constants.PrimaryNetworkID, nodeIDs[0], nil, ids.GenerateTestID(), 1)) vdrs := validators.NewManager() - vdrs.RegisterCallbackListener(constants.PrimaryNetworkID, &gossipTrackerCallback) for _, nodeID := range nodeIDs { require.NoError(vdrs.AddStaker(constants.PrimaryNetworkID, nodeID, nil, ids.GenerateTestID(), 1)) } config := config - config.GossipTracker = g config.Beacons = beacons config.Validators = vdrs @@ -244,7 +235,7 @@ func newFullyConnectedTestNetwork(t *testing.T, handlers []router.InboundHandler config, msgCreator, registry, - log, + logging.NoLog{}, listeners[i], dialer, &testHandler{ @@ -405,15 +396,17 @@ func TestTrackVerifiesSignatures(t *testing.T) { nodeID, tlsCert, _ := getTLS(t, 1) require.NoError(network.config.Validators.AddStaker(constants.PrimaryNetworkID, nodeID, nil, ids.Empty, 1)) - _, err := network.Track(ids.EmptyNodeID, []*ips.ClaimedIPPort{{ - Cert: staking.CertificateFromX509(tlsCert.Leaf), - IPPort: ips.IPPort{ - IP: net.IPv4(123, 132, 123, 123), - Port: 10000, - }, - Timestamp: 1000, - Signature: nil, - }}) + err := network.Track([]*ips.ClaimedIPPort{ + ips.NewClaimedIPPort( + staking.CertificateFromX509(tlsCert.Leaf), + ips.IPPort{ + IP: net.IPv4(123, 132, 123, 123), + Port: 10000, + }, + 1000, // timestamp + nil, // signature + ), + }) // The signature is wrong so this peer tracking info isn't useful. require.ErrorIs(err, rsa.ErrVerification) @@ -437,27 +430,16 @@ func TestTrackDoesNotDialPrivateIPs(t *testing.T) { msgCreator := newMessageCreator(t) registry := prometheus.NewRegistry() - g, err := peer.NewGossipTracker(registry, "foobar") - require.NoError(err) - - log := logging.NoLog{} - gossipTrackerCallback := peer.GossipTrackerCallback{ - Log: log, - GossipTracker: g, - } - beacons := validators.NewManager() require.NoError(beacons.AddStaker(constants.PrimaryNetworkID, nodeIDs[0], nil, ids.GenerateTestID(), 1)) vdrs := validators.NewManager() - vdrs.RegisterCallbackListener(constants.PrimaryNetworkID, &gossipTrackerCallback) for _, nodeID := range nodeIDs { require.NoError(vdrs.AddStaker(constants.PrimaryNetworkID, nodeID, nil, ids.GenerateTestID(), 1)) } config := config - config.GossipTracker = g config.Beacons = beacons config.Validators = vdrs config.AllowPrivateIPs = false @@ -466,7 +448,7 @@ func TestTrackDoesNotDialPrivateIPs(t *testing.T) { config, msgCreator, registry, - log, + logging.NoLog{}, listeners[i], dialer, &testHandler{ @@ -532,23 +514,11 @@ func TestDialDeletesNonValidators(t *testing.T) { msgCreator := newMessageCreator(t) registry := prometheus.NewRegistry() - g, err := peer.NewGossipTracker(registry, "foobar") - require.NoError(err) - - log := logging.NoLog{} - gossipTrackerCallback := peer.GossipTrackerCallback{ - Log: log, - GossipTracker: g, - } - beacons := validators.NewManager() require.NoError(beacons.AddStaker(constants.PrimaryNetworkID, nodeIDs[0], nil, ids.GenerateTestID(), 1)) - vdrs.RegisterCallbackListener(constants.PrimaryNetworkID, &gossipTrackerCallback) - config := config - config.GossipTracker = g config.Beacons = beacons config.Validators = vdrs config.AllowPrivateIPs = false @@ -557,7 +527,7 @@ func TestDialDeletesNonValidators(t *testing.T) { config, msgCreator, registry, - log, + logging.NoLog{}, listeners[i], dialer, &testHandler{ @@ -581,16 +551,15 @@ func TestDialDeletesNonValidators(t *testing.T) { wg.Add(len(networks)) for i, net := range networks { if i != 0 { - peerAcks, err := net.Track(config.MyNodeID, []*ips.ClaimedIPPort{{ - Cert: staking.CertificateFromX509(config.TLSConfig.Certificates[0].Leaf), - IPPort: ip.IPPort, - Timestamp: ip.Timestamp, - Signature: ip.Signature, - }}) + err := net.Track([]*ips.ClaimedIPPort{ + ips.NewClaimedIPPort( + staking.CertificateFromX509(config.TLSConfig.Certificates[0].Leaf), + ip.IPPort, + ip.Timestamp, + ip.Signature, + ), + }) require.NoError(err) - // peerAcks is empty because we aren't actually connected to - // MyNodeID yet - require.Empty(peerAcks) } go func(net Network) { @@ -694,25 +663,14 @@ func TestAllowConnectionAsAValidator(t *testing.T) { msgCreator := newMessageCreator(t) registry := prometheus.NewRegistry() - g, err := peer.NewGossipTracker(registry, "foobar") - require.NoError(err) - - log := logging.NoLog{} - gossipTrackerCallback := peer.GossipTrackerCallback{ - Log: log, - GossipTracker: g, - } - beacons := validators.NewManager() require.NoError(beacons.AddStaker(constants.PrimaryNetworkID, nodeIDs[0], nil, ids.GenerateTestID(), 1)) vdrs := validators.NewManager() - vdrs.RegisterCallbackListener(constants.PrimaryNetworkID, &gossipTrackerCallback) require.NoError(vdrs.AddStaker(constants.PrimaryNetworkID, nodeIDs[0], nil, ids.GenerateTestID(), 1)) config := config - config.GossipTracker = g config.Beacons = beacons config.Validators = vdrs config.RequireValidatorToConnect = true @@ -721,7 +679,7 @@ func TestAllowConnectionAsAValidator(t *testing.T) { config, msgCreator, registry, - log, + logging.NoLog{}, listeners[i], dialer, &testHandler{ diff --git a/network/peer/gossip_tracker.go b/network/peer/gossip_tracker.go deleted file mode 100644 index 105d3e5ce64d..000000000000 --- a/network/peer/gossip_tracker.go +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package peer - -import ( - "fmt" - "sync" - - "github.com/prometheus/client_golang/prometheus" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/set" -) - -// GossipTracker tracks the validators that we're currently aware of, as well as -// the validators we've told each peers about. This data is stored in a bitset -// to optimize space, where only N (num validators) bits will be used per peer. -// -// This is done by recording some state information of both what validators this -// node is aware of, and what validators we've told each peer about. -// As an example, say we track three peers and three validators (MSB first): -// -// trackedPeers: { -// p1: [1, 1, 1] // we have already told [p1] about all validators -// p2: [0, 1, 1] // [p2] doesn't know about [v3] -// p3: [0, 0, 1] // [p3] knows only about [v3] -// } -// -// GetUnknown computes the validators we haven't sent to a given peer. Ex: -// -// GetUnknown(p1) - [0, 0, 0] -// GetUnknown(p2) - [1, 0, 0] -// GetUnknown(p3) - [1, 1, 0] -// -// Using the gossipTracker, we can quickly compute the validators each peer -// doesn't know about using GetUnknown so that in subsequent PeerList gossip -// messages we only send information that this peer (most likely) doesn't -// already know about. The only case where we'll send a redundant set of -// bytes is if another remote peer gossips to the same peer we're trying to -// gossip to first. -type GossipTracker interface { - // Tracked returns if a peer is being tracked - // Returns: - // bool: False if [peerID] is not tracked. True otherwise. - Tracked(peerID ids.NodeID) bool - - // StartTrackingPeer starts tracking a peer - // Returns: - // bool: False if [peerID] was already tracked. True otherwise. - StartTrackingPeer(peerID ids.NodeID) bool - // StopTrackingPeer stops tracking a given peer - // Returns: - // bool: False if [peerID] was not tracked. True otherwise. - StopTrackingPeer(peerID ids.NodeID) bool - - // AddValidator adds a validator that can be gossiped about - // bool: False if a validator with the same node ID or txID as [validator] - // is present. True otherwise. - AddValidator(validator ValidatorID) bool - // GetNodeID maps a txID into a nodeIDs - // nodeID: The nodeID that was registered by [txID] - // bool: False if [validator] was not present. True otherwise. - GetNodeID(txID ids.ID) (ids.NodeID, bool) - // RemoveValidator removes a validator that can be gossiped about - // bool: False if [validator] was already not present. True otherwise. - RemoveValidator(validatorID ids.NodeID) bool - // ResetValidator resets known gossip status of [validatorID] to unknown - // for all peers - // bool: False if [validator] was not present. True otherwise. - ResetValidator(validatorID ids.NodeID) bool - - // AddKnown adds [knownTxIDs] to the txIDs known by [peerID] and filters - // [txIDs] for non-validators. - // Returns: - // txIDs: The txIDs in [txIDs] that are currently validators. - // bool: False if [peerID] is not tracked. True otherwise. - AddKnown( - peerID ids.NodeID, - knownTxIDs []ids.ID, - txIDs []ids.ID, - ) ([]ids.ID, bool) - // GetUnknown gets the peers that we haven't sent to this peer - // Returns: - // []ValidatorID: a slice of ValidatorIDs that [peerID] doesn't know about. - // bool: False if [peerID] is not tracked. True otherwise. - GetUnknown(peerID ids.NodeID) ([]ValidatorID, bool) -} - -type gossipTracker struct { - lock sync.RWMutex - // a mapping of txIDs => the validator added to the validiator set by that - // tx. - txIDsToNodeIDs map[ids.ID]ids.NodeID - // a mapping of validators => the index they occupy in the bitsets - nodeIDsToIndices map[ids.NodeID]int - // each validator in the index it occupies in the bitset - validatorIDs []ValidatorID - // a mapping of each peer => the validators they know about - trackedPeers map[ids.NodeID]set.Bits - - metrics gossipTrackerMetrics -} - -// NewGossipTracker returns an instance of gossipTracker -func NewGossipTracker( - registerer prometheus.Registerer, - namespace string, -) (GossipTracker, error) { - m, err := newGossipTrackerMetrics(registerer, fmt.Sprintf("%s_gossip_tracker", namespace)) - if err != nil { - return nil, err - } - - return &gossipTracker{ - txIDsToNodeIDs: make(map[ids.ID]ids.NodeID), - nodeIDsToIndices: make(map[ids.NodeID]int), - trackedPeers: make(map[ids.NodeID]set.Bits), - metrics: m, - }, nil -} - -func (g *gossipTracker) Tracked(peerID ids.NodeID) bool { - g.lock.RLock() - defer g.lock.RUnlock() - - _, ok := g.trackedPeers[peerID] - return ok -} - -func (g *gossipTracker) StartTrackingPeer(peerID ids.NodeID) bool { - g.lock.Lock() - defer g.lock.Unlock() - - // don't track the peer if it's already being tracked - if _, ok := g.trackedPeers[peerID]; ok { - return false - } - - // start tracking the peer. Initialize their bitset to zero since we - // haven't sent them anything yet. - g.trackedPeers[peerID] = set.NewBits() - - // emit metrics - g.metrics.trackedPeersSize.Set(float64(len(g.trackedPeers))) - - return true -} - -func (g *gossipTracker) StopTrackingPeer(peerID ids.NodeID) bool { - g.lock.Lock() - defer g.lock.Unlock() - - // only stop tracking peers that are actually being tracked - if _, ok := g.trackedPeers[peerID]; !ok { - return false - } - - // stop tracking the peer by removing them - delete(g.trackedPeers, peerID) - g.metrics.trackedPeersSize.Set(float64(len(g.trackedPeers))) - - return true -} - -func (g *gossipTracker) AddValidator(validator ValidatorID) bool { - g.lock.Lock() - defer g.lock.Unlock() - - // only add validators that are not already present - if _, ok := g.txIDsToNodeIDs[validator.TxID]; ok { - return false - } - if _, ok := g.nodeIDsToIndices[validator.NodeID]; ok { - return false - } - - // add the validator to the MSB of the bitset. - msb := len(g.validatorIDs) - g.txIDsToNodeIDs[validator.TxID] = validator.NodeID - g.nodeIDsToIndices[validator.NodeID] = msb - g.validatorIDs = append(g.validatorIDs, validator) - - // emit metrics - g.metrics.validatorsSize.Set(float64(len(g.validatorIDs))) - - return true -} - -func (g *gossipTracker) GetNodeID(txID ids.ID) (ids.NodeID, bool) { - g.lock.RLock() - defer g.lock.RUnlock() - - nodeID, ok := g.txIDsToNodeIDs[txID] - return nodeID, ok -} - -func (g *gossipTracker) RemoveValidator(validatorID ids.NodeID) bool { - g.lock.Lock() - defer g.lock.Unlock() - - // only remove validators that are already present - indexToRemove, ok := g.nodeIDsToIndices[validatorID] - if !ok { - return false - } - validatorToRemove := g.validatorIDs[indexToRemove] - - // swap the validator-to-be-removed with the validator in the last index - // if the element we're swapping with is ourselves, we can skip this swap - // since we only need to delete instead - lastIndex := len(g.validatorIDs) - 1 - if indexToRemove != lastIndex { - lastValidator := g.validatorIDs[lastIndex] - - g.nodeIDsToIndices[lastValidator.NodeID] = indexToRemove - g.validatorIDs[indexToRemove] = lastValidator - } - - delete(g.txIDsToNodeIDs, validatorToRemove.TxID) - delete(g.nodeIDsToIndices, validatorID) - g.validatorIDs = g.validatorIDs[:lastIndex] - - // Invariant: We must remove the validator from everyone else's validator - // bitsets to make sure that each validator occupies the same position in - // each bitset. - for _, knownPeers := range g.trackedPeers { - // swap the element to be removed with the msb - if indexToRemove != lastIndex { - if knownPeers.Contains(lastIndex) { - knownPeers.Add(indexToRemove) - } else { - knownPeers.Remove(indexToRemove) - } - } - knownPeers.Remove(lastIndex) - } - - // emit metrics - g.metrics.validatorsSize.Set(float64(len(g.validatorIDs))) - - return true -} - -func (g *gossipTracker) ResetValidator(validatorID ids.NodeID) bool { - g.lock.Lock() - defer g.lock.Unlock() - - // only reset validators that exist - indexToReset, ok := g.nodeIDsToIndices[validatorID] - if !ok { - return false - } - - for _, knownPeers := range g.trackedPeers { - knownPeers.Remove(indexToReset) - } - - return true -} - -// AddKnown invariants: -// -// 1. [peerID] SHOULD only be a nodeID that has been tracked with -// StartTrackingPeer(). -func (g *gossipTracker) AddKnown( - peerID ids.NodeID, - knownTxIDs []ids.ID, - txIDs []ids.ID, -) ([]ids.ID, bool) { - g.lock.Lock() - defer g.lock.Unlock() - - knownPeers, ok := g.trackedPeers[peerID] - if !ok { - return nil, false - } - for _, txID := range knownTxIDs { - nodeID, ok := g.txIDsToNodeIDs[txID] - if !ok { - // We don't know about this txID, this can happen due to differences - // between our current validator set and the peer's current - // validator set. - continue - } - - // Because we fetched the nodeID from [g.txIDsToNodeIDs], we are - // guaranteed that the index is populated. - index := g.nodeIDsToIndices[nodeID] - knownPeers.Add(index) - } - - validatorTxIDs := make([]ids.ID, 0, len(txIDs)) - for _, txID := range txIDs { - if _, ok := g.txIDsToNodeIDs[txID]; ok { - validatorTxIDs = append(validatorTxIDs, txID) - } - } - return validatorTxIDs, true -} - -func (g *gossipTracker) GetUnknown(peerID ids.NodeID) ([]ValidatorID, bool) { - g.lock.RLock() - defer g.lock.RUnlock() - - // return false if this peer isn't tracked - knownPeers, ok := g.trackedPeers[peerID] - if !ok { - return nil, false - } - - // Calculate the unknown information we need to send to this peer. We do - // this by computing the difference between the validators we know about - // and the validators we know we've sent to [peerID]. - result := make([]ValidatorID, 0, len(g.validatorIDs)) - for i, validatorID := range g.validatorIDs { - if !knownPeers.Contains(i) { - result = append(result, validatorID) - } - } - - return result, true -} diff --git a/network/peer/gossip_tracker_callback.go b/network/peer/gossip_tracker_callback.go deleted file mode 100644 index 5863b236e069..000000000000 --- a/network/peer/gossip_tracker_callback.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package peer - -import ( - "go.uber.org/zap" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/crypto/bls" - "github.com/ava-labs/avalanchego/utils/logging" -) - -var _ validators.SetCallbackListener = (*GossipTrackerCallback)(nil) - -// GossipTrackerCallback synchronizes GossipTracker's validator state with the -// validator set it's registered to. -type GossipTrackerCallback struct { - Log logging.Logger - GossipTracker GossipTracker -} - -// OnValidatorAdded adds [validatorID] to the set of validators that can be -// gossiped about -func (g *GossipTrackerCallback) OnValidatorAdded( - nodeID ids.NodeID, - _ *bls.PublicKey, - txID ids.ID, - _ uint64, -) { - vdr := ValidatorID{ - NodeID: nodeID, - TxID: txID, - } - if !g.GossipTracker.AddValidator(vdr) { - g.Log.Error("failed to add a validator", - zap.Stringer("nodeID", nodeID), - zap.Stringer("txID", txID), - ) - } -} - -// OnValidatorRemoved removes [validatorID] from the set of validators that can -// be gossiped about. -func (g *GossipTrackerCallback) OnValidatorRemoved(nodeID ids.NodeID, _ uint64) { - if !g.GossipTracker.RemoveValidator(nodeID) { - g.Log.Error("failed to remove a validator", - zap.Stringer("nodeID", nodeID), - ) - } -} - -// OnValidatorWeightChanged does nothing because PeerList gossip doesn't care -// about validator weights. -func (*GossipTrackerCallback) OnValidatorWeightChanged(ids.NodeID, uint64, uint64) {} diff --git a/network/peer/gossip_tracker_metrics.go b/network/peer/gossip_tracker_metrics.go deleted file mode 100644 index 080f37fde5c1..000000000000 --- a/network/peer/gossip_tracker_metrics.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package peer - -import ( - "github.com/prometheus/client_golang/prometheus" - - "github.com/ava-labs/avalanchego/utils" -) - -type gossipTrackerMetrics struct { - trackedPeersSize prometheus.Gauge - validatorsSize prometheus.Gauge -} - -func newGossipTrackerMetrics(registerer prometheus.Registerer, namespace string) (gossipTrackerMetrics, error) { - m := gossipTrackerMetrics{ - trackedPeersSize: prometheus.NewGauge( - prometheus.GaugeOpts{ - Namespace: namespace, - Name: "tracked_peers_size", - Help: "amount of peers that are being tracked", - }, - ), - validatorsSize: prometheus.NewGauge( - prometheus.GaugeOpts{ - Namespace: namespace, - Name: "validators_size", - Help: "number of validators this node is tracking", - }, - ), - } - - err := utils.Err( - registerer.Register(m.trackedPeersSize), - registerer.Register(m.validatorsSize), - ) - return m, err -} diff --git a/network/peer/gossip_tracker_test.go b/network/peer/gossip_tracker_test.go deleted file mode 100644 index c9ab1ef8e026..000000000000 --- a/network/peer/gossip_tracker_test.go +++ /dev/null @@ -1,620 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package peer - -import ( - "testing" - - "github.com/prometheus/client_golang/prometheus" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" -) - -var ( - // peers - p1 = ids.GenerateTestNodeID() - p2 = ids.GenerateTestNodeID() - p3 = ids.GenerateTestNodeID() - - // validators - v1 = ValidatorID{ - NodeID: ids.GenerateTestNodeID(), - TxID: ids.GenerateTestID(), - } - v2 = ValidatorID{ - NodeID: ids.GenerateTestNodeID(), - TxID: ids.GenerateTestID(), - } - v3 = ValidatorID{ - NodeID: ids.GenerateTestNodeID(), - TxID: ids.GenerateTestID(), - } -) - -func TestGossipTracker_Contains(t *testing.T) { - tests := []struct { - name string - track []ids.NodeID - contains ids.NodeID - expected bool - }{ - { - name: "empty", - track: []ids.NodeID{}, - contains: p1, - expected: false, - }, - { - name: "populated - does not contain", - track: []ids.NodeID{p1, p2}, - contains: p3, - expected: false, - }, - { - name: "populated - contains", - track: []ids.NodeID{p1, p2, p3}, - contains: p3, - expected: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - for _, add := range test.track { - require.True(g.StartTrackingPeer(add)) - } - - require.Equal(test.expected, g.Tracked(test.contains)) - }) - } -} - -func TestGossipTracker_StartTrackingPeer(t *testing.T) { - tests := []struct { - name string - toStartTracking []ids.NodeID - expected []bool - }{ - { - // Tracking new peers always works - name: "unique adds", - toStartTracking: []ids.NodeID{p1, p2, p3}, - expected: []bool{true, true, true}, - }, - { - // We shouldn't be able to track a peer more than once - name: "duplicate adds", - toStartTracking: []ids.NodeID{p1, p1, p1}, - expected: []bool{true, false, false}, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - for i, p := range test.toStartTracking { - require.Equal(test.expected[i], g.StartTrackingPeer(p)) - require.True(g.Tracked(p)) - } - }) - } -} - -func TestGossipTracker_StopTrackingPeer(t *testing.T) { - tests := []struct { - name string - toStartTracking []ids.NodeID - expectedStartTracking []bool - toStopTracking []ids.NodeID - expectedStopTracking []bool - }{ - { - // We should be able to stop tracking that we are tracking - name: "stop tracking tracked peers", - toStartTracking: []ids.NodeID{p1, p2, p3}, - toStopTracking: []ids.NodeID{p1, p2, p3}, - expectedStopTracking: []bool{true, true, true}, - }, - { - // We shouldn't be able to stop tracking peers we've stopped tracking - name: "stop tracking twice", - toStartTracking: []ids.NodeID{p1}, - toStopTracking: []ids.NodeID{p1, p1}, - expectedStopTracking: []bool{true, false}, - }, - { - // We shouldn't be able to stop tracking peers we were never tracking - name: "remove non-existent elements", - toStartTracking: []ids.NodeID{}, - expectedStartTracking: []bool{}, - toStopTracking: []ids.NodeID{p1, p2, p3}, - expectedStopTracking: []bool{false, false, false}, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - for _, add := range test.toStartTracking { - require.True(g.StartTrackingPeer(add)) - require.True(g.Tracked(add)) - } - - for i, p := range test.toStopTracking { - require.Equal(test.expectedStopTracking[i], g.StopTrackingPeer(p)) - } - }) - } -} - -func TestGossipTracker_AddValidator(t *testing.T) { - type args struct { - validator ValidatorID - } - - tests := []struct { - name string - validators []ValidatorID - args args - expected bool - }{ - { - name: "not present", - validators: []ValidatorID{}, - args: args{validator: v1}, - expected: true, - }, - { - name: "already present txID but with different nodeID", - validators: []ValidatorID{v1}, - args: args{validator: ValidatorID{ - NodeID: ids.GenerateTestNodeID(), - TxID: v1.TxID, - }}, - expected: false, - }, - { - name: "already present nodeID but with different txID", - validators: []ValidatorID{v1}, - args: args{validator: ValidatorID{ - NodeID: v1.NodeID, - TxID: ids.GenerateTestID(), - }}, - expected: false, - }, - { - name: "already present validatorID", - validators: []ValidatorID{v1}, - args: args{validator: v1}, - expected: false, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - for _, v := range test.validators { - require.True(g.AddValidator(v)) - } - - require.Equal(test.expected, g.AddValidator(test.args.validator)) - }) - } -} - -func TestGossipTracker_RemoveValidator(t *testing.T) { - type args struct { - id ids.NodeID - } - - tests := []struct { - name string - validators []ValidatorID - args args - expected bool - }{ - { - name: "not already present", - validators: []ValidatorID{}, - args: args{id: v1.NodeID}, - expected: false, - }, - { - name: "already present", - validators: []ValidatorID{v1}, - args: args{id: v1.NodeID}, - expected: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - for _, v := range test.validators { - require.True(g.AddValidator(v)) - } - - require.Equal(test.expected, g.RemoveValidator(test.args.id)) - }) - } -} - -func TestGossipTracker_ResetValidator(t *testing.T) { - type args struct { - id ids.NodeID - } - - tests := []struct { - name string - validators []ValidatorID - args args - expected bool - }{ - { - name: "non-existent validator", - validators: []ValidatorID{}, - args: args{id: v1.NodeID}, - expected: false, - }, - { - name: "existing validator", - validators: []ValidatorID{v1}, - args: args{id: v1.NodeID}, - expected: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - require.True(g.StartTrackingPeer(p1)) - - for _, v := range test.validators { - require.True(g.AddValidator(v)) - g.AddKnown(p1, []ids.ID{v.TxID}, nil) - - unknown, ok := g.GetUnknown(p1) - require.True(ok) - require.NotContains(unknown, v) - } - - require.Equal(test.expected, g.ResetValidator(test.args.id)) - - for _, v := range test.validators { - unknown, ok := g.GetUnknown(p1) - require.True(ok) - require.Contains(unknown, v) - } - }) - } -} - -func TestGossipTracker_AddKnown(t *testing.T) { - type args struct { - peerID ids.NodeID - txIDs []ids.ID - } - - tests := []struct { - name string - trackedPeers []ids.NodeID - validators []ValidatorID - args args - expectedTxIDs []ids.ID - expectedOk bool - }{ - { - // We should not be able to update an untracked peer - name: "untracked peer - empty", - trackedPeers: []ids.NodeID{}, - validators: []ValidatorID{}, - args: args{peerID: p1, txIDs: []ids.ID{}}, - expectedTxIDs: nil, - expectedOk: false, - }, - { - // We should not be able to update an untracked peer - name: "untracked peer - populated", - trackedPeers: []ids.NodeID{p2, p3}, - validators: []ValidatorID{}, - args: args{peerID: p1, txIDs: []ids.ID{}}, - expectedTxIDs: nil, - expectedOk: false, - }, - { - // We shouldn't be able to look up a peer that isn't tracked - name: "untracked peer - unknown validator", - trackedPeers: []ids.NodeID{}, - validators: []ValidatorID{}, - args: args{peerID: p1, txIDs: []ids.ID{v1.TxID}}, - expectedTxIDs: nil, - expectedOk: false, - }, - { - // We shouldn't fail on a validator that's not registered - name: "tracked peer - unknown validator", - trackedPeers: []ids.NodeID{p1}, - validators: []ValidatorID{}, - args: args{peerID: p1, txIDs: []ids.ID{v1.TxID}}, - expectedTxIDs: []ids.ID{}, - expectedOk: true, - }, - { - // We should be able to update a tracked validator - name: "update tracked validator", - trackedPeers: []ids.NodeID{p1, p2, p3}, - validators: []ValidatorID{v1}, - args: args{peerID: p1, txIDs: []ids.ID{v1.TxID}}, - expectedTxIDs: []ids.ID{v1.TxID}, - expectedOk: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - for _, p := range test.trackedPeers { - require.True(g.StartTrackingPeer(p)) - require.True(g.Tracked(p)) - } - - for _, v := range test.validators { - require.True(g.AddValidator(v)) - } - - txIDs, ok := g.AddKnown(test.args.peerID, test.args.txIDs, test.args.txIDs) - require.Equal(test.expectedOk, ok) - require.Equal(test.expectedTxIDs, txIDs) - }) - } -} - -func TestGossipTracker_GetUnknown(t *testing.T) { - tests := []struct { - name string - peerID ids.NodeID - peersToTrack []ids.NodeID - validators []ValidatorID - expectedUnknown []ValidatorID - expectedOk bool - }{ - { - name: "non tracked peer", - peerID: p1, - validators: []ValidatorID{v2}, - peersToTrack: []ids.NodeID{}, - expectedUnknown: nil, - expectedOk: false, - }, - { - name: "only validators", - peerID: p1, - peersToTrack: []ids.NodeID{p1}, - validators: []ValidatorID{v2}, - expectedUnknown: []ValidatorID{v2}, - expectedOk: true, - }, - { - name: "only non-validators", - peerID: p1, - peersToTrack: []ids.NodeID{p1, p2}, - validators: []ValidatorID{}, - expectedUnknown: []ValidatorID{}, - expectedOk: true, - }, - { - name: "validators and non-validators", - peerID: p1, - peersToTrack: []ids.NodeID{p1, p3}, - validators: []ValidatorID{v2}, - expectedUnknown: []ValidatorID{v2}, - expectedOk: true, - }, - { - name: "same as limit", - peerID: p1, - peersToTrack: []ids.NodeID{p1}, - validators: []ValidatorID{v2, v3}, - expectedUnknown: []ValidatorID{v2, v3}, - expectedOk: true, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - // add our validators - for _, validator := range test.validators { - require.True(g.AddValidator(validator)) - } - - // start tracking our peers - for _, nonValidator := range test.peersToTrack { - require.True(g.StartTrackingPeer(nonValidator)) - require.True(g.Tracked(nonValidator)) - } - - // get the unknown peers for this peer - result, ok := g.GetUnknown(test.peerID) - require.Equal(test.expectedOk, ok) - require.Len(result, len(test.expectedUnknown)) - for _, v := range test.expectedUnknown { - require.Contains(result, v) - } - }) - } -} - -func TestGossipTracker_E2E(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - // [v1, v2, v3] are validators - require.True(g.AddValidator(v1)) - require.True(g.AddValidator(v2)) - - // we should get an empty unknown since we're not tracking anything - unknown, ok := g.GetUnknown(p1) - require.False(ok) - require.Nil(unknown) - - // we should get a unknown of [v1, v2] since v1 and v2 are registered - require.True(g.StartTrackingPeer(p1)) - require.True(g.Tracked(p1)) - - // check p1's unknown - unknown, ok = g.GetUnknown(p1) - require.True(ok) - require.Contains(unknown, v1) - require.Contains(unknown, v2) - require.Len(unknown, 2) - - // Check p2's unknown. We should get nothing since we're not tracking it - // yet. - unknown, ok = g.GetUnknown(p2) - require.False(ok) - require.Nil(unknown) - - // Start tracking p2 - require.True(g.StartTrackingPeer(p2)) - - // check p2's unknown - unknown, ok = g.GetUnknown(p2) - require.True(ok) - require.Contains(unknown, v1) - require.Contains(unknown, v2) - require.Len(unknown, 2) - - // p1 now knows about v1, but not v2, so it should see [v2] in its unknown - // p2 still knows nothing, so it should see both - txIDs, ok := g.AddKnown(p1, []ids.ID{v1.TxID}, []ids.ID{v1.TxID}) - require.True(ok) - require.Equal([]ids.ID{v1.TxID}, txIDs) - - // p1 should have an unknown of [v2], since it knows v1 - unknown, ok = g.GetUnknown(p1) - require.True(ok) - require.Contains(unknown, v2) - require.Len(unknown, 1) - - // p2 should have a unknown of [v1, v2], since it knows nothing - unknown, ok = g.GetUnknown(p2) - require.True(ok) - require.Contains(unknown, v1) - require.Contains(unknown, v2) - require.Len(unknown, 2) - - // Add v3 - require.True(g.AddValidator(v3)) - - // track p3, who knows of v1, v2, and v3 - // p1 and p2 still don't know of v3 - require.True(g.StartTrackingPeer(p3)) - - txIDs, ok = g.AddKnown(p3, []ids.ID{v1.TxID, v2.TxID, v3.TxID}, []ids.ID{v1.TxID, v2.TxID, v3.TxID}) - require.True(ok) - require.Equal([]ids.ID{v1.TxID, v2.TxID, v3.TxID}, txIDs) - - // p1 doesn't know about [v2, v3] - unknown, ok = g.GetUnknown(p1) - require.True(ok) - require.Contains(unknown, v2) - require.Contains(unknown, v3) - require.Len(unknown, 2) - - // p2 doesn't know about [v1, v2, v3] - unknown, ok = g.GetUnknown(p2) - require.True(ok) - require.Contains(unknown, v1) - require.Contains(unknown, v2) - require.Contains(unknown, v3) - require.Len(unknown, 3) - - // p3 knows about everyone - unknown, ok = g.GetUnknown(p3) - require.True(ok) - require.Empty(unknown) - - // stop tracking p2 - require.True(g.StopTrackingPeer(p2)) - unknown, ok = g.GetUnknown(p2) - require.False(ok) - require.Nil(unknown) - - // p1 doesn't know about [v2, v3] because v2 is still registered as - // a validator - unknown, ok = g.GetUnknown(p1) - require.True(ok) - require.Contains(unknown, v2) - require.Contains(unknown, v3) - require.Len(unknown, 2) - - // Remove p2 from the validator set - require.True(g.RemoveValidator(v2.NodeID)) - - // p1 doesn't know about [v3] since v2 left the validator set - unknown, ok = g.GetUnknown(p1) - require.True(ok) - require.Contains(unknown, v3) - require.Len(unknown, 1) - - // p3 knows about everyone since it learned about v1 and v3 earlier. - unknown, ok = g.GetUnknown(p3) - require.Empty(unknown) - require.True(ok) -} - -func TestGossipTracker_Regression_IncorrectTxIDDeletion(t *testing.T) { - require := require.New(t) - - g, err := NewGossipTracker(prometheus.NewRegistry(), "foobar") - require.NoError(err) - - require.True(g.AddValidator(v1)) - require.True(g.AddValidator(v2)) - - require.True(g.RemoveValidator(v1.NodeID)) - - require.False(g.AddValidator(ValidatorID{ - NodeID: ids.GenerateTestNodeID(), - TxID: v2.TxID, - })) -} diff --git a/network/peer/network.go b/network/peer/network.go index 8c18ef0ac899..b8fb01814546 100644 --- a/network/peer/network.go +++ b/network/peer/network.go @@ -5,7 +5,7 @@ package peer import ( "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/avalanchego/utils/bloom" "github.com/ava-labs/avalanchego/utils/ips" ) @@ -19,15 +19,9 @@ type Network interface { // connection is no longer desired and should be terminated. AllowConnection(peerID ids.NodeID) bool - // Track allows the peer to notify the network of a potential new peer to - // connect to, given the [ips] of the peers it sent us during the peer - // handshake. - // - // Returns which IPs should not be gossipped to this node again. - Track(peerID ids.NodeID, ips []*ips.ClaimedIPPort) ([]*p2p.PeerAck, error) - - // MarkTracked stops sending gossip about [ips] to [peerID]. - MarkTracked(peerID ids.NodeID, ips []*p2p.PeerAck) error + // Track allows the peer to notify the network of potential new peers to + // connect to. + Track(ips []*ips.ClaimedIPPort) error // Disconnected is called when the peer finishes shutting down. It is not // guaranteed that [Connected] was called for the provided peer. However, it @@ -35,6 +29,13 @@ type Network interface { // for a given [Peer] object. Disconnected(peerID ids.NodeID) - // Peers returns peers that [peerID] might not know about. - Peers(peerID ids.NodeID) ([]ips.ClaimedIPPort, error) + // KnownPeers returns the bloom filter of the known peers. + KnownPeers() (bloomFilter []byte, salt []byte) + + // Peers returns peers that are not known. + Peers( + peerID ids.NodeID, + knownPeers *bloom.ReadFilter, + peerSalt []byte, + ) []*ips.ClaimedIPPort } diff --git a/network/peer/peer.go b/network/peer/peer.go index 16b5d3ab3090..db2cb5485b04 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/proto/pb/p2p" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/bloom" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/ips" "github.com/ava-labs/avalanchego/utils/json" @@ -29,6 +30,10 @@ import ( "github.com/ava-labs/avalanchego/version" ) +// maxBloomSaltLen restricts the allowed size of the bloom salt to prevent +// excessively expensive bloom filter contains checks. +const maxBloomSaltLen = 32 + var ( errClosed = errors.New("closed") @@ -91,6 +96,11 @@ type Peer interface { // sent. StartSendPeerList() + // StartSendGetPeerList attempts to send a GetPeerList message to this peer + // on this peer's gossip routine. It is not guaranteed that a GetPeerList + // will be sent. + StartSendGetPeerList() + // StartClose will begin shutting down the peer. It will not block. StartClose() @@ -170,6 +180,10 @@ type peer struct { // peerListChan signals that we should attempt to send a PeerList to this // peer peerListChan chan struct{} + + // getPeerListChan signals that we should attempt to send a GetPeerList to + // this peer + getPeerListChan chan struct{} } // Start a new peer instance. @@ -197,6 +211,7 @@ func Start( onClosed: make(chan struct{}), observedUptimes: make(map[ids.ID]uint32), peerListChan: make(chan struct{}, 1), + getPeerListChan: make(chan struct{}, 1), } go p.readMessages() @@ -310,6 +325,13 @@ func (p *peer) StartSendPeerList() { } } +func (p *peer) StartSendGetPeerList() { + select { + case p.getPeerListChan <- struct{}{}: + default: + } +} + func (p *peer) StartClose() { p.startClosingOnce.Do(func() { if err := p.conn.Close(); err != nil { @@ -516,6 +538,8 @@ func (p *peer) writeMessages() { Patch: myVersion.Patch, } + knownPeersFilter, knownPeersSalt := p.Network.KnownPeers() + msg, err := p.MessageCreator.Handshake( p.NetworkID, p.Clock.Unix(), @@ -530,6 +554,8 @@ func (p *peer) writeMessages() { p.MySubnets.List(), p.SupportedACPs, p.ObjectedACPs, + knownPeersFilter, + knownPeersSalt, ) if err != nil { p.Log.Error("failed to create message", @@ -621,15 +647,7 @@ func (p *peer) sendNetworkMessages() { for { select { case <-p.peerListChan: - peerIPs, err := p.Config.Network.Peers(p.id) - if err != nil { - p.Log.Error("failed to get peers to gossip", - zap.Stringer("nodeID", p.id), - zap.Error(err), - ) - return - } - + peerIPs := p.Config.Network.Peers(p.id, bloom.EmptyFilter, nil) if len(peerIPs) == 0 { p.Log.Verbo( "skipping peer gossip as there are no unknown peers", @@ -654,6 +672,22 @@ func (p *peer) sendNetworkMessages() { zap.Stringer("nodeID", p.id), ) } + case <-p.getPeerListChan: + knownPeersFilter, knownPeersSalt := p.Config.Network.KnownPeers() + msg, err := p.Config.MessageCreator.GetPeerList(knownPeersFilter, knownPeersSalt) + if err != nil { + p.Log.Error("failed to create get peer list message", + zap.Stringer("nodeID", p.id), + zap.Error(err), + ) + continue + } + + if !p.Send(p.onClosingCtx, msg) { + p.Log.Debug("failed to send get peer list", + zap.Stringer("nodeID", p.id), + ) + } case <-sendPingsTicker.C: if !p.Network.AllowConnection(p.id) { p.Log.Debug("disconnecting from peer", @@ -707,12 +741,12 @@ func (p *peer) handle(msg message.InboundMessage) { p.handleHandshake(m) msg.OnFinishedHandling() return - case *p2p.PeerList: - p.handlePeerList(m) + case *p2p.GetPeerList: + p.handleGetPeerList(m) msg.OnFinishedHandling() return - case *p2p.PeerListAck: - p.handlePeerListAck(m) + case *p2p.PeerList: + p.handlePeerList(m) msg.OnFinishedHandling() return } @@ -992,6 +1026,37 @@ func (p *peer) handleHandshake(msg *p2p.Handshake) { return } + var ( + knownPeers = bloom.EmptyFilter + salt []byte + ) + if msg.KnownPeers != nil { + var err error + knownPeers, err = bloom.Parse(msg.KnownPeers.Filter) + if err != nil { + p.Log.Debug("message with invalid field", + zap.Stringer("nodeID", p.id), + zap.Stringer("messageOp", message.HandshakeOp), + zap.String("field", "KnownPeers.Filter"), + zap.Error(err), + ) + p.StartClose() + return + } + + salt = msg.KnownPeers.Salt + if saltLen := len(salt); saltLen > maxBloomSaltLen { + p.Log.Debug("message with invalid field", + zap.Stringer("nodeID", p.id), + zap.Stringer("messageOp", message.HandshakeOp), + zap.String("field", "KnownPeers.Salt"), + zap.Int("saltLen", saltLen), + ) + p.StartClose() + return + } + } + // "net.IP" type in Golang is 16-byte if ipLen := len(msg.IpAddr); ipLen != net.IPv6len { p.Log.Debug("message with invalid field", @@ -1035,14 +1100,7 @@ func (p *peer) handleHandshake(msg *p2p.Handshake) { p.gotHandshake.Set(true) - peerIPs, err := p.Network.Peers(p.id) - if err != nil { - p.Log.Error("failed to get peers to gossip for handshake", - zap.Stringer("nodeID", p.id), - zap.Error(err), - ) - return - } + peerIPs := p.Network.Peers(p.id, knownPeers, salt) // We bypass throttling here to ensure that the peerlist message is // acknowledged timely. @@ -1066,6 +1124,65 @@ func (p *peer) handleHandshake(msg *p2p.Handshake) { } } +func (p *peer) handleGetPeerList(msg *p2p.GetPeerList) { + if !p.finishedHandshake.Get() { + p.Log.Verbo("dropping get peer list message", + zap.Stringer("nodeID", p.id), + ) + return + } + + knownPeersMsg := msg.GetKnownPeers() + filter, err := bloom.Parse(knownPeersMsg.GetFilter()) + if err != nil { + p.Log.Debug("message with invalid field", + zap.Stringer("nodeID", p.id), + zap.Stringer("messageOp", message.GetPeerListOp), + zap.String("field", "KnownPeers.Filter"), + zap.Error(err), + ) + p.StartClose() + return + } + + salt := knownPeersMsg.GetSalt() + if saltLen := len(salt); saltLen > maxBloomSaltLen { + p.Log.Debug("message with invalid field", + zap.Stringer("nodeID", p.id), + zap.Stringer("messageOp", message.GetPeerListOp), + zap.String("field", "KnownPeers.Salt"), + zap.Int("saltLen", saltLen), + ) + p.StartClose() + return + } + + peerIPs := p.Network.Peers(p.id, filter, salt) + if len(peerIPs) == 0 { + p.Log.Debug("skipping sending of empty peer list", + zap.Stringer("nodeID", p.id), + ) + return + } + + // Bypass throttling is disabled here to follow the non-handshake message + // sending pattern. + peerListMsg, err := p.Config.MessageCreator.PeerList(peerIPs, false /*=bypassThrottling*/) + if err != nil { + p.Log.Error("failed to create peer list message", + zap.Stringer("nodeID", p.id), + zap.Error(err), + ) + return + } + + if !p.Send(p.onClosingCtx, peerListMsg) { + p.Log.Debug("failed to send peer list", + zap.Stringer("nodeID", p.id), + ) + } +} + func (p *peer) handlePeerList(msg *p2p.PeerList) { if !p.finishedHandshake.Get() { if !p.gotHandshake.Get() { @@ -1114,32 +1231,18 @@ func (p *peer) handlePeerList(msg *p2p.PeerList) { continue } - txID, err := ids.ToID(claimedIPPort.TxId) - if err != nil { - p.Log.Debug("message with invalid field", - zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.PeerListOp), - zap.String("field", "txID"), - zap.Error(err), - ) - p.StartClose() - return - } - - discoveredIPs[i] = &ips.ClaimedIPPort{ - Cert: tlsCert, - IPPort: ips.IPPort{ + discoveredIPs[i] = ips.NewClaimedIPPort( + tlsCert, + ips.IPPort{ IP: claimedIPPort.IpAddr, Port: uint16(claimedIPPort.IpPort), }, - Timestamp: claimedIPPort.Timestamp, - Signature: claimedIPPort.Signature, - TxID: txID, - } + claimedIPPort.Timestamp, + claimedIPPort.Signature, + ) } - trackedPeers, err := p.Network.Track(p.id, discoveredIPs) - if err != nil { + if err := p.Network.Track(discoveredIPs); err != nil { p.Log.Debug("message with invalid field", zap.Stringer("nodeID", p.id), zap.Stringer("messageOp", message.PeerListOp), @@ -1147,42 +1250,6 @@ func (p *peer) handlePeerList(msg *p2p.PeerList) { zap.Error(err), ) p.StartClose() - return - } - if len(trackedPeers) == 0 { - p.Log.Debug("skipping peerlist ack as there were no tracked peers", - zap.Stringer("nodeID", p.id), - ) - return - } - - peerListAckMsg, err := p.Config.MessageCreator.PeerListAck(trackedPeers) - if err != nil { - p.Log.Error("failed to create message", - zap.Stringer("messageOp", message.PeerListAckOp), - zap.Stringer("nodeID", p.id), - zap.Error(err), - ) - return - } - - if !p.Send(p.onClosingCtx, peerListAckMsg) { - p.Log.Debug("failed to send peer list ack", - zap.Stringer("nodeID", p.id), - ) - } -} - -func (p *peer) handlePeerListAck(msg *p2p.PeerListAck) { - err := p.Network.MarkTracked(p.id, msg.PeerAcks) - if err != nil { - p.Log.Debug("message with invalid field", - zap.Stringer("nodeID", p.id), - zap.Stringer("messageOp", message.PeerListAckOp), - zap.String("field", "txID"), - zap.Error(err), - ) - p.StartClose() } } diff --git a/network/peer/test_network.go b/network/peer/test_network.go index 1ba047e1d423..01a341ae9abc 100644 --- a/network/peer/test_network.go +++ b/network/peer/test_network.go @@ -5,7 +5,7 @@ package peer import ( "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/avalanchego/utils/bloom" "github.com/ava-labs/avalanchego/utils/ips" ) @@ -19,16 +19,16 @@ func (testNetwork) AllowConnection(ids.NodeID) bool { return true } -func (testNetwork) Track(ids.NodeID, []*ips.ClaimedIPPort) ([]*p2p.PeerAck, error) { - return nil, nil -} - -func (testNetwork) MarkTracked(ids.NodeID, []*p2p.PeerAck) error { +func (testNetwork) Track([]*ips.ClaimedIPPort) error { return nil } func (testNetwork) Disconnected(ids.NodeID) {} -func (testNetwork) Peers(ids.NodeID) ([]ips.ClaimedIPPort, error) { - return nil, nil +func (testNetwork) KnownPeers() ([]byte, []byte) { + return bloom.EmptyFilter.Marshal(), nil +} + +func (testNetwork) Peers(ids.NodeID, *bloom.ReadFilter, []byte) []*ips.ClaimedIPPort { + return nil } diff --git a/network/test_network.go b/network/test_network.go index 0811875b4c43..8079e76240c1 100644 --- a/network/test_network.go +++ b/network/test_network.go @@ -156,6 +156,8 @@ func NewTestNetwork( PeerListNonValidatorGossipSize: constants.DefaultNetworkPeerListNonValidatorGossipSize, PeerListPeersGossipSize: constants.DefaultNetworkPeerListPeersGossipSize, PeerListGossipFreq: constants.DefaultNetworkPeerListGossipFreq, + PeerListPullGossipFreq: constants.DefaultNetworkPeerListPullGossipFreq, + PeerListBloomResetFreq: constants.DefaultNetworkPeerListBloomResetFreq, }, DelayConfig: DelayConfig{ @@ -186,9 +188,8 @@ func NewTestNetwork( networkConfig.TLSConfig = tlsConfig networkConfig.TLSKey = tlsCert.PrivateKey.(crypto.Signer) - beacons := validators.NewManager() networkConfig.Validators = currentValidators - networkConfig.Beacons = beacons + networkConfig.Beacons = validators.NewManager() // This never actually does anything because we never initialize the P-chain networkConfig.UptimeCalculator = uptime.NoOpCalculator @@ -227,11 +228,6 @@ func NewTestNetwork( networkConfig.MyIPPort = ips.NewDynamicIPPort(net.IPv4zero, 1) - networkConfig.GossipTracker, err = peer.NewGossipTracker(metrics, "") - if err != nil { - return nil, err - } - return NewNetwork( &networkConfig, msgCreator, diff --git a/node/node.go b/node/node.go index 8fce5df75550..24f5c1711767 100644 --- a/node/node.go +++ b/node/node.go @@ -583,18 +583,6 @@ func (n *Node) initNetworking() error { }() } - // initialize gossip tracker - gossipTracker, err := peer.NewGossipTracker(n.MetricsRegisterer, n.networkNamespace) - if err != nil { - return err - } - - // keep gossip tracker synchronized with the validator set - n.vdrs.RegisterCallbackListener(constants.PrimaryNetworkID, &peer.GossipTrackerCallback{ - Log: n.Log, - GossipTracker: gossipTracker, - }) - // add node configs to network config n.Config.NetworkConfig.Namespace = n.networkNamespace n.Config.NetworkConfig.MyNodeID = n.ID @@ -610,7 +598,6 @@ func (n *Node) initNetworking() error { n.Config.NetworkConfig.ResourceTracker = n.resourceTracker n.Config.NetworkConfig.CPUTargeter = n.cpuTargeter n.Config.NetworkConfig.DiskTargeter = n.diskTargeter - n.Config.NetworkConfig.GossipTracker = gossipTracker n.Net, err = network.NewNetwork( &n.Config.NetworkConfig, diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index 53a4d3d2126a..6b5deacc7e01 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -8,6 +8,8 @@ option go_package = "github.com/ava-labs/avalanchego/proto/pb/p2p"; // Represents peer-to-peer messages. // Only one type can be non-null. message Message { + reserved 33; // Until after durango activation. + reserved 36; // Next unused field number. // NOTES // Use "oneof" for each message type and set rest to null if not used. // That is because when the compression is enabled, we don't want to include uncompressed fields. @@ -29,6 +31,7 @@ message Message { Ping ping = 11; Pong pong = 12; Handshake handshake = 13; + GetPeerList get_peer_list = 35; PeerList peer_list = 14; // State-sync messages: @@ -56,8 +59,6 @@ message Message { AppRequest app_request = 30; AppResponse app_response = 31; AppGossip app_gossip = 32; - - PeerListAck peer_list_ack = 33; AppError app_error = 34; } } @@ -118,6 +119,7 @@ message Handshake { Client client = 9; repeated uint32 supported_acps = 10; repeated uint32 objected_acps = 11; + BloomFilter known_peers = 12; } // Metadata about a peer's P2P client used to determine compatibility @@ -130,6 +132,12 @@ message Client { uint32 patch = 4; } +// BloomFilter with a random salt to prevent consistent hash collisions +message BloomFilter { + bytes filter = 1; + bytes salt = 2; +} + // ClaimedIpPort contains metadata needed to connect to a peer message ClaimedIpPort { // X509 certificate of the peer @@ -146,38 +154,29 @@ message ClaimedIpPort { bytes tx_id = 6; } +// GetPeerList contains a bloom filter of the currently known validator IPs. +// +// GetPeerList must not be responded to until finishing the handshake. After the +// handshake is completed, GetPeerlist messages should be responded to with a +// Peerlist message containing validators that are not present in the bloom +// filter. +message GetPeerList { + BloomFilter known_peers = 1; +} + // PeerList contains network-level metadata for a set of validators. // // PeerList must be sent in response to an inbound Handshake message from a // remote peer a peer wants to connect to. Once a PeerList is received after // a Handshake message, the p2p handshake is complete and the connection is // established. - -// Peers should periodically send PeerList messages to allow peers to -// discover each other. // -// PeerListAck should be sent in response to a PeerList. +// PeerList should be sent in response to a GetPeerlist message if the handshake +// has been completed. message PeerList { repeated ClaimedIpPort claimed_ip_ports = 1; } -// PeerAck acknowledges that a gossiped peer in a PeerList message will be -// tracked by the remote peer. -message PeerAck { - // P-Chain transaction that added the acknowledged peer to the validator - // set - bytes tx_id = 1; - // Timestamp of the signed ip of the peer - uint64 timestamp = 2; -} - -// PeerListAck is sent in response to PeerList to acknowledge the subset of -// peers that the peer will attempt to connect to. -message PeerListAck { - reserved 1; // deprecated; used to be tx_ids - repeated PeerAck peer_acks = 2; -} - // GetStateSummaryFrontier requests a peer's most recently accepted state // summary message GetStateSummaryFrontier { diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index 166a8d11f493..0732bf1a13c8 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -89,7 +89,8 @@ type Message struct { // *Message_Ping // *Message_Pong // *Message_Handshake - // *Message_PeerList + // *Message_GetPeerList + // *Message_PeerList_ // *Message_GetStateSummaryFrontier // *Message_StateSummaryFrontier_ // *Message_GetAcceptedStateSummary @@ -108,7 +109,6 @@ type Message struct { // *Message_AppRequest // *Message_AppResponse // *Message_AppGossip - // *Message_PeerListAck // *Message_AppError Message isMessage_Message `protobuf_oneof:"message"` } @@ -187,9 +187,16 @@ func (x *Message) GetHandshake() *Handshake { return nil } -func (x *Message) GetPeerList() *PeerList { - if x, ok := x.GetMessage().(*Message_PeerList); ok { - return x.PeerList +func (x *Message) GetGetPeerList() *GetPeerList { + if x, ok := x.GetMessage().(*Message_GetPeerList); ok { + return x.GetPeerList + } + return nil +} + +func (x *Message) GetPeerList_() *PeerList { + if x, ok := x.GetMessage().(*Message_PeerList_); ok { + return x.PeerList_ } return nil } @@ -320,13 +327,6 @@ func (x *Message) GetAppGossip() *AppGossip { return nil } -func (x *Message) GetPeerListAck() *PeerListAck { - if x, ok := x.GetMessage().(*Message_PeerListAck); ok { - return x.PeerListAck - } - return nil -} - func (x *Message) GetAppError() *AppError { if x, ok := x.GetMessage().(*Message_AppError); ok { return x.AppError @@ -365,8 +365,12 @@ type Message_Handshake struct { Handshake *Handshake `protobuf:"bytes,13,opt,name=handshake,proto3,oneof"` } -type Message_PeerList struct { - PeerList *PeerList `protobuf:"bytes,14,opt,name=peer_list,json=peerList,proto3,oneof"` +type Message_GetPeerList struct { + GetPeerList *GetPeerList `protobuf:"bytes,35,opt,name=get_peer_list,json=getPeerList,proto3,oneof"` +} + +type Message_PeerList_ struct { + PeerList_ *PeerList `protobuf:"bytes,14,opt,name=peer_list,json=peerList,proto3,oneof"` } type Message_GetStateSummaryFrontier struct { @@ -445,10 +449,6 @@ type Message_AppGossip struct { AppGossip *AppGossip `protobuf:"bytes,32,opt,name=app_gossip,json=appGossip,proto3,oneof"` } -type Message_PeerListAck struct { - PeerListAck *PeerListAck `protobuf:"bytes,33,opt,name=peer_list_ack,json=peerListAck,proto3,oneof"` -} - type Message_AppError struct { AppError *AppError `protobuf:"bytes,34,opt,name=app_error,json=appError,proto3,oneof"` } @@ -463,7 +463,9 @@ func (*Message_Pong) isMessage_Message() {} func (*Message_Handshake) isMessage_Message() {} -func (*Message_PeerList) isMessage_Message() {} +func (*Message_GetPeerList) isMessage_Message() {} + +func (*Message_PeerList_) isMessage_Message() {} func (*Message_GetStateSummaryFrontier) isMessage_Message() {} @@ -501,8 +503,6 @@ func (*Message_AppResponse) isMessage_Message() {} func (*Message_AppGossip) isMessage_Message() {} -func (*Message_PeerListAck) isMessage_Message() {} - func (*Message_AppError) isMessage_Message() {} // Ping reports a peer's perceived uptime percentage. @@ -711,10 +711,11 @@ type Handshake struct { // Signature of the peer IP port pair at a provided timestamp Sig []byte `protobuf:"bytes,7,opt,name=sig,proto3" json:"sig,omitempty"` // Subnets the peer is tracking - TrackedSubnets [][]byte `protobuf:"bytes,8,rep,name=tracked_subnets,json=trackedSubnets,proto3" json:"tracked_subnets,omitempty"` - Client *Client `protobuf:"bytes,9,opt,name=client,proto3" json:"client,omitempty"` - SupportedAcps []uint32 `protobuf:"varint,10,rep,packed,name=supported_acps,json=supportedAcps,proto3" json:"supported_acps,omitempty"` - ObjectedAcps []uint32 `protobuf:"varint,11,rep,packed,name=objected_acps,json=objectedAcps,proto3" json:"objected_acps,omitempty"` + TrackedSubnets [][]byte `protobuf:"bytes,8,rep,name=tracked_subnets,json=trackedSubnets,proto3" json:"tracked_subnets,omitempty"` + Client *Client `protobuf:"bytes,9,opt,name=client,proto3" json:"client,omitempty"` + SupportedAcps []uint32 `protobuf:"varint,10,rep,packed,name=supported_acps,json=supportedAcps,proto3" json:"supported_acps,omitempty"` + ObjectedAcps []uint32 `protobuf:"varint,11,rep,packed,name=objected_acps,json=objectedAcps,proto3" json:"objected_acps,omitempty"` + KnownPeers *BloomFilter `protobuf:"bytes,12,opt,name=known_peers,json=knownPeers,proto3" json:"known_peers,omitempty"` } func (x *Handshake) Reset() { @@ -826,6 +827,13 @@ func (x *Handshake) GetObjectedAcps() []uint32 { return nil } +func (x *Handshake) GetKnownPeers() *BloomFilter { + if x != nil { + return x.KnownPeers + } + return nil +} + // Metadata about a peer's P2P client used to determine compatibility type Client struct { state protoimpl.MessageState @@ -900,6 +908,62 @@ func (x *Client) GetPatch() uint32 { return 0 } +// BloomFilter with a random salt to prevent consistent hash collisions +type BloomFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filter []byte `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` + Salt []byte `protobuf:"bytes,2,opt,name=salt,proto3" json:"salt,omitempty"` +} + +func (x *BloomFilter) Reset() { + *x = BloomFilter{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BloomFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BloomFilter) ProtoMessage() {} + +func (x *BloomFilter) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BloomFilter.ProtoReflect.Descriptor instead. +func (*BloomFilter) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{6} +} + +func (x *BloomFilter) GetFilter() []byte { + if x != nil { + return x.Filter + } + return nil +} + +func (x *BloomFilter) GetSalt() []byte { + if x != nil { + return x.Salt + } + return nil +} + // ClaimedIpPort contains metadata needed to connect to a peer type ClaimedIpPort struct { state protoimpl.MessageState @@ -923,7 +987,7 @@ type ClaimedIpPort struct { func (x *ClaimedIpPort) Reset() { *x = ClaimedIpPort{} if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[6] + mi := &file_p2p_p2p_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -936,7 +1000,7 @@ func (x *ClaimedIpPort) String() string { func (*ClaimedIpPort) ProtoMessage() {} func (x *ClaimedIpPort) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[6] + mi := &file_p2p_p2p_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -949,7 +1013,7 @@ func (x *ClaimedIpPort) ProtoReflect() protoreflect.Message { // Deprecated: Use ClaimedIpPort.ProtoReflect.Descriptor instead. func (*ClaimedIpPort) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{6} + return file_p2p_p2p_proto_rawDescGZIP(), []int{7} } func (x *ClaimedIpPort) GetX509Certificate() []byte { @@ -994,73 +1058,22 @@ func (x *ClaimedIpPort) GetTxId() []byte { return nil } -// Peers should periodically send PeerList messages to allow peers to -// discover each other. +// GetPeerList contains a bloom filter of the currently known validator IPs. // -// PeerListAck should be sent in response to a PeerList. -type PeerList struct { +// GetPeerList must not be responded to until finishing the handshake. After the +// handshake is completed, GetPeerlist messages should be responded to with a +// Peerlist message containing validators that are not present in the bloom +// filter. +type GetPeerList struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ClaimedIpPorts []*ClaimedIpPort `protobuf:"bytes,1,rep,name=claimed_ip_ports,json=claimedIpPorts,proto3" json:"claimed_ip_ports,omitempty"` + KnownPeers *BloomFilter `protobuf:"bytes,1,opt,name=known_peers,json=knownPeers,proto3" json:"known_peers,omitempty"` } -func (x *PeerList) Reset() { - *x = PeerList{} - if protoimpl.UnsafeEnabled { - mi := &file_p2p_p2p_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PeerList) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PeerList) ProtoMessage() {} - -func (x *PeerList) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PeerList.ProtoReflect.Descriptor instead. -func (*PeerList) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{7} -} - -func (x *PeerList) GetClaimedIpPorts() []*ClaimedIpPort { - if x != nil { - return x.ClaimedIpPorts - } - return nil -} - -// PeerAck acknowledges that a gossiped peer in a PeerList message will be -// tracked by the remote peer. -type PeerAck struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // P-Chain transaction that added the acknowledged peer to the validator - // set - TxId []byte `protobuf:"bytes,1,opt,name=tx_id,json=txId,proto3" json:"tx_id,omitempty"` - // Timestamp of the signed ip of the peer - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` -} - -func (x *PeerAck) Reset() { - *x = PeerAck{} +func (x *GetPeerList) Reset() { + *x = GetPeerList{} if protoimpl.UnsafeEnabled { mi := &file_p2p_p2p_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1068,13 +1081,13 @@ func (x *PeerAck) Reset() { } } -func (x *PeerAck) String() string { +func (x *GetPeerList) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PeerAck) ProtoMessage() {} +func (*GetPeerList) ProtoMessage() {} -func (x *PeerAck) ProtoReflect() protoreflect.Message { +func (x *GetPeerList) ProtoReflect() protoreflect.Message { mi := &file_p2p_p2p_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1086,37 +1099,37 @@ func (x *PeerAck) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PeerAck.ProtoReflect.Descriptor instead. -func (*PeerAck) Descriptor() ([]byte, []int) { +// Deprecated: Use GetPeerList.ProtoReflect.Descriptor instead. +func (*GetPeerList) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{8} } -func (x *PeerAck) GetTxId() []byte { +func (x *GetPeerList) GetKnownPeers() *BloomFilter { if x != nil { - return x.TxId + return x.KnownPeers } return nil } -func (x *PeerAck) GetTimestamp() uint64 { - if x != nil { - return x.Timestamp - } - return 0 -} - -// PeerListAck is sent in response to PeerList to acknowledge the subset of -// peers that the peer will attempt to connect to. -type PeerListAck struct { +// PeerList contains network-level metadata for a set of validators. +// +// PeerList must be sent in response to an inbound Handshake message from a +// remote peer a peer wants to connect to. Once a PeerList is received after +// a Handshake message, the p2p handshake is complete and the connection is +// established. +// +// PeerList should be sent in response to a GetPeerlist message if the handshake +// has been completed. +type PeerList struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - PeerAcks []*PeerAck `protobuf:"bytes,2,rep,name=peer_acks,json=peerAcks,proto3" json:"peer_acks,omitempty"` + ClaimedIpPorts []*ClaimedIpPort `protobuf:"bytes,1,rep,name=claimed_ip_ports,json=claimedIpPorts,proto3" json:"claimed_ip_ports,omitempty"` } -func (x *PeerListAck) Reset() { - *x = PeerListAck{} +func (x *PeerList) Reset() { + *x = PeerList{} if protoimpl.UnsafeEnabled { mi := &file_p2p_p2p_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1124,13 +1137,13 @@ func (x *PeerListAck) Reset() { } } -func (x *PeerListAck) String() string { +func (x *PeerList) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PeerListAck) ProtoMessage() {} +func (*PeerList) ProtoMessage() {} -func (x *PeerListAck) ProtoReflect() protoreflect.Message { +func (x *PeerList) ProtoReflect() protoreflect.Message { mi := &file_p2p_p2p_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1142,14 +1155,14 @@ func (x *PeerListAck) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PeerListAck.ProtoReflect.Descriptor instead. -func (*PeerListAck) Descriptor() ([]byte, []int) { +// Deprecated: Use PeerList.ProtoReflect.Descriptor instead. +func (*PeerList) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{9} } -func (x *PeerListAck) GetPeerAcks() []*PeerAck { +func (x *PeerList) GetClaimedIpPorts() []*ClaimedIpPort { if x != nil { - return x.PeerAcks + return x.ClaimedIpPorts } return nil } @@ -2620,7 +2633,7 @@ var File_p2p_p2p_proto protoreflect.FileDescriptor var file_p2p_p2p_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x03, 0x70, 0x32, 0x70, 0x22, 0x92, 0x0b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x03, 0x70, 0x32, 0x70, 0x22, 0x9e, 0x0b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x7a, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x47, 0x7a, 0x69, 0x70, 0x12, 0x29, 0x0a, 0x0f, 0x63, @@ -2633,334 +2646,337 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x2e, 0x0a, 0x09, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x48, 0x00, 0x52, 0x09, 0x68, - 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x2c, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x70, 0x65, - 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, - 0x74, 0x69, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, - 0x69, 0x65, 0x72, 0x12, 0x51, 0x0a, 0x16, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x10, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, - 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, - 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x5b, 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x41, - 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x12, 0x51, 0x0a, 0x16, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x12, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, - 0x52, 0x14, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x4e, 0x0a, 0x15, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, - 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, - 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, - 0x00, 0x52, 0x13, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, - 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x11, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, - 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0c, - 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, - 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, - 0x12, 0x38, 0x0a, 0x0d, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, - 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x67, 0x65, - 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, - 0x70, 0x32, 0x70, 0x2e, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, - 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x67, 0x65, - 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, - 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x18, - 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x74, 0x48, - 0x00, 0x52, 0x03, 0x70, 0x75, 0x74, 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, - 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x6c, 0x6c, 0x5f, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, - 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x22, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x74, - 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x68, - 0x69, 0x74, 0x73, 0x48, 0x00, 0x52, 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, - 0x61, 0x70, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x35, 0x0a, 0x0c, 0x61, 0x70, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x5f, 0x67, - 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x48, 0x00, 0x52, 0x09, 0x61, - 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x36, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x63, 0x6b, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, - 0x6b, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x6b, + 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x67, 0x65, 0x74, 0x5f, + 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x48, 0x00, 0x52, 0x0b, 0x67, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, + 0x12, 0x2c, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, + 0x73, 0x74, 0x48, 0x00, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x5b, + 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x51, 0x0a, 0x16, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x66, 0x72, 0x6f, + 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, + 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x14, 0x73, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x5b, + 0x0a, 0x1a, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x48, 0x00, 0x52, 0x17, 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x51, 0x0a, 0x16, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52, 0x14, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x4e, + 0x0a, 0x15, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x13, 0x67, 0x65, 0x74, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x44, + 0x0a, 0x11, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, + 0x48, 0x00, 0x52, 0x10, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, + 0x74, 0x69, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x0c, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0b, + 0x67, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x08, 0x61, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x08, + 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x38, 0x0a, 0x0d, 0x67, 0x65, 0x74, 0x5f, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x67, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x18, + 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x6e, 0x63, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x73, 0x48, 0x00, 0x52, 0x09, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x08, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, + 0x12, 0x1c, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x74, 0x48, 0x00, 0x52, 0x03, 0x70, 0x75, 0x74, 0x12, 0x2f, + 0x0a, 0x0a, 0x70, 0x75, 0x73, 0x68, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, + 0x2f, 0x0a, 0x0a, 0x70, 0x75, 0x6c, 0x6c, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x1c, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x48, 0x00, 0x52, 0x09, 0x70, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x12, 0x22, 0x0a, 0x05, 0x63, 0x68, 0x69, 0x74, 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0a, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x68, 0x69, 0x74, 0x73, 0x48, 0x00, 0x52, 0x05, 0x63, + 0x68, 0x69, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x70, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x35, 0x0a, 0x0c, 0x61, 0x70, 0x70, 0x5f, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x48, 0x00, 0x52, 0x0b, 0x61, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x2f, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x5f, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x20, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, + 0x73, 0x69, 0x70, 0x48, 0x00, 0x52, 0x09, 0x61, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x2c, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x08, 0x61, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x69, 0x6e, - 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, - 0x6e, 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, - 0x74, 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x22, 0x43, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, - 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, - 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, - 0x65, 0x74, 0x5f, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, - 0x69, 0x6d, 0x65, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x22, 0xe8, 0x02, 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, - 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x06, 0x6d, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, - 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x79, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x6d, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x70, 0x5f, - 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0d, 0x69, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, - 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, - 0x73, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, - 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, - 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, - 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, - 0x63, 0x70, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, - 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x22, 0x5e, 0x0a, - 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, - 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, - 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0xbd, 0x01, - 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, - 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, - 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, - 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x48, 0x0a, - 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, - 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, - 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, - 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x07, 0x50, 0x65, 0x65, 0x72, 0x41, - 0x63, 0x6b, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3e, 0x0a, 0x0b, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, - 0x74, 0x41, 0x63, 0x6b, 0x12, 0x29, 0x0a, 0x09, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x6b, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x65, - 0x65, 0x72, 0x41, 0x63, 0x6b, 0x52, 0x08, 0x70, 0x65, 0x65, 0x72, 0x41, 0x63, 0x6b, 0x73, 0x4a, - 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4a, 0x04, 0x08, 0x21, 0x10, 0x22, 0x4a, + 0x04, 0x08, 0x24, 0x10, 0x25, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, + 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, + 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, + 0x52, 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, + 0x43, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, + 0x1b, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x08, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, + 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x22, 0x58, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, + 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x5f, 0x75, + 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, + 0x0d, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x22, 0x9b, + 0x03, 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, + 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x79, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, + 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, + 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x79, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x79, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x70, 0x5f, 0x73, 0x69, 0x67, 0x6e, + 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, + 0x69, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x73, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x12, + 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, + 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, + 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, + 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, + 0x0a, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x41, 0x63, 0x70, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x31, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x22, 0x5e, 0x0a, 0x06, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, + 0x6a, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, + 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x39, 0x0a, 0x0b, + 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, + 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, + 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, + 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, + 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x40, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x65, + 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, + 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, + 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, + 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, + 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, + 0x72, 0x74, 0x73, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, - 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, - 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, - 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, + 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, + 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, + 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, + 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x30, 0x0a, + 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, + 0x75, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, + 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, + 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, - 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, - 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x75, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, - 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, + 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x22, 0x6f, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, + 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, + 0x08, 0x04, 0x10, 0x05, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x64, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, + 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb0, 0x01, + 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, + 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, - 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x64, 0x73, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, - 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x6f, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, - 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, - 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, - 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, + 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, + 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x6b, 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, + 0x70, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, + 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, - 0xb0, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, - 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, - 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, - 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, - 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, - 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, - 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, - 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, - 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, - 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, - 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, + 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, + 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, + 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, + 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, + 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, + 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, + 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, - 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, - 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, - 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, - 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, - 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, - 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, - 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, - 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, - 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, + 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, + 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, + 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, + 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, + 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, + 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2985,10 +3001,10 @@ var file_p2p_p2p_proto_goTypes = []interface{}{ (*Pong)(nil), // 4: p2p.Pong (*Handshake)(nil), // 5: p2p.Handshake (*Client)(nil), // 6: p2p.Client - (*ClaimedIpPort)(nil), // 7: p2p.ClaimedIpPort - (*PeerList)(nil), // 8: p2p.PeerList - (*PeerAck)(nil), // 9: p2p.PeerAck - (*PeerListAck)(nil), // 10: p2p.PeerListAck + (*BloomFilter)(nil), // 7: p2p.BloomFilter + (*ClaimedIpPort)(nil), // 8: p2p.ClaimedIpPort + (*GetPeerList)(nil), // 9: p2p.GetPeerList + (*PeerList)(nil), // 10: p2p.PeerList (*GetStateSummaryFrontier)(nil), // 11: p2p.GetStateSummaryFrontier (*StateSummaryFrontier)(nil), // 12: p2p.StateSummaryFrontier (*GetAcceptedStateSummary)(nil), // 13: p2p.GetAcceptedStateSummary @@ -3013,44 +3029,45 @@ var file_p2p_p2p_proto_depIdxs = []int32{ 2, // 0: p2p.Message.ping:type_name -> p2p.Ping 4, // 1: p2p.Message.pong:type_name -> p2p.Pong 5, // 2: p2p.Message.handshake:type_name -> p2p.Handshake - 8, // 3: p2p.Message.peer_list:type_name -> p2p.PeerList - 11, // 4: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier - 12, // 5: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier - 13, // 6: p2p.Message.get_accepted_state_summary:type_name -> p2p.GetAcceptedStateSummary - 14, // 7: p2p.Message.accepted_state_summary:type_name -> p2p.AcceptedStateSummary - 15, // 8: p2p.Message.get_accepted_frontier:type_name -> p2p.GetAcceptedFrontier - 16, // 9: p2p.Message.accepted_frontier:type_name -> p2p.AcceptedFrontier - 17, // 10: p2p.Message.get_accepted:type_name -> p2p.GetAccepted - 18, // 11: p2p.Message.accepted:type_name -> p2p.Accepted - 19, // 12: p2p.Message.get_ancestors:type_name -> p2p.GetAncestors - 20, // 13: p2p.Message.ancestors:type_name -> p2p.Ancestors - 21, // 14: p2p.Message.get:type_name -> p2p.Get - 22, // 15: p2p.Message.put:type_name -> p2p.Put - 23, // 16: p2p.Message.push_query:type_name -> p2p.PushQuery - 24, // 17: p2p.Message.pull_query:type_name -> p2p.PullQuery - 25, // 18: p2p.Message.chits:type_name -> p2p.Chits - 26, // 19: p2p.Message.app_request:type_name -> p2p.AppRequest - 27, // 20: p2p.Message.app_response:type_name -> p2p.AppResponse - 29, // 21: p2p.Message.app_gossip:type_name -> p2p.AppGossip - 10, // 22: p2p.Message.peer_list_ack:type_name -> p2p.PeerListAck + 9, // 3: p2p.Message.get_peer_list:type_name -> p2p.GetPeerList + 10, // 4: p2p.Message.peer_list:type_name -> p2p.PeerList + 11, // 5: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier + 12, // 6: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier + 13, // 7: p2p.Message.get_accepted_state_summary:type_name -> p2p.GetAcceptedStateSummary + 14, // 8: p2p.Message.accepted_state_summary:type_name -> p2p.AcceptedStateSummary + 15, // 9: p2p.Message.get_accepted_frontier:type_name -> p2p.GetAcceptedFrontier + 16, // 10: p2p.Message.accepted_frontier:type_name -> p2p.AcceptedFrontier + 17, // 11: p2p.Message.get_accepted:type_name -> p2p.GetAccepted + 18, // 12: p2p.Message.accepted:type_name -> p2p.Accepted + 19, // 13: p2p.Message.get_ancestors:type_name -> p2p.GetAncestors + 20, // 14: p2p.Message.ancestors:type_name -> p2p.Ancestors + 21, // 15: p2p.Message.get:type_name -> p2p.Get + 22, // 16: p2p.Message.put:type_name -> p2p.Put + 23, // 17: p2p.Message.push_query:type_name -> p2p.PushQuery + 24, // 18: p2p.Message.pull_query:type_name -> p2p.PullQuery + 25, // 19: p2p.Message.chits:type_name -> p2p.Chits + 26, // 20: p2p.Message.app_request:type_name -> p2p.AppRequest + 27, // 21: p2p.Message.app_response:type_name -> p2p.AppResponse + 29, // 22: p2p.Message.app_gossip:type_name -> p2p.AppGossip 28, // 23: p2p.Message.app_error:type_name -> p2p.AppError 3, // 24: p2p.Ping.subnet_uptimes:type_name -> p2p.SubnetUptime 3, // 25: p2p.Pong.subnet_uptimes:type_name -> p2p.SubnetUptime 6, // 26: p2p.Handshake.client:type_name -> p2p.Client - 7, // 27: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort - 9, // 28: p2p.PeerListAck.peer_acks:type_name -> p2p.PeerAck - 0, // 29: p2p.GetAcceptedFrontier.engine_type:type_name -> p2p.EngineType - 0, // 30: p2p.GetAccepted.engine_type:type_name -> p2p.EngineType - 0, // 31: p2p.GetAncestors.engine_type:type_name -> p2p.EngineType - 0, // 32: p2p.Get.engine_type:type_name -> p2p.EngineType - 0, // 33: p2p.Put.engine_type:type_name -> p2p.EngineType - 0, // 34: p2p.PushQuery.engine_type:type_name -> p2p.EngineType - 0, // 35: p2p.PullQuery.engine_type:type_name -> p2p.EngineType - 36, // [36:36] is the sub-list for method output_type - 36, // [36:36] is the sub-list for method input_type - 36, // [36:36] is the sub-list for extension type_name - 36, // [36:36] is the sub-list for extension extendee - 0, // [0:36] is the sub-list for field type_name + 7, // 27: p2p.Handshake.known_peers:type_name -> p2p.BloomFilter + 7, // 28: p2p.GetPeerList.known_peers:type_name -> p2p.BloomFilter + 8, // 29: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort + 0, // 30: p2p.GetAcceptedFrontier.engine_type:type_name -> p2p.EngineType + 0, // 31: p2p.GetAccepted.engine_type:type_name -> p2p.EngineType + 0, // 32: p2p.GetAncestors.engine_type:type_name -> p2p.EngineType + 0, // 33: p2p.Get.engine_type:type_name -> p2p.EngineType + 0, // 34: p2p.Put.engine_type:type_name -> p2p.EngineType + 0, // 35: p2p.PushQuery.engine_type:type_name -> p2p.EngineType + 0, // 36: p2p.PullQuery.engine_type:type_name -> p2p.EngineType + 37, // [37:37] is the sub-list for method output_type + 37, // [37:37] is the sub-list for method input_type + 37, // [37:37] is the sub-list for extension type_name + 37, // [37:37] is the sub-list for extension extendee + 0, // [0:37] is the sub-list for field type_name } func init() { file_p2p_p2p_proto_init() } @@ -3132,7 +3149,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClaimedIpPort); i { + switch v := v.(*BloomFilter); i { case 0: return &v.state case 1: @@ -3144,7 +3161,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerList); i { + switch v := v.(*ClaimedIpPort); i { case 0: return &v.state case 1: @@ -3156,7 +3173,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerAck); i { + switch v := v.(*GetPeerList); i { case 0: return &v.state case 1: @@ -3168,7 +3185,7 @@ func file_p2p_p2p_proto_init() { } } file_p2p_p2p_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PeerListAck); i { + switch v := v.(*PeerList); i { case 0: return &v.state case 1: @@ -3414,7 +3431,8 @@ func file_p2p_p2p_proto_init() { (*Message_Ping)(nil), (*Message_Pong)(nil), (*Message_Handshake)(nil), - (*Message_PeerList)(nil), + (*Message_GetPeerList)(nil), + (*Message_PeerList_)(nil), (*Message_GetStateSummaryFrontier)(nil), (*Message_StateSummaryFrontier_)(nil), (*Message_GetAcceptedStateSummary)(nil), @@ -3433,7 +3451,6 @@ func file_p2p_p2p_proto_init() { (*Message_AppRequest)(nil), (*Message_AppResponse)(nil), (*Message_AppGossip)(nil), - (*Message_PeerListAck)(nil), (*Message_AppError)(nil), } type x struct{} diff --git a/utils/bloom/read_filter.go b/utils/bloom/read_filter.go index 8c32e143b1c4..075d77ed7a38 100644 --- a/utils/bloom/read_filter.go +++ b/utils/bloom/read_filter.go @@ -8,6 +8,23 @@ import ( "fmt" ) +var ( + EmptyFilter = &ReadFilter{ + hashSeeds: make([]uint64, minHashes), + entries: make([]byte, minEntries), + } + FullFilter = &ReadFilter{ + hashSeeds: make([]uint64, minHashes), + entries: make([]byte, minEntries), + } +) + +func init() { + for i := range FullFilter.entries { + FullFilter.entries[i] = 0xFF + } +} + type ReadFilter struct { hashSeeds []uint64 entries []byte diff --git a/utils/constants/networking.go b/utils/constants/networking.go index 8d60d27af58a..7a4ea89b8241 100644 --- a/utils/constants/networking.go +++ b/utils/constants/networking.go @@ -32,6 +32,8 @@ const ( DefaultNetworkPeerListNonValidatorGossipSize = 0 DefaultNetworkPeerListPeersGossipSize = 10 DefaultNetworkPeerListGossipFreq = time.Minute + DefaultNetworkPeerListPullGossipFreq = 2 * time.Second + DefaultNetworkPeerListBloomResetFreq = time.Minute // Inbound Connection Throttling DefaultInboundConnUpgradeThrottlerCooldown = 10 * time.Second diff --git a/utils/ips/claimed_ip_port.go b/utils/ips/claimed_ip_port.go index 76920f31559d..2ef6c0a71087 100644 --- a/utils/ips/claimed_ip_port.go +++ b/utils/ips/claimed_ip_port.go @@ -6,16 +6,14 @@ package ips import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/wrappers" ) -// Can't import these from wrappers package due to circular import. const ( - intLen = 4 - longLen = 8 - ipLen = 18 - idLen = 32 // Certificate length, signature length, IP, timestamp, tx ID - baseIPCertDescLen = 2*intLen + ipLen + longLen + idLen + baseIPCertDescLen = 2*wrappers.IntLen + IPPortLen + wrappers.LongLen + ids.IDLen + preimageLen = ids.IDLen + wrappers.LongLen ) // A self contained proof that a peer is claiming ownership of an IPPort at a @@ -32,12 +30,36 @@ type ClaimedIPPort struct { // actually claimed by the peer in question, and not by a malicious peer // trying to get us to dial bogus IPPorts. Signature []byte - // The txID that added this peer into the validator set - TxID ids.ID + // NodeID derived from the peer certificate. + NodeID ids.NodeID + // GossipID derived from the nodeID and timestamp. + GossipID ids.ID } -// Returns the length of the byte representation of this ClaimedIPPort. -func (i *ClaimedIPPort) BytesLen() int { - // See wrappers.PackPeerTrackInfo. +func NewClaimedIPPort( + cert *staking.Certificate, + ipPort IPPort, + timestamp uint64, + signature []byte, +) *ClaimedIPPort { + ip := &ClaimedIPPort{ + Cert: cert, + IPPort: ipPort, + Timestamp: timestamp, + Signature: signature, + NodeID: ids.NodeIDFromCert(cert), + } + + packer := wrappers.Packer{ + Bytes: make([]byte, preimageLen), + } + packer.PackFixedBytes(ip.NodeID[:]) + packer.PackLong(timestamp) + ip.GossipID = hashing.ComputeHash256Array(packer.Bytes) + return ip +} + +// Returns the approximate size of the binary representation of this ClaimedIPPort. +func (i *ClaimedIPPort) Size() int { return baseIPCertDescLen + len(i.Cert.Raw) + len(i.Signature) } diff --git a/utils/ips/ip_port.go b/utils/ips/ip_port.go index 661747cb9cbe..a60e6300ed49 100644 --- a/utils/ips/ip_port.go +++ b/utils/ips/ip_port.go @@ -12,7 +12,10 @@ import ( "github.com/ava-labs/avalanchego/utils/wrappers" ) -const nullStr = "null" +const ( + IPPortLen = 16 + wrappers.ShortLen + nullStr = "null" +) var ( errMissingQuotes = errors.New("first and last characters should be quotes") From dc48be8c89252e09136c1b21914b9d16dc67f253 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 15 Jan 2024 11:43:21 -0500 Subject: [PATCH 246/267] Log critical consensus values during health checks (#2609) --- snow/engine/common/request.go | 10 +++++++- snow/engine/common/request_test.go | 24 +++++++++++++++++ snow/engine/snowman/transitive.go | 9 +++++++ utils/bimap/bimap.go | 41 +++++++++++++++++++++++++++++- utils/bimap/bimap_test.go | 28 ++++++++++++++++++++ 5 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 snow/engine/common/request_test.go diff --git a/snow/engine/common/request.go b/snow/engine/common/request.go index f9cccb3b0d29..f92e347cc73b 100644 --- a/snow/engine/common/request.go +++ b/snow/engine/common/request.go @@ -3,9 +3,17 @@ package common -import "github.com/ava-labs/avalanchego/ids" +import ( + "fmt" + + "github.com/ava-labs/avalanchego/ids" +) type Request struct { NodeID ids.NodeID RequestID uint32 } + +func (r Request) MarshalText() ([]byte, error) { + return []byte(fmt.Sprintf("%s:%d", r.NodeID, r.RequestID)), nil +} diff --git a/snow/engine/common/request_test.go b/snow/engine/common/request_test.go new file mode 100644 index 000000000000..0da4c8c438f7 --- /dev/null +++ b/snow/engine/common/request_test.go @@ -0,0 +1,24 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package common + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" +) + +func TestRequestJSONMarshal(t *testing.T) { + requestMap := map[Request]ids.ID{ + { + NodeID: ids.GenerateTestNodeID(), + RequestID: 12345, + }: ids.GenerateTestID(), + } + _, err := json.Marshal(requestMap) + require.NoError(t, err) +} diff --git a/snow/engine/snowman/transitive.go b/snow/engine/snowman/transitive.go index 34954885a66d..bf76970b5295 100644 --- a/snow/engine/snowman/transitive.go +++ b/snow/engine/snowman/transitive.go @@ -556,6 +556,15 @@ func (t *Transitive) HealthCheck(ctx context.Context) (interface{}, error) { t.Ctx.Lock.Lock() defer t.Ctx.Lock.Unlock() + t.Ctx.Log.Verbo("running health check", + zap.Uint32("requestID", t.requestID), + zap.Int("gossipCounter", t.gossipCounter), + zap.Stringer("polls", t.polls), + zap.Reflect("outstandingBlockRequests", t.blkReqs), + zap.Stringer("blockedJobs", &t.blocked), + zap.Int("pendingBuildBlocks", t.pendingBuildBlocks), + ) + consensusIntf, consensusErr := t.Consensus.HealthCheck(ctx) vmIntf, vmErr := t.VM.HealthCheck(ctx) intf := map[string]interface{}{ diff --git a/utils/bimap/bimap.go b/utils/bimap/bimap.go index c44ff0ff60a9..d0651ff36cd2 100644 --- a/utils/bimap/bimap.go +++ b/utils/bimap/bimap.go @@ -3,7 +3,21 @@ package bimap -import "github.com/ava-labs/avalanchego/utils" +import ( + "bytes" + "encoding/json" + "errors" + + "github.com/ava-labs/avalanchego/utils" +) + +var ( + _ json.Marshaler = (*BiMap[int, int])(nil) + _ json.Unmarshaler = (*BiMap[int, int])(nil) + + nullBytes = []byte("null") + errNotBijective = errors.New("map not bijective") +) type Entry[K, V any] struct { Key K @@ -100,3 +114,28 @@ func (m *BiMap[K, V]) DeleteValue(val V) (K, bool) { func (m *BiMap[K, V]) Len() int { return len(m.keyToValue) } + +func (m *BiMap[K, V]) MarshalJSON() ([]byte, error) { + return json.Marshal(m.keyToValue) +} + +func (m *BiMap[K, V]) UnmarshalJSON(b []byte) error { + if bytes.Equal(b, nullBytes) { + return nil + } + var keyToValue map[K]V + if err := json.Unmarshal(b, &keyToValue); err != nil { + return err + } + valueToKey := make(map[V]K, len(keyToValue)) + for k, v := range keyToValue { + valueToKey[v] = k + } + if len(keyToValue) != len(valueToKey) { + return errNotBijective + } + + m.keyToValue = keyToValue + m.valueToKey = valueToKey + return nil +} diff --git a/utils/bimap/bimap_test.go b/utils/bimap/bimap_test.go index dffa80dc008d..9b4433a51c70 100644 --- a/utils/bimap/bimap_test.go +++ b/utils/bimap/bimap_test.go @@ -4,6 +4,7 @@ package bimap import ( + "encoding/json" "testing" "github.com/stretchr/testify/require" @@ -326,3 +327,30 @@ func TestBiMapLen(t *testing.T) { m.DeleteKey(1) require.Zero(m.Len()) } + +func TestBiMapJSON(t *testing.T) { + require := require.New(t) + + expectedMap := New[int, int]() + expectedMap.Put(1, 2) + expectedMap.Put(2, 3) + + jsonBytes, err := json.Marshal(expectedMap) + require.NoError(err) + + expectedJSONBytes := []byte(`{"1":2,"2":3}`) + require.Equal(expectedJSONBytes, jsonBytes) + + var unmarshalledMap BiMap[int, int] + require.NoError(json.Unmarshal(jsonBytes, &unmarshalledMap)) + require.Equal(expectedMap, &unmarshalledMap) +} + +func TestBiMapInvalidJSON(t *testing.T) { + require := require.New(t) + + invalidJSONBytes := []byte(`{"1":2,"2":2}`) + var unmarshalledMap BiMap[int, int] + err := json.Unmarshal(invalidJSONBytes, &unmarshalledMap) + require.ErrorIs(err, errNotBijective) +} From 226cd2149b2bbfc38f34e0831e6127eac170f276 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Mon, 15 Jan 2024 17:08:37 -0500 Subject: [PATCH 247/267] Update contributions branch to master (#2610) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index affb43575fca..2e850274d96f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,7 @@ To start developing on AvalancheGo, you'll need a few things installed. - Open a new GitHub pull request containing your changes. - Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. -- The PR should be opened against the `dev` branch. +- The PR should be opened against the `master` branch. - If your PR isn't ready to be reviewed just yet, you can open it as a draft to collect early feedback on your changes. - Once the PR is ready for review, mark it as ready-for-review and request review from one of the maintainers. From 003ed7fbc9b1e959990c1f4f0e2dbdcc32e0e8f3 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 16 Jan 2024 09:55:43 -0500 Subject: [PATCH 248/267] Add ip bloom metrics (#2614) --- network/ip_tracker.go | 79 ++++++++++++++++++++++++++++++++++++-- network/ip_tracker_test.go | 23 ++++++++++- network/network.go | 2 +- 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/network/ip_tracker.go b/network/ip_tracker.go index 7bc6cb293810..eb8dcddb6e76 100644 --- a/network/ip_tracker.go +++ b/network/ip_tracker.go @@ -7,12 +7,15 @@ import ( "crypto/rand" "sync" + "github.com/prometheus/client_golang/prometheus" + "go.uber.org/zap" "golang.org/x/exp/maps" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/bloom" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/ips" @@ -34,19 +37,77 @@ const ( var _ validators.SetCallbackListener = (*ipTracker)(nil) -func newIPTracker(log logging.Logger) (*ipTracker, error) { +func newIPTracker( + log logging.Logger, + namespace string, + registerer prometheus.Registerer, +) (*ipTracker, error) { tracker := &ipTracker{ - log: log, + log: log, + numValidatorIPs: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "validator_ips", + Help: "Number of known validator IPs", + }), + numGossipable: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "gossipable_ips", + Help: "Number of IPs this node is willing to gossip", + }), + bloomCount: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "ip_bloom_count", + Help: "Number of IP entries added to the bloom", + }), + bloomNumHashes: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "ip_bloom_hashes", + Help: "Number of hashes in the IP bloom", + }), + bloomNumEntries: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "ip_bloom_entries", + Help: "Number of entry slots in the IP bloom", + }), + bloomMaxCount: prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: namespace, + Name: "ip_bloom_max_count", + Help: "Maximum number of IP entries that can be added to the bloom before resetting", + }), + bloomResetCount: prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Name: "ip_bloom_reset_count", + Help: "Number times the IP bloom has been reset", + }), connected: make(map[ids.NodeID]*ips.ClaimedIPPort), mostRecentValidatorIPs: make(map[ids.NodeID]*ips.ClaimedIPPort), gossipableIndicies: make(map[ids.NodeID]int), bloomAdditions: make(map[ids.NodeID]int), } + err := utils.Err( + registerer.Register(tracker.numValidatorIPs), + registerer.Register(tracker.numGossipable), + registerer.Register(tracker.bloomCount), + registerer.Register(tracker.bloomNumHashes), + registerer.Register(tracker.bloomNumEntries), + registerer.Register(tracker.bloomMaxCount), + registerer.Register(tracker.bloomResetCount), + ) + if err != nil { + return nil, err + } return tracker, tracker.resetBloom() } type ipTracker struct { - log logging.Logger + log logging.Logger + numValidatorIPs prometheus.Gauge + numGossipable prometheus.Gauge + bloomCount prometheus.Gauge + bloomNumHashes prometheus.Gauge + bloomNumEntries prometheus.Gauge + bloomMaxCount prometheus.Gauge + bloomResetCount prometheus.Counter lock sync.RWMutex // Manually tracked nodes are always treated like validators @@ -220,12 +281,16 @@ func (i *ipTracker) OnValidatorRemoved(nodeID ids.NodeID, _ uint64) { } delete(i.mostRecentValidatorIPs, nodeID) + i.numValidatorIPs.Set(float64(len(i.mostRecentValidatorIPs))) + i.validators.Remove(nodeID) i.removeGossipableIP(nodeID) } func (i *ipTracker) updateMostRecentValidatorIP(ip *ips.ClaimedIPPort) { i.mostRecentValidatorIPs[ip.NodeID] = ip + i.numValidatorIPs.Set(float64(len(i.mostRecentValidatorIPs))) + oldCount := i.bloomAdditions[ip.NodeID] if oldCount >= maxIPEntriesPerValidator { return @@ -250,11 +315,13 @@ func (i *ipTracker) updateMostRecentValidatorIP(ip *ips.ClaimedIPPort) { i.bloomAdditions[ip.NodeID] = oldCount + 1 bloom.Add(i.bloom, ip.GossipID[:], i.bloomSalt) + i.bloomCount.Inc() } func (i *ipTracker) addGossipableIP(ip *ips.ClaimedIPPort) { i.gossipableIndicies[ip.NodeID] = len(i.gossipableIPs) i.gossipableIPs = append(i.gossipableIPs, ip) + i.numGossipable.Inc() } func (i *ipTracker) removeGossipableIP(nodeID ids.NodeID) { @@ -273,6 +340,7 @@ func (i *ipTracker) removeGossipableIP(nodeID ids.NodeID) { delete(i.gossipableIndicies, nodeID) i.gossipableIPs[newNumGossipable] = nil i.gossipableIPs = i.gossipableIPs[:newNumGossipable] + i.numGossipable.Dec() } // GetGossipableIPs returns the latest IPs of connected validators. The returned @@ -360,5 +428,10 @@ func (i *ipTracker) resetBloom() error { bloom.Add(newFilter, ip.GossipID[:], newSalt) i.bloomAdditions[nodeID] = 1 } + i.bloomCount.Set(float64(len(i.mostRecentValidatorIPs))) + i.bloomNumHashes.Set(float64(numHashes)) + i.bloomNumEntries.Set(float64(numEntries)) + i.bloomMaxCount.Set(float64(i.maxBloomCount)) + i.bloomResetCount.Inc() return nil } diff --git a/network/ip_tracker_test.go b/network/ip_tracker_test.go index 882c0a47ce8c..921f2f33d655 100644 --- a/network/ip_tracker_test.go +++ b/network/ip_tracker_test.go @@ -6,6 +6,9 @@ package network import ( "testing" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" @@ -15,7 +18,7 @@ import ( ) func newTestIPTracker(t *testing.T) *ipTracker { - tracker, err := newIPTracker(logging.NoLog{}) + tracker, err := newIPTracker(logging.NoLog{}, "", prometheus.NewRegistry()) require.NoError(t, err) return tracker } @@ -41,6 +44,14 @@ func requireEqual(t *testing.T, expected, actual *ipTracker) { require.Equal(expected.maxBloomCount, actual.maxBloomCount) } +func requireMetricsConsistent(t *testing.T, tracker *ipTracker) { + require := require.New(t) + require.Equal(float64(len(tracker.mostRecentValidatorIPs)), testutil.ToFloat64(tracker.numValidatorIPs)) + require.Equal(float64(len(tracker.gossipableIPs)), testutil.ToFloat64(tracker.numGossipable)) + require.Equal(float64(tracker.bloom.Count()), testutil.ToFloat64(tracker.bloomCount)) + require.Equal(float64(tracker.maxBloomCount), testutil.ToFloat64(tracker.bloomMaxCount)) +} + func TestIPTracker_ManuallyTrack(t *testing.T) { tests := []struct { name string @@ -118,6 +129,7 @@ func TestIPTracker_ManuallyTrack(t *testing.T) { t.Run(test.name, func(t *testing.T) { test.initialState.ManuallyTrack(test.nodeID) requireEqual(t, test.expectedState, test.initialState) + requireMetricsConsistent(t, test.initialState) }) } } @@ -235,6 +247,7 @@ func TestIPTracker_AddIP(t *testing.T) { updated := test.initialState.AddIP(test.ip) require.Equal(t, test.expectedUpdated, updated) requireEqual(t, test.expectedState, test.initialState) + requireMetricsConsistent(t, test.initialState) }) } } @@ -344,6 +357,7 @@ func TestIPTracker_Connected(t *testing.T) { t.Run(test.name, func(t *testing.T) { test.initialState.Connected(test.ip) requireEqual(t, test.expectedState, test.initialState) + requireMetricsConsistent(t, test.initialState) }) } } @@ -416,6 +430,7 @@ func TestIPTracker_Disconnected(t *testing.T) { t.Run(test.name, func(t *testing.T) { test.initialState.Disconnected(test.nodeID) requireEqual(t, test.expectedState, test.initialState) + requireMetricsConsistent(t, test.initialState) }) } } @@ -477,6 +492,7 @@ func TestIPTracker_OnValidatorAdded(t *testing.T) { t.Run(test.name, func(t *testing.T) { test.initialState.OnValidatorAdded(test.nodeID, nil, ids.Empty, 0) requireEqual(t, test.expectedState, test.initialState) + requireMetricsConsistent(t, test.initialState) }) } } @@ -577,6 +593,7 @@ func TestIPTracker_OnValidatorRemoved(t *testing.T) { t.Run(test.name, func(t *testing.T) { test.initialState.OnValidatorRemoved(test.nodeID, 0) requireEqual(t, test.expectedState, test.initialState) + requireMetricsConsistent(t, test.initialState) }) } } @@ -637,9 +654,11 @@ func TestIPTracker_BloomGrowsWithValidatorSet(t *testing.T) { for i := 0; i < 2048; i++ { tracker.onValidatorAdded(ids.GenerateTestNodeID()) } + requireMetricsConsistent(t, tracker) require.NoError(tracker.ResetBloom()) require.Greater(tracker.maxBloomCount, initialMaxBloomCount) + requireMetricsConsistent(t, tracker) } func TestIPTracker_BloomResetsDynamically(t *testing.T) { @@ -652,6 +671,7 @@ func TestIPTracker_BloomResetsDynamically(t *testing.T) { tracker.maxBloomCount = 1 tracker.Connected(otherIP) tracker.onValidatorAdded(otherIP.NodeID) + requireMetricsConsistent(t, tracker) bloomBytes, salt := tracker.Bloom() readFilter, err := bloom.Parse(bloomBytes) @@ -673,6 +693,7 @@ func TestIPTracker_PreventBloomFilterAddition(t *testing.T) { require.True(tracker.AddIP(newerIP)) require.True(tracker.AddIP(newestIP)) require.Equal(maxIPEntriesPerValidator, tracker.bloomAdditions[ip.NodeID]) + requireMetricsConsistent(t, tracker) } func TestIPTracker_ShouldVerifyIP(t *testing.T) { diff --git a/network/network.go b/network/network.go index 374038883ba7..51c2d223829e 100644 --- a/network/network.go +++ b/network/network.go @@ -237,7 +237,7 @@ func NewNetwork( return nil, fmt.Errorf("initializing network metrics failed with: %w", err) } - ipTracker, err := newIPTracker(log) + ipTracker, err := newIPTracker(log, config.Namespace, metricsRegisterer) if err != nil { return nil, fmt.Errorf("initializing ip tracker failed with: %w", err) } From 68986d301a0e7f7b50238ccef8daf54e364cec41 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:33:39 -0500 Subject: [PATCH 249/267] `x/sync`: Auto-generate `MockNetworkClient` (#2617) --- scripts/mocks.mockgen.txt | 1 + x/sync/client_test.go | 3 --- x/sync/mock_network_client.go | 32 ++++++++++---------------------- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index c3bb7d3ffd24..84c44c2966e6 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -42,3 +42,4 @@ github.com/ava-labs/avalanchego/vms/registry=VMRegisterer=vms/registry/mock_vm_r github.com/ava-labs/avalanchego/vms/registry=VMRegistry=vms/registry/mock_vm_registry.go github.com/ava-labs/avalanchego/vms=Factory,Manager=vms/mock_manager.go github.com/ava-labs/avalanchego/x/sync=Client=x/sync/mock_client.go +github.com/ava-labs/avalanchego/x/sync=NetworkClient=x/sync/mock_network_client.go diff --git a/x/sync/client_test.go b/x/sync/client_test.go index e81d1a44010c..d394aa654c14 100644 --- a/x/sync/client_test.go +++ b/x/sync/client_test.go @@ -123,9 +123,6 @@ func sendRangeProofRequest( }, ).AnyTimes() - // Handle bandwidth tracking calls from client. - networkClient.EXPECT().TrackBandwidth(gomock.Any(), gomock.Any()).AnyTimes() - // The server should expect to "send" a response to the client. sender.EXPECT().SendAppResponse( gomock.Any(), // ctx diff --git a/x/sync/mock_network_client.go b/x/sync/mock_network_client.go index 8021a015f062..027b4f549366 100644 --- a/x/sync/mock_network_client.go +++ b/x/sync/mock_network_client.go @@ -1,7 +1,7 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: x/sync/network_client.go +// Source: github.com/ava-labs/avalanchego/x/sync (interfaces: NetworkClient) -// Package mock_sync is a generated GoMock package. +// Package sync is a generated GoMock package. package sync import ( @@ -93,24 +93,24 @@ func (mr *MockNetworkClientMockRecorder) Disconnected(arg0, arg1 interface{}) *g } // Request mocks base method. -func (m *MockNetworkClient) Request(ctx context.Context, nodeID ids.NodeID, request []byte) ([]byte, error) { +func (m *MockNetworkClient) Request(arg0 context.Context, arg1 ids.NodeID, arg2 []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Request", ctx, nodeID, request) + ret := m.ctrl.Call(m, "Request", arg0, arg1, arg2) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Request indicates an expected call of Request. -func (mr *MockNetworkClientMockRecorder) Request(ctx, nodeID, request interface{}) *gomock.Call { +func (mr *MockNetworkClientMockRecorder) Request(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Request", reflect.TypeOf((*MockNetworkClient)(nil).Request), ctx, nodeID, request) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Request", reflect.TypeOf((*MockNetworkClient)(nil).Request), arg0, arg1, arg2) } // RequestAny mocks base method. -func (m *MockNetworkClient) RequestAny(ctx context.Context, minVersion *version.Application, request []byte) (ids.NodeID, []byte, error) { +func (m *MockNetworkClient) RequestAny(arg0 context.Context, arg1 *version.Application, arg2 []byte) (ids.NodeID, []byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RequestAny", ctx, minVersion, request) + ret := m.ctrl.Call(m, "RequestAny", arg0, arg1, arg2) ret0, _ := ret[0].(ids.NodeID) ret1, _ := ret[1].([]byte) ret2, _ := ret[2].(error) @@ -118,19 +118,7 @@ func (m *MockNetworkClient) RequestAny(ctx context.Context, minVersion *version. } // RequestAny indicates an expected call of RequestAny. -func (mr *MockNetworkClientMockRecorder) RequestAny(ctx, minVersion, request interface{}) *gomock.Call { +func (mr *MockNetworkClientMockRecorder) RequestAny(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestAny", reflect.TypeOf((*MockNetworkClient)(nil).RequestAny), ctx, minVersion, request) -} - -// TrackBandwidth mocks base method. -func (m *MockNetworkClient) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "TrackBandwidth", nodeID, bandwidth) -} - -// TrackBandwidth indicates an expected call of TrackBandwidth. -func (mr *MockNetworkClientMockRecorder) TrackBandwidth(nodeID, bandwidth interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TrackBandwidth", reflect.TypeOf((*MockNetworkClient)(nil).TrackBandwidth), nodeID, bandwidth) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestAny", reflect.TypeOf((*MockNetworkClient)(nil).RequestAny), arg0, arg1, arg2) } From fdaee4a6910f0ac078602b642a5d7b4c95c35bf9 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:36:00 -0500 Subject: [PATCH 250/267] Remove CreateStaticHandlers from VM interface (#2589) Signed-off-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --- api/admin/service.go | 2 +- api/admin/service_test.go | 6 +- node/node.go | 15 +- proto/pb/vm/vm.pb.go | 1471 ++++++++++---------- proto/pb/vm/vm_grpc.pb.go | 49 - proto/vm/vm.proto | 11 - scripts/mocks.mockgen.txt | 1 - snow/engine/avalanche/vertex/mock_vm.go | 15 - snow/engine/common/test_vm.go | 15 +- snow/engine/common/vm.go | 17 - snow/engine/snowman/block/mock_chain_vm.go | 15 - tests/e2e/e2e_test.go | 1 - tests/e2e/static-handlers/suites.go | 169 --- utils/constants/aliases.go | 9 +- vms/avm/static_client.go | 36 - vms/avm/static_service_test.go | 103 -- vms/avm/vm.go | 11 - vms/example/xsvm/vm.go | 4 - vms/platformvm/api/static_client.go | 44 - vms/platformvm/vm.go | 13 - vms/registry/mock_vm_registerer.go | 65 - vms/registry/mock_vm_registry.go | 16 - vms/registry/vm_registerer.go | 164 --- vms/registry/vm_registerer_test.go | 436 ------ vms/registry/vm_registry.go | 20 +- vms/registry/vm_registry_test.go | 134 +- vms/rpcchainvm/vm_client.go | 19 - vms/rpcchainvm/vm_server.go | 26 - 28 files changed, 733 insertions(+), 2154 deletions(-) delete mode 100644 tests/e2e/static-handlers/suites.go delete mode 100644 vms/avm/static_client.go delete mode 100644 vms/avm/static_service_test.go delete mode 100644 vms/platformvm/api/static_client.go delete mode 100644 vms/registry/mock_vm_registerer.go delete mode 100644 vms/registry/vm_registerer.go delete mode 100644 vms/registry/vm_registerer_test.go diff --git a/api/admin/service.go b/api/admin/service.go index 5a60193acce8..cf57a28264e7 100644 --- a/api/admin/service.go +++ b/api/admin/service.go @@ -334,7 +334,7 @@ func (a *Admin) LoadVMs(r *http.Request, _ *struct{}, reply *LoadVMsReply) error defer a.lock.Unlock() ctx := r.Context() - loadedVMs, failedVMs, err := a.VMRegistry.ReloadWithReadLock(ctx) + loadedVMs, failedVMs, err := a.VMRegistry.Reload(ctx) if err != nil { return err } diff --git a/api/admin/service_test.go b/api/admin/service_test.go index 2076a5756b0b..ea159c655c63 100644 --- a/api/admin/service_test.go +++ b/api/admin/service_test.go @@ -64,7 +64,7 @@ func TestLoadVMsSuccess(t *testing.T) { id2: alias2[1:], } - resources.mockVMRegistry.EXPECT().ReloadWithReadLock(gomock.Any()).Times(1).Return(newVMs, failedVMs, nil) + resources.mockVMRegistry.EXPECT().Reload(gomock.Any()).Times(1).Return(newVMs, failedVMs, nil) resources.mockVMManager.EXPECT().Aliases(id1).Times(1).Return(alias1, nil) resources.mockVMManager.EXPECT().Aliases(id2).Times(1).Return(alias2, nil) @@ -81,7 +81,7 @@ func TestLoadVMsReloadFails(t *testing.T) { resources := initLoadVMsTest(t) // Reload fails - resources.mockVMRegistry.EXPECT().ReloadWithReadLock(gomock.Any()).Times(1).Return(nil, nil, errTest) + resources.mockVMRegistry.EXPECT().Reload(gomock.Any()).Times(1).Return(nil, nil, errTest) reply := LoadVMsReply{} err := resources.admin.LoadVMs(&http.Request{}, nil, &reply) @@ -103,7 +103,7 @@ func TestLoadVMsGetAliasesFails(t *testing.T) { // every vm is at least aliased to itself. alias1 := []string{id1.String(), "vm1-alias-1", "vm1-alias-2"} - resources.mockVMRegistry.EXPECT().ReloadWithReadLock(gomock.Any()).Times(1).Return(newVMs, failedVMs, nil) + resources.mockVMRegistry.EXPECT().Reload(gomock.Any()).Times(1).Return(newVMs, failedVMs, nil) resources.mockVMManager.EXPECT().Aliases(id1).Times(1).Return(alias1, nil) resources.mockVMManager.EXPECT().Aliases(id2).Times(1).Return(nil, errTest) diff --git a/node/node.go b/node/node.go index 24f5c1711767..1aeaddcf6245 100644 --- a/node/node.go +++ b/node/node.go @@ -1172,13 +1172,6 @@ func (n *Node) initVMs() error { vdrs = validators.NewManager() } - vmRegisterer := registry.NewVMRegisterer(registry.VMRegistererConfig{ - APIServer: n.APIServer, - Log: n.Log, - VMFactoryLog: n.VMFactoryLog, - VMManager: n.VMManager, - }) - durangoTime := version.GetDurangoTime(n.Config.NetworkID) if err := txs.InitCodec(durangoTime); err != nil { return err @@ -1192,7 +1185,7 @@ func (n *Node) initVMs() error { // Register the VMs that Avalanche supports err := utils.Err( - vmRegisterer.Register(context.TODO(), constants.PlatformVMID, &platformvm.Factory{ + n.VMManager.RegisterFactory(context.TODO(), constants.PlatformVMID, &platformvm.Factory{ Config: platformconfig.Config{ Chains: n.chainManager, Validators: vdrs, @@ -1225,14 +1218,14 @@ func (n *Node) initVMs() error { UseCurrentHeight: n.Config.UseCurrentHeight, }, }), - vmRegisterer.Register(context.TODO(), constants.AVMID, &avm.Factory{ + n.VMManager.RegisterFactory(context.TODO(), constants.AVMID, &avm.Factory{ Config: avmconfig.Config{ TxFee: n.Config.TxFee, CreateAssetTxFee: n.Config.CreateAssetTxFee, DurangoTime: durangoTime, }, }), - vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + n.VMManager.RegisterFactory(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), @@ -1253,7 +1246,7 @@ func (n *Node) initVMs() error { CPUTracker: n.resourceManager, RuntimeTracker: n.runtimeManager, }), - VMRegisterer: vmRegisterer, + VMManager: n.VMManager, }) // register any vms that need to be installed as plugins from disk diff --git a/proto/pb/vm/vm.pb.go b/proto/pb/vm/vm.pb.go index f7d48de642d7..7f38e5bbf4a7 100644 --- a/proto/pb/vm/vm.pb.go +++ b/proto/pb/vm/vm.pb.go @@ -232,7 +232,7 @@ func (x StateSummaryAcceptResponse_Mode) Number() protoreflect.EnumNumber { // Deprecated: Use StateSummaryAcceptResponse_Mode.Descriptor instead. func (StateSummaryAcceptResponse_Mode) EnumDescriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{45, 0} + return file_vm_vm_proto_rawDescGZIP(), []int{44, 0} } type InitializeRequest struct { @@ -643,53 +643,6 @@ func (x *CreateHandlersResponse) GetHandlers() []*Handler { return nil } -type CreateStaticHandlersResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Handlers []*Handler `protobuf:"bytes,1,rep,name=handlers,proto3" json:"handlers,omitempty"` -} - -func (x *CreateStaticHandlersResponse) Reset() { - *x = CreateStaticHandlersResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateStaticHandlersResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateStaticHandlersResponse) ProtoMessage() {} - -func (x *CreateStaticHandlersResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateStaticHandlersResponse.ProtoReflect.Descriptor instead. -func (*CreateStaticHandlersResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{5} -} - -func (x *CreateStaticHandlersResponse) GetHandlers() []*Handler { - if x != nil { - return x.Handlers - } - return nil -} - type Handler struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -704,7 +657,7 @@ type Handler struct { func (x *Handler) Reset() { *x = Handler{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[6] + mi := &file_vm_vm_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -717,7 +670,7 @@ func (x *Handler) String() string { func (*Handler) ProtoMessage() {} func (x *Handler) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[6] + mi := &file_vm_vm_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -730,7 +683,7 @@ func (x *Handler) ProtoReflect() protoreflect.Message { // Deprecated: Use Handler.ProtoReflect.Descriptor instead. func (*Handler) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{6} + return file_vm_vm_proto_rawDescGZIP(), []int{5} } func (x *Handler) GetPrefix() string { @@ -758,7 +711,7 @@ type BuildBlockRequest struct { func (x *BuildBlockRequest) Reset() { *x = BuildBlockRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[7] + mi := &file_vm_vm_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -771,7 +724,7 @@ func (x *BuildBlockRequest) String() string { func (*BuildBlockRequest) ProtoMessage() {} func (x *BuildBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[7] + mi := &file_vm_vm_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -784,7 +737,7 @@ func (x *BuildBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BuildBlockRequest.ProtoReflect.Descriptor instead. func (*BuildBlockRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{7} + return file_vm_vm_proto_rawDescGZIP(), []int{6} } func (x *BuildBlockRequest) GetPChainHeight() uint64 { @@ -811,7 +764,7 @@ type BuildBlockResponse struct { func (x *BuildBlockResponse) Reset() { *x = BuildBlockResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[8] + mi := &file_vm_vm_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -824,7 +777,7 @@ func (x *BuildBlockResponse) String() string { func (*BuildBlockResponse) ProtoMessage() {} func (x *BuildBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[8] + mi := &file_vm_vm_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -837,7 +790,7 @@ func (x *BuildBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BuildBlockResponse.ProtoReflect.Descriptor instead. func (*BuildBlockResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{8} + return file_vm_vm_proto_rawDescGZIP(), []int{7} } func (x *BuildBlockResponse) GetId() []byte { @@ -893,7 +846,7 @@ type ParseBlockRequest struct { func (x *ParseBlockRequest) Reset() { *x = ParseBlockRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[9] + mi := &file_vm_vm_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -906,7 +859,7 @@ func (x *ParseBlockRequest) String() string { func (*ParseBlockRequest) ProtoMessage() {} func (x *ParseBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[9] + mi := &file_vm_vm_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -919,7 +872,7 @@ func (x *ParseBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseBlockRequest.ProtoReflect.Descriptor instead. func (*ParseBlockRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{9} + return file_vm_vm_proto_rawDescGZIP(), []int{8} } func (x *ParseBlockRequest) GetBytes() []byte { @@ -945,7 +898,7 @@ type ParseBlockResponse struct { func (x *ParseBlockResponse) Reset() { *x = ParseBlockResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[10] + mi := &file_vm_vm_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -958,7 +911,7 @@ func (x *ParseBlockResponse) String() string { func (*ParseBlockResponse) ProtoMessage() {} func (x *ParseBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[10] + mi := &file_vm_vm_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -971,7 +924,7 @@ func (x *ParseBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseBlockResponse.ProtoReflect.Descriptor instead. func (*ParseBlockResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{10} + return file_vm_vm_proto_rawDescGZIP(), []int{9} } func (x *ParseBlockResponse) GetId() []byte { @@ -1027,7 +980,7 @@ type GetBlockRequest struct { func (x *GetBlockRequest) Reset() { *x = GetBlockRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[11] + mi := &file_vm_vm_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1040,7 +993,7 @@ func (x *GetBlockRequest) String() string { func (*GetBlockRequest) ProtoMessage() {} func (x *GetBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[11] + mi := &file_vm_vm_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1053,7 +1006,7 @@ func (x *GetBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockRequest.ProtoReflect.Descriptor instead. func (*GetBlockRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{11} + return file_vm_vm_proto_rawDescGZIP(), []int{10} } func (x *GetBlockRequest) GetId() []byte { @@ -1081,7 +1034,7 @@ type GetBlockResponse struct { func (x *GetBlockResponse) Reset() { *x = GetBlockResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[12] + mi := &file_vm_vm_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1094,7 +1047,7 @@ func (x *GetBlockResponse) String() string { func (*GetBlockResponse) ProtoMessage() {} func (x *GetBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[12] + mi := &file_vm_vm_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1107,7 +1060,7 @@ func (x *GetBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockResponse.ProtoReflect.Descriptor instead. func (*GetBlockResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{12} + return file_vm_vm_proto_rawDescGZIP(), []int{11} } func (x *GetBlockResponse) GetParentId() []byte { @@ -1170,7 +1123,7 @@ type SetPreferenceRequest struct { func (x *SetPreferenceRequest) Reset() { *x = SetPreferenceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[13] + mi := &file_vm_vm_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1183,7 +1136,7 @@ func (x *SetPreferenceRequest) String() string { func (*SetPreferenceRequest) ProtoMessage() {} func (x *SetPreferenceRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[13] + mi := &file_vm_vm_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1196,7 +1149,7 @@ func (x *SetPreferenceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SetPreferenceRequest.ProtoReflect.Descriptor instead. func (*SetPreferenceRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{13} + return file_vm_vm_proto_rawDescGZIP(), []int{12} } func (x *SetPreferenceRequest) GetId() []byte { @@ -1220,7 +1173,7 @@ type BlockVerifyRequest struct { func (x *BlockVerifyRequest) Reset() { *x = BlockVerifyRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[14] + mi := &file_vm_vm_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1233,7 +1186,7 @@ func (x *BlockVerifyRequest) String() string { func (*BlockVerifyRequest) ProtoMessage() {} func (x *BlockVerifyRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[14] + mi := &file_vm_vm_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1246,7 +1199,7 @@ func (x *BlockVerifyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockVerifyRequest.ProtoReflect.Descriptor instead. func (*BlockVerifyRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{14} + return file_vm_vm_proto_rawDescGZIP(), []int{13} } func (x *BlockVerifyRequest) GetBytes() []byte { @@ -1274,7 +1227,7 @@ type BlockVerifyResponse struct { func (x *BlockVerifyResponse) Reset() { *x = BlockVerifyResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[15] + mi := &file_vm_vm_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1287,7 +1240,7 @@ func (x *BlockVerifyResponse) String() string { func (*BlockVerifyResponse) ProtoMessage() {} func (x *BlockVerifyResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[15] + mi := &file_vm_vm_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1300,7 +1253,7 @@ func (x *BlockVerifyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockVerifyResponse.ProtoReflect.Descriptor instead. func (*BlockVerifyResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{15} + return file_vm_vm_proto_rawDescGZIP(), []int{14} } func (x *BlockVerifyResponse) GetTimestamp() *timestamppb.Timestamp { @@ -1321,7 +1274,7 @@ type BlockAcceptRequest struct { func (x *BlockAcceptRequest) Reset() { *x = BlockAcceptRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[16] + mi := &file_vm_vm_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1334,7 +1287,7 @@ func (x *BlockAcceptRequest) String() string { func (*BlockAcceptRequest) ProtoMessage() {} func (x *BlockAcceptRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[16] + mi := &file_vm_vm_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1347,7 +1300,7 @@ func (x *BlockAcceptRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockAcceptRequest.ProtoReflect.Descriptor instead. func (*BlockAcceptRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{16} + return file_vm_vm_proto_rawDescGZIP(), []int{15} } func (x *BlockAcceptRequest) GetId() []byte { @@ -1368,7 +1321,7 @@ type BlockRejectRequest struct { func (x *BlockRejectRequest) Reset() { *x = BlockRejectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[17] + mi := &file_vm_vm_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1381,7 +1334,7 @@ func (x *BlockRejectRequest) String() string { func (*BlockRejectRequest) ProtoMessage() {} func (x *BlockRejectRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[17] + mi := &file_vm_vm_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1394,7 +1347,7 @@ func (x *BlockRejectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BlockRejectRequest.ProtoReflect.Descriptor instead. func (*BlockRejectRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{17} + return file_vm_vm_proto_rawDescGZIP(), []int{16} } func (x *BlockRejectRequest) GetId() []byte { @@ -1415,7 +1368,7 @@ type HealthResponse struct { func (x *HealthResponse) Reset() { *x = HealthResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[18] + mi := &file_vm_vm_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1428,7 +1381,7 @@ func (x *HealthResponse) String() string { func (*HealthResponse) ProtoMessage() {} func (x *HealthResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[18] + mi := &file_vm_vm_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1441,7 +1394,7 @@ func (x *HealthResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use HealthResponse.ProtoReflect.Descriptor instead. func (*HealthResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{18} + return file_vm_vm_proto_rawDescGZIP(), []int{17} } func (x *HealthResponse) GetDetails() []byte { @@ -1462,7 +1415,7 @@ type VersionResponse struct { func (x *VersionResponse) Reset() { *x = VersionResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[19] + mi := &file_vm_vm_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1475,7 +1428,7 @@ func (x *VersionResponse) String() string { func (*VersionResponse) ProtoMessage() {} func (x *VersionResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[19] + mi := &file_vm_vm_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1488,7 +1441,7 @@ func (x *VersionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead. func (*VersionResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{19} + return file_vm_vm_proto_rawDescGZIP(), []int{18} } func (x *VersionResponse) GetVersion() string { @@ -1516,7 +1469,7 @@ type AppRequestMsg struct { func (x *AppRequestMsg) Reset() { *x = AppRequestMsg{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[20] + mi := &file_vm_vm_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1529,7 +1482,7 @@ func (x *AppRequestMsg) String() string { func (*AppRequestMsg) ProtoMessage() {} func (x *AppRequestMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[20] + mi := &file_vm_vm_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1542,7 +1495,7 @@ func (x *AppRequestMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use AppRequestMsg.ProtoReflect.Descriptor instead. func (*AppRequestMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{20} + return file_vm_vm_proto_rawDescGZIP(), []int{19} } func (x *AppRequestMsg) GetNodeId() []byte { @@ -1591,7 +1544,7 @@ type AppRequestFailedMsg struct { func (x *AppRequestFailedMsg) Reset() { *x = AppRequestFailedMsg{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[21] + mi := &file_vm_vm_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1604,7 +1557,7 @@ func (x *AppRequestFailedMsg) String() string { func (*AppRequestFailedMsg) ProtoMessage() {} func (x *AppRequestFailedMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[21] + mi := &file_vm_vm_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1617,7 +1570,7 @@ func (x *AppRequestFailedMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use AppRequestFailedMsg.ProtoReflect.Descriptor instead. func (*AppRequestFailedMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{21} + return file_vm_vm_proto_rawDescGZIP(), []int{20} } func (x *AppRequestFailedMsg) GetNodeId() []byte { @@ -1664,7 +1617,7 @@ type AppResponseMsg struct { func (x *AppResponseMsg) Reset() { *x = AppResponseMsg{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[22] + mi := &file_vm_vm_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1677,7 +1630,7 @@ func (x *AppResponseMsg) String() string { func (*AppResponseMsg) ProtoMessage() {} func (x *AppResponseMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[22] + mi := &file_vm_vm_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1690,7 +1643,7 @@ func (x *AppResponseMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use AppResponseMsg.ProtoReflect.Descriptor instead. func (*AppResponseMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{22} + return file_vm_vm_proto_rawDescGZIP(), []int{21} } func (x *AppResponseMsg) GetNodeId() []byte { @@ -1728,7 +1681,7 @@ type AppGossipMsg struct { func (x *AppGossipMsg) Reset() { *x = AppGossipMsg{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[23] + mi := &file_vm_vm_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1741,7 +1694,7 @@ func (x *AppGossipMsg) String() string { func (*AppGossipMsg) ProtoMessage() {} func (x *AppGossipMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[23] + mi := &file_vm_vm_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1754,7 +1707,7 @@ func (x *AppGossipMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use AppGossipMsg.ProtoReflect.Descriptor instead. func (*AppGossipMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{23} + return file_vm_vm_proto_rawDescGZIP(), []int{22} } func (x *AppGossipMsg) GetNodeId() []byte { @@ -1789,7 +1742,7 @@ type CrossChainAppRequestMsg struct { func (x *CrossChainAppRequestMsg) Reset() { *x = CrossChainAppRequestMsg{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[24] + mi := &file_vm_vm_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1802,7 +1755,7 @@ func (x *CrossChainAppRequestMsg) String() string { func (*CrossChainAppRequestMsg) ProtoMessage() {} func (x *CrossChainAppRequestMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[24] + mi := &file_vm_vm_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1815,7 +1768,7 @@ func (x *CrossChainAppRequestMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use CrossChainAppRequestMsg.ProtoReflect.Descriptor instead. func (*CrossChainAppRequestMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{24} + return file_vm_vm_proto_rawDescGZIP(), []int{23} } func (x *CrossChainAppRequestMsg) GetChainId() []byte { @@ -1864,7 +1817,7 @@ type CrossChainAppRequestFailedMsg struct { func (x *CrossChainAppRequestFailedMsg) Reset() { *x = CrossChainAppRequestFailedMsg{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[25] + mi := &file_vm_vm_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1877,7 +1830,7 @@ func (x *CrossChainAppRequestFailedMsg) String() string { func (*CrossChainAppRequestFailedMsg) ProtoMessage() {} func (x *CrossChainAppRequestFailedMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[25] + mi := &file_vm_vm_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1890,7 +1843,7 @@ func (x *CrossChainAppRequestFailedMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use CrossChainAppRequestFailedMsg.ProtoReflect.Descriptor instead. func (*CrossChainAppRequestFailedMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{25} + return file_vm_vm_proto_rawDescGZIP(), []int{24} } func (x *CrossChainAppRequestFailedMsg) GetChainId() []byte { @@ -1937,7 +1890,7 @@ type CrossChainAppResponseMsg struct { func (x *CrossChainAppResponseMsg) Reset() { *x = CrossChainAppResponseMsg{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[26] + mi := &file_vm_vm_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1950,7 +1903,7 @@ func (x *CrossChainAppResponseMsg) String() string { func (*CrossChainAppResponseMsg) ProtoMessage() {} func (x *CrossChainAppResponseMsg) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[26] + mi := &file_vm_vm_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1963,7 +1916,7 @@ func (x *CrossChainAppResponseMsg) ProtoReflect() protoreflect.Message { // Deprecated: Use CrossChainAppResponseMsg.ProtoReflect.Descriptor instead. func (*CrossChainAppResponseMsg) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{26} + return file_vm_vm_proto_rawDescGZIP(), []int{25} } func (x *CrossChainAppResponseMsg) GetChainId() []byte { @@ -2004,7 +1957,7 @@ type ConnectedRequest struct { func (x *ConnectedRequest) Reset() { *x = ConnectedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[27] + mi := &file_vm_vm_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2017,7 +1970,7 @@ func (x *ConnectedRequest) String() string { func (*ConnectedRequest) ProtoMessage() {} func (x *ConnectedRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[27] + mi := &file_vm_vm_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2030,7 +1983,7 @@ func (x *ConnectedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConnectedRequest.ProtoReflect.Descriptor instead. func (*ConnectedRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{27} + return file_vm_vm_proto_rawDescGZIP(), []int{26} } func (x *ConnectedRequest) GetNodeId() []byte { @@ -2079,7 +2032,7 @@ type DisconnectedRequest struct { func (x *DisconnectedRequest) Reset() { *x = DisconnectedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[28] + mi := &file_vm_vm_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2092,7 +2045,7 @@ func (x *DisconnectedRequest) String() string { func (*DisconnectedRequest) ProtoMessage() {} func (x *DisconnectedRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[28] + mi := &file_vm_vm_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2105,7 +2058,7 @@ func (x *DisconnectedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DisconnectedRequest.ProtoReflect.Descriptor instead. func (*DisconnectedRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{28} + return file_vm_vm_proto_rawDescGZIP(), []int{27} } func (x *DisconnectedRequest) GetNodeId() []byte { @@ -2129,7 +2082,7 @@ type GetAncestorsRequest struct { func (x *GetAncestorsRequest) Reset() { *x = GetAncestorsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[29] + mi := &file_vm_vm_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2142,7 +2095,7 @@ func (x *GetAncestorsRequest) String() string { func (*GetAncestorsRequest) ProtoMessage() {} func (x *GetAncestorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[29] + mi := &file_vm_vm_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2155,7 +2108,7 @@ func (x *GetAncestorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAncestorsRequest.ProtoReflect.Descriptor instead. func (*GetAncestorsRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{29} + return file_vm_vm_proto_rawDescGZIP(), []int{28} } func (x *GetAncestorsRequest) GetBlkId() []byte { @@ -2197,7 +2150,7 @@ type GetAncestorsResponse struct { func (x *GetAncestorsResponse) Reset() { *x = GetAncestorsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[30] + mi := &file_vm_vm_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2210,7 +2163,7 @@ func (x *GetAncestorsResponse) String() string { func (*GetAncestorsResponse) ProtoMessage() {} func (x *GetAncestorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[30] + mi := &file_vm_vm_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2223,7 +2176,7 @@ func (x *GetAncestorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAncestorsResponse.ProtoReflect.Descriptor instead. func (*GetAncestorsResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{30} + return file_vm_vm_proto_rawDescGZIP(), []int{29} } func (x *GetAncestorsResponse) GetBlksBytes() [][]byte { @@ -2244,7 +2197,7 @@ type BatchedParseBlockRequest struct { func (x *BatchedParseBlockRequest) Reset() { *x = BatchedParseBlockRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[31] + mi := &file_vm_vm_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2257,7 +2210,7 @@ func (x *BatchedParseBlockRequest) String() string { func (*BatchedParseBlockRequest) ProtoMessage() {} func (x *BatchedParseBlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[31] + mi := &file_vm_vm_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2270,7 +2223,7 @@ func (x *BatchedParseBlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchedParseBlockRequest.ProtoReflect.Descriptor instead. func (*BatchedParseBlockRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{31} + return file_vm_vm_proto_rawDescGZIP(), []int{30} } func (x *BatchedParseBlockRequest) GetRequest() [][]byte { @@ -2291,7 +2244,7 @@ type BatchedParseBlockResponse struct { func (x *BatchedParseBlockResponse) Reset() { *x = BatchedParseBlockResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[32] + mi := &file_vm_vm_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2304,7 +2257,7 @@ func (x *BatchedParseBlockResponse) String() string { func (*BatchedParseBlockResponse) ProtoMessage() {} func (x *BatchedParseBlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[32] + mi := &file_vm_vm_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2317,7 +2270,7 @@ func (x *BatchedParseBlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BatchedParseBlockResponse.ProtoReflect.Descriptor instead. func (*BatchedParseBlockResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{32} + return file_vm_vm_proto_rawDescGZIP(), []int{31} } func (x *BatchedParseBlockResponse) GetResponse() []*ParseBlockResponse { @@ -2338,7 +2291,7 @@ type VerifyHeightIndexResponse struct { func (x *VerifyHeightIndexResponse) Reset() { *x = VerifyHeightIndexResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[33] + mi := &file_vm_vm_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2351,7 +2304,7 @@ func (x *VerifyHeightIndexResponse) String() string { func (*VerifyHeightIndexResponse) ProtoMessage() {} func (x *VerifyHeightIndexResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[33] + mi := &file_vm_vm_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2364,7 +2317,7 @@ func (x *VerifyHeightIndexResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VerifyHeightIndexResponse.ProtoReflect.Descriptor instead. func (*VerifyHeightIndexResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{33} + return file_vm_vm_proto_rawDescGZIP(), []int{32} } func (x *VerifyHeightIndexResponse) GetErr() Error { @@ -2385,7 +2338,7 @@ type GetBlockIDAtHeightRequest struct { func (x *GetBlockIDAtHeightRequest) Reset() { *x = GetBlockIDAtHeightRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[34] + mi := &file_vm_vm_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2398,7 +2351,7 @@ func (x *GetBlockIDAtHeightRequest) String() string { func (*GetBlockIDAtHeightRequest) ProtoMessage() {} func (x *GetBlockIDAtHeightRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[34] + mi := &file_vm_vm_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2411,7 +2364,7 @@ func (x *GetBlockIDAtHeightRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockIDAtHeightRequest.ProtoReflect.Descriptor instead. func (*GetBlockIDAtHeightRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{34} + return file_vm_vm_proto_rawDescGZIP(), []int{33} } func (x *GetBlockIDAtHeightRequest) GetHeight() uint64 { @@ -2433,7 +2386,7 @@ type GetBlockIDAtHeightResponse struct { func (x *GetBlockIDAtHeightResponse) Reset() { *x = GetBlockIDAtHeightResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[35] + mi := &file_vm_vm_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2446,7 +2399,7 @@ func (x *GetBlockIDAtHeightResponse) String() string { func (*GetBlockIDAtHeightResponse) ProtoMessage() {} func (x *GetBlockIDAtHeightResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[35] + mi := &file_vm_vm_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2459,7 +2412,7 @@ func (x *GetBlockIDAtHeightResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetBlockIDAtHeightResponse.ProtoReflect.Descriptor instead. func (*GetBlockIDAtHeightResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{35} + return file_vm_vm_proto_rawDescGZIP(), []int{34} } func (x *GetBlockIDAtHeightResponse) GetBlkId() []byte { @@ -2487,7 +2440,7 @@ type GatherResponse struct { func (x *GatherResponse) Reset() { *x = GatherResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[36] + mi := &file_vm_vm_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2500,7 +2453,7 @@ func (x *GatherResponse) String() string { func (*GatherResponse) ProtoMessage() {} func (x *GatherResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[36] + mi := &file_vm_vm_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2513,7 +2466,7 @@ func (x *GatherResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GatherResponse.ProtoReflect.Descriptor instead. func (*GatherResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{36} + return file_vm_vm_proto_rawDescGZIP(), []int{35} } func (x *GatherResponse) GetMetricFamilies() []*_go.MetricFamily { @@ -2535,7 +2488,7 @@ type StateSyncEnabledResponse struct { func (x *StateSyncEnabledResponse) Reset() { *x = StateSyncEnabledResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[37] + mi := &file_vm_vm_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2548,7 +2501,7 @@ func (x *StateSyncEnabledResponse) String() string { func (*StateSyncEnabledResponse) ProtoMessage() {} func (x *StateSyncEnabledResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[37] + mi := &file_vm_vm_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2561,7 +2514,7 @@ func (x *StateSyncEnabledResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSyncEnabledResponse.ProtoReflect.Descriptor instead. func (*StateSyncEnabledResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{37} + return file_vm_vm_proto_rawDescGZIP(), []int{36} } func (x *StateSyncEnabledResponse) GetEnabled() bool { @@ -2592,7 +2545,7 @@ type GetOngoingSyncStateSummaryResponse struct { func (x *GetOngoingSyncStateSummaryResponse) Reset() { *x = GetOngoingSyncStateSummaryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[38] + mi := &file_vm_vm_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2605,7 +2558,7 @@ func (x *GetOngoingSyncStateSummaryResponse) String() string { func (*GetOngoingSyncStateSummaryResponse) ProtoMessage() {} func (x *GetOngoingSyncStateSummaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[38] + mi := &file_vm_vm_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2618,7 +2571,7 @@ func (x *GetOngoingSyncStateSummaryResponse) ProtoReflect() protoreflect.Message // Deprecated: Use GetOngoingSyncStateSummaryResponse.ProtoReflect.Descriptor instead. func (*GetOngoingSyncStateSummaryResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{38} + return file_vm_vm_proto_rawDescGZIP(), []int{37} } func (x *GetOngoingSyncStateSummaryResponse) GetId() []byte { @@ -2663,7 +2616,7 @@ type GetLastStateSummaryResponse struct { func (x *GetLastStateSummaryResponse) Reset() { *x = GetLastStateSummaryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[39] + mi := &file_vm_vm_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2676,7 +2629,7 @@ func (x *GetLastStateSummaryResponse) String() string { func (*GetLastStateSummaryResponse) ProtoMessage() {} func (x *GetLastStateSummaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[39] + mi := &file_vm_vm_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2689,7 +2642,7 @@ func (x *GetLastStateSummaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLastStateSummaryResponse.ProtoReflect.Descriptor instead. func (*GetLastStateSummaryResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{39} + return file_vm_vm_proto_rawDescGZIP(), []int{38} } func (x *GetLastStateSummaryResponse) GetId() []byte { @@ -2731,7 +2684,7 @@ type ParseStateSummaryRequest struct { func (x *ParseStateSummaryRequest) Reset() { *x = ParseStateSummaryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[40] + mi := &file_vm_vm_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2744,7 +2697,7 @@ func (x *ParseStateSummaryRequest) String() string { func (*ParseStateSummaryRequest) ProtoMessage() {} func (x *ParseStateSummaryRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[40] + mi := &file_vm_vm_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2757,7 +2710,7 @@ func (x *ParseStateSummaryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseStateSummaryRequest.ProtoReflect.Descriptor instead. func (*ParseStateSummaryRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{40} + return file_vm_vm_proto_rawDescGZIP(), []int{39} } func (x *ParseStateSummaryRequest) GetBytes() []byte { @@ -2780,7 +2733,7 @@ type ParseStateSummaryResponse struct { func (x *ParseStateSummaryResponse) Reset() { *x = ParseStateSummaryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[41] + mi := &file_vm_vm_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2793,7 +2746,7 @@ func (x *ParseStateSummaryResponse) String() string { func (*ParseStateSummaryResponse) ProtoMessage() {} func (x *ParseStateSummaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[41] + mi := &file_vm_vm_proto_msgTypes[40] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2806,7 +2759,7 @@ func (x *ParseStateSummaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseStateSummaryResponse.ProtoReflect.Descriptor instead. func (*ParseStateSummaryResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{41} + return file_vm_vm_proto_rawDescGZIP(), []int{40} } func (x *ParseStateSummaryResponse) GetId() []byte { @@ -2841,7 +2794,7 @@ type GetStateSummaryRequest struct { func (x *GetStateSummaryRequest) Reset() { *x = GetStateSummaryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[42] + mi := &file_vm_vm_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2854,7 +2807,7 @@ func (x *GetStateSummaryRequest) String() string { func (*GetStateSummaryRequest) ProtoMessage() {} func (x *GetStateSummaryRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[42] + mi := &file_vm_vm_proto_msgTypes[41] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2867,7 +2820,7 @@ func (x *GetStateSummaryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateSummaryRequest.ProtoReflect.Descriptor instead. func (*GetStateSummaryRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{42} + return file_vm_vm_proto_rawDescGZIP(), []int{41} } func (x *GetStateSummaryRequest) GetHeight() uint64 { @@ -2890,7 +2843,7 @@ type GetStateSummaryResponse struct { func (x *GetStateSummaryResponse) Reset() { *x = GetStateSummaryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[43] + mi := &file_vm_vm_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2903,7 +2856,7 @@ func (x *GetStateSummaryResponse) String() string { func (*GetStateSummaryResponse) ProtoMessage() {} func (x *GetStateSummaryResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[43] + mi := &file_vm_vm_proto_msgTypes[42] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2916,7 +2869,7 @@ func (x *GetStateSummaryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateSummaryResponse.ProtoReflect.Descriptor instead. func (*GetStateSummaryResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{43} + return file_vm_vm_proto_rawDescGZIP(), []int{42} } func (x *GetStateSummaryResponse) GetId() []byte { @@ -2951,7 +2904,7 @@ type StateSummaryAcceptRequest struct { func (x *StateSummaryAcceptRequest) Reset() { *x = StateSummaryAcceptRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[44] + mi := &file_vm_vm_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2964,7 +2917,7 @@ func (x *StateSummaryAcceptRequest) String() string { func (*StateSummaryAcceptRequest) ProtoMessage() {} func (x *StateSummaryAcceptRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[44] + mi := &file_vm_vm_proto_msgTypes[43] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2977,7 +2930,7 @@ func (x *StateSummaryAcceptRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryAcceptRequest.ProtoReflect.Descriptor instead. func (*StateSummaryAcceptRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{44} + return file_vm_vm_proto_rawDescGZIP(), []int{43} } func (x *StateSummaryAcceptRequest) GetBytes() []byte { @@ -2999,7 +2952,7 @@ type StateSummaryAcceptResponse struct { func (x *StateSummaryAcceptResponse) Reset() { *x = StateSummaryAcceptResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[45] + mi := &file_vm_vm_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3012,7 +2965,7 @@ func (x *StateSummaryAcceptResponse) String() string { func (*StateSummaryAcceptResponse) ProtoMessage() {} func (x *StateSummaryAcceptResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[45] + mi := &file_vm_vm_proto_msgTypes[44] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3025,7 +2978,7 @@ func (x *StateSummaryAcceptResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryAcceptResponse.ProtoReflect.Descriptor instead. func (*StateSummaryAcceptResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{45} + return file_vm_vm_proto_rawDescGZIP(), []int{44} } func (x *StateSummaryAcceptResponse) GetMode() StateSummaryAcceptResponse_Mode { @@ -3117,431 +3070,421 @@ var file_vm_vm_proto_rawDesc = []byte{ 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x08, 0x68, - 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x47, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x6c, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x76, 0x6d, 0x2e, 0x48, - 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x08, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, - 0x22, 0x42, 0x0a, 0x07, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x70, - 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, - 0x66, 0x69, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x41, 0x64, 0x64, 0x72, 0x22, 0x51, 0x0a, 0x11, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x5f, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xd9, 0x01, 0x0a, 0x12, 0x42, 0x75, 0x69, 0x6c, - 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, - 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, 0x69, - 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x22, 0x29, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xe7, - 0x01, 0x0a, 0x12, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x22, 0x42, 0x0a, 0x07, 0x48, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x22, 0x51, 0x0a, 0x11, 0x42, + 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, + 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xd9, + 0x01, 0x0a, 0x12, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, - 0x66, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x57, 0x69, 0x74, - 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x21, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, - 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x88, 0x02, 0x0a, 0x10, - 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, - 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, - 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x26, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x68, - 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x5f, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x48, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x4f, 0x0a, 0x13, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x24, 0x0a, 0x12, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, - 0x24, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x57, + 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x29, 0x0a, 0x11, 0x50, 0x61, + 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xe7, 0x01, 0x0a, 0x12, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x76, 0x6d, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x2e, 0x0a, 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x21, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, + 0x69, 0x64, 0x22, 0x88, 0x02, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x76, 0x6d, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, + 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x12, 0x2e, 0x0a, + 0x13, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x57, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x26, 0x0a, + 0x14, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2a, 0x0a, 0x0e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, - 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x22, 0x2b, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x99, - 0x01, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, - 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x91, 0x01, 0x0a, 0x13, 0x41, - 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, - 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x68, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x12, 0x29, 0x0a, 0x0e, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0c, 0x70, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, + 0x5f, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, + 0x4f, 0x0a, 0x13, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x22, 0x24, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x24, 0x0a, 0x12, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x22, 0x2a, 0x0a, 0x0e, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x2b, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x99, 0x01, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x36, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x91, 0x01, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x64, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x0c, 0x41, + 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0xa5, 0x01, 0x0a, 0x17, 0x43, 0x72, 0x6f, 0x73, 0x73, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, + 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x08, + 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9d, + 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, + 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x64, - 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, - 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, - 0x70, 0x4d, 0x73, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x10, 0x0a, - 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, - 0xa5, 0x01, 0x0a, 0x17, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, - 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x9d, 0x01, 0x0a, 0x1d, 0x43, 0x72, 0x6f, 0x73, - 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, - 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x70, 0x0a, 0x18, 0x43, 0x72, 0x6f, 0x73, 0x73, - 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x10, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, - 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, - 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, - 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x2e, 0x0a, - 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x22, 0xb3, 0x01, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, - 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4e, - 0x75, 0x6d, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, - 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, - 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, - 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, - 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x54, - 0x69, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, - 0x6c, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, - 0x09, 0x62, 0x6c, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x34, 0x0a, 0x18, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x22, 0x4f, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, - 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x38, 0x0a, 0x19, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, - 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, - 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x33, 0x0a, 0x19, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x22, 0x50, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, - 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, - 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, - 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x70, + 0x0a, 0x18, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x81, 0x01, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, + 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, + 0x61, 0x74, 0x63, 0x68, 0x22, 0x2e, 0x0a, 0x13, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x22, 0xb3, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, + 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, + 0x6b, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6d, 0x61, 0x78, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x4e, 0x75, 0x6d, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, + 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x53, 0x69, 0x7a, + 0x65, 0x12, 0x37, 0x0a, 0x18, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, + 0x72, 0x65, 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, + 0x74, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x22, 0x34, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4f, 0x0a, 0x19, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x08, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x0a, 0x19, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, - 0x72, 0x72, 0x22, 0x5d, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x66, - 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, - 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, - 0x73, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, - 0x03, 0x65, 0x72, 0x72, 0x22, 0x7f, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, - 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x78, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, - 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, - 0x30, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x22, 0x60, 0x0a, 0x19, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, - 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5c, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, - 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x1a, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1b, + 0x72, 0x72, 0x22, 0x33, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, + 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x50, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x62, 0x6c, 0x6b, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x03, + 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x5d, 0x0a, 0x0e, 0x47, 0x61, 0x74, + 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x69, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, + 0x68, 0x65, 0x75, 0x73, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x69, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x18, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, - 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x51, 0x0a, 0x04, 0x4d, - 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, - 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, - 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, - 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x10, 0x03, 0x2a, 0x65, - 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, - 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, - 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, - 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, - 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, - 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x61, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, - 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, - 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, - 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0x8e, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, - 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, - 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, - 0x45, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, - 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x04, 0x32, 0xa4, 0x12, 0x0a, 0x02, 0x56, 0x4d, - 0x12, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, - 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, - 0x08, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, - 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, - 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, + 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x7f, 0x0a, 0x22, 0x47, + 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, + 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, + 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x78, 0x0a, 0x1b, + 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x18, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x60, 0x0a, 0x19, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, + 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x30, 0x0a, 0x16, 0x47, 0x65, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x5c, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, + 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc5, 0x01, + 0x0a, 0x1a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, 0x6d, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, + 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, + 0x72, 0x72, 0x22, 0x51, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, + 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, + 0x43, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, + 0x4d, 0x49, 0x43, 0x10, 0x03, 0x2a, 0x65, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, + 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, + 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x45, + 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x61, 0x0a, 0x06, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, + 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, + 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, + 0x8e, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x49, 0x4e, + 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4e, + 0x4f, 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x04, + 0x32, 0xd2, 0x11, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, + 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x53, + 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, + 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, 0x2e, 0x76, 0x6d, 0x2e, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0a, 0x42, 0x75, 0x69, + 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, + 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, + 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, + 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0d, 0x53, 0x65, + 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x76, 0x6d, + 0x2e, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, + 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x41, + 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x76, 0x6d, 0x2e, 0x41, + 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, - 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, - 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, - 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, - 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, - 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, - 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, - 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, + 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x41, 0x70, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, - 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, + 0x70, 0x12, 0x10, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, + 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x06, 0x47, + 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, + 0x76, 0x6d, 0x2e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x4b, 0x0a, 0x14, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, + 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x43, + 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x57, + 0x0a, 0x1a, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x2e, 0x76, + 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x43, 0x72, 0x6f, 0x73, 0x73, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x06, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, + 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, + 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, + 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, 0x56, + 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, - 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x14, - 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, - 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x57, 0x0a, 0x1a, 0x43, 0x72, 0x6f, - 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x21, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, - 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x6d, - 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, - 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6d, 0x2e, - 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, - 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, - 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, - 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1d, 0x2e, + 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, + 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x10, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, + 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x76, + 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, - 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, - 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, - 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, - 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, - 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x76, - 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, - 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x16, 0x2e, 0x76, - 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, - 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x53, 0x0a, 0x12, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, - 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, - 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, - 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x76, 0x6d, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x50, + 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, + 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x47, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x53, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, + 0x62, 0x2f, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3557,7 +3500,7 @@ func file_vm_vm_proto_rawDescGZIP() []byte { } var file_vm_vm_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_vm_vm_proto_msgTypes = make([]protoimpl.MessageInfo, 46) +var file_vm_vm_proto_msgTypes = make([]protoimpl.MessageInfo, 45) var file_vm_vm_proto_goTypes = []interface{}{ (State)(0), // 0: vm.State (Status)(0), // 1: vm.Status @@ -3568,150 +3511,146 @@ var file_vm_vm_proto_goTypes = []interface{}{ (*SetStateRequest)(nil), // 6: vm.SetStateRequest (*SetStateResponse)(nil), // 7: vm.SetStateResponse (*CreateHandlersResponse)(nil), // 8: vm.CreateHandlersResponse - (*CreateStaticHandlersResponse)(nil), // 9: vm.CreateStaticHandlersResponse - (*Handler)(nil), // 10: vm.Handler - (*BuildBlockRequest)(nil), // 11: vm.BuildBlockRequest - (*BuildBlockResponse)(nil), // 12: vm.BuildBlockResponse - (*ParseBlockRequest)(nil), // 13: vm.ParseBlockRequest - (*ParseBlockResponse)(nil), // 14: vm.ParseBlockResponse - (*GetBlockRequest)(nil), // 15: vm.GetBlockRequest - (*GetBlockResponse)(nil), // 16: vm.GetBlockResponse - (*SetPreferenceRequest)(nil), // 17: vm.SetPreferenceRequest - (*BlockVerifyRequest)(nil), // 18: vm.BlockVerifyRequest - (*BlockVerifyResponse)(nil), // 19: vm.BlockVerifyResponse - (*BlockAcceptRequest)(nil), // 20: vm.BlockAcceptRequest - (*BlockRejectRequest)(nil), // 21: vm.BlockRejectRequest - (*HealthResponse)(nil), // 22: vm.HealthResponse - (*VersionResponse)(nil), // 23: vm.VersionResponse - (*AppRequestMsg)(nil), // 24: vm.AppRequestMsg - (*AppRequestFailedMsg)(nil), // 25: vm.AppRequestFailedMsg - (*AppResponseMsg)(nil), // 26: vm.AppResponseMsg - (*AppGossipMsg)(nil), // 27: vm.AppGossipMsg - (*CrossChainAppRequestMsg)(nil), // 28: vm.CrossChainAppRequestMsg - (*CrossChainAppRequestFailedMsg)(nil), // 29: vm.CrossChainAppRequestFailedMsg - (*CrossChainAppResponseMsg)(nil), // 30: vm.CrossChainAppResponseMsg - (*ConnectedRequest)(nil), // 31: vm.ConnectedRequest - (*DisconnectedRequest)(nil), // 32: vm.DisconnectedRequest - (*GetAncestorsRequest)(nil), // 33: vm.GetAncestorsRequest - (*GetAncestorsResponse)(nil), // 34: vm.GetAncestorsResponse - (*BatchedParseBlockRequest)(nil), // 35: vm.BatchedParseBlockRequest - (*BatchedParseBlockResponse)(nil), // 36: vm.BatchedParseBlockResponse - (*VerifyHeightIndexResponse)(nil), // 37: vm.VerifyHeightIndexResponse - (*GetBlockIDAtHeightRequest)(nil), // 38: vm.GetBlockIDAtHeightRequest - (*GetBlockIDAtHeightResponse)(nil), // 39: vm.GetBlockIDAtHeightResponse - (*GatherResponse)(nil), // 40: vm.GatherResponse - (*StateSyncEnabledResponse)(nil), // 41: vm.StateSyncEnabledResponse - (*GetOngoingSyncStateSummaryResponse)(nil), // 42: vm.GetOngoingSyncStateSummaryResponse - (*GetLastStateSummaryResponse)(nil), // 43: vm.GetLastStateSummaryResponse - (*ParseStateSummaryRequest)(nil), // 44: vm.ParseStateSummaryRequest - (*ParseStateSummaryResponse)(nil), // 45: vm.ParseStateSummaryResponse - (*GetStateSummaryRequest)(nil), // 46: vm.GetStateSummaryRequest - (*GetStateSummaryResponse)(nil), // 47: vm.GetStateSummaryResponse - (*StateSummaryAcceptRequest)(nil), // 48: vm.StateSummaryAcceptRequest - (*StateSummaryAcceptResponse)(nil), // 49: vm.StateSummaryAcceptResponse - (*timestamppb.Timestamp)(nil), // 50: google.protobuf.Timestamp - (*_go.MetricFamily)(nil), // 51: io.prometheus.client.MetricFamily - (*emptypb.Empty)(nil), // 52: google.protobuf.Empty + (*Handler)(nil), // 9: vm.Handler + (*BuildBlockRequest)(nil), // 10: vm.BuildBlockRequest + (*BuildBlockResponse)(nil), // 11: vm.BuildBlockResponse + (*ParseBlockRequest)(nil), // 12: vm.ParseBlockRequest + (*ParseBlockResponse)(nil), // 13: vm.ParseBlockResponse + (*GetBlockRequest)(nil), // 14: vm.GetBlockRequest + (*GetBlockResponse)(nil), // 15: vm.GetBlockResponse + (*SetPreferenceRequest)(nil), // 16: vm.SetPreferenceRequest + (*BlockVerifyRequest)(nil), // 17: vm.BlockVerifyRequest + (*BlockVerifyResponse)(nil), // 18: vm.BlockVerifyResponse + (*BlockAcceptRequest)(nil), // 19: vm.BlockAcceptRequest + (*BlockRejectRequest)(nil), // 20: vm.BlockRejectRequest + (*HealthResponse)(nil), // 21: vm.HealthResponse + (*VersionResponse)(nil), // 22: vm.VersionResponse + (*AppRequestMsg)(nil), // 23: vm.AppRequestMsg + (*AppRequestFailedMsg)(nil), // 24: vm.AppRequestFailedMsg + (*AppResponseMsg)(nil), // 25: vm.AppResponseMsg + (*AppGossipMsg)(nil), // 26: vm.AppGossipMsg + (*CrossChainAppRequestMsg)(nil), // 27: vm.CrossChainAppRequestMsg + (*CrossChainAppRequestFailedMsg)(nil), // 28: vm.CrossChainAppRequestFailedMsg + (*CrossChainAppResponseMsg)(nil), // 29: vm.CrossChainAppResponseMsg + (*ConnectedRequest)(nil), // 30: vm.ConnectedRequest + (*DisconnectedRequest)(nil), // 31: vm.DisconnectedRequest + (*GetAncestorsRequest)(nil), // 32: vm.GetAncestorsRequest + (*GetAncestorsResponse)(nil), // 33: vm.GetAncestorsResponse + (*BatchedParseBlockRequest)(nil), // 34: vm.BatchedParseBlockRequest + (*BatchedParseBlockResponse)(nil), // 35: vm.BatchedParseBlockResponse + (*VerifyHeightIndexResponse)(nil), // 36: vm.VerifyHeightIndexResponse + (*GetBlockIDAtHeightRequest)(nil), // 37: vm.GetBlockIDAtHeightRequest + (*GetBlockIDAtHeightResponse)(nil), // 38: vm.GetBlockIDAtHeightResponse + (*GatherResponse)(nil), // 39: vm.GatherResponse + (*StateSyncEnabledResponse)(nil), // 40: vm.StateSyncEnabledResponse + (*GetOngoingSyncStateSummaryResponse)(nil), // 41: vm.GetOngoingSyncStateSummaryResponse + (*GetLastStateSummaryResponse)(nil), // 42: vm.GetLastStateSummaryResponse + (*ParseStateSummaryRequest)(nil), // 43: vm.ParseStateSummaryRequest + (*ParseStateSummaryResponse)(nil), // 44: vm.ParseStateSummaryResponse + (*GetStateSummaryRequest)(nil), // 45: vm.GetStateSummaryRequest + (*GetStateSummaryResponse)(nil), // 46: vm.GetStateSummaryResponse + (*StateSummaryAcceptRequest)(nil), // 47: vm.StateSummaryAcceptRequest + (*StateSummaryAcceptResponse)(nil), // 48: vm.StateSummaryAcceptResponse + (*timestamppb.Timestamp)(nil), // 49: google.protobuf.Timestamp + (*_go.MetricFamily)(nil), // 50: io.prometheus.client.MetricFamily + (*emptypb.Empty)(nil), // 51: google.protobuf.Empty } var file_vm_vm_proto_depIdxs = []int32{ - 50, // 0: vm.InitializeResponse.timestamp:type_name -> google.protobuf.Timestamp + 49, // 0: vm.InitializeResponse.timestamp:type_name -> google.protobuf.Timestamp 0, // 1: vm.SetStateRequest.state:type_name -> vm.State - 50, // 2: vm.SetStateResponse.timestamp:type_name -> google.protobuf.Timestamp - 10, // 3: vm.CreateHandlersResponse.handlers:type_name -> vm.Handler - 10, // 4: vm.CreateStaticHandlersResponse.handlers:type_name -> vm.Handler - 50, // 5: vm.BuildBlockResponse.timestamp:type_name -> google.protobuf.Timestamp - 1, // 6: vm.ParseBlockResponse.status:type_name -> vm.Status - 50, // 7: vm.ParseBlockResponse.timestamp:type_name -> google.protobuf.Timestamp - 1, // 8: vm.GetBlockResponse.status:type_name -> vm.Status - 50, // 9: vm.GetBlockResponse.timestamp:type_name -> google.protobuf.Timestamp - 2, // 10: vm.GetBlockResponse.err:type_name -> vm.Error - 50, // 11: vm.BlockVerifyResponse.timestamp:type_name -> google.protobuf.Timestamp - 50, // 12: vm.AppRequestMsg.deadline:type_name -> google.protobuf.Timestamp - 50, // 13: vm.CrossChainAppRequestMsg.deadline:type_name -> google.protobuf.Timestamp - 14, // 14: vm.BatchedParseBlockResponse.response:type_name -> vm.ParseBlockResponse - 2, // 15: vm.VerifyHeightIndexResponse.err:type_name -> vm.Error - 2, // 16: vm.GetBlockIDAtHeightResponse.err:type_name -> vm.Error - 51, // 17: vm.GatherResponse.metric_families:type_name -> io.prometheus.client.MetricFamily - 2, // 18: vm.StateSyncEnabledResponse.err:type_name -> vm.Error - 2, // 19: vm.GetOngoingSyncStateSummaryResponse.err:type_name -> vm.Error - 2, // 20: vm.GetLastStateSummaryResponse.err:type_name -> vm.Error - 2, // 21: vm.ParseStateSummaryResponse.err:type_name -> vm.Error - 2, // 22: vm.GetStateSummaryResponse.err:type_name -> vm.Error - 3, // 23: vm.StateSummaryAcceptResponse.mode:type_name -> vm.StateSummaryAcceptResponse.Mode - 2, // 24: vm.StateSummaryAcceptResponse.err:type_name -> vm.Error - 4, // 25: vm.VM.Initialize:input_type -> vm.InitializeRequest - 6, // 26: vm.VM.SetState:input_type -> vm.SetStateRequest - 52, // 27: vm.VM.Shutdown:input_type -> google.protobuf.Empty - 52, // 28: vm.VM.CreateHandlers:input_type -> google.protobuf.Empty - 52, // 29: vm.VM.CreateStaticHandlers:input_type -> google.protobuf.Empty - 31, // 30: vm.VM.Connected:input_type -> vm.ConnectedRequest - 32, // 31: vm.VM.Disconnected:input_type -> vm.DisconnectedRequest - 11, // 32: vm.VM.BuildBlock:input_type -> vm.BuildBlockRequest - 13, // 33: vm.VM.ParseBlock:input_type -> vm.ParseBlockRequest - 15, // 34: vm.VM.GetBlock:input_type -> vm.GetBlockRequest - 17, // 35: vm.VM.SetPreference:input_type -> vm.SetPreferenceRequest - 52, // 36: vm.VM.Health:input_type -> google.protobuf.Empty - 52, // 37: vm.VM.Version:input_type -> google.protobuf.Empty - 24, // 38: vm.VM.AppRequest:input_type -> vm.AppRequestMsg - 25, // 39: vm.VM.AppRequestFailed:input_type -> vm.AppRequestFailedMsg - 26, // 40: vm.VM.AppResponse:input_type -> vm.AppResponseMsg - 27, // 41: vm.VM.AppGossip:input_type -> vm.AppGossipMsg - 52, // 42: vm.VM.Gather:input_type -> google.protobuf.Empty - 28, // 43: vm.VM.CrossChainAppRequest:input_type -> vm.CrossChainAppRequestMsg - 29, // 44: vm.VM.CrossChainAppRequestFailed:input_type -> vm.CrossChainAppRequestFailedMsg - 30, // 45: vm.VM.CrossChainAppResponse:input_type -> vm.CrossChainAppResponseMsg - 33, // 46: vm.VM.GetAncestors:input_type -> vm.GetAncestorsRequest - 35, // 47: vm.VM.BatchedParseBlock:input_type -> vm.BatchedParseBlockRequest - 52, // 48: vm.VM.VerifyHeightIndex:input_type -> google.protobuf.Empty - 38, // 49: vm.VM.GetBlockIDAtHeight:input_type -> vm.GetBlockIDAtHeightRequest - 52, // 50: vm.VM.StateSyncEnabled:input_type -> google.protobuf.Empty - 52, // 51: vm.VM.GetOngoingSyncStateSummary:input_type -> google.protobuf.Empty - 52, // 52: vm.VM.GetLastStateSummary:input_type -> google.protobuf.Empty - 44, // 53: vm.VM.ParseStateSummary:input_type -> vm.ParseStateSummaryRequest - 46, // 54: vm.VM.GetStateSummary:input_type -> vm.GetStateSummaryRequest - 18, // 55: vm.VM.BlockVerify:input_type -> vm.BlockVerifyRequest - 20, // 56: vm.VM.BlockAccept:input_type -> vm.BlockAcceptRequest - 21, // 57: vm.VM.BlockReject:input_type -> vm.BlockRejectRequest - 48, // 58: vm.VM.StateSummaryAccept:input_type -> vm.StateSummaryAcceptRequest - 5, // 59: vm.VM.Initialize:output_type -> vm.InitializeResponse - 7, // 60: vm.VM.SetState:output_type -> vm.SetStateResponse - 52, // 61: vm.VM.Shutdown:output_type -> google.protobuf.Empty - 8, // 62: vm.VM.CreateHandlers:output_type -> vm.CreateHandlersResponse - 9, // 63: vm.VM.CreateStaticHandlers:output_type -> vm.CreateStaticHandlersResponse - 52, // 64: vm.VM.Connected:output_type -> google.protobuf.Empty - 52, // 65: vm.VM.Disconnected:output_type -> google.protobuf.Empty - 12, // 66: vm.VM.BuildBlock:output_type -> vm.BuildBlockResponse - 14, // 67: vm.VM.ParseBlock:output_type -> vm.ParseBlockResponse - 16, // 68: vm.VM.GetBlock:output_type -> vm.GetBlockResponse - 52, // 69: vm.VM.SetPreference:output_type -> google.protobuf.Empty - 22, // 70: vm.VM.Health:output_type -> vm.HealthResponse - 23, // 71: vm.VM.Version:output_type -> vm.VersionResponse - 52, // 72: vm.VM.AppRequest:output_type -> google.protobuf.Empty - 52, // 73: vm.VM.AppRequestFailed:output_type -> google.protobuf.Empty - 52, // 74: vm.VM.AppResponse:output_type -> google.protobuf.Empty - 52, // 75: vm.VM.AppGossip:output_type -> google.protobuf.Empty - 40, // 76: vm.VM.Gather:output_type -> vm.GatherResponse - 52, // 77: vm.VM.CrossChainAppRequest:output_type -> google.protobuf.Empty - 52, // 78: vm.VM.CrossChainAppRequestFailed:output_type -> google.protobuf.Empty - 52, // 79: vm.VM.CrossChainAppResponse:output_type -> google.protobuf.Empty - 34, // 80: vm.VM.GetAncestors:output_type -> vm.GetAncestorsResponse - 36, // 81: vm.VM.BatchedParseBlock:output_type -> vm.BatchedParseBlockResponse - 37, // 82: vm.VM.VerifyHeightIndex:output_type -> vm.VerifyHeightIndexResponse - 39, // 83: vm.VM.GetBlockIDAtHeight:output_type -> vm.GetBlockIDAtHeightResponse - 41, // 84: vm.VM.StateSyncEnabled:output_type -> vm.StateSyncEnabledResponse - 42, // 85: vm.VM.GetOngoingSyncStateSummary:output_type -> vm.GetOngoingSyncStateSummaryResponse - 43, // 86: vm.VM.GetLastStateSummary:output_type -> vm.GetLastStateSummaryResponse - 45, // 87: vm.VM.ParseStateSummary:output_type -> vm.ParseStateSummaryResponse - 47, // 88: vm.VM.GetStateSummary:output_type -> vm.GetStateSummaryResponse - 19, // 89: vm.VM.BlockVerify:output_type -> vm.BlockVerifyResponse - 52, // 90: vm.VM.BlockAccept:output_type -> google.protobuf.Empty - 52, // 91: vm.VM.BlockReject:output_type -> google.protobuf.Empty - 49, // 92: vm.VM.StateSummaryAccept:output_type -> vm.StateSummaryAcceptResponse - 59, // [59:93] is the sub-list for method output_type - 25, // [25:59] is the sub-list for method input_type - 25, // [25:25] is the sub-list for extension type_name - 25, // [25:25] is the sub-list for extension extendee - 0, // [0:25] is the sub-list for field type_name + 49, // 2: vm.SetStateResponse.timestamp:type_name -> google.protobuf.Timestamp + 9, // 3: vm.CreateHandlersResponse.handlers:type_name -> vm.Handler + 49, // 4: vm.BuildBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 1, // 5: vm.ParseBlockResponse.status:type_name -> vm.Status + 49, // 6: vm.ParseBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 1, // 7: vm.GetBlockResponse.status:type_name -> vm.Status + 49, // 8: vm.GetBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 2, // 9: vm.GetBlockResponse.err:type_name -> vm.Error + 49, // 10: vm.BlockVerifyResponse.timestamp:type_name -> google.protobuf.Timestamp + 49, // 11: vm.AppRequestMsg.deadline:type_name -> google.protobuf.Timestamp + 49, // 12: vm.CrossChainAppRequestMsg.deadline:type_name -> google.protobuf.Timestamp + 13, // 13: vm.BatchedParseBlockResponse.response:type_name -> vm.ParseBlockResponse + 2, // 14: vm.VerifyHeightIndexResponse.err:type_name -> vm.Error + 2, // 15: vm.GetBlockIDAtHeightResponse.err:type_name -> vm.Error + 50, // 16: vm.GatherResponse.metric_families:type_name -> io.prometheus.client.MetricFamily + 2, // 17: vm.StateSyncEnabledResponse.err:type_name -> vm.Error + 2, // 18: vm.GetOngoingSyncStateSummaryResponse.err:type_name -> vm.Error + 2, // 19: vm.GetLastStateSummaryResponse.err:type_name -> vm.Error + 2, // 20: vm.ParseStateSummaryResponse.err:type_name -> vm.Error + 2, // 21: vm.GetStateSummaryResponse.err:type_name -> vm.Error + 3, // 22: vm.StateSummaryAcceptResponse.mode:type_name -> vm.StateSummaryAcceptResponse.Mode + 2, // 23: vm.StateSummaryAcceptResponse.err:type_name -> vm.Error + 4, // 24: vm.VM.Initialize:input_type -> vm.InitializeRequest + 6, // 25: vm.VM.SetState:input_type -> vm.SetStateRequest + 51, // 26: vm.VM.Shutdown:input_type -> google.protobuf.Empty + 51, // 27: vm.VM.CreateHandlers:input_type -> google.protobuf.Empty + 30, // 28: vm.VM.Connected:input_type -> vm.ConnectedRequest + 31, // 29: vm.VM.Disconnected:input_type -> vm.DisconnectedRequest + 10, // 30: vm.VM.BuildBlock:input_type -> vm.BuildBlockRequest + 12, // 31: vm.VM.ParseBlock:input_type -> vm.ParseBlockRequest + 14, // 32: vm.VM.GetBlock:input_type -> vm.GetBlockRequest + 16, // 33: vm.VM.SetPreference:input_type -> vm.SetPreferenceRequest + 51, // 34: vm.VM.Health:input_type -> google.protobuf.Empty + 51, // 35: vm.VM.Version:input_type -> google.protobuf.Empty + 23, // 36: vm.VM.AppRequest:input_type -> vm.AppRequestMsg + 24, // 37: vm.VM.AppRequestFailed:input_type -> vm.AppRequestFailedMsg + 25, // 38: vm.VM.AppResponse:input_type -> vm.AppResponseMsg + 26, // 39: vm.VM.AppGossip:input_type -> vm.AppGossipMsg + 51, // 40: vm.VM.Gather:input_type -> google.protobuf.Empty + 27, // 41: vm.VM.CrossChainAppRequest:input_type -> vm.CrossChainAppRequestMsg + 28, // 42: vm.VM.CrossChainAppRequestFailed:input_type -> vm.CrossChainAppRequestFailedMsg + 29, // 43: vm.VM.CrossChainAppResponse:input_type -> vm.CrossChainAppResponseMsg + 32, // 44: vm.VM.GetAncestors:input_type -> vm.GetAncestorsRequest + 34, // 45: vm.VM.BatchedParseBlock:input_type -> vm.BatchedParseBlockRequest + 51, // 46: vm.VM.VerifyHeightIndex:input_type -> google.protobuf.Empty + 37, // 47: vm.VM.GetBlockIDAtHeight:input_type -> vm.GetBlockIDAtHeightRequest + 51, // 48: vm.VM.StateSyncEnabled:input_type -> google.protobuf.Empty + 51, // 49: vm.VM.GetOngoingSyncStateSummary:input_type -> google.protobuf.Empty + 51, // 50: vm.VM.GetLastStateSummary:input_type -> google.protobuf.Empty + 43, // 51: vm.VM.ParseStateSummary:input_type -> vm.ParseStateSummaryRequest + 45, // 52: vm.VM.GetStateSummary:input_type -> vm.GetStateSummaryRequest + 17, // 53: vm.VM.BlockVerify:input_type -> vm.BlockVerifyRequest + 19, // 54: vm.VM.BlockAccept:input_type -> vm.BlockAcceptRequest + 20, // 55: vm.VM.BlockReject:input_type -> vm.BlockRejectRequest + 47, // 56: vm.VM.StateSummaryAccept:input_type -> vm.StateSummaryAcceptRequest + 5, // 57: vm.VM.Initialize:output_type -> vm.InitializeResponse + 7, // 58: vm.VM.SetState:output_type -> vm.SetStateResponse + 51, // 59: vm.VM.Shutdown:output_type -> google.protobuf.Empty + 8, // 60: vm.VM.CreateHandlers:output_type -> vm.CreateHandlersResponse + 51, // 61: vm.VM.Connected:output_type -> google.protobuf.Empty + 51, // 62: vm.VM.Disconnected:output_type -> google.protobuf.Empty + 11, // 63: vm.VM.BuildBlock:output_type -> vm.BuildBlockResponse + 13, // 64: vm.VM.ParseBlock:output_type -> vm.ParseBlockResponse + 15, // 65: vm.VM.GetBlock:output_type -> vm.GetBlockResponse + 51, // 66: vm.VM.SetPreference:output_type -> google.protobuf.Empty + 21, // 67: vm.VM.Health:output_type -> vm.HealthResponse + 22, // 68: vm.VM.Version:output_type -> vm.VersionResponse + 51, // 69: vm.VM.AppRequest:output_type -> google.protobuf.Empty + 51, // 70: vm.VM.AppRequestFailed:output_type -> google.protobuf.Empty + 51, // 71: vm.VM.AppResponse:output_type -> google.protobuf.Empty + 51, // 72: vm.VM.AppGossip:output_type -> google.protobuf.Empty + 39, // 73: vm.VM.Gather:output_type -> vm.GatherResponse + 51, // 74: vm.VM.CrossChainAppRequest:output_type -> google.protobuf.Empty + 51, // 75: vm.VM.CrossChainAppRequestFailed:output_type -> google.protobuf.Empty + 51, // 76: vm.VM.CrossChainAppResponse:output_type -> google.protobuf.Empty + 33, // 77: vm.VM.GetAncestors:output_type -> vm.GetAncestorsResponse + 35, // 78: vm.VM.BatchedParseBlock:output_type -> vm.BatchedParseBlockResponse + 36, // 79: vm.VM.VerifyHeightIndex:output_type -> vm.VerifyHeightIndexResponse + 38, // 80: vm.VM.GetBlockIDAtHeight:output_type -> vm.GetBlockIDAtHeightResponse + 40, // 81: vm.VM.StateSyncEnabled:output_type -> vm.StateSyncEnabledResponse + 41, // 82: vm.VM.GetOngoingSyncStateSummary:output_type -> vm.GetOngoingSyncStateSummaryResponse + 42, // 83: vm.VM.GetLastStateSummary:output_type -> vm.GetLastStateSummaryResponse + 44, // 84: vm.VM.ParseStateSummary:output_type -> vm.ParseStateSummaryResponse + 46, // 85: vm.VM.GetStateSummary:output_type -> vm.GetStateSummaryResponse + 18, // 86: vm.VM.BlockVerify:output_type -> vm.BlockVerifyResponse + 51, // 87: vm.VM.BlockAccept:output_type -> google.protobuf.Empty + 51, // 88: vm.VM.BlockReject:output_type -> google.protobuf.Empty + 48, // 89: vm.VM.StateSummaryAccept:output_type -> vm.StateSummaryAcceptResponse + 57, // [57:90] is the sub-list for method output_type + 24, // [24:57] is the sub-list for method input_type + 24, // [24:24] is the sub-list for extension type_name + 24, // [24:24] is the sub-list for extension extendee + 0, // [0:24] is the sub-list for field type_name } func init() { file_vm_vm_proto_init() } @@ -3781,18 +3720,6 @@ func file_vm_vm_proto_init() { } } file_vm_vm_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateStaticHandlersResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_vm_vm_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Handler); i { case 0: return &v.state @@ -3804,7 +3731,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BuildBlockRequest); i { case 0: return &v.state @@ -3816,7 +3743,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BuildBlockResponse); i { case 0: return &v.state @@ -3828,7 +3755,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ParseBlockRequest); i { case 0: return &v.state @@ -3840,7 +3767,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ParseBlockResponse); i { case 0: return &v.state @@ -3852,7 +3779,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlockRequest); i { case 0: return &v.state @@ -3864,7 +3791,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlockResponse); i { case 0: return &v.state @@ -3876,7 +3803,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SetPreferenceRequest); i { case 0: return &v.state @@ -3888,7 +3815,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlockVerifyRequest); i { case 0: return &v.state @@ -3900,7 +3827,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlockVerifyResponse); i { case 0: return &v.state @@ -3912,7 +3839,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlockAcceptRequest); i { case 0: return &v.state @@ -3924,7 +3851,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlockRejectRequest); i { case 0: return &v.state @@ -3936,7 +3863,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HealthResponse); i { case 0: return &v.state @@ -3948,7 +3875,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VersionResponse); i { case 0: return &v.state @@ -3960,7 +3887,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppRequestMsg); i { case 0: return &v.state @@ -3972,7 +3899,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppRequestFailedMsg); i { case 0: return &v.state @@ -3984,7 +3911,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppResponseMsg); i { case 0: return &v.state @@ -3996,7 +3923,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AppGossipMsg); i { case 0: return &v.state @@ -4008,7 +3935,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CrossChainAppRequestMsg); i { case 0: return &v.state @@ -4020,7 +3947,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CrossChainAppRequestFailedMsg); i { case 0: return &v.state @@ -4032,7 +3959,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CrossChainAppResponseMsg); i { case 0: return &v.state @@ -4044,7 +3971,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ConnectedRequest); i { case 0: return &v.state @@ -4056,7 +3983,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DisconnectedRequest); i { case 0: return &v.state @@ -4068,7 +3995,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetAncestorsRequest); i { case 0: return &v.state @@ -4080,7 +4007,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetAncestorsResponse); i { case 0: return &v.state @@ -4092,7 +4019,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BatchedParseBlockRequest); i { case 0: return &v.state @@ -4104,7 +4031,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BatchedParseBlockResponse); i { case 0: return &v.state @@ -4116,7 +4043,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*VerifyHeightIndexResponse); i { case 0: return &v.state @@ -4128,7 +4055,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlockIDAtHeightRequest); i { case 0: return &v.state @@ -4140,7 +4067,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetBlockIDAtHeightResponse); i { case 0: return &v.state @@ -4152,7 +4079,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GatherResponse); i { case 0: return &v.state @@ -4164,7 +4091,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StateSyncEnabledResponse); i { case 0: return &v.state @@ -4176,7 +4103,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetOngoingSyncStateSummaryResponse); i { case 0: return &v.state @@ -4188,7 +4115,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetLastStateSummaryResponse); i { case 0: return &v.state @@ -4200,7 +4127,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ParseStateSummaryRequest); i { case 0: return &v.state @@ -4212,7 +4139,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ParseStateSummaryResponse); i { case 0: return &v.state @@ -4224,7 +4151,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetStateSummaryRequest); i { case 0: return &v.state @@ -4236,7 +4163,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetStateSummaryResponse); i { case 0: return &v.state @@ -4248,7 +4175,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StateSummaryAcceptRequest); i { case 0: return &v.state @@ -4260,7 +4187,7 @@ func file_vm_vm_proto_init() { return nil } } - file_vm_vm_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + file_vm_vm_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StateSummaryAcceptResponse); i { case 0: return &v.state @@ -4273,15 +4200,15 @@ func file_vm_vm_proto_init() { } } } - file_vm_vm_proto_msgTypes[7].OneofWrappers = []interface{}{} - file_vm_vm_proto_msgTypes[14].OneofWrappers = []interface{}{} + file_vm_vm_proto_msgTypes[6].OneofWrappers = []interface{}{} + file_vm_vm_proto_msgTypes[13].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vm_vm_proto_rawDesc, NumEnums: 4, - NumMessages: 46, + NumMessages: 45, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/pb/vm/vm_grpc.pb.go b/proto/pb/vm/vm_grpc.pb.go index 917e04d25e96..6d7bb17f6c33 100644 --- a/proto/pb/vm/vm_grpc.pb.go +++ b/proto/pb/vm/vm_grpc.pb.go @@ -24,7 +24,6 @@ const ( VM_SetState_FullMethodName = "/vm.VM/SetState" VM_Shutdown_FullMethodName = "/vm.VM/Shutdown" VM_CreateHandlers_FullMethodName = "/vm.VM/CreateHandlers" - VM_CreateStaticHandlers_FullMethodName = "/vm.VM/CreateStaticHandlers" VM_Connected_FullMethodName = "/vm.VM/Connected" VM_Disconnected_FullMethodName = "/vm.VM/Disconnected" VM_BuildBlock_FullMethodName = "/vm.VM/BuildBlock" @@ -70,13 +69,6 @@ type VMClient interface { Shutdown(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) // Creates the HTTP handlers for custom chain network calls. CreateHandlers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateHandlersResponse, error) - // Creates the HTTP handlers for custom VM network calls. - // - // Note: RPC Chain VM Factory will start a new instance of the VM in a - // separate process which will populate the static handlers. After this - // process is created other processes will be created to populate blockchains, - // but they will not have the static handlers be called again. - CreateStaticHandlers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateStaticHandlersResponse, error) Connected(ctx context.Context, in *ConnectedRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) Disconnected(ctx context.Context, in *DisconnectedRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) // Attempt to create a new block from data contained in the VM. @@ -177,15 +169,6 @@ func (c *vMClient) CreateHandlers(ctx context.Context, in *emptypb.Empty, opts . return out, nil } -func (c *vMClient) CreateStaticHandlers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*CreateStaticHandlersResponse, error) { - out := new(CreateStaticHandlersResponse) - err := c.cc.Invoke(ctx, VM_CreateStaticHandlers_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *vMClient) Connected(ctx context.Context, in *ConnectedRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, VM_Connected_FullMethodName, in, out, opts...) @@ -461,13 +444,6 @@ type VMServer interface { Shutdown(context.Context, *emptypb.Empty) (*emptypb.Empty, error) // Creates the HTTP handlers for custom chain network calls. CreateHandlers(context.Context, *emptypb.Empty) (*CreateHandlersResponse, error) - // Creates the HTTP handlers for custom VM network calls. - // - // Note: RPC Chain VM Factory will start a new instance of the VM in a - // separate process which will populate the static handlers. After this - // process is created other processes will be created to populate blockchains, - // but they will not have the static handlers be called again. - CreateStaticHandlers(context.Context, *emptypb.Empty) (*CreateStaticHandlersResponse, error) Connected(context.Context, *ConnectedRequest) (*emptypb.Empty, error) Disconnected(context.Context, *DisconnectedRequest) (*emptypb.Empty, error) // Attempt to create a new block from data contained in the VM. @@ -541,9 +517,6 @@ func (UnimplementedVMServer) Shutdown(context.Context, *emptypb.Empty) (*emptypb func (UnimplementedVMServer) CreateHandlers(context.Context, *emptypb.Empty) (*CreateHandlersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateHandlers not implemented") } -func (UnimplementedVMServer) CreateStaticHandlers(context.Context, *emptypb.Empty) (*CreateStaticHandlersResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CreateStaticHandlers not implemented") -} func (UnimplementedVMServer) Connected(context.Context, *ConnectedRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method Connected not implemented") } @@ -716,24 +689,6 @@ func _VM_CreateHandlers_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } -func _VM_CreateStaticHandlers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(VMServer).CreateStaticHandlers(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: VM_CreateStaticHandlers_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(VMServer).CreateStaticHandlers(ctx, req.(*emptypb.Empty)) - } - return interceptor(ctx, in, info, handler) -} - func _VM_Connected_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ConnectedRequest) if err := dec(in); err != nil { @@ -1279,10 +1234,6 @@ var VM_ServiceDesc = grpc.ServiceDesc{ MethodName: "CreateHandlers", Handler: _VM_CreateHandlers_Handler, }, - { - MethodName: "CreateStaticHandlers", - Handler: _VM_CreateStaticHandlers_Handler, - }, { MethodName: "Connected", Handler: _VM_Connected_Handler, diff --git a/proto/vm/vm.proto b/proto/vm/vm.proto index ff50de1eb6cb..4a0557ba4e67 100644 --- a/proto/vm/vm.proto +++ b/proto/vm/vm.proto @@ -21,13 +21,6 @@ service VM { rpc Shutdown(google.protobuf.Empty) returns (google.protobuf.Empty); // Creates the HTTP handlers for custom chain network calls. rpc CreateHandlers(google.protobuf.Empty) returns (CreateHandlersResponse); - // Creates the HTTP handlers for custom VM network calls. - // - // Note: RPC Chain VM Factory will start a new instance of the VM in a - // separate process which will populate the static handlers. After this - // process is created other processes will be created to populate blockchains, - // but they will not have the static handlers be called again. - rpc CreateStaticHandlers(google.protobuf.Empty) returns (CreateStaticHandlersResponse); rpc Connected(ConnectedRequest) returns (google.protobuf.Empty); rpc Disconnected(DisconnectedRequest) returns (google.protobuf.Empty); // Attempt to create a new block from data contained in the VM. @@ -158,10 +151,6 @@ message CreateHandlersResponse { repeated Handler handlers = 1; } -message CreateStaticHandlersResponse { - repeated Handler handlers = 1; -} - message Handler { string prefix = 1; // server_addr is the address of the gRPC server which serves the diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 84c44c2966e6..ba2be886b0b6 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -38,7 +38,6 @@ github.com/ava-labs/avalanchego/vms/proposervm/scheduler=Scheduler=vms/proposerv github.com/ava-labs/avalanchego/vms/proposervm/state=State=vms/proposervm/state/mock_state.go github.com/ava-labs/avalanchego/vms/proposervm=PostForkBlock=vms/proposervm/mock_post_fork_block.go github.com/ava-labs/avalanchego/vms/registry=VMGetter=vms/registry/mock_vm_getter.go -github.com/ava-labs/avalanchego/vms/registry=VMRegisterer=vms/registry/mock_vm_registerer.go github.com/ava-labs/avalanchego/vms/registry=VMRegistry=vms/registry/mock_vm_registry.go github.com/ava-labs/avalanchego/vms=Factory,Manager=vms/mock_manager.go github.com/ava-labs/avalanchego/x/sync=Client=x/sync/mock_client.go diff --git a/snow/engine/avalanche/vertex/mock_vm.go b/snow/engine/avalanche/vertex/mock_vm.go index b0c4362b4551..c1b67c7421c6 100644 --- a/snow/engine/avalanche/vertex/mock_vm.go +++ b/snow/engine/avalanche/vertex/mock_vm.go @@ -143,21 +143,6 @@ func (mr *MockLinearizableVMMockRecorder) CreateHandlers(arg0 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHandlers", reflect.TypeOf((*MockLinearizableVM)(nil).CreateHandlers), arg0) } -// CreateStaticHandlers mocks base method. -func (m *MockLinearizableVM) CreateStaticHandlers(arg0 context.Context) (map[string]http.Handler, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateStaticHandlers", arg0) - ret0, _ := ret[0].(map[string]http.Handler) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreateStaticHandlers indicates an expected call of CreateStaticHandlers. -func (mr *MockLinearizableVMMockRecorder) CreateStaticHandlers(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStaticHandlers", reflect.TypeOf((*MockLinearizableVM)(nil).CreateStaticHandlers), arg0) -} - // CrossChainAppRequest mocks base method. func (m *MockLinearizableVM) CrossChainAppRequest(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 time.Time, arg4 []byte) error { m.ctrl.T.Helper() diff --git a/snow/engine/common/test_vm.go b/snow/engine/common/test_vm.go index b576e8e389c7..828b49f5e1fe 100644 --- a/snow/engine/common/test_vm.go +++ b/snow/engine/common/test_vm.go @@ -23,7 +23,6 @@ var ( errSetState = errors.New("unexpectedly called SetState") errShutdown = errors.New("unexpectedly called Shutdown") errCreateHandlers = errors.New("unexpectedly called CreateHandlers") - errCreateStaticHandlers = errors.New("unexpectedly called CreateStaticHandlers") errHealthCheck = errors.New("unexpectedly called HealthCheck") errConnected = errors.New("unexpectedly called Connected") errDisconnected = errors.New("unexpectedly called Disconnected") @@ -44,7 +43,7 @@ type TestVM struct { T *testing.T CantInitialize, CantSetState, - CantShutdown, CantCreateHandlers, CantCreateStaticHandlers, + CantShutdown, CantCreateHandlers, CantHealthCheck, CantConnected, CantDisconnected, CantVersion, CantAppRequest, CantAppResponse, CantAppGossip, CantAppRequestFailed, CantCrossChainAppRequest, CantCrossChainAppResponse, CantCrossChainAppRequestFailed bool @@ -53,7 +52,6 @@ type TestVM struct { SetStateF func(ctx context.Context, state snow.State) error ShutdownF func(context.Context) error CreateHandlersF func(context.Context) (map[string]http.Handler, error) - CreateStaticHandlersF func(context.Context) (map[string]http.Handler, error) ConnectedF func(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error DisconnectedF func(ctx context.Context, nodeID ids.NodeID) error HealthCheckF func(context.Context) (interface{}, error) @@ -72,7 +70,6 @@ func (vm *TestVM) Default(cant bool) { vm.CantSetState = cant vm.CantShutdown = cant vm.CantCreateHandlers = cant - vm.CantCreateStaticHandlers = cant vm.CantHealthCheck = cant vm.CantAppRequest = cant vm.CantAppRequestFailed = cant @@ -152,16 +149,6 @@ func (vm *TestVM) CreateHandlers(ctx context.Context) (map[string]http.Handler, return nil, nil } -func (vm *TestVM) CreateStaticHandlers(ctx context.Context) (map[string]http.Handler, error) { - if vm.CreateStaticHandlersF != nil { - return vm.CreateStaticHandlersF(ctx) - } - if vm.CantCreateStaticHandlers && vm.T != nil { - require.FailNow(vm.T, errCreateStaticHandlers.Error()) - } - return nil, nil -} - func (vm *TestVM) HealthCheck(ctx context.Context) (interface{}, error) { if vm.HealthCheckF != nil { return vm.HealthCheckF(ctx) diff --git a/snow/engine/common/vm.go b/snow/engine/common/vm.go index dc201c95602f..65cbfb158656 100644 --- a/snow/engine/common/vm.go +++ b/snow/engine/common/vm.go @@ -65,23 +65,6 @@ type VM interface { // Version returns the version of the VM. Version(context.Context) (string, error) - // Creates the HTTP handlers for custom VM network calls. - // - // This exposes handlers that the outside world can use to communicate with - // a static reference to the VM. Each handler has the path: - // [Address of node]/ext/VM/[VM ID]/[extension] - // - // Returns a mapping from [extension]s to HTTP handlers. - // - // For example, it might make sense to have an extension for creating - // genesis bytes this VM can interpret. - // - // Note: If this method is called, no other method will be called on this VM. - // Each registered VM will have a single instance created to handle static - // APIs. This instance will be handled separately from instances created to - // service an instance of a chain. - CreateStaticHandlers(context.Context) (map[string]http.Handler, error) - // Creates the HTTP handlers for custom chain network calls. // // This exposes handlers that the outside world can use to communicate with diff --git a/snow/engine/snowman/block/mock_chain_vm.go b/snow/engine/snowman/block/mock_chain_vm.go index 27b6aef75ed6..8cb9acb75ed0 100644 --- a/snow/engine/snowman/block/mock_chain_vm.go +++ b/snow/engine/snowman/block/mock_chain_vm.go @@ -142,21 +142,6 @@ func (mr *MockChainVMMockRecorder) CreateHandlers(arg0 interface{}) *gomock.Call return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHandlers", reflect.TypeOf((*MockChainVM)(nil).CreateHandlers), arg0) } -// CreateStaticHandlers mocks base method. -func (m *MockChainVM) CreateStaticHandlers(arg0 context.Context) (map[string]http.Handler, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateStaticHandlers", arg0) - ret0, _ := ret[0].(map[string]http.Handler) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreateStaticHandlers indicates an expected call of CreateStaticHandlers. -func (mr *MockChainVMMockRecorder) CreateStaticHandlers(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateStaticHandlers", reflect.TypeOf((*MockChainVM)(nil).CreateStaticHandlers), arg0) -} - // CrossChainAppRequest mocks base method. func (m *MockChainVM) CrossChainAppRequest(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 time.Time, arg4 []byte) error { m.ctrl.T.Helper() diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 7b9677dd7fc9..aec783441e80 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -17,7 +17,6 @@ import ( _ "github.com/ava-labs/avalanchego/tests/e2e/c" _ "github.com/ava-labs/avalanchego/tests/e2e/faultinjection" _ "github.com/ava-labs/avalanchego/tests/e2e/p" - _ "github.com/ava-labs/avalanchego/tests/e2e/static-handlers" _ "github.com/ava-labs/avalanchego/tests/e2e/x" _ "github.com/ava-labs/avalanchego/tests/e2e/x/transfer" ) diff --git a/tests/e2e/static-handlers/suites.go b/tests/e2e/static-handlers/suites.go deleted file mode 100644 index e18f16adaebf..000000000000 --- a/tests/e2e/static-handlers/suites.go +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Implements static handlers tests for avm and platformvm -package statichandlers - -import ( - "time" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/formatting" - "github.com/ava-labs/avalanchego/utils/formatting/address" - "github.com/ava-labs/avalanchego/utils/json" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/avm" - "github.com/ava-labs/avalanchego/vms/platformvm/api" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" -) - -var _ = ginkgo.Describe("[StaticHandlers]", func() { - require := require.New(ginkgo.GinkgoT()) - - ginkgo.It("can make calls to avm static api", - func() { - addrMap := map[string]string{} - for _, addrStr := range []string{ - "A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy", - "6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv", - "6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa", - "Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7", - } { - addr, err := ids.ShortFromString(addrStr) - require.NoError(err) - addrMap[addrStr], err = address.FormatBech32(constants.NetworkIDToHRP[constants.LocalID], addr[:]) - require.NoError(err) - } - avmArgs := avm.BuildGenesisArgs{ - Encoding: formatting.Hex, - GenesisData: map[string]avm.AssetDefinition{ - "asset1": { - Name: "myFixedCapAsset", - Symbol: "MFCA", - Denomination: 8, - InitialState: map[string][]interface{}{ - "fixedCap": { - avm.Holder{ - Amount: 100000, - Address: addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"], - }, - avm.Holder{ - Amount: 100000, - Address: addrMap["6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv"], - }, - avm.Holder{ - Amount: json.Uint64(50000), - Address: addrMap["6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa"], - }, - avm.Holder{ - Amount: json.Uint64(50000), - Address: addrMap["Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7"], - }, - }, - }, - }, - "asset2": { - Name: "myVarCapAsset", - Symbol: "MVCA", - InitialState: map[string][]interface{}{ - "variableCap": { - avm.Owners{ - Threshold: 1, - Minters: []string{ - addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"], - addrMap["6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv"], - }, - }, - avm.Owners{ - Threshold: 2, - Minters: []string{ - addrMap["6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa"], - addrMap["Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7"], - }, - }, - }, - }, - }, - "asset3": { - Name: "myOtherVarCapAsset", - InitialState: map[string][]interface{}{ - "variableCap": { - avm.Owners{ - Threshold: 1, - Minters: []string{ - addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"], - }, - }, - }, - }, - }, - }, - } - staticClient := avm.NewStaticClient(e2e.Env.GetRandomNodeURI().URI) - resp, err := staticClient.BuildGenesis(e2e.DefaultContext(), &avmArgs) - require.NoError(err) - require.Equal(resp.Bytes, "0x0000000000030006617373657431000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6d794669786564436170417373657400044d4643410800000001000000000000000400000007000000000000c350000000000000000000000001000000013f78e510df62bc48b0829ec06d6a6b98062d695300000007000000000000c35000000000000000000000000100000001c54903de5177a16f7811771ef2f4659d9e8646710000000700000000000186a0000000000000000000000001000000013f58fda2e9ea8d9e4b181832a07b26dae286f2cb0000000700000000000186a000000000000000000000000100000001645938bb7ae2193270e6ffef009e3664d11e07c10006617373657432000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d6d79566172436170417373657400044d5643410000000001000000000000000200000006000000000000000000000001000000023f58fda2e9ea8d9e4b181832a07b26dae286f2cb645938bb7ae2193270e6ffef009e3664d11e07c100000006000000000000000000000001000000023f78e510df62bc48b0829ec06d6a6b98062d6953c54903de5177a16f7811771ef2f4659d9e864671000661737365743300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000126d794f7468657256617243617041737365740000000000000100000000000000010000000600000000000000000000000100000001645938bb7ae2193270e6ffef009e3664d11e07c1279fa028") - }) - - ginkgo.It("can make calls to platformvm static api", func() { - keys := secp256k1.TestKeys() - - genesisUTXOs := make([]api.UTXO, len(keys)) - hrp := constants.NetworkIDToHRP[constants.UnitTestID] - for i, key := range keys { - id := key.PublicKey().Address() - addr, err := address.FormatBech32(hrp, id.Bytes()) - require.NoError(err) - genesisUTXOs[i] = api.UTXO{ - Amount: json.Uint64(50000 * units.MilliAvax), - Address: addr, - } - } - - genesisValidators := make([]api.GenesisPermissionlessValidator, len(keys)) - for i, key := range keys { - id := key.PublicKey().Address() - addr, err := address.FormatBech32(hrp, id.Bytes()) - require.NoError(err) - genesisValidators[i] = api.GenesisPermissionlessValidator{ - GenesisValidator: api.GenesisValidator{ - StartTime: json.Uint64(time.Date(1997, 1, 1, 0, 0, 0, 0, time.UTC).Unix()), - EndTime: json.Uint64(time.Date(1997, 1, 30, 0, 0, 0, 0, time.UTC).Unix()), - NodeID: ids.BuildTestNodeID(id[:]), - }, - RewardOwner: &api.Owner{ - Threshold: 1, - Addresses: []string{addr}, - }, - Staked: []api.UTXO{{ - Amount: json.Uint64(10000), - Address: addr, - }}, - DelegationFee: reward.PercentDenominator, - } - } - - buildGenesisArgs := api.BuildGenesisArgs{ - NetworkID: json.Uint32(constants.UnitTestID), - AvaxAssetID: ids.ID{'a', 'v', 'a', 'x'}, - UTXOs: genesisUTXOs, - Validators: genesisValidators, - Chains: nil, - Time: json.Uint64(time.Date(1997, 1, 1, 0, 0, 0, 0, time.UTC).Unix()), - InitialSupply: json.Uint64(360 * units.MegaAvax), - Encoding: formatting.Hex, - } - - staticClient := api.NewStaticClient(e2e.Env.GetRandomNodeURI().URI) - resp, err := staticClient.BuildGenesis(e2e.DefaultContext(), &buildGenesisArgs) - require.NoError(err) - require.Equal(resp.Bytes, "0x0000000000050000000000000000000000000000000000000000000000000000000000000000000000006176617800000000000000000000000000000000000000000000000000000000000000070000000ba43b740000000000000000000000000100000001fceda8f90fcb5d30614b99d79fc4baa293077626000000000000000000000000000000000000000000000000000000000000000000000000000000016176617800000000000000000000000000000000000000000000000000000000000000070000000ba43b7400000000000000000000000001000000016ead693c17abb1be422bb50b30b9711ff98d667e000000000000000000000000000000000000000000000000000000000000000000000000000000026176617800000000000000000000000000000000000000000000000000000000000000070000000ba43b740000000000000000000000000100000001f2420846876e69f473dda256172967e992f0ee31000000000000000000000000000000000000000000000000000000000000000000000000000000036176617800000000000000000000000000000000000000000000000000000000000000070000000ba43b7400000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000000000000000000000000000000000000000000000000000000000000000000000000000046176617800000000000000000000000000000000000000000000000000000000000000070000000ba43b74000000000000000000000000010000000187c4ec0736fdad03fd9ec8c3ba609de958601a7b00000000000000050000000c0000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fceda8f90fcb5d30614b99d79fc4baa2930776260000000032c9a9000000000032efe480000000000000271000000001617661780000000000000000000000000000000000000000000000000000000000000007000000000000271000000000000000000000000100000001fceda8f90fcb5d30614b99d79fc4baa2930776260000000b00000000000000000000000100000001fceda8f90fcb5d30614b99d79fc4baa29307762600000000000000000000000c0000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000006ead693c17abb1be422bb50b30b9711ff98d667e0000000032c9a9000000000032efe4800000000000002710000000016176617800000000000000000000000000000000000000000000000000000000000000070000000000002710000000000000000000000001000000016ead693c17abb1be422bb50b30b9711ff98d667e0000000b000000000000000000000001000000016ead693c17abb1be422bb50b30b9711ff98d667e00000000000000000000000c0000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f2420846876e69f473dda256172967e992f0ee310000000032c9a9000000000032efe480000000000000271000000001617661780000000000000000000000000000000000000000000000000000000000000007000000000000271000000000000000000000000100000001f2420846876e69f473dda256172967e992f0ee310000000b00000000000000000000000100000001f2420846876e69f473dda256172967e992f0ee3100000000000000000000000c0000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000032c9a9000000000032efe4800000000000002710000000016176617800000000000000000000000000000000000000000000000000000000000000070000000000002710000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000000000000000000000c0000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087c4ec0736fdad03fd9ec8c3ba609de958601a7b0000000032c9a9000000000032efe48000000000000027100000000161766178000000000000000000000000000000000000000000000000000000000000000700000000000027100000000000000000000000010000000187c4ec0736fdad03fd9ec8c3ba609de958601a7b0000000b0000000000000000000000010000000187c4ec0736fdad03fd9ec8c3ba609de958601a7b0000000000000000000000000000000032c9a90004fefa17b724000000008e96cbef") - }) -}) diff --git a/utils/constants/aliases.go b/utils/constants/aliases.go index 494165019688..dd8388246d39 100644 --- a/utils/constants/aliases.go +++ b/utils/constants/aliases.go @@ -3,10 +3,5 @@ package constants -const ( - // ChainAliasPrefix denotes a prefix for an alias that belongs to a blockchain ID. - ChainAliasPrefix string = "bc" - - // VMAliasPrefix denotes a prefix for an alias that belongs to a VM ID. - VMAliasPrefix string = "vm" -) +// ChainAliasPrefix denotes a prefix for an alias that belongs to a blockchain ID. +const ChainAliasPrefix string = "bc" diff --git a/vms/avm/static_client.go b/vms/avm/static_client.go deleted file mode 100644 index f31634313aac..000000000000 --- a/vms/avm/static_client.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package avm - -import ( - "context" - - "github.com/ava-labs/avalanchego/utils/rpc" -) - -var _ StaticClient = (*staticClient)(nil) - -// StaticClient for interacting with the AVM static api -type StaticClient interface { - BuildGenesis(ctx context.Context, args *BuildGenesisArgs, options ...rpc.Option) (*BuildGenesisReply, error) -} - -// staticClient is an implementation of an AVM client for interacting with the -// avm static api -type staticClient struct { - requester rpc.EndpointRequester -} - -// NewClient returns an AVM client for interacting with the avm static api -func NewStaticClient(uri string) StaticClient { - return &staticClient{requester: rpc.NewEndpointRequester( - uri + "/ext/vm/avm", - )} -} - -func (c *staticClient) BuildGenesis(ctx context.Context, args *BuildGenesisArgs, options ...rpc.Option) (resp *BuildGenesisReply, err error) { - resp = &BuildGenesisReply{} - err = c.requester.SendRequest(ctx, "avm.buildGenesis", args, resp, options...) - return resp, err -} diff --git a/vms/avm/static_service_test.go b/vms/avm/static_service_test.go deleted file mode 100644 index d5bd645190a2..000000000000 --- a/vms/avm/static_service_test.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package avm - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/formatting" - "github.com/ava-labs/avalanchego/utils/formatting/address" - "github.com/ava-labs/avalanchego/utils/json" -) - -var addrStrArray = []string{ - "A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy", - "6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv", - "6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa", - "Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7", -} - -func TestBuildGenesis(t *testing.T) { - require := require.New(t) - - ss := CreateStaticService() - addrMap := map[string]string{} - for _, addrStr := range addrStrArray { - addr, err := ids.ShortFromString(addrStr) - require.NoError(err) - addrMap[addrStr], err = address.FormatBech32(constants.UnitTestHRP, addr[:]) - require.NoError(err) - } - args := BuildGenesisArgs{ - Encoding: formatting.Hex, - GenesisData: map[string]AssetDefinition{ - "asset1": { - Name: "myFixedCapAsset", - Symbol: "MFCA", - Denomination: 8, - InitialState: map[string][]interface{}{ - "fixedCap": { - Holder{ - Amount: 100000, - Address: addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"], - }, - Holder{ - Amount: 100000, - Address: addrMap["6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv"], - }, - Holder{ - Amount: json.Uint64(startBalance), - Address: addrMap["6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa"], - }, - Holder{ - Amount: json.Uint64(startBalance), - Address: addrMap["Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7"], - }, - }, - }, - }, - "asset2": { - Name: "myVarCapAsset", - Symbol: "MVCA", - InitialState: map[string][]interface{}{ - "variableCap": { - Owners{ - Threshold: 1, - Minters: []string{ - addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"], - addrMap["6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv"], - }, - }, - Owners{ - Threshold: 2, - Minters: []string{ - addrMap["6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa"], - addrMap["Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7"], - }, - }, - }, - }, - }, - "asset3": { - Name: "myOtherVarCapAsset", - InitialState: map[string][]interface{}{ - "variableCap": { - Owners{ - Threshold: 1, - Minters: []string{ - addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"], - }, - }, - }, - }, - }, - }, - } - reply := BuildGenesisReply{} - require.NoError(ss.BuildGenesis(nil, &args, &reply)) -} diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 59907c934e91..2b3577082813 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -362,17 +362,6 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) { }, err } -func (*VM) CreateStaticHandlers(context.Context) (map[string]http.Handler, error) { - server := rpc.NewServer() - codec := json.NewCodec() - server.RegisterCodec(codec, "application/json") - server.RegisterCodec(codec, "application/json;charset=UTF-8") - staticService := CreateStaticService() - return map[string]http.Handler{ - "": server, - }, server.RegisterService(staticService, "avm") -} - /* ****************************************************************************** ********************************** Chain VM ********************************** diff --git a/vms/example/xsvm/vm.go b/vms/example/xsvm/vm.go index b69360f838d7..f090ff468fe2 100644 --- a/vms/example/xsvm/vm.go +++ b/vms/example/xsvm/vm.go @@ -112,10 +112,6 @@ func (*VM) Version(context.Context) (string, error) { return Version.String(), nil } -func (*VM) CreateStaticHandlers(context.Context) (map[string]http.Handler, error) { - return nil, nil -} - func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) { server := rpc.NewServer() server.RegisterCodec(json.NewCodec(), "application/json") diff --git a/vms/platformvm/api/static_client.go b/vms/platformvm/api/static_client.go deleted file mode 100644 index c10943fe19d9..000000000000 --- a/vms/platformvm/api/static_client.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package api - -import ( - "context" - - "github.com/ava-labs/avalanchego/utils/rpc" -) - -var _ StaticClient = (*staticClient)(nil) - -// StaticClient for interacting with the platformvm static api -type StaticClient interface { - BuildGenesis( - ctx context.Context, - args *BuildGenesisArgs, - options ...rpc.Option, - ) (*BuildGenesisReply, error) -} - -// staticClient is an implementation of a platformvm client for interacting with -// the platformvm static api -type staticClient struct { - requester rpc.EndpointRequester -} - -// NewClient returns a platformvm client for interacting with the platformvm static api -func NewStaticClient(uri string) StaticClient { - return &staticClient{requester: rpc.NewEndpointRequester( - uri + "/ext/vm/platform", - )} -} - -func (c *staticClient) BuildGenesis( - ctx context.Context, - args *BuildGenesisArgs, - options ...rpc.Option, -) (resp *BuildGenesisReply, err error) { - resp = &BuildGenesisReply{} - err = c.requester.SendRequest(ctx, "platform.buildGenesis", args, resp, options...) - return resp, err -} diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 33053aef97f7..746826666c6d 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -35,7 +35,6 @@ import ( "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -508,18 +507,6 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]http.Handler, error) { }, err } -// CreateStaticHandlers returns a map where: -// * keys are API endpoint extensions -// * values are API handlers -func (*VM) CreateStaticHandlers(context.Context) (map[string]http.Handler, error) { - server := rpc.NewServer() - server.RegisterCodec(json.NewCodec(), "application/json") - server.RegisterCodec(json.NewCodec(), "application/json;charset=UTF-8") - return map[string]http.Handler{ - "": server, - }, server.RegisterService(&api.StaticService{}, "platform") -} - func (vm *VM) Connected(_ context.Context, nodeID ids.NodeID, _ *version.Application) error { return vm.uptimeManager.Connect(nodeID, constants.PrimaryNetworkID) } diff --git a/vms/registry/mock_vm_registerer.go b/vms/registry/mock_vm_registerer.go deleted file mode 100644 index dbddd9ec02c3..000000000000 --- a/vms/registry/mock_vm_registerer.go +++ /dev/null @@ -1,65 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/registry (interfaces: VMRegisterer) - -// Package registry is a generated GoMock package. -package registry - -import ( - context "context" - reflect "reflect" - - ids "github.com/ava-labs/avalanchego/ids" - vms "github.com/ava-labs/avalanchego/vms" - gomock "go.uber.org/mock/gomock" -) - -// MockVMRegisterer is a mock of VMRegisterer interface. -type MockVMRegisterer struct { - ctrl *gomock.Controller - recorder *MockVMRegistererMockRecorder -} - -// MockVMRegistererMockRecorder is the mock recorder for MockVMRegisterer. -type MockVMRegistererMockRecorder struct { - mock *MockVMRegisterer -} - -// NewMockVMRegisterer creates a new mock instance. -func NewMockVMRegisterer(ctrl *gomock.Controller) *MockVMRegisterer { - mock := &MockVMRegisterer{ctrl: ctrl} - mock.recorder = &MockVMRegistererMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockVMRegisterer) EXPECT() *MockVMRegistererMockRecorder { - return m.recorder -} - -// Register mocks base method. -func (m *MockVMRegisterer) Register(arg0 context.Context, arg1 ids.ID, arg2 vms.Factory) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Register", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// Register indicates an expected call of Register. -func (mr *MockVMRegistererMockRecorder) Register(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Register", reflect.TypeOf((*MockVMRegisterer)(nil).Register), arg0, arg1, arg2) -} - -// RegisterWithReadLock mocks base method. -func (m *MockVMRegisterer) RegisterWithReadLock(arg0 context.Context, arg1 ids.ID, arg2 vms.Factory) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterWithReadLock", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// RegisterWithReadLock indicates an expected call of RegisterWithReadLock. -func (mr *MockVMRegistererMockRecorder) RegisterWithReadLock(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterWithReadLock", reflect.TypeOf((*MockVMRegisterer)(nil).RegisterWithReadLock), arg0, arg1, arg2) -} diff --git a/vms/registry/mock_vm_registry.go b/vms/registry/mock_vm_registry.go index eb54c8e65aab..4febab38fc5e 100644 --- a/vms/registry/mock_vm_registry.go +++ b/vms/registry/mock_vm_registry.go @@ -50,19 +50,3 @@ func (mr *MockVMRegistryMockRecorder) Reload(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reload", reflect.TypeOf((*MockVMRegistry)(nil).Reload), arg0) } - -// ReloadWithReadLock mocks base method. -func (m *MockVMRegistry) ReloadWithReadLock(arg0 context.Context) ([]ids.ID, map[ids.ID]error, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReloadWithReadLock", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(map[ids.ID]error) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// ReloadWithReadLock indicates an expected call of ReloadWithReadLock. -func (mr *MockVMRegistryMockRecorder) ReloadWithReadLock(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReloadWithReadLock", reflect.TypeOf((*MockVMRegistry)(nil).ReloadWithReadLock), arg0) -} diff --git a/vms/registry/vm_registerer.go b/vms/registry/vm_registerer.go deleted file mode 100644 index fec5fba78f57..000000000000 --- a/vms/registry/vm_registerer.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package registry - -import ( - "context" - "errors" - "fmt" - "net/http" - "path" - - "go.uber.org/zap" - - "github.com/ava-labs/avalanchego/api/server" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/vms" -) - -var ( - _ VMRegisterer = (*vmRegisterer)(nil) - - errNotVM = errors.New("not a VM") -) - -// VMRegisterer defines functionality to install a virtual machine. -type VMRegisterer interface { - registerer - // RegisterWithReadLock installs the VM assuming that the http read-lock is - // held. - RegisterWithReadLock(context.Context, ids.ID, vms.Factory) error -} - -type registerer interface { - // Register installs the VM. - Register(context.Context, ids.ID, vms.Factory) error -} - -// VMRegistererConfig configures settings for VMRegisterer. -type VMRegistererConfig struct { - APIServer server.Server - Log logging.Logger - VMFactoryLog logging.Logger - VMManager vms.Manager -} - -type vmRegisterer struct { - config VMRegistererConfig -} - -// NewVMRegisterer returns an instance of VMRegisterer -func NewVMRegisterer(config VMRegistererConfig) VMRegisterer { - return &vmRegisterer{ - config: config, - } -} - -func (r *vmRegisterer) Register(ctx context.Context, vmID ids.ID, factory vms.Factory) error { - return r.register(ctx, r.config.APIServer, vmID, factory) -} - -func (r *vmRegisterer) RegisterWithReadLock(ctx context.Context, vmID ids.ID, factory vms.Factory) error { - return r.register(ctx, server.PathWriterFromWithReadLock(r.config.APIServer), vmID, factory) -} - -func (r *vmRegisterer) register(ctx context.Context, pathAdder server.PathAdder, vmID ids.ID, factory vms.Factory) error { - if err := r.config.VMManager.RegisterFactory(ctx, vmID, factory); err != nil { - return err - } - handlers, err := r.createStaticHandlers(ctx, vmID, factory) - if err != nil { - return err - } - - // all static endpoints go to the vm endpoint, defaulting to the vm id - defaultEndpoint := path.Join(constants.VMAliasPrefix, vmID.String()) - - if err := r.createStaticEndpoints(pathAdder, handlers, defaultEndpoint); err != nil { - return err - } - urlAliases, err := r.getURLAliases(vmID, defaultEndpoint) - if err != nil { - return err - } - return pathAdder.AddAliases(defaultEndpoint, urlAliases...) -} - -// Creates a dedicated VM instance for the sole purpose of serving the static -// handlers. -func (r *vmRegisterer) createStaticHandlers( - ctx context.Context, - vmID ids.ID, - factory vms.Factory, -) (map[string]http.Handler, error) { - vm, err := factory.New(r.config.VMFactoryLog) - if err != nil { - return nil, err - } - - commonVM, ok := vm.(common.VM) - if !ok { - return nil, fmt.Errorf("%s is %w", vmID, errNotVM) - } - - handlers, err := commonVM.CreateStaticHandlers(ctx) - if err != nil { - r.config.Log.Error("failed to create static API endpoints", - zap.Stringer("vmID", vmID), - zap.Error(err), - ) - - if err := commonVM.Shutdown(ctx); err != nil { - return nil, fmt.Errorf("shutting down VM errored with: %w", err) - } - return nil, err - } - return handlers, nil -} - -func (r *vmRegisterer) createStaticEndpoints(pathAdder server.PathAdder, handlers map[string]http.Handler, defaultEndpoint string) error { - // register the static endpoints - for extension, service := range handlers { - r.config.Log.Verbo("adding static API endpoint", - zap.String("endpoint", defaultEndpoint), - zap.String("extension", extension), - ) - if err := pathAdder.AddRoute(service, defaultEndpoint, extension); err != nil { - return fmt.Errorf( - "failed to add static API endpoint %s%s: %w", - defaultEndpoint, - extension, - err, - ) - } - } - return nil -} - -func (r vmRegisterer) getURLAliases(vmID ids.ID, defaultEndpoint string) ([]string, error) { - aliases, err := r.config.VMManager.Aliases(vmID) - if err != nil { - return nil, err - } - - var urlAliases []string - for _, alias := range aliases { - urlAlias := path.Join(constants.VMAliasPrefix, alias) - if urlAlias != defaultEndpoint { - urlAliases = append(urlAliases, urlAlias) - } - } - return urlAliases, err -} - -type readRegisterer struct { - registerer VMRegisterer -} - -func (r readRegisterer) Register(ctx context.Context, vmID ids.ID, factory vms.Factory) error { - return r.registerer.RegisterWithReadLock(ctx, vmID, factory) -} diff --git a/vms/registry/vm_registerer_test.go b/vms/registry/vm_registerer_test.go deleted file mode 100644 index 666a9174525a..000000000000 --- a/vms/registry/vm_registerer_test.go +++ /dev/null @@ -1,436 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package registry - -import ( - "context" - "net/http" - "path" - "testing" - - "github.com/stretchr/testify/require" - - "go.uber.org/mock/gomock" - - "github.com/ava-labs/avalanchego/api/server" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/vms" -) - -var id = ids.GenerateTestID() - -// Register should succeed even if we can't register a VM -func TestRegisterRegisterVMFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - - // We fail to register the VM - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(errTest) - - err := resources.registerer.Register(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests Register if a VM doesn't actually implement VM. -func TestRegisterBadVM(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := "this is not a vm..." - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - // Since this factory produces a bad vm, we should get an error. - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - - err := resources.registerer.Register(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errNotVM) -} - -// Tests Register if creating endpoints for a VM fails + shutdown fails -func TestRegisterCreateHandlersAndShutdownFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - // We fail to create handlers + fail to shutdown - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(nil, errTest).Times(1) - vm.EXPECT().Shutdown(gomock.Any()).Return(errTest).Times(1) - - err := resources.registerer.Register(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests Register if creating endpoints for a VM fails + shutdown succeeds -func TestRegisterCreateHandlersFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - // We fail to create handlers + but succeed our shutdown - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(nil, errTest).Times(1) - vm.EXPECT().Shutdown(gomock.Any()).Return(nil).Times(1) - - err := resources.registerer.Register(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests Register if we fail to register the new endpoint on the server. -func TestRegisterAddRouteFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - handlers := map[string]http.Handler{ - "foo": nil, - } - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(handlers, nil).Times(1) - // We fail to create an endpoint for the handler - resources.mockServer.EXPECT(). - AddRoute( - handlers["foo"], - path.Join(constants.VMAliasPrefix, id.String()), - "foo", - ). - Times(1). - Return(errTest) - - err := resources.registerer.Register(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests Register we can't find the alias for the newly registered vm -func TestRegisterAliasLookupFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - handlers := map[string]http.Handler{ - "foo": nil, - } - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(handlers, nil).Times(1) - // Registering the route fails - resources.mockServer.EXPECT(). - AddRoute( - handlers["foo"], - path.Join(constants.VMAliasPrefix, id.String()), - "foo", - ). - Times(1). - Return(nil) - resources.mockManager.EXPECT().Aliases(id).Times(1).Return(nil, errTest) - - err := resources.registerer.Register(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests Register if adding aliases for the newly registered vm fails -func TestRegisterAddAliasesFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - handlers := map[string]http.Handler{ - "foo": nil, - } - aliases := []string{"alias-1", "alias-2"} - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(handlers, nil).Times(1) - resources.mockServer.EXPECT(). - AddRoute( - handlers["foo"], - path.Join(constants.VMAliasPrefix, id.String()), - "foo", - ). - Times(1). - Return(nil) - resources.mockManager.EXPECT().Aliases(id).Times(1).Return(aliases, nil) - // Adding aliases fails - resources.mockServer.EXPECT(). - AddAliases( - path.Join(constants.VMAliasPrefix, id.String()), - path.Join(constants.VMAliasPrefix, aliases[0]), - path.Join(constants.VMAliasPrefix, aliases[1]), - ). - Return(errTest) - - err := resources.registerer.Register(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests Register if no errors are thrown -func TestRegisterHappyCase(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - handlers := map[string]http.Handler{ - "foo": nil, - } - aliases := []string{"alias-1", "alias-2"} - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(handlers, nil).Times(1) - resources.mockServer.EXPECT(). - AddRoute( - handlers["foo"], - path.Join(constants.VMAliasPrefix, id.String()), - "foo", - ). - Times(1). - Return(nil) - resources.mockManager.EXPECT().Aliases(id).Times(1).Return(aliases, nil) - resources.mockServer.EXPECT(). - AddAliases( - path.Join(constants.VMAliasPrefix, id.String()), - path.Join(constants.VMAliasPrefix, aliases[0]), - path.Join(constants.VMAliasPrefix, aliases[1]), - ). - Times(1). - Return(nil) - - require.NoError(t, resources.registerer.Register(context.Background(), id, vmFactory)) -} - -// RegisterWithReadLock should succeed even if we can't register a VM -func TestRegisterWithReadLockRegisterVMFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - - // We fail to register the VM - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(errTest) - - err := resources.registerer.RegisterWithReadLock(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests RegisterWithReadLock if a VM doesn't actually implement VM. -func TestRegisterWithReadLockBadVM(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := "this is not a vm..." - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - // Since this factory produces a bad vm, we should get an error. - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - - err := resources.registerer.RegisterWithReadLock(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errNotVM) -} - -// Tests RegisterWithReadLock if creating endpoints for a VM fails + shutdown fails -func TestRegisterWithReadLockCreateHandlersAndShutdownFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - // We fail to create handlers + fail to shutdown - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(nil, errTest).Times(1) - vm.EXPECT().Shutdown(gomock.Any()).Return(errTest).Times(1) - - err := resources.registerer.RegisterWithReadLock(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests RegisterWithReadLock if creating endpoints for a VM fails + shutdown succeeds -func TestRegisterWithReadLockCreateHandlersFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - // We fail to create handlers + but succeed our shutdown - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(nil, errTest).Times(1) - vm.EXPECT().Shutdown(gomock.Any()).Return(nil).Times(1) - - err := resources.registerer.RegisterWithReadLock(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests RegisterWithReadLock if we fail to register the new endpoint on the server. -func TestRegisterWithReadLockAddRouteWithReadLockFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - handlers := map[string]http.Handler{ - "foo": nil, - } - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(handlers, nil).Times(1) - // We fail to create an endpoint for the handler - resources.mockServer.EXPECT(). - AddRouteWithReadLock( - handlers["foo"], - path.Join(constants.VMAliasPrefix, id.String()), - "foo", - ). - Times(1). - Return(errTest) - - err := resources.registerer.RegisterWithReadLock(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests RegisterWithReadLock we can't find the alias for the newly registered vm -func TestRegisterWithReadLockAliasLookupFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - handlers := map[string]http.Handler{ - "foo": nil, - } - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(handlers, nil).Times(1) - // RegisterWithReadLocking the route fails - resources.mockServer.EXPECT(). - AddRouteWithReadLock( - handlers["foo"], - path.Join(constants.VMAliasPrefix, id.String()), - "foo", - ). - Times(1). - Return(nil) - resources.mockManager.EXPECT().Aliases(id).Times(1).Return(nil, errTest) - - err := resources.registerer.RegisterWithReadLock(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests RegisterWithReadLock if adding aliases for the newly registered vm fails -func TestRegisterWithReadLockAddAliasesFails(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - handlers := map[string]http.Handler{ - "foo": nil, - } - aliases := []string{"alias-1", "alias-2"} - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(handlers, nil).Times(1) - resources.mockServer.EXPECT(). - AddRouteWithReadLock( - handlers["foo"], - path.Join(constants.VMAliasPrefix, id.String()), - "foo", - ). - Times(1). - Return(nil) - resources.mockManager.EXPECT().Aliases(id).Times(1).Return(aliases, nil) - // Adding aliases fails - resources.mockServer.EXPECT(). - AddAliasesWithReadLock( - path.Join(constants.VMAliasPrefix, id.String()), - path.Join(constants.VMAliasPrefix, aliases[0]), - path.Join(constants.VMAliasPrefix, aliases[1]), - ). - Return(errTest) - - err := resources.registerer.RegisterWithReadLock(context.Background(), id, vmFactory) - require.ErrorIs(t, err, errTest) -} - -// Tests RegisterWithReadLock if no errors are thrown -func TestRegisterWithReadLockHappyCase(t *testing.T) { - resources := initRegistererTest(t) - - vmFactory := vms.NewMockFactory(resources.ctrl) - vm := block.NewMockChainVM(resources.ctrl) - - handlers := map[string]http.Handler{ - "foo": nil, - } - aliases := []string{"alias-1", "alias-2"} - - resources.mockManager.EXPECT().RegisterFactory(gomock.Any(), id, vmFactory).Times(1).Return(nil) - vmFactory.EXPECT().New(logging.NoLog{}).Times(1).Return(vm, nil) - vm.EXPECT().CreateStaticHandlers(gomock.Any()).Return(handlers, nil).Times(1) - resources.mockServer.EXPECT(). - AddRouteWithReadLock( - handlers["foo"], - path.Join(constants.VMAliasPrefix, id.String()), - "foo", - ). - Times(1). - Return(nil) - resources.mockManager.EXPECT().Aliases(id).Times(1).Return(aliases, nil) - resources.mockServer.EXPECT(). - AddAliasesWithReadLock( - path.Join(constants.VMAliasPrefix, id.String()), - path.Join(constants.VMAliasPrefix, aliases[0]), - path.Join(constants.VMAliasPrefix, aliases[1]), - ). - Times(1). - Return(nil) - - require.NoError(t, resources.registerer.RegisterWithReadLock(context.Background(), id, vmFactory)) -} - -type vmRegistererTestResources struct { - ctrl *gomock.Controller - mockManager *vms.MockManager - mockServer *server.MockServer - registerer VMRegisterer -} - -func initRegistererTest(t *testing.T) *vmRegistererTestResources { - ctrl := gomock.NewController(t) - - mockManager := vms.NewMockManager(ctrl) - mockServer := server.NewMockServer(ctrl) - - registerer := NewVMRegisterer(VMRegistererConfig{ - APIServer: mockServer, - Log: logging.NoLog{}, - VMFactoryLog: logging.NoLog{}, - VMManager: mockManager, - }) - - return &vmRegistererTestResources{ - ctrl: ctrl, - mockManager: mockManager, - mockServer: mockServer, - registerer: registerer, - } -} diff --git a/vms/registry/vm_registry.go b/vms/registry/vm_registry.go index 3c8f5b942e25..1374c4d46b8e 100644 --- a/vms/registry/vm_registry.go +++ b/vms/registry/vm_registry.go @@ -7,6 +7,7 @@ import ( "context" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms" ) var _ VMRegistry = (*vmRegistry)(nil) @@ -16,15 +17,12 @@ var _ VMRegistry = (*vmRegistry)(nil) type VMRegistry interface { // Reload installs all non-installed vms on the node. Reload(ctx context.Context) ([]ids.ID, map[ids.ID]error, error) - // ReloadWithReadLock installs all non-installed vms on the node assuming - // the http read lock is currently held. - ReloadWithReadLock(ctx context.Context) ([]ids.ID, map[ids.ID]error, error) } // VMRegistryConfig defines configurations for VMRegistry type VMRegistryConfig struct { - VMGetter VMGetter - VMRegisterer VMRegisterer + VMGetter VMGetter + VMManager vms.Manager } type vmRegistry struct { @@ -39,16 +37,6 @@ func NewVMRegistry(config VMRegistryConfig) VMRegistry { } func (r *vmRegistry) Reload(ctx context.Context) ([]ids.ID, map[ids.ID]error, error) { - return r.reload(ctx, r.config.VMRegisterer) -} - -func (r *vmRegistry) ReloadWithReadLock(ctx context.Context) ([]ids.ID, map[ids.ID]error, error) { - return r.reload(ctx, readRegisterer{ - registerer: r.config.VMRegisterer, - }) -} - -func (r *vmRegistry) reload(ctx context.Context, registerer registerer) ([]ids.ID, map[ids.ID]error, error) { _, unregisteredVMs, err := r.config.VMGetter.Get() if err != nil { return nil, nil, err @@ -58,7 +46,7 @@ func (r *vmRegistry) reload(ctx context.Context, registerer registerer) ([]ids.I failedVMs := make(map[ids.ID]error) for vmID, factory := range unregisteredVMs { - if err := registerer.Register(ctx, vmID, factory); err != nil { + if err := r.config.VMManager.RegisterFactory(ctx, vmID, factory); err != nil { failedVMs[vmID] = err continue } diff --git a/vms/registry/vm_registry_test.go b/vms/registry/vm_registry_test.go index 5f5eccc1c204..12e39a7c29c9 100644 --- a/vms/registry/vm_registry_test.go +++ b/vms/registry/vm_registry_test.go @@ -47,12 +47,12 @@ func TestReload_Success(t *testing.T) { Get(). Times(1). Return(registeredVms, unregisteredVms, nil) - resources.mockVMRegisterer.EXPECT(). - Register(gomock.Any(), id3, factory3). + resources.mockVMManager.EXPECT(). + RegisterFactory(gomock.Any(), id3, factory3). Times(1). Return(nil) - resources.mockVMRegisterer.EXPECT(). - Register(gomock.Any(), id4, factory4). + resources.mockVMManager.EXPECT(). + RegisterFactory(gomock.Any(), id4, factory4). Times(1). Return(nil) @@ -101,12 +101,12 @@ func TestReload_PartialRegisterFailure(t *testing.T) { Get(). Times(1). Return(registeredVms, unregisteredVms, nil) - resources.mockVMRegisterer.EXPECT(). - Register(gomock.Any(), id3, factory3). + resources.mockVMManager.EXPECT(). + RegisterFactory(gomock.Any(), id3, factory3). Times(1). Return(errTest) - resources.mockVMRegisterer.EXPECT(). - Register(gomock.Any(), id4, factory4). + resources.mockVMManager.EXPECT(). + RegisterFactory(gomock.Any(), id4, factory4). Times(1). Return(nil) @@ -118,126 +118,30 @@ func TestReload_PartialRegisterFailure(t *testing.T) { require.Equal(id4, installedVMs[0]) } -// Tests the happy case where Reload succeeds. -func TestReloadWithReadLock_Success(t *testing.T) { - require := require.New(t) - - resources := initVMRegistryTest(t) - - factory1 := vms.NewMockFactory(resources.ctrl) - factory2 := vms.NewMockFactory(resources.ctrl) - factory3 := vms.NewMockFactory(resources.ctrl) - factory4 := vms.NewMockFactory(resources.ctrl) - - registeredVms := map[ids.ID]vms.Factory{ - id1: factory1, - id2: factory2, - } - - unregisteredVms := map[ids.ID]vms.Factory{ - id3: factory3, - id4: factory4, - } - - resources.mockVMGetter.EXPECT(). - Get(). - Times(1). - Return(registeredVms, unregisteredVms, nil) - resources.mockVMRegisterer.EXPECT(). - RegisterWithReadLock(gomock.Any(), id3, factory3). - Times(1). - Return(nil) - resources.mockVMRegisterer.EXPECT(). - RegisterWithReadLock(gomock.Any(), id4, factory4). - Times(1). - Return(nil) - - installedVMs, failedVMs, err := resources.vmRegistry.ReloadWithReadLock(context.Background()) - require.NoError(err) - require.ElementsMatch([]ids.ID{id3, id4}, installedVMs) - require.Empty(failedVMs) -} - -// Tests that we fail if we're not able to get the vms on disk -func TestReloadWithReadLock_GetNewVMsFails(t *testing.T) { - require := require.New(t) - - resources := initVMRegistryTest(t) - - resources.mockVMGetter.EXPECT().Get().Times(1).Return(nil, nil, errTest) - - installedVMs, failedVMs, err := resources.vmRegistry.ReloadWithReadLock(context.Background()) - require.ErrorIs(err, errTest) - require.Empty(installedVMs) - require.Empty(failedVMs) -} - -// Tests that if we fail to register a VM, we fail. -func TestReloadWithReadLock_PartialRegisterFailure(t *testing.T) { - require := require.New(t) - - resources := initVMRegistryTest(t) - - factory1 := vms.NewMockFactory(resources.ctrl) - factory2 := vms.NewMockFactory(resources.ctrl) - factory3 := vms.NewMockFactory(resources.ctrl) - factory4 := vms.NewMockFactory(resources.ctrl) - - registeredVms := map[ids.ID]vms.Factory{ - id1: factory1, - id2: factory2, - } - - unregisteredVms := map[ids.ID]vms.Factory{ - id3: factory3, - id4: factory4, - } - - resources.mockVMGetter.EXPECT(). - Get(). - Times(1). - Return(registeredVms, unregisteredVms, nil) - resources.mockVMRegisterer.EXPECT(). - RegisterWithReadLock(gomock.Any(), id3, factory3). - Times(1). - Return(errTest) - resources.mockVMRegisterer.EXPECT(). - RegisterWithReadLock(gomock.Any(), id4, factory4). - Times(1). - Return(nil) - - installedVMs, failedVMs, err := resources.vmRegistry.ReloadWithReadLock(context.Background()) - require.NoError(err) - require.Len(failedVMs, 1) - require.ErrorIs(failedVMs[id3], errTest) - require.Len(installedVMs, 1) - require.Equal(id4, installedVMs[0]) -} - type registryTestResources struct { - ctrl *gomock.Controller - mockVMGetter *MockVMGetter - mockVMRegisterer *MockVMRegisterer - vmRegistry VMRegistry + ctrl *gomock.Controller + mockVMGetter *MockVMGetter + mockVMManager *vms.MockManager + vmRegistry VMRegistry } func initVMRegistryTest(t *testing.T) *registryTestResources { ctrl := gomock.NewController(t) mockVMGetter := NewMockVMGetter(ctrl) - mockVMRegisterer := NewMockVMRegisterer(ctrl) + mockVMManager := vms.NewMockManager(ctrl) vmRegistry := NewVMRegistry( VMRegistryConfig{ - VMGetter: mockVMGetter, - VMRegisterer: mockVMRegisterer, + VMGetter: mockVMGetter, + VMManager: mockVMManager, }, ) return ®istryTestResources{ - ctrl: ctrl, - mockVMGetter: mockVMGetter, - mockVMRegisterer: mockVMRegisterer, - vmRegistry: vmRegistry, + ctrl: ctrl, + mockVMGetter: mockVMGetter, + mockVMManager: mockVMManager, + vmRegistry: vmRegistry, } } diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go index 0ee7882b96d9..3ca090011dd3 100644 --- a/vms/rpcchainvm/vm_client.go +++ b/vms/rpcchainvm/vm_client.go @@ -375,25 +375,6 @@ func (vm *VMClient) CreateHandlers(ctx context.Context) (map[string]http.Handler return handlers, nil } -func (vm *VMClient) CreateStaticHandlers(ctx context.Context) (map[string]http.Handler, error) { - resp, err := vm.client.CreateStaticHandlers(ctx, &emptypb.Empty{}) - if err != nil { - return nil, err - } - - handlers := make(map[string]http.Handler, len(resp.Handlers)) - for _, handler := range resp.Handlers { - clientConn, err := grpcutils.Dial(handler.ServerAddr) - if err != nil { - return nil, err - } - - vm.conns = append(vm.conns, clientConn) - handlers[handler.Prefix] = ghttp.NewClient(httppb.NewHTTPClient(clientConn)) - } - return handlers, nil -} - func (vm *VMClient) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { _, err := vm.client.Connected(ctx, &vmpb.ConnectedRequest{ NodeId: nodeID.Bytes(), diff --git a/vms/rpcchainvm/vm_server.go b/vms/rpcchainvm/vm_server.go index 4338d87f1ed2..5c0c22de1ae9 100644 --- a/vms/rpcchainvm/vm_server.go +++ b/vms/rpcchainvm/vm_server.go @@ -337,32 +337,6 @@ func (vm *VMServer) CreateHandlers(ctx context.Context, _ *emptypb.Empty) (*vmpb return resp, nil } -func (vm *VMServer) CreateStaticHandlers(ctx context.Context, _ *emptypb.Empty) (*vmpb.CreateStaticHandlersResponse, error) { - handlers, err := vm.vm.CreateStaticHandlers(ctx) - if err != nil { - return nil, err - } - resp := &vmpb.CreateStaticHandlersResponse{} - for prefix, handler := range handlers { - serverListener, err := grpcutils.NewListener() - if err != nil { - return nil, err - } - server := grpcutils.NewServer() - vm.serverCloser.Add(server) - httppb.RegisterHTTPServer(server, ghttp.NewServer(handler)) - - // Start HTTP service - go grpcutils.Serve(serverListener, server) - - resp.Handlers = append(resp.Handlers, &vmpb.Handler{ - Prefix: prefix, - ServerAddr: serverListener.Addr().String(), - }) - } - return resp, nil -} - func (vm *VMServer) Connected(ctx context.Context, req *vmpb.ConnectedRequest) (*emptypb.Empty, error) { nodeID, err := ids.ToNodeID(req.NodeId) if err != nil { From 26e329a66f2a53e1286a54f9868a214609d99f01 Mon Sep 17 00:00:00 2001 From: marun Date: Wed, 17 Jan 2024 16:49:44 +0100 Subject: [PATCH 251/267] `tmpnet`: Add support for subnets (#2492) --- tests/e2e/e2e_test.go | 3 +- tests/fixture/e2e/env.go | 60 ++++- tests/fixture/e2e/flags.go | 19 +- tests/fixture/e2e/helpers.go | 25 +- tests/fixture/tmpnet/README.md | 61 +++-- tests/fixture/tmpnet/cmd/main.go | 50 ++-- tests/fixture/tmpnet/defaults.go | 13 +- tests/fixture/tmpnet/network.go | 314 ++++++++++++++++++++--- tests/fixture/tmpnet/network_config.go | 18 +- tests/fixture/tmpnet/network_test.go | 5 +- tests/fixture/tmpnet/node.go | 9 + tests/fixture/tmpnet/subnet.go | 333 +++++++++++++++++++++++++ tests/upgrade/upgrade_test.go | 4 +- 13 files changed, 825 insertions(+), 89 deletions(-) create mode 100644 tests/fixture/tmpnet/subnet.go diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index aec783441e80..d363ff775086 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -11,6 +11,7 @@ import ( "github.com/onsi/gomega" "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" // ensure test packages are scanned by ginkgo _ "github.com/ava-labs/avalanchego/tests/e2e/banff" @@ -34,7 +35,7 @@ func init() { var _ = ginkgo.SynchronizedBeforeSuite(func() []byte { // Run only once in the first ginkgo process - return e2e.NewTestEnvironment(flagVars).Marshal() + return e2e.NewTestEnvironment(flagVars, &tmpnet.Network{}).Marshal() }, func(envBytes []byte) { // Run in every ginkgo process diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index d87c0985edd6..9019c9438b9e 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -14,6 +14,8 @@ import ( "github.com/stretchr/testify/require" + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/tests" "github.com/ava-labs/avalanchego/tests/fixture" "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" @@ -29,10 +31,9 @@ var Env *TestEnvironment func InitSharedTestEnvironment(envBytes []byte) { require := require.New(ginkgo.GinkgoT()) require.Nil(Env, "env already initialized") - Env = &TestEnvironment{ - require: require, - } + Env = &TestEnvironment{} require.NoError(json.Unmarshal(envBytes, Env)) + Env.require = require } type TestEnvironment struct { @@ -53,7 +54,7 @@ func (te *TestEnvironment) Marshal() []byte { } // Initialize a new test environment with a shared network (either pre-existing or newly created). -func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { +func NewTestEnvironment(flagVars *FlagVars, desiredNetwork *tmpnet.Network) *TestEnvironment { require := require.New(ginkgo.GinkgoT()) networkDir := flagVars.NetworkDir() @@ -65,10 +66,44 @@ func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { network, err = tmpnet.ReadNetwork(networkDir) require.NoError(err) tests.Outf("{{yellow}}Using an existing network configured at %s{{/}}\n", network.Dir) + + // Set the desired subnet configuration to ensure subsequent creation. + for _, subnet := range desiredNetwork.Subnets { + if existing := network.GetSubnet(subnet.Name); existing != nil { + // Already present + continue + } + network.Subnets = append(network.Subnets, subnet) + } } else { - network = StartNetwork(flagVars.AvalancheGoExecPath(), DefaultNetworkDir) + network = desiredNetwork + StartNetwork(network, DefaultNetworkDir, flagVars.AvalancheGoExecPath(), flagVars.PluginDir()) } + // A new network will always need subnet creation and an existing + // network will also need subnets to be created the first time it + // is used. + require.NoError(network.CreateSubnets(DefaultContext(), ginkgo.GinkgoWriter)) + + // Wait for chains to have bootstrapped on all nodes + Eventually(func() bool { + for _, subnet := range network.Subnets { + for _, validatorID := range subnet.ValidatorIDs { + uri, err := network.GetURIForNodeID(validatorID) + require.NoError(err) + infoClient := info.NewClient(uri) + for _, chain := range subnet.Chains { + isBootstrapped, err := infoClient.IsBootstrapped(DefaultContext(), chain.ChainID.String()) + // Ignore errors since a chain id that is not yet known will result in a recoverable error. + if err != nil || !isBootstrapped { + return false + } + } + } + } + return true + }, DefaultTimeout, DefaultPollingInterval, "failed to see all chains bootstrap before timeout") + uris := network.GetNodeURIs() require.NotEmpty(uris, "network contains no nodes") tests.Outf("{{green}}network URIs: {{/}} %+v\n", uris) @@ -83,6 +118,7 @@ func NewTestEnvironment(flagVars *FlagVars) *TestEnvironment { NetworkDir: network.Dir, URIs: uris, TestDataServerURI: testDataServerURI, + require: require, } } @@ -127,10 +163,22 @@ func (te *TestEnvironment) NewPrivateNetwork() *tmpnet.Network { sharedNetwork, err := tmpnet.ReadNetwork(te.NetworkDir) te.require.NoError(err) + network := &tmpnet.Network{} + // The private networks dir is under the shared network dir to ensure it // will be included in the artifact uploaded in CI. privateNetworksDir := filepath.Join(sharedNetwork.Dir, PrivateNetworksDirName) te.require.NoError(os.MkdirAll(privateNetworksDir, perms.ReadWriteExecute)) - return StartNetwork(sharedNetwork.DefaultRuntimeConfig.AvalancheGoPath, privateNetworksDir) + pluginDir, err := sharedNetwork.DefaultFlags.GetStringVal(config.PluginDirKey) + te.require.NoError(err) + + StartNetwork( + network, + privateNetworksDir, + sharedNetwork.DefaultRuntimeConfig.AvalancheGoPath, + pluginDir, + ) + + return network } diff --git a/tests/fixture/e2e/flags.go b/tests/fixture/e2e/flags.go index 6cedf003b3a3..2a00df97a885 100644 --- a/tests/fixture/e2e/flags.go +++ b/tests/fixture/e2e/flags.go @@ -13,10 +13,19 @@ import ( type FlagVars struct { avalancheGoExecPath string + pluginDir string networkDir string useExistingNetwork bool } +func (v *FlagVars) AvalancheGoExecPath() string { + return v.avalancheGoExecPath +} + +func (v *FlagVars) PluginDir() string { + return v.pluginDir +} + func (v *FlagVars) NetworkDir() string { if !v.useExistingNetwork { return "" @@ -27,10 +36,6 @@ func (v *FlagVars) NetworkDir() string { return os.Getenv(tmpnet.NetworkDirEnvName) } -func (v *FlagVars) AvalancheGoExecPath() string { - return v.avalancheGoExecPath -} - func (v *FlagVars) UseExistingNetwork() bool { return v.useExistingNetwork } @@ -43,6 +48,12 @@ func RegisterFlags() *FlagVars { os.Getenv(tmpnet.AvalancheGoPathEnvName), fmt.Sprintf("avalanchego executable path (required if not using an existing network). Also possible to configure via the %s env variable.", tmpnet.AvalancheGoPathEnvName), ) + flag.StringVar( + &vars.pluginDir, + "plugin-dir", + os.ExpandEnv("$HOME/.avalanchego/plugins"), + "[optional] the dir containing VM plugins.", + ) flag.StringVar( &vars.networkDir, "network-dir", diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 706af72dde05..c1d87a4beba8 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -34,15 +34,15 @@ const ( // contention. DefaultTimeout = 2 * time.Minute - // Interval appropriate for network operations that should be - // retried periodically but not too often. - DefaultPollingInterval = 500 * time.Millisecond + DefaultPollingInterval = tmpnet.DefaultPollingInterval // Setting this env will disable post-test bootstrap // checks. Useful for speeding up iteration during test // development. SkipBootstrapChecksEnvName = "E2E_SKIP_BOOTSTRAP_CHECKS" + DefaultValidatorStartTimeDiff = tmpnet.DefaultValidatorStartTimeDiff + DefaultGasLimit = uint64(21000) // Standard gas limit // An empty string prompts the use of the default path which ensures a @@ -217,13 +217,20 @@ func CheckBootstrapIsPossible(network *tmpnet.Network) { } // Start a temporary network with the provided avalanchego binary. -func StartNetwork(avalancheGoExecPath string, rootNetworkDir string) *tmpnet.Network { +func StartNetwork(network *tmpnet.Network, rootNetworkDir string, avalancheGoExecPath string, pluginDir string) { require := require.New(ginkgo.GinkgoT()) - network, err := tmpnet.NewDefaultNetwork(ginkgo.GinkgoWriter, avalancheGoExecPath, tmpnet.DefaultNodeCount) - require.NoError(err) - require.NoError(network.Create(rootNetworkDir)) - require.NoError(network.Start(DefaultContext(), ginkgo.GinkgoWriter)) + require.NoError( + tmpnet.StartNewNetwork( + DefaultContext(), + ginkgo.GinkgoWriter, + network, + rootNetworkDir, + avalancheGoExecPath, + pluginDir, + tmpnet.DefaultNodeCount, + ), + ) ginkgo.DeferCleanup(func() { tests.Outf("Shutting down network\n") @@ -233,6 +240,4 @@ func StartNetwork(avalancheGoExecPath string, rootNetworkDir string) *tmpnet.Net }) tests.Outf("{{green}}Successfully started network{{/}}\n") - - return network } diff --git a/tests/fixture/tmpnet/README.md b/tests/fixture/tmpnet/README.md index abccbf52cf79..909a29c6ee12 100644 --- a/tests/fixture/tmpnet/README.md +++ b/tests/fixture/tmpnet/README.md @@ -34,6 +34,7 @@ the following non-test files: | node.go | Node | Orchestrates and configures nodes | | node_config.go | Node | Reads and writes node configuration | | node_process.go | NodeProcess | Orchestrates node processes | +| subnet.go | Subnet | Orchestrates subnets | | utils.go | | Defines shared utility functions | ## Usage @@ -74,16 +75,33 @@ network. A temporary network can be managed in code: ```golang -network, _ := tmpnet.NewDefaultNetwork( +network := &tmpnet.Network{ // Configure non-default values for the new network + DefaultFlags: tmpnet.FlagsMap{ + config.LogLevelKey: "INFO", // Change one of the network's defaults + }, + Subnets: []*tmpnet.Subnet{ // Subnets to create on the new network once it is running + { + Name: "xsvm-a", // User-defined name used to reference subnet in code and on disk + Chains: []*tmpnet.Chain{ + { + VMName: "xsvm", // Name of the VM the chain will run, will be used to derive the name of the VM binary + Genesis: , // Genesis bytes used to initialize the custom chain + PreFundedKey: , // (Optional) A private key that is funded in the genesis bytes + }, + }, + }, + }, +} + +_ := tmpnet.StartNewNetwork( // Start the network + ctx, // Context used to limit duration of waiting for network health ginkgo.GinkgoWriter, // Writer to report progress of initialization + network, + "", // Empty string uses the default network path (~/tmpnet/networks) "/path/to/avalanchego", // The path to the binary that nodes will execute + "/path/to/plugins", // The path nodes will use for plugin binaries (suggested value ~/.avalanchego/plugins) 5, // Number of initial validating nodes ) -_ = network.Create("") // Finalize network configuration and write to disk -_ = network.Start( // Start the nodes of the network and wait until they report healthy - ctx, // Context used to limit duration of waiting for network health - ginkgo.GinkgoWriter, // Writer to report progress of network start -) uris := network.GetNodeURIs() @@ -125,11 +143,16 @@ HOME │ │ └── ... │ └── process.json // Node process details (PID, API URI, staking address) ├── chains - │ └── C - │ └── config.json // C-Chain config for all nodes + │ ├── C + │ │ └── config.json // C-Chain config for all nodes + │ └── raZ51bwfepaSaZ1MNSRNYNs3ZPfj...U7pa3 + │ └── config.json // Custom chain configuration for all nodes ├── config.json // Common configuration (including defaults and pre-funded keys) ├── genesis.json // Genesis for all nodes - └── network.env // Sets network dir env var to simplify network usage + ├── network.env // Sets network dir env var to simplify network usage + └── subnets // Parent directory for subnet definitions + ├─ subnet-a.json // Configuration for subnet-a and its chain(s) + └─ subnet-b.json // Configuration for subnet-b and its chain(s) ``` ### Common networking configuration @@ -148,17 +171,19 @@ content will be generated with reasonable defaults if not supplied. Each node in the network can override the default by setting an explicit value for `--genesis-file` or `--genesis-file-content`. -### C-Chain config +### Chain configuration -The C-Chain config for a temporary network is stored at -`[network-dir]/chains/C/config.json` and referenced by default by all -nodes in the network. The C-Chain config will be generated with -reasonable defaults if not supplied. Each node in the network can -override the default by setting an explicit value for -`--chain-config-dir` and ensuring the C-Chain config file exists at -`[chain-config-dir]/C/config.json`. +The chain configuration for a temporary network is stored at +`[network-dir]/chains/[chain alias or ID]/config.json` and referenced +by all nodes in the network. The C-Chain config will be generated with +reasonable defaults if not supplied. X-Chain and P-Chain will use +implicit defaults. The configuration for custom chains can be provided +with subnet configuration and will be writen to the appropriate path. -TODO(marun) Enable configuration of X-Chain and P-Chain. +Each node in the network can override network-level chain +configuration by setting `--chain-config-dir` to an explicit value and +ensuring that configuration files for all chains exist at +`[custom-chain-config-dir]/[chain alias or ID]/config.json`. ### Network env diff --git a/tests/fixture/tmpnet/cmd/main.go b/tests/fixture/tmpnet/cmd/main.go index 1ab3f2648325..dd59c300bbb3 100644 --- a/tests/fixture/tmpnet/cmd/main.go +++ b/tests/fixture/tmpnet/cmd/main.go @@ -26,10 +26,12 @@ var ( ) func main() { + var networkDir string rootCmd := &cobra.Command{ Use: "tmpnetctl", Short: "tmpnetctl commands", } + rootCmd.PersistentFlags().StringVar(&networkDir, "network-dir", os.Getenv(tmpnet.NetworkDirEnvName), "The path to the configuration directory of a temporary network") versionCmd := &cobra.Command{ Use: "version", @@ -46,35 +48,38 @@ func main() { rootCmd.AddCommand(versionCmd) var ( - rootDir string - execPath string - nodeCount uint8 + rootDir string + avalancheGoPath string + pluginDir string + nodeCount uint8 ) startNetworkCmd := &cobra.Command{ Use: "start-network", Short: "Start a new temporary network", RunE: func(*cobra.Command, []string) error { - if len(execPath) == 0 { + if len(avalancheGoPath) == 0 { return errAvalancheGoRequired } // Root dir will be defaulted on start if not provided - network, err := tmpnet.NewDefaultNetwork(os.Stdout, execPath, int(nodeCount)) - if err != nil { - return err - } - - if err := network.Create(rootDir); err != nil { - return err - } + network := &tmpnet.Network{} // Extreme upper bound, should never take this long networkStartTimeout := 2 * time.Minute ctx, cancel := context.WithTimeout(context.Background(), networkStartTimeout) defer cancel() - if err := network.Start(ctx, os.Stdout); err != nil { + err := tmpnet.StartNewNetwork( + ctx, + os.Stdout, + network, + rootDir, + avalancheGoPath, + pluginDir, + int(nodeCount), + ) + if err != nil { return err } @@ -98,11 +103,11 @@ func main() { }, } startNetworkCmd.PersistentFlags().StringVar(&rootDir, "root-dir", os.Getenv(tmpnet.RootDirEnvName), "The path to the root directory for temporary networks") - startNetworkCmd.PersistentFlags().StringVar(&execPath, "avalanchego-path", os.Getenv(tmpnet.AvalancheGoPathEnvName), "The path to an avalanchego binary") + startNetworkCmd.PersistentFlags().StringVar(&avalancheGoPath, "avalanchego-path", os.Getenv(tmpnet.AvalancheGoPathEnvName), "The path to an avalanchego binary") + startNetworkCmd.PersistentFlags().StringVar(&pluginDir, "plugin-dir", os.ExpandEnv("$HOME/.avalanchego/plugins"), "[optional] the dir containing VM plugins") startNetworkCmd.PersistentFlags().Uint8Var(&nodeCount, "node-count", tmpnet.DefaultNodeCount, "Number of nodes the network should initially consist of") rootCmd.AddCommand(startNetworkCmd) - var networkDir string stopNetworkCmd := &cobra.Command{ Use: "stop-network", Short: "Stop a temporary network", @@ -119,9 +124,22 @@ func main() { return nil }, } - stopNetworkCmd.PersistentFlags().StringVar(&networkDir, "network-dir", os.Getenv(tmpnet.NetworkDirEnvName), "The path to the configuration directory of a temporary network") rootCmd.AddCommand(stopNetworkCmd) + restartNetworkCmd := &cobra.Command{ + Use: "restart-network", + Short: "Restart a temporary network", + RunE: func(*cobra.Command, []string) error { + if len(networkDir) == 0 { + return errNetworkDirRequired + } + ctx, cancel := context.WithTimeout(context.Background(), tmpnet.DefaultNetworkTimeout) + defer cancel() + return tmpnet.RestartNetwork(ctx, os.Stdout, networkDir) + }, + } + rootCmd.AddCommand(restartNetworkCmd) + if err := rootCmd.Execute(); err != nil { fmt.Fprintf(os.Stderr, "tmpnetctl failed: %v\n", err) os.Exit(1) diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index ce09def2582a..2b88ef49afc1 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -7,9 +7,19 @@ import ( "time" "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" ) const ( + // Interval appropriate for network operations that should be + // retried periodically but not too often. + DefaultPollingInterval = 500 * time.Millisecond + + // Validator start time must be a minimum of SyncBound from the + // current time for validator addition to succeed, and adding 20 + // seconds provides a buffer in case of any delay in processing. + DefaultValidatorStartTimeDiff = executor.SyncBound + 20*time.Second + DefaultNetworkTimeout = 2 * time.Minute // Minimum required to ensure connectivity-based health checks will pass @@ -50,7 +60,8 @@ func DefaultChainConfigs() map[string]FlagsMap { // values will be used. Available C-Chain configuration options are // defined in the `github.com/ava-labs/coreth/evm` package. "C": { - "log-level": "trace", + "warp-api-enabled": true, + "log-level": "trace", }, } } diff --git a/tests/fixture/tmpnet/network.go b/tests/fixture/tmpnet/network.go index 3352f7dcb1cf..01829da70da5 100644 --- a/tests/fixture/tmpnet/network.go +++ b/tests/fixture/tmpnet/network.go @@ -5,6 +5,7 @@ package tmpnet import ( "context" + "encoding/hex" "errors" "fmt" "io" @@ -12,6 +13,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "time" "github.com/ava-labs/avalanchego/config" @@ -21,6 +23,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/perms" "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/platformvm" ) // The Network type is defined in this file (orchestration) and @@ -36,8 +39,26 @@ const ( // startup, as smaller intervals (e.g. 50ms) seemed to noticeably // increase the time for a network's nodes to be seen as healthy. networkHealthCheckInterval = 200 * time.Millisecond + + // eth address: 0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC + HardHatKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" ) +// HardhatKey is a legacy used for hardhat testing in subnet-evm +// TODO(marun) Remove when no longer needed. +var HardhatKey *secp256k1.PrivateKey + +func init() { + hardhatKeyBytes, err := hex.DecodeString(HardHatKeyStr) + if err != nil { + panic(err) + } + HardhatKey, err = secp256k1.ToPrivateKey(hardhatKeyBytes) + if err != nil { + panic(err) + } +} + // Collects the configuration for running a temporary avalanchego network type Network struct { // Path where network configuration and data is stored @@ -56,6 +77,9 @@ type Network struct { // Nodes that constitute the network Nodes []*Node + + // Subnets that have been enabled on the network + Subnets []*Subnet } // Ensure a real and absolute network dir so that node @@ -69,35 +93,22 @@ func toCanonicalDir(dir string) (string, error) { return filepath.EvalSymlinks(absDir) } -// Initializes a new network with default configuration. -func NewDefaultNetwork(w io.Writer, avalancheGoPath string, nodeCount int) (*Network, error) { - if _, err := fmt.Fprintf(w, "Preparing configuration for new network with %s\n", avalancheGoPath); err != nil { - return nil, err - } - - keys, err := NewPrivateKeys(DefaultPreFundedKeyCount) - if err != nil { - return nil, err - } - - network := &Network{ - DefaultFlags: DefaultFlags(), - DefaultRuntimeConfig: NodeRuntimeConfig{ - AvalancheGoPath: avalancheGoPath, - }, - PreFundedKeys: keys, - ChainConfigs: DefaultChainConfigs(), +func StartNewNetwork( + ctx context.Context, + w io.Writer, + network *Network, + rootNetworkDir string, + avalancheGoExecPath string, + pluginDir string, + nodeCount int, +) error { + if err := network.EnsureDefaultConfig(w, avalancheGoExecPath, pluginDir, nodeCount); err != nil { + return err } - - network.Nodes = make([]*Node, nodeCount) - for i := range network.Nodes { - network.Nodes[i] = NewNode("") - if err := network.EnsureNodeConfig(network.Nodes[i]); err != nil { - return nil, err - } + if err := network.Create(rootNetworkDir); err != nil { + return err } - - return network, nil + return network.Start(ctx, w) } // Stops the nodes of the network configured in the provided directory. @@ -109,6 +120,15 @@ func StopNetwork(ctx context.Context, dir string) error { return network.Stop(ctx) } +// Restarts the nodes of the network configured in the provided directory. +func RestartNetwork(ctx context.Context, w io.Writer, dir string) error { + network, err := ReadNetwork(dir) + if err != nil { + return err + } + return network.Restart(ctx, w) +} + // Reads a network from the provided directory. func ReadNetwork(dir string) (*Network, error) { canonicalDir, err := toCanonicalDir(dir) @@ -124,6 +144,68 @@ func ReadNetwork(dir string) (*Network, error) { return network, nil } +// Initializes a new network with default configuration. +func (n *Network) EnsureDefaultConfig(w io.Writer, avalancheGoPath string, pluginDir string, nodeCount int) error { + if _, err := fmt.Fprintf(w, "Preparing configuration for new network with %s\n", avalancheGoPath); err != nil { + return err + } + + // Ensure default flags + if n.DefaultFlags == nil { + n.DefaultFlags = FlagsMap{} + } + n.DefaultFlags.SetDefaults(DefaultFlags()) + + // Only configure the plugin dir with a non-empty value to ensure + // the use of the default value (`[datadir]/plugins`) when + // no plugin dir is configured. + if len(pluginDir) > 0 { + if _, ok := n.DefaultFlags[config.PluginDirKey]; !ok { + n.DefaultFlags[config.PluginDirKey] = pluginDir + } + } + + // Ensure pre-funded keys + if len(n.PreFundedKeys) == 0 { + keys, err := NewPrivateKeys(DefaultPreFundedKeyCount) + if err != nil { + return err + } + n.PreFundedKeys = keys + } + + // Ensure primary chains are configured + if n.ChainConfigs == nil { + n.ChainConfigs = map[string]FlagsMap{} + } + defaultChainConfigs := DefaultChainConfigs() + for alias, chainConfig := range defaultChainConfigs { + if _, ok := n.ChainConfigs[alias]; !ok { + n.ChainConfigs[alias] = FlagsMap{} + } + n.ChainConfigs[alias].SetDefaults(chainConfig) + } + + // Ensure runtime is configured + if len(n.DefaultRuntimeConfig.AvalancheGoPath) == 0 { + n.DefaultRuntimeConfig.AvalancheGoPath = avalancheGoPath + } + + // Ensure nodes are created + if len(n.Nodes) == 0 { + n.Nodes = NewNodes(nodeCount) + } + + // Ensure nodes are configured + for i := range n.Nodes { + if err := n.EnsureNodeConfig(n.Nodes[i]); err != nil { + return err + } + } + + return nil +} + // Creates the network on disk, choosing its network id and generating its genesis in the process. func (n *Network) Create(rootDir string) error { if len(rootDir) == 0 { @@ -170,8 +252,30 @@ func (n *Network) Create(rootDir string) error { } n.Dir = canonicalDir + pluginDir, err := n.DefaultFlags.GetStringVal(config.PluginDirKey) + if err != nil { + return err + } + if len(pluginDir) > 0 { + // Ensure the existence of the plugin directory or nodes won't be able to start. + if err := os.MkdirAll(pluginDir, perms.ReadWriteExecute); err != nil { + return fmt.Errorf("failed to create plugin dir: %w", err) + } + } + if n.Genesis == nil { - genesis, err := NewTestGenesis(networkID, n.Nodes, n.PreFundedKeys) + // Pre-fund known legacy keys to support ad-hoc testing. Usage of a legacy key will + // require knowing the key beforehand rather than retrieving it from the set of pre-funded + // keys exposed by a network. Since allocation will not be exclusive, a test using a + // legacy key is unlikely to be a good candidate for parallel execution. + keysToFund := []*secp256k1.PrivateKey{ + genesis.VMRQKey, + genesis.EWOQKey, + HardhatKey, + } + keysToFund = append(keysToFund, n.PreFundedKeys...) + + genesis, err := NewTestGenesis(networkID, n.Nodes, keysToFund) if err != nil { return err } @@ -317,6 +421,28 @@ func (n *Network) Stop(ctx context.Context) error { return nil } +// Restarts all non-ephemeral nodes in the network. +func (n *Network) Restart(ctx context.Context, w io.Writer) error { + if _, err := fmt.Fprintf(w, " restarting network\n"); err != nil { + return err + } + for _, node := range n.Nodes { + if err := node.Stop(ctx); err != nil { + return fmt.Errorf("failed to stop node %s: %w", node.NodeID, err) + } + if err := n.StartNode(ctx, w, node); err != nil { + return fmt.Errorf("failed to start node %s: %w", node.NodeID, err) + } + if _, err := fmt.Fprintf(w, " waiting for node %s to report healthy\n", node.NodeID); err != nil { + return err + } + if err := WaitForHealthy(ctx, node); err != nil { + return err + } + } + return nil +} + // Ensures the provided node has the configuration it needs to start. If the data dir is not // set, it will be defaulted to [nodeParentDir]/[node ID]. For a not-yet-created network, // no action will be taken. @@ -359,9 +485,141 @@ func (n *Network) EnsureNodeConfig(node *Node) error { } } + // Ensure available subnets are tracked + subnetIDs := make([]string, 0, len(n.Subnets)) + for _, subnet := range n.Subnets { + if subnet.SubnetID == ids.Empty { + continue + } + subnetIDs = append(subnetIDs, subnet.SubnetID.String()) + } + flags[config.TrackSubnetsKey] = strings.Join(subnetIDs, ",") + + return nil +} + +func (n *Network) GetSubnet(name string) *Subnet { + for _, subnet := range n.Subnets { + if subnet.Name == name { + return subnet + } + } + return nil +} + +// Ensure that each subnet on the network is created and that it is validated by all non-ephemeral nodes. +func (n *Network) CreateSubnets(ctx context.Context, w io.Writer) error { + createdSubnets := make([]*Subnet, 0, len(n.Subnets)) + for _, subnet := range n.Subnets { + if _, err := fmt.Fprintf(w, "Creating subnet %q\n", subnet.Name); err != nil { + return err + } + if subnet.SubnetID != ids.Empty { + // The subnet already exists + continue + } + + if subnet.OwningKey == nil { + // Allocate a pre-funded key and remove it from the network so it won't be used for + // other purposes + if len(n.PreFundedKeys) == 0 { + return fmt.Errorf("no pre-funded keys available to create subnet %q", subnet.Name) + } + subnet.OwningKey = n.PreFundedKeys[len(n.PreFundedKeys)-1] + n.PreFundedKeys = n.PreFundedKeys[:len(n.PreFundedKeys)-1] + } + + // Create the subnet on the network + if err := subnet.Create(ctx, n.Nodes[0].URI); err != nil { + return err + } + + if _, err := fmt.Fprintf(w, " created subnet %q as %q\n", subnet.Name, subnet.SubnetID); err != nil { + return err + } + + // Persist the subnet configuration + if err := subnet.Write(n.getSubnetDir(), n.getChainConfigDir()); err != nil { + return err + } + + if _, err := fmt.Fprintf(w, " wrote configuration for subnet %q\n", subnet.Name); err != nil { + return err + } + + createdSubnets = append(createdSubnets, subnet) + } + + if len(createdSubnets) == 0 { + return nil + } + + // Ensure the in-memory subnet state + n.Subnets = append(n.Subnets, createdSubnets...) + + // Ensure the pre-funded key changes are persisted to disk + if err := n.Write(); err != nil { + return err + } + + // Reconfigure nodes for the new subnets and their chains + if _, err := fmt.Fprintf(w, "Configured nodes to track new subnet(s). Restart is required.\n"); err != nil { + return err + } + for _, node := range n.Nodes { + if err := n.EnsureNodeConfig(node); err != nil { + return err + } + } + + // Restart nodes to allow new configuration to take effect + if err := n.Restart(ctx, w); err != nil { + return err + } + + // Add each node as a subnet validator + for _, subnet := range createdSubnets { + if _, err := fmt.Fprintf(w, "Adding validators for subnet %q\n", subnet.Name); err != nil { + return err + } + if err := subnet.AddValidators(ctx, w, n.Nodes); err != nil { + return err + } + } + + // Wait for nodes to become subnet validators + pChainClient := platformvm.NewClient(n.Nodes[0].URI) + for _, subnet := range createdSubnets { + if err := waitForActiveValidators(ctx, w, pChainClient, subnet); err != nil { + return err + } + + // It should now be safe to create chains for the subnet + if err := subnet.CreateChains(ctx, w, n.Nodes[0].URI); err != nil { + return err + } + + // Persist the chain configuration + if err := subnet.Write(n.getSubnetDir(), n.getChainConfigDir()); err != nil { + return err + } + if _, err := fmt.Fprintf(w, " wrote chain configuration for subnet %q\n", subnet.Name); err != nil { + return err + } + } + return nil } +func (n *Network) GetURIForNodeID(nodeID ids.NodeID) (string, error) { + for _, node := range n.Nodes { + if node.NodeID == nodeID { + return node.URI, nil + } + } + return "", fmt.Errorf("%s is not known to the network", nodeID) +} + func (n *Network) GetNodeURIs() []NodeURI { return GetNodeURIs(n.Nodes) } diff --git a/tests/fixture/tmpnet/network_config.go b/tests/fixture/tmpnet/network_config.go index 967a2b1b4ee3..4c68af240e98 100644 --- a/tests/fixture/tmpnet/network_config.go +++ b/tests/fixture/tmpnet/network_config.go @@ -25,7 +25,10 @@ func (n *Network) Read() error { if err := n.readNetwork(); err != nil { return err } - return n.readNodes() + if err := n.readNodes(); err != nil { + return err + } + return n.readSubnets() } // Write network configuration to disk. @@ -218,3 +221,16 @@ func (n *Network) writeEnvFile() error { } return nil } + +func (n *Network) getSubnetDir() string { + return filepath.Join(n.Dir, defaultSubnetDirName) +} + +func (n *Network) readSubnets() error { + subnets, err := readSubnets(n.getSubnetDir()) + if err != nil { + return err + } + n.Subnets = subnets + return nil +} diff --git a/tests/fixture/tmpnet/network_test.go b/tests/fixture/tmpnet/network_test.go index 3cbbb8ffcae8..c04c497c2485 100644 --- a/tests/fixture/tmpnet/network_test.go +++ b/tests/fixture/tmpnet/network_test.go @@ -15,10 +15,9 @@ func TestNetworkSerialization(t *testing.T) { tmpDir := t.TempDir() - network, err := NewDefaultNetwork(&bytes.Buffer{}, "/path/to/avalanche/go", 1) - require.NoError(err) + network := &Network{} + require.NoError(network.EnsureDefaultConfig(&bytes.Buffer{}, "/path/to/avalanche/go", "", 1)) require.NoError(network.Create(tmpDir)) - // Ensure node runtime is initialized require.NoError(network.readNodes()) diff --git a/tests/fixture/tmpnet/node.go b/tests/fixture/tmpnet/node.go index d1f97c7ead9c..59025b649112 100644 --- a/tests/fixture/tmpnet/node.go +++ b/tests/fixture/tmpnet/node.go @@ -83,6 +83,15 @@ func NewNode(dataDir string) *Node { } } +// Initializes the specified number of nodes. +func NewNodes(count int) []*Node { + nodes := make([]*Node, count) + for i := range nodes { + nodes[i] = NewNode("") + } + return nodes +} + // Reads a node's configuration from the specified directory. func ReadNode(dataDir string) (*Node, error) { node := NewNode(dataDir) diff --git a/tests/fixture/tmpnet/subnet.go b/tests/fixture/tmpnet/subnet.go new file mode 100644 index 000000000000..0eb1feab5f38 --- /dev/null +++ b/tests/fixture/tmpnet/subnet.go @@ -0,0 +1,333 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package tmpnet + +import ( + "context" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/perms" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/platformvm" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +const defaultSubnetDirName = "subnets" + +type Chain struct { + // Set statically + VMID ids.ID + Config string + Genesis []byte + + // Set at runtime + ChainID ids.ID + PreFundedKey *secp256k1.PrivateKey +} + +// Write the chain configuration to the specified directory. +func (c *Chain) WriteConfig(chainDir string) error { + if len(c.Config) == 0 { + return nil + } + + chainConfigDir := filepath.Join(chainDir, c.ChainID.String()) + if err := os.MkdirAll(chainConfigDir, perms.ReadWriteExecute); err != nil { + return fmt.Errorf("failed to create chain config dir: %w", err) + } + + path := filepath.Join(chainConfigDir, defaultConfigFilename) + if err := os.WriteFile(path, []byte(c.Config), perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write chain config: %w", err) + } + + return nil +} + +type Subnet struct { + // A unique string that can be used to refer to the subnet across different temporary + // networks (since the SubnetID will be different every time the subnet is created) + Name string + + // The ID of the transaction that created the subnet + SubnetID ids.ID + + // The private key that owns the subnet + OwningKey *secp256k1.PrivateKey + + // IDs of the nodes responsible for validating the subnet + ValidatorIDs []ids.NodeID + + Chains []*Chain +} + +// Retrieves a wallet configured for use with the subnet +func (s *Subnet) GetWallet(ctx context.Context, uri string) (primary.Wallet, error) { + keychain := secp256k1fx.NewKeychain(s.OwningKey) + + // Only fetch the subnet transaction if a subnet ID is present. This won't be true when + // the wallet is first used to create the subnet. + txIDs := set.Set[ids.ID]{} + if s.SubnetID != ids.Empty { + txIDs.Add(s.SubnetID) + } + + return primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: keychain, + EthKeychain: keychain, + PChainTxsToFetch: txIDs, + }) +} + +// Issues the subnet creation transaction and retains the result. The URI of a node is +// required to issue the transaction. +func (s *Subnet) Create(ctx context.Context, uri string) error { + wallet, err := s.GetWallet(ctx, uri) + if err != nil { + return err + } + pWallet := wallet.P() + + subnetTx, err := pWallet.IssueCreateSubnetTx( + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + s.OwningKey.Address(), + }, + }, + common.WithContext(ctx), + ) + if err != nil { + return fmt.Errorf("failed to create subnet %s: %w", s.Name, err) + } + s.SubnetID = subnetTx.ID() + + return nil +} + +func (s *Subnet) CreateChains(ctx context.Context, w io.Writer, uri string) error { + wallet, err := s.GetWallet(ctx, uri) + if err != nil { + return err + } + pWallet := wallet.P() + + if _, err := fmt.Fprintf(w, "Creating chains for subnet %q\n", s.Name); err != nil { + return err + } + + for _, chain := range s.Chains { + createChainTx, err := pWallet.IssueCreateChainTx( + s.SubnetID, + chain.Genesis, + chain.VMID, + nil, + "", + common.WithContext(ctx), + ) + if err != nil { + return fmt.Errorf("failed to create chain: %w", err) + } + chain.ChainID = createChainTx.ID() + + if _, err := fmt.Fprintf(w, " created chain %q for VM %q on subnet %q\n", chain.ChainID, chain.VMID, s.Name); err != nil { + return err + } + } + return nil +} + +// Add validators to the subnet +func (s *Subnet) AddValidators(ctx context.Context, w io.Writer, nodes []*Node) error { + apiURI := nodes[0].URI + + wallet, err := s.GetWallet(ctx, apiURI) + if err != nil { + return err + } + pWallet := wallet.P() + + // Collect the end times for current validators to reuse for subnet validators + pvmClient := platformvm.NewClient(apiURI) + validators, err := pvmClient.GetCurrentValidators(ctx, constants.PrimaryNetworkID, nil) + if err != nil { + return err + } + endTimes := make(map[ids.NodeID]uint64) + for _, validator := range validators { + endTimes[validator.NodeID] = validator.EndTime + } + + startTime := time.Now().Add(DefaultValidatorStartTimeDiff) + for _, node := range nodes { + endTime, ok := endTimes[node.NodeID] + if !ok { + return fmt.Errorf("failed to find end time for %s", node.NodeID) + } + + _, err := pWallet.IssueAddSubnetValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: node.NodeID, + Start: uint64(startTime.Unix()), + End: endTime, + Wght: units.Schmeckle, + }, + Subnet: s.SubnetID, + }, + common.WithContext(ctx), + ) + if err != nil { + return err + } + + if _, err := fmt.Fprintf(w, " added %s as validator for subnet `%s`\n", node.NodeID, s.Name); err != nil { + return err + } + + s.ValidatorIDs = append(s.ValidatorIDs, node.NodeID) + } + + return nil +} + +// Write the subnet configuration to disk +func (s *Subnet) Write(subnetDir string, chainDir string) error { + if err := os.MkdirAll(subnetDir, perms.ReadWriteExecute); err != nil { + return fmt.Errorf("failed to create subnet dir: %w", err) + } + path := filepath.Join(subnetDir, s.Name+".json") + + // Since subnets are expected to be serialized for the first time + // without their chains having been created (i.e. chains will have + // empty IDs), use the absence of chain IDs as a prompt for a + // subnet name uniquness check. + if len(s.Chains) > 0 && s.Chains[0].ChainID == ids.Empty { + _, err := os.Stat(path) + if err != nil && !os.IsNotExist(err) { + return err + } + if err == nil { + return fmt.Errorf("a subnet with name %s already exists", s.Name) + } + } + + bytes, err := DefaultJSONMarshal(s) + if err != nil { + return fmt.Errorf("failed to marshal subnet %s: %w", s.Name, err) + } + if err := os.WriteFile(path, bytes, perms.ReadWrite); err != nil { + return fmt.Errorf("failed to write subnet %s: %w", s.Name, err) + } + + for _, chain := range s.Chains { + if err := chain.WriteConfig(chainDir); err != nil { + return err + } + } + + return nil +} + +func waitForActiveValidators( + ctx context.Context, + w io.Writer, + pChainClient platformvm.Client, + subnet *Subnet, +) error { + ticker := time.NewTicker(DefaultPollingInterval) + defer ticker.Stop() + + if _, err := fmt.Fprintf(w, "Waiting for validators of subnet %q to become active\n", subnet.Name); err != nil { + return err + } + + if _, err := fmt.Fprintf(w, " "); err != nil { + return err + } + + for { + if _, err := fmt.Fprintf(w, "."); err != nil { + return err + } + validators, err := pChainClient.GetCurrentValidators(ctx, subnet.SubnetID, nil) + if err != nil { + return err + } + validatorSet := set.NewSet[ids.NodeID](len(validators)) + for _, validator := range validators { + validatorSet.Add(validator.NodeID) + } + allActive := true + for _, validatorID := range subnet.ValidatorIDs { + if !validatorSet.Contains(validatorID) { + allActive = false + } + } + if allActive { + if _, err := fmt.Fprintf(w, "\n saw the expected active validators of subnet %q\n", subnet.Name); err != nil { + return err + } + return nil + } + + select { + case <-ctx.Done(): + return fmt.Errorf("failed to see the expected active validators of subnet %q before timeout", subnet.Name) + case <-ticker.C: + } + } +} + +// Reads subnets from [network dir]/subnets/[subnet name].json +func readSubnets(subnetDir string) ([]*Subnet, error) { + if _, err := os.Stat(subnetDir); os.IsNotExist(err) { + return nil, nil + } else if err != nil { + return nil, err + } + + entries, err := os.ReadDir(subnetDir) + if err != nil { + return nil, fmt.Errorf("failed to read subnet dir: %w", err) + } + + subnets := []*Subnet{} + for _, entry := range entries { + if entry.IsDir() { + // Looking only for files + continue + } + if filepath.Ext(entry.Name()) != ".json" { + // Subnet files should have a .json extension + continue + } + + subnetPath := filepath.Join(subnetDir, entry.Name()) + bytes, err := os.ReadFile(subnetPath) + if err != nil { + return nil, fmt.Errorf("failed to read subnet file %s: %w", subnetPath, err) + } + subnet := &Subnet{} + if err := json.Unmarshal(bytes, subnet); err != nil { + return nil, fmt.Errorf("failed to unmarshal subnet from %s: %w", subnetPath, err) + } + subnets = append(subnets, subnet) + } + + return subnets, nil +} diff --git a/tests/upgrade/upgrade_test.go b/tests/upgrade/upgrade_test.go index 37c2fd259e66..4dba94c17f23 100644 --- a/tests/upgrade/upgrade_test.go +++ b/tests/upgrade/upgrade_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" ) func TestUpgrade(t *testing.T) { @@ -46,7 +47,8 @@ var _ = ginkgo.Describe("[Upgrade]", func() { require := require.New(ginkgo.GinkgoT()) ginkgo.It("can upgrade versions", func() { - network := e2e.StartNetwork(avalancheGoExecPath, e2e.DefaultNetworkDir) + network := &tmpnet.Network{} + e2e.StartNetwork(network, e2e.DefaultNetworkDir, avalancheGoExecPath, "" /* pluginDir */) ginkgo.By(fmt.Sprintf("restarting all nodes with %q binary", avalancheGoExecPathToUpgradeTo)) for _, node := range network.Nodes { From 0fcc746f0a6a0178ca5e9e5f8d1bcd83d1207d24 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:13:01 -0500 Subject: [PATCH 252/267] Update `go.uber.org/mock/gomock` to `v0.4.0` (#2618) --- api/server/mock_server.go | 23 +- chains/atomic/mock_shared_memory.go | 15 +- codec/mock_manager.go | 19 +- database/mock_batch.go | 11 +- database/mock_iterator.go | 5 + go.mod | 2 +- go.sum | 4 +- message/mock_message.go | 5 + message/mock_outbound_message_builder.go | 51 +++-- network/p2p/validators_test.go | 2 +- scripts/mock.gen.sh | 2 +- snow/consensus/snowman/mock_block.go | 11 +- snow/engine/avalanche/vertex/mock_vm.go | 57 ++--- .../block/mock_build_block_with_context_vm.go | 7 +- snow/engine/snowman/block/mock_chain_vm.go | 53 +++-- .../snowman/block/mock_state_syncable_vm.go | 15 +- .../snowman/block/mock_with_verify_context.go | 9 +- snow/networking/handler/mock_handler.go | 29 ++- snow/networking/timeout/mock_manager.go | 15 +- .../tracker/mock_resource_tracker.go | 9 +- snow/networking/tracker/mock_targeter.go | 7 +- snow/uptime/mock_calculator.go | 11 +- snow/validators/mock_state.go | 13 +- snow/validators/mock_subnet_connector.go | 7 +- utils/crypto/keychain/mock_ledger.go | 13 +- utils/filesystem/mock_io.go | 7 +- utils/hashing/consistent/ring_test.go | 2 +- utils/hashing/mock_hasher.go | 7 +- utils/resource/mock_user.go | 5 + vms/avm/block/mock_block.go | 9 +- vms/avm/metrics/mock_metrics.go | 13 +- vms/avm/state/mock_state.go | 73 +++--- vms/avm/txs/mempool/mock_mempool.go | 19 +- vms/components/avax/mock_transferable_in.go | 7 +- vms/components/verify/mock_verifiable.go | 5 + vms/mock_manager.go | 27 ++- vms/platformvm/block/mock_block.go | 11 +- vms/platformvm/state/mock_staker_iterator.go | 5 + vms/platformvm/state/mock_state.go | 211 +++++++++--------- vms/platformvm/txs/mempool/mock_mempool.go | 21 +- vms/platformvm/utxo/mock_verifier.go | 9 +- vms/proposervm/mock_post_fork_block.go | 27 ++- vms/proposervm/proposer/mock_windower.go | 13 +- vms/proposervm/scheduler/mock_scheduler.go | 9 +- vms/proposervm/state/mock_state.go | 23 +- vms/registry/mock_vm_getter.go | 5 + vms/registry/mock_vm_registry.go | 7 +- x/sync/mock_client.go | 9 +- x/sync/mock_network_client.go | 17 +- 49 files changed, 578 insertions(+), 358 deletions(-) diff --git a/api/server/mock_server.go b/api/server/mock_server.go index b30b36e50ac8..769df9baa26f 100644 --- a/api/server/mock_server.go +++ b/api/server/mock_server.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/api/server (interfaces: Server) +// +// Generated by this command: +// +// mockgen -package=server -destination=api/server/mock_server.go github.com/ava-labs/avalanchego/api/server Server +// // Package server is a generated GoMock package. package server @@ -39,7 +44,7 @@ func (m *MockServer) EXPECT() *MockServerMockRecorder { // AddAliases mocks base method. func (m *MockServer) AddAliases(arg0 string, arg1 ...string) error { m.ctrl.T.Helper() - varargs := []interface{}{arg0} + varargs := []any{arg0} for _, a := range arg1 { varargs = append(varargs, a) } @@ -49,16 +54,16 @@ func (m *MockServer) AddAliases(arg0 string, arg1 ...string) error { } // AddAliases indicates an expected call of AddAliases. -func (mr *MockServerMockRecorder) AddAliases(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockServerMockRecorder) AddAliases(arg0 any, arg1 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) + varargs := append([]any{arg0}, arg1...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAliases", reflect.TypeOf((*MockServer)(nil).AddAliases), varargs...) } // AddAliasesWithReadLock mocks base method. func (m *MockServer) AddAliasesWithReadLock(arg0 string, arg1 ...string) error { m.ctrl.T.Helper() - varargs := []interface{}{arg0} + varargs := []any{arg0} for _, a := range arg1 { varargs = append(varargs, a) } @@ -68,9 +73,9 @@ func (m *MockServer) AddAliasesWithReadLock(arg0 string, arg1 ...string) error { } // AddAliasesWithReadLock indicates an expected call of AddAliasesWithReadLock. -func (mr *MockServerMockRecorder) AddAliasesWithReadLock(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockServerMockRecorder) AddAliasesWithReadLock(arg0 any, arg1 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) + varargs := append([]any{arg0}, arg1...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAliasesWithReadLock", reflect.TypeOf((*MockServer)(nil).AddAliasesWithReadLock), varargs...) } @@ -83,7 +88,7 @@ func (m *MockServer) AddRoute(arg0 http.Handler, arg1, arg2 string) error { } // AddRoute indicates an expected call of AddRoute. -func (mr *MockServerMockRecorder) AddRoute(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockServerMockRecorder) AddRoute(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRoute", reflect.TypeOf((*MockServer)(nil).AddRoute), arg0, arg1, arg2) } @@ -97,7 +102,7 @@ func (m *MockServer) AddRouteWithReadLock(arg0 http.Handler, arg1, arg2 string) } // AddRouteWithReadLock indicates an expected call of AddRouteWithReadLock. -func (mr *MockServerMockRecorder) AddRouteWithReadLock(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockServerMockRecorder) AddRouteWithReadLock(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRouteWithReadLock", reflect.TypeOf((*MockServer)(nil).AddRouteWithReadLock), arg0, arg1, arg2) } @@ -123,7 +128,7 @@ func (m *MockServer) RegisterChain(arg0 string, arg1 *snow.ConsensusContext, arg } // RegisterChain indicates an expected call of RegisterChain. -func (mr *MockServerMockRecorder) RegisterChain(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockServerMockRecorder) RegisterChain(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterChain", reflect.TypeOf((*MockServer)(nil).RegisterChain), arg0, arg1, arg2) } diff --git a/chains/atomic/mock_shared_memory.go b/chains/atomic/mock_shared_memory.go index b6afac750e70..0e63179314da 100644 --- a/chains/atomic/mock_shared_memory.go +++ b/chains/atomic/mock_shared_memory.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/chains/atomic (interfaces: SharedMemory) +// +// Generated by this command: +// +// mockgen -package=atomic -destination=chains/atomic/mock_shared_memory.go github.com/ava-labs/avalanchego/chains/atomic SharedMemory +// // Package atomic is a generated GoMock package. package atomic @@ -38,7 +43,7 @@ func (m *MockSharedMemory) EXPECT() *MockSharedMemoryMockRecorder { // Apply mocks base method. func (m *MockSharedMemory) Apply(arg0 map[ids.ID]*Requests, arg1 ...database.Batch) error { m.ctrl.T.Helper() - varargs := []interface{}{arg0} + varargs := []any{arg0} for _, a := range arg1 { varargs = append(varargs, a) } @@ -48,9 +53,9 @@ func (m *MockSharedMemory) Apply(arg0 map[ids.ID]*Requests, arg1 ...database.Bat } // Apply indicates an expected call of Apply. -func (mr *MockSharedMemoryMockRecorder) Apply(arg0 interface{}, arg1 ...interface{}) *gomock.Call { +func (mr *MockSharedMemoryMockRecorder) Apply(arg0 any, arg1 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]interface{}{arg0}, arg1...) + varargs := append([]any{arg0}, arg1...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockSharedMemory)(nil).Apply), varargs...) } @@ -64,7 +69,7 @@ func (m *MockSharedMemory) Get(arg0 ids.ID, arg1 [][]byte) ([][]byte, error) { } // Get indicates an expected call of Get. -func (mr *MockSharedMemoryMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSharedMemoryMockRecorder) Get(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockSharedMemory)(nil).Get), arg0, arg1) } @@ -81,7 +86,7 @@ func (m *MockSharedMemory) Indexed(arg0 ids.ID, arg1 [][]byte, arg2, arg3 []byte } // Indexed indicates an expected call of Indexed. -func (mr *MockSharedMemoryMockRecorder) Indexed(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockSharedMemoryMockRecorder) Indexed(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Indexed", reflect.TypeOf((*MockSharedMemory)(nil).Indexed), arg0, arg1, arg2, arg3, arg4) } diff --git a/codec/mock_manager.go b/codec/mock_manager.go index 53fe543f8984..36bbae57e96f 100644 --- a/codec/mock_manager.go +++ b/codec/mock_manager.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/codec (interfaces: Manager) +// +// Generated by this command: +// +// mockgen -package=codec -destination=codec/mock_manager.go github.com/ava-labs/avalanchego/codec Manager +// // Package codec is a generated GoMock package. package codec @@ -34,7 +39,7 @@ func (m *MockManager) EXPECT() *MockManagerMockRecorder { } // Marshal mocks base method. -func (m *MockManager) Marshal(arg0 uint16, arg1 interface{}) ([]byte, error) { +func (m *MockManager) Marshal(arg0 uint16, arg1 any) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Marshal", arg0, arg1) ret0, _ := ret[0].([]byte) @@ -43,7 +48,7 @@ func (m *MockManager) Marshal(arg0 uint16, arg1 interface{}) ([]byte, error) { } // Marshal indicates an expected call of Marshal. -func (mr *MockManagerMockRecorder) Marshal(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) Marshal(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Marshal", reflect.TypeOf((*MockManager)(nil).Marshal), arg0, arg1) } @@ -57,13 +62,13 @@ func (m *MockManager) RegisterCodec(arg0 uint16, arg1 Codec) error { } // RegisterCodec indicates an expected call of RegisterCodec. -func (mr *MockManagerMockRecorder) RegisterCodec(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RegisterCodec(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterCodec", reflect.TypeOf((*MockManager)(nil).RegisterCodec), arg0, arg1) } // Size mocks base method. -func (m *MockManager) Size(arg0 uint16, arg1 interface{}) (int, error) { +func (m *MockManager) Size(arg0 uint16, arg1 any) (int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Size", arg0, arg1) ret0, _ := ret[0].(int) @@ -72,13 +77,13 @@ func (m *MockManager) Size(arg0 uint16, arg1 interface{}) (int, error) { } // Size indicates an expected call of Size. -func (mr *MockManagerMockRecorder) Size(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) Size(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Size", reflect.TypeOf((*MockManager)(nil).Size), arg0, arg1) } // Unmarshal mocks base method. -func (m *MockManager) Unmarshal(arg0 []byte, arg1 interface{}) (uint16, error) { +func (m *MockManager) Unmarshal(arg0 []byte, arg1 any) (uint16, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Unmarshal", arg0, arg1) ret0, _ := ret[0].(uint16) @@ -87,7 +92,7 @@ func (m *MockManager) Unmarshal(arg0 []byte, arg1 interface{}) (uint16, error) { } // Unmarshal indicates an expected call of Unmarshal. -func (mr *MockManagerMockRecorder) Unmarshal(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) Unmarshal(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unmarshal", reflect.TypeOf((*MockManager)(nil).Unmarshal), arg0, arg1) } diff --git a/database/mock_batch.go b/database/mock_batch.go index 552d917fc95f..e3762514954f 100644 --- a/database/mock_batch.go +++ b/database/mock_batch.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/database (interfaces: Batch) +// +// Generated by this command: +// +// mockgen -package=database -destination=database/mock_batch.go github.com/ava-labs/avalanchego/database Batch +// // Package database is a generated GoMock package. package database @@ -42,7 +47,7 @@ func (m *MockBatch) Delete(arg0 []byte) error { } // Delete indicates an expected call of Delete. -func (mr *MockBatchMockRecorder) Delete(arg0 interface{}) *gomock.Call { +func (mr *MockBatchMockRecorder) Delete(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockBatch)(nil).Delete), arg0) } @@ -70,7 +75,7 @@ func (m *MockBatch) Put(arg0, arg1 []byte) error { } // Put indicates an expected call of Put. -func (mr *MockBatchMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockBatchMockRecorder) Put(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockBatch)(nil).Put), arg0, arg1) } @@ -84,7 +89,7 @@ func (m *MockBatch) Replay(arg0 KeyValueWriterDeleter) error { } // Replay indicates an expected call of Replay. -func (mr *MockBatchMockRecorder) Replay(arg0 interface{}) *gomock.Call { +func (mr *MockBatchMockRecorder) Replay(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Replay", reflect.TypeOf((*MockBatch)(nil).Replay), arg0) } diff --git a/database/mock_iterator.go b/database/mock_iterator.go index 7703e89206a3..77856c92ea5e 100644 --- a/database/mock_iterator.go +++ b/database/mock_iterator.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/database (interfaces: Iterator) +// +// Generated by this command: +// +// mockgen -package=database -destination=database/mock_iterator.go github.com/ava-labs/avalanchego/database Iterator +// // Package database is a generated GoMock package. package database diff --git a/go.mod b/go.mod index 5f2bea429f7b..f85c1327317b 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,7 @@ require ( go.opentelemetry.io/otel/sdk v1.11.0 go.opentelemetry.io/otel/trace v1.11.0 go.uber.org/goleak v1.2.1 - go.uber.org/mock v0.2.0 + go.uber.org/mock v0.4.0 go.uber.org/zap v1.26.0 golang.org/x/crypto v0.17.0 golang.org/x/exp v0.0.0-20231127185646-65229373498e diff --git a/go.sum b/go.sum index 489a6ee12e1d..d963cb879e44 100644 --- a/go.sum +++ b/go.sum @@ -669,8 +669,8 @@ go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= -go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= -go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= diff --git a/message/mock_message.go b/message/mock_message.go index e52a665b7575..ea6b9a67afcf 100644 --- a/message/mock_message.go +++ b/message/mock_message.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/message (interfaces: OutboundMessage) +// +// Generated by this command: +// +// mockgen -package=message -destination=message/mock_message.go github.com/ava-labs/avalanchego/message OutboundMessage +// // Package message is a generated GoMock package. package message diff --git a/message/mock_outbound_message_builder.go b/message/mock_outbound_message_builder.go index 21cb518976ae..0d053f71090b 100644 --- a/message/mock_outbound_message_builder.go +++ b/message/mock_outbound_message_builder.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/message (interfaces: OutboundMsgBuilder) +// +// Generated by this command: +// +// mockgen -package=message -destination=message/mock_outbound_message_builder.go github.com/ava-labs/avalanchego/message OutboundMsgBuilder +// // Package message is a generated GoMock package. package message @@ -47,7 +52,7 @@ func (m *MockOutboundMsgBuilder) Accepted(arg0 ids.ID, arg1 uint32, arg2 []ids.I } // Accepted indicates an expected call of Accepted. -func (mr *MockOutboundMsgBuilderMockRecorder) Accepted(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Accepted(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accepted", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Accepted), arg0, arg1, arg2) } @@ -62,7 +67,7 @@ func (m *MockOutboundMsgBuilder) AcceptedFrontier(arg0 ids.ID, arg1 uint32, arg2 } // AcceptedFrontier indicates an expected call of AcceptedFrontier. -func (mr *MockOutboundMsgBuilderMockRecorder) AcceptedFrontier(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) AcceptedFrontier(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).AcceptedFrontier), arg0, arg1, arg2) } @@ -77,7 +82,7 @@ func (m *MockOutboundMsgBuilder) AcceptedStateSummary(arg0 ids.ID, arg1 uint32, } // AcceptedStateSummary indicates an expected call of AcceptedStateSummary. -func (mr *MockOutboundMsgBuilderMockRecorder) AcceptedStateSummary(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) AcceptedStateSummary(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedStateSummary", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).AcceptedStateSummary), arg0, arg1, arg2) } @@ -92,7 +97,7 @@ func (m *MockOutboundMsgBuilder) Ancestors(arg0 ids.ID, arg1 uint32, arg2 [][]by } // Ancestors indicates an expected call of Ancestors. -func (mr *MockOutboundMsgBuilderMockRecorder) Ancestors(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Ancestors(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ancestors", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Ancestors), arg0, arg1, arg2) } @@ -107,7 +112,7 @@ func (m *MockOutboundMsgBuilder) AppGossip(arg0 ids.ID, arg1 []byte) (OutboundMe } // AppGossip indicates an expected call of AppGossip. -func (mr *MockOutboundMsgBuilderMockRecorder) AppGossip(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) AppGossip(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).AppGossip), arg0, arg1) } @@ -122,7 +127,7 @@ func (m *MockOutboundMsgBuilder) AppRequest(arg0 ids.ID, arg1 uint32, arg2 time. } // AppRequest indicates an expected call of AppRequest. -func (mr *MockOutboundMsgBuilderMockRecorder) AppRequest(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) AppRequest(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).AppRequest), arg0, arg1, arg2, arg3) } @@ -137,7 +142,7 @@ func (m *MockOutboundMsgBuilder) AppResponse(arg0 ids.ID, arg1 uint32, arg2 []by } // AppResponse indicates an expected call of AppResponse. -func (mr *MockOutboundMsgBuilderMockRecorder) AppResponse(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) AppResponse(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).AppResponse), arg0, arg1, arg2) } @@ -152,7 +157,7 @@ func (m *MockOutboundMsgBuilder) Chits(arg0 ids.ID, arg1 uint32, arg2, arg3, arg } // Chits indicates an expected call of Chits. -func (mr *MockOutboundMsgBuilderMockRecorder) Chits(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Chits(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chits", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Chits), arg0, arg1, arg2, arg3, arg4) } @@ -167,7 +172,7 @@ func (m *MockOutboundMsgBuilder) Get(arg0 ids.ID, arg1 uint32, arg2 time.Duratio } // Get indicates an expected call of Get. -func (mr *MockOutboundMsgBuilderMockRecorder) Get(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Get(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Get), arg0, arg1, arg2, arg3, arg4) } @@ -182,7 +187,7 @@ func (m *MockOutboundMsgBuilder) GetAccepted(arg0 ids.ID, arg1 uint32, arg2 time } // GetAccepted indicates an expected call of GetAccepted. -func (mr *MockOutboundMsgBuilderMockRecorder) GetAccepted(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) GetAccepted(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccepted", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAccepted), arg0, arg1, arg2, arg3, arg4) } @@ -197,7 +202,7 @@ func (m *MockOutboundMsgBuilder) GetAcceptedFrontier(arg0 ids.ID, arg1 uint32, a } // GetAcceptedFrontier indicates an expected call of GetAcceptedFrontier. -func (mr *MockOutboundMsgBuilderMockRecorder) GetAcceptedFrontier(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) GetAcceptedFrontier(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAcceptedFrontier), arg0, arg1, arg2, arg3) } @@ -212,7 +217,7 @@ func (m *MockOutboundMsgBuilder) GetAcceptedStateSummary(arg0 ids.ID, arg1 uint3 } // GetAcceptedStateSummary indicates an expected call of GetAcceptedStateSummary. -func (mr *MockOutboundMsgBuilderMockRecorder) GetAcceptedStateSummary(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) GetAcceptedStateSummary(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedStateSummary", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAcceptedStateSummary), arg0, arg1, arg2, arg3) } @@ -227,7 +232,7 @@ func (m *MockOutboundMsgBuilder) GetAncestors(arg0 ids.ID, arg1 uint32, arg2 tim } // GetAncestors indicates an expected call of GetAncestors. -func (mr *MockOutboundMsgBuilderMockRecorder) GetAncestors(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) GetAncestors(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAncestors", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetAncestors), arg0, arg1, arg2, arg3, arg4) } @@ -242,7 +247,7 @@ func (m *MockOutboundMsgBuilder) GetPeerList(arg0, arg1 []byte) (OutboundMessage } // GetPeerList indicates an expected call of GetPeerList. -func (mr *MockOutboundMsgBuilderMockRecorder) GetPeerList(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) GetPeerList(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPeerList", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetPeerList), arg0, arg1) } @@ -257,7 +262,7 @@ func (m *MockOutboundMsgBuilder) GetStateSummaryFrontier(arg0 ids.ID, arg1 uint3 } // GetStateSummaryFrontier indicates an expected call of GetStateSummaryFrontier. -func (mr *MockOutboundMsgBuilderMockRecorder) GetStateSummaryFrontier(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) GetStateSummaryFrontier(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateSummaryFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).GetStateSummaryFrontier), arg0, arg1, arg2) } @@ -272,7 +277,7 @@ func (m *MockOutboundMsgBuilder) Handshake(arg0 uint32, arg1 uint64, arg2 ips.IP } // Handshake indicates an expected call of Handshake. -func (mr *MockOutboundMsgBuilderMockRecorder) Handshake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Handshake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Handshake), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14) } @@ -287,7 +292,7 @@ func (m *MockOutboundMsgBuilder) PeerList(arg0 []*ips.ClaimedIPPort, arg1 bool) } // PeerList indicates an expected call of PeerList. -func (mr *MockOutboundMsgBuilderMockRecorder) PeerList(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) PeerList(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerList", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).PeerList), arg0, arg1) } @@ -302,7 +307,7 @@ func (m *MockOutboundMsgBuilder) Ping(arg0 uint32, arg1 []*p2p.SubnetUptime) (Ou } // Ping indicates an expected call of Ping. -func (mr *MockOutboundMsgBuilderMockRecorder) Ping(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Ping(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Ping), arg0, arg1) } @@ -317,7 +322,7 @@ func (m *MockOutboundMsgBuilder) Pong(arg0 uint32, arg1 []*p2p.SubnetUptime) (Ou } // Pong indicates an expected call of Pong. -func (mr *MockOutboundMsgBuilderMockRecorder) Pong(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Pong(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Pong", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Pong), arg0, arg1) } @@ -332,7 +337,7 @@ func (m *MockOutboundMsgBuilder) PullQuery(arg0 ids.ID, arg1 uint32, arg2 time.D } // PullQuery indicates an expected call of PullQuery. -func (mr *MockOutboundMsgBuilderMockRecorder) PullQuery(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) PullQuery(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PullQuery", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).PullQuery), arg0, arg1, arg2, arg3, arg4, arg5) } @@ -347,7 +352,7 @@ func (m *MockOutboundMsgBuilder) PushQuery(arg0 ids.ID, arg1 uint32, arg2 time.D } // PushQuery indicates an expected call of PushQuery. -func (mr *MockOutboundMsgBuilderMockRecorder) PushQuery(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) PushQuery(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushQuery", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).PushQuery), arg0, arg1, arg2, arg3, arg4, arg5) } @@ -362,7 +367,7 @@ func (m *MockOutboundMsgBuilder) Put(arg0 ids.ID, arg1 uint32, arg2 []byte, arg3 } // Put indicates an expected call of Put. -func (mr *MockOutboundMsgBuilderMockRecorder) Put(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) Put(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).Put), arg0, arg1, arg2, arg3) } @@ -377,7 +382,7 @@ func (m *MockOutboundMsgBuilder) StateSummaryFrontier(arg0 ids.ID, arg1 uint32, } // StateSummaryFrontier indicates an expected call of StateSummaryFrontier. -func (mr *MockOutboundMsgBuilderMockRecorder) StateSummaryFrontier(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockOutboundMsgBuilderMockRecorder) StateSummaryFrontier(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*MockOutboundMsgBuilder)(nil).StateSummaryFrontier), arg0, arg1, arg2) } diff --git a/network/p2p/validators_test.go b/network/p2p/validators_test.go index a5d4e7724cdd..4671a20fdcae 100644 --- a/network/p2p/validators_test.go +++ b/network/p2p/validators_test.go @@ -158,7 +158,7 @@ func TestValidatorsSample(t *testing.T) { ctrl := gomock.NewController(t) mockValidators := validators.NewMockState(ctrl) - calls := make([]*gomock.Call, 0) + calls := make([]any, 0) for _, call := range tt.calls { calls = append(calls, mockValidators.EXPECT(). GetCurrentHeight(gomock.Any()).Return(call.height, call.getCurrentHeightErr)) diff --git a/scripts/mock.gen.sh b/scripts/mock.gen.sh index c3feff7a545c..a4e74488c5df 100755 --- a/scripts/mock.gen.sh +++ b/scripts/mock.gen.sh @@ -11,7 +11,7 @@ if ! command -v mockgen &> /dev/null then echo "mockgen not found, installing..." # https://github.com/uber-go/mock - go install -v go.uber.org/mock/mockgen@v0.2.0 + go install -v go.uber.org/mock/mockgen@v0.4.0 fi source ./scripts/constants.sh diff --git a/snow/consensus/snowman/mock_block.go b/snow/consensus/snowman/mock_block.go index 164df8d45e80..45393bfe7bdb 100644 --- a/snow/consensus/snowman/mock_block.go +++ b/snow/consensus/snowman/mock_block.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/consensus/snowman (interfaces: Block) +// +// Generated by this command: +// +// mockgen -package=snowman -destination=snow/consensus/snowman/mock_block.go github.com/ava-labs/avalanchego/snow/consensus/snowman Block +// // Package snowman is a generated GoMock package. package snowman @@ -46,7 +51,7 @@ func (m *MockBlock) Accept(arg0 context.Context) error { } // Accept indicates an expected call of Accept. -func (mr *MockBlockMockRecorder) Accept(arg0 interface{}) *gomock.Call { +func (mr *MockBlockMockRecorder) Accept(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockBlock)(nil).Accept), arg0) } @@ -116,7 +121,7 @@ func (m *MockBlock) Reject(arg0 context.Context) error { } // Reject indicates an expected call of Reject. -func (mr *MockBlockMockRecorder) Reject(arg0 interface{}) *gomock.Call { +func (mr *MockBlockMockRecorder) Reject(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reject", reflect.TypeOf((*MockBlock)(nil).Reject), arg0) } @@ -158,7 +163,7 @@ func (m *MockBlock) Verify(arg0 context.Context) error { } // Verify indicates an expected call of Verify. -func (mr *MockBlockMockRecorder) Verify(arg0 interface{}) *gomock.Call { +func (mr *MockBlockMockRecorder) Verify(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verify", reflect.TypeOf((*MockBlock)(nil).Verify), arg0) } diff --git a/snow/engine/avalanche/vertex/mock_vm.go b/snow/engine/avalanche/vertex/mock_vm.go index c1b67c7421c6..7ad293f6313f 100644 --- a/snow/engine/avalanche/vertex/mock_vm.go +++ b/snow/engine/avalanche/vertex/mock_vm.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex (interfaces: LinearizableVM) +// +// Generated by this command: +// +// mockgen -package=vertex -destination=snow/engine/avalanche/vertex/mock_vm.go github.com/ava-labs/avalanchego/snow/engine/avalanche/vertex LinearizableVM +// // Package vertex is a generated GoMock package. package vertex @@ -52,7 +57,7 @@ func (m *MockLinearizableVM) AppGossip(arg0 context.Context, arg1 ids.NodeID, ar } // AppGossip indicates an expected call of AppGossip. -func (mr *MockLinearizableVMMockRecorder) AppGossip(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) AppGossip(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*MockLinearizableVM)(nil).AppGossip), arg0, arg1, arg2) } @@ -66,7 +71,7 @@ func (m *MockLinearizableVM) AppRequest(arg0 context.Context, arg1 ids.NodeID, a } // AppRequest indicates an expected call of AppRequest. -func (mr *MockLinearizableVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*MockLinearizableVM)(nil).AppRequest), arg0, arg1, arg2, arg3, arg4) } @@ -80,7 +85,7 @@ func (m *MockLinearizableVM) AppRequestFailed(arg0 context.Context, arg1 ids.Nod } // AppRequestFailed indicates an expected call of AppRequestFailed. -func (mr *MockLinearizableVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*MockLinearizableVM)(nil).AppRequestFailed), arg0, arg1, arg2, arg3) } @@ -94,7 +99,7 @@ func (m *MockLinearizableVM) AppResponse(arg0 context.Context, arg1 ids.NodeID, } // AppResponse indicates an expected call of AppResponse. -func (mr *MockLinearizableVMMockRecorder) AppResponse(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) AppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*MockLinearizableVM)(nil).AppResponse), arg0, arg1, arg2, arg3) } @@ -109,7 +114,7 @@ func (m *MockLinearizableVM) BuildBlock(arg0 context.Context) (snowman.Block, er } // BuildBlock indicates an expected call of BuildBlock. -func (mr *MockLinearizableVMMockRecorder) BuildBlock(arg0 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) BuildBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildBlock", reflect.TypeOf((*MockLinearizableVM)(nil).BuildBlock), arg0) } @@ -123,7 +128,7 @@ func (m *MockLinearizableVM) Connected(arg0 context.Context, arg1 ids.NodeID, ar } // Connected indicates an expected call of Connected. -func (mr *MockLinearizableVMMockRecorder) Connected(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) Connected(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*MockLinearizableVM)(nil).Connected), arg0, arg1, arg2) } @@ -138,7 +143,7 @@ func (m *MockLinearizableVM) CreateHandlers(arg0 context.Context) (map[string]ht } // CreateHandlers indicates an expected call of CreateHandlers. -func (mr *MockLinearizableVMMockRecorder) CreateHandlers(arg0 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) CreateHandlers(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHandlers", reflect.TypeOf((*MockLinearizableVM)(nil).CreateHandlers), arg0) } @@ -152,7 +157,7 @@ func (m *MockLinearizableVM) CrossChainAppRequest(arg0 context.Context, arg1 ids } // CrossChainAppRequest indicates an expected call of CrossChainAppRequest. -func (mr *MockLinearizableVMMockRecorder) CrossChainAppRequest(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) CrossChainAppRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequest", reflect.TypeOf((*MockLinearizableVM)(nil).CrossChainAppRequest), arg0, arg1, arg2, arg3, arg4) } @@ -166,7 +171,7 @@ func (m *MockLinearizableVM) CrossChainAppRequestFailed(arg0 context.Context, ar } // CrossChainAppRequestFailed indicates an expected call of CrossChainAppRequestFailed. -func (mr *MockLinearizableVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequestFailed", reflect.TypeOf((*MockLinearizableVM)(nil).CrossChainAppRequestFailed), arg0, arg1, arg2, arg3) } @@ -180,7 +185,7 @@ func (m *MockLinearizableVM) CrossChainAppResponse(arg0 context.Context, arg1 id } // CrossChainAppResponse indicates an expected call of CrossChainAppResponse. -func (mr *MockLinearizableVMMockRecorder) CrossChainAppResponse(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) CrossChainAppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppResponse", reflect.TypeOf((*MockLinearizableVM)(nil).CrossChainAppResponse), arg0, arg1, arg2, arg3) } @@ -194,7 +199,7 @@ func (m *MockLinearizableVM) Disconnected(arg0 context.Context, arg1 ids.NodeID) } // Disconnected indicates an expected call of Disconnected. -func (mr *MockLinearizableVMMockRecorder) Disconnected(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) Disconnected(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*MockLinearizableVM)(nil).Disconnected), arg0, arg1) } @@ -209,7 +214,7 @@ func (m *MockLinearizableVM) GetBlock(arg0 context.Context, arg1 ids.ID) (snowma } // GetBlock indicates an expected call of GetBlock. -func (mr *MockLinearizableVMMockRecorder) GetBlock(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) GetBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockLinearizableVM)(nil).GetBlock), arg0, arg1) } @@ -224,22 +229,22 @@ func (m *MockLinearizableVM) GetBlockIDAtHeight(arg0 context.Context, arg1 uint6 } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *MockLinearizableVMMockRecorder) GetBlockIDAtHeight(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) GetBlockIDAtHeight(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockLinearizableVM)(nil).GetBlockIDAtHeight), arg0, arg1) } // HealthCheck mocks base method. -func (m *MockLinearizableVM) HealthCheck(arg0 context.Context) (interface{}, error) { +func (m *MockLinearizableVM) HealthCheck(arg0 context.Context) (any, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HealthCheck", arg0) - ret0, _ := ret[0].(interface{}) + ret0, _ := ret[0].(any) ret1, _ := ret[1].(error) return ret0, ret1 } // HealthCheck indicates an expected call of HealthCheck. -func (mr *MockLinearizableVMMockRecorder) HealthCheck(arg0 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) HealthCheck(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockLinearizableVM)(nil).HealthCheck), arg0) } @@ -253,7 +258,7 @@ func (m *MockLinearizableVM) Initialize(arg0 context.Context, arg1 *snow.Context } // Initialize indicates an expected call of Initialize. -func (mr *MockLinearizableVMMockRecorder) Initialize(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) Initialize(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*MockLinearizableVM)(nil).Initialize), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } @@ -268,7 +273,7 @@ func (m *MockLinearizableVM) LastAccepted(arg0 context.Context) (ids.ID, error) } // LastAccepted indicates an expected call of LastAccepted. -func (mr *MockLinearizableVMMockRecorder) LastAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) LastAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastAccepted", reflect.TypeOf((*MockLinearizableVM)(nil).LastAccepted), arg0) } @@ -282,7 +287,7 @@ func (m *MockLinearizableVM) Linearize(arg0 context.Context, arg1 ids.ID) error } // Linearize indicates an expected call of Linearize. -func (mr *MockLinearizableVMMockRecorder) Linearize(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) Linearize(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Linearize", reflect.TypeOf((*MockLinearizableVM)(nil).Linearize), arg0, arg1) } @@ -297,7 +302,7 @@ func (m *MockLinearizableVM) ParseBlock(arg0 context.Context, arg1 []byte) (snow } // ParseBlock indicates an expected call of ParseBlock. -func (mr *MockLinearizableVMMockRecorder) ParseBlock(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) ParseBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseBlock", reflect.TypeOf((*MockLinearizableVM)(nil).ParseBlock), arg0, arg1) } @@ -312,7 +317,7 @@ func (m *MockLinearizableVM) ParseTx(arg0 context.Context, arg1 []byte) (snowsto } // ParseTx indicates an expected call of ParseTx. -func (mr *MockLinearizableVMMockRecorder) ParseTx(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) ParseTx(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseTx", reflect.TypeOf((*MockLinearizableVM)(nil).ParseTx), arg0, arg1) } @@ -326,7 +331,7 @@ func (m *MockLinearizableVM) SetPreference(arg0 context.Context, arg1 ids.ID) er } // SetPreference indicates an expected call of SetPreference. -func (mr *MockLinearizableVMMockRecorder) SetPreference(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) SetPreference(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockLinearizableVM)(nil).SetPreference), arg0, arg1) } @@ -340,7 +345,7 @@ func (m *MockLinearizableVM) SetState(arg0 context.Context, arg1 snow.State) err } // SetState indicates an expected call of SetState. -func (mr *MockLinearizableVMMockRecorder) SetState(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) SetState(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*MockLinearizableVM)(nil).SetState), arg0, arg1) } @@ -354,7 +359,7 @@ func (m *MockLinearizableVM) Shutdown(arg0 context.Context) error { } // Shutdown indicates an expected call of Shutdown. -func (mr *MockLinearizableVMMockRecorder) Shutdown(arg0 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) Shutdown(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*MockLinearizableVM)(nil).Shutdown), arg0) } @@ -368,7 +373,7 @@ func (m *MockLinearizableVM) VerifyHeightIndex(arg0 context.Context) error { } // VerifyHeightIndex indicates an expected call of VerifyHeightIndex. -func (mr *MockLinearizableVMMockRecorder) VerifyHeightIndex(arg0 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) VerifyHeightIndex(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyHeightIndex", reflect.TypeOf((*MockLinearizableVM)(nil).VerifyHeightIndex), arg0) } @@ -383,7 +388,7 @@ func (m *MockLinearizableVM) Version(arg0 context.Context) (string, error) { } // Version indicates an expected call of Version. -func (mr *MockLinearizableVMMockRecorder) Version(arg0 interface{}) *gomock.Call { +func (mr *MockLinearizableVMMockRecorder) Version(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockLinearizableVM)(nil).Version), arg0) } diff --git a/snow/engine/snowman/block/mock_build_block_with_context_vm.go b/snow/engine/snowman/block/mock_build_block_with_context_vm.go index 9cb5f3e77833..016007b0dee7 100644 --- a/snow/engine/snowman/block/mock_build_block_with_context_vm.go +++ b/snow/engine/snowman/block/mock_build_block_with_context_vm.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/snowman/block (interfaces: BuildBlockWithContextChainVM) +// +// Generated by this command: +// +// mockgen -package=block -destination=snow/engine/snowman/block/mock_build_block_with_context_vm.go github.com/ava-labs/avalanchego/snow/engine/snowman/block BuildBlockWithContextChainVM +// // Package block is a generated GoMock package. package block @@ -45,7 +50,7 @@ func (m *MockBuildBlockWithContextChainVM) BuildBlockWithContext(arg0 context.Co } // BuildBlockWithContext indicates an expected call of BuildBlockWithContext. -func (mr *MockBuildBlockWithContextChainVMMockRecorder) BuildBlockWithContext(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockBuildBlockWithContextChainVMMockRecorder) BuildBlockWithContext(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildBlockWithContext", reflect.TypeOf((*MockBuildBlockWithContextChainVM)(nil).BuildBlockWithContext), arg0, arg1) } diff --git a/snow/engine/snowman/block/mock_chain_vm.go b/snow/engine/snowman/block/mock_chain_vm.go index 8cb9acb75ed0..ad99e3f716d0 100644 --- a/snow/engine/snowman/block/mock_chain_vm.go +++ b/snow/engine/snowman/block/mock_chain_vm.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/snowman/block (interfaces: ChainVM) +// +// Generated by this command: +// +// mockgen -package=block -destination=snow/engine/snowman/block/mock_chain_vm.go github.com/ava-labs/avalanchego/snow/engine/snowman/block ChainVM +// // Package block is a generated GoMock package. package block @@ -51,7 +56,7 @@ func (m *MockChainVM) AppGossip(arg0 context.Context, arg1 ids.NodeID, arg2 []by } // AppGossip indicates an expected call of AppGossip. -func (mr *MockChainVMMockRecorder) AppGossip(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) AppGossip(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*MockChainVM)(nil).AppGossip), arg0, arg1, arg2) } @@ -65,7 +70,7 @@ func (m *MockChainVM) AppRequest(arg0 context.Context, arg1 ids.NodeID, arg2 uin } // AppRequest indicates an expected call of AppRequest. -func (mr *MockChainVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*MockChainVM)(nil).AppRequest), arg0, arg1, arg2, arg3, arg4) } @@ -79,7 +84,7 @@ func (m *MockChainVM) AppRequestFailed(arg0 context.Context, arg1 ids.NodeID, ar } // AppRequestFailed indicates an expected call of AppRequestFailed. -func (mr *MockChainVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*MockChainVM)(nil).AppRequestFailed), arg0, arg1, arg2, arg3) } @@ -93,7 +98,7 @@ func (m *MockChainVM) AppResponse(arg0 context.Context, arg1 ids.NodeID, arg2 ui } // AppResponse indicates an expected call of AppResponse. -func (mr *MockChainVMMockRecorder) AppResponse(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) AppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*MockChainVM)(nil).AppResponse), arg0, arg1, arg2, arg3) } @@ -108,7 +113,7 @@ func (m *MockChainVM) BuildBlock(arg0 context.Context) (snowman.Block, error) { } // BuildBlock indicates an expected call of BuildBlock. -func (mr *MockChainVMMockRecorder) BuildBlock(arg0 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) BuildBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildBlock", reflect.TypeOf((*MockChainVM)(nil).BuildBlock), arg0) } @@ -122,7 +127,7 @@ func (m *MockChainVM) Connected(arg0 context.Context, arg1 ids.NodeID, arg2 *ver } // Connected indicates an expected call of Connected. -func (mr *MockChainVMMockRecorder) Connected(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) Connected(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*MockChainVM)(nil).Connected), arg0, arg1, arg2) } @@ -137,7 +142,7 @@ func (m *MockChainVM) CreateHandlers(arg0 context.Context) (map[string]http.Hand } // CreateHandlers indicates an expected call of CreateHandlers. -func (mr *MockChainVMMockRecorder) CreateHandlers(arg0 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) CreateHandlers(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateHandlers", reflect.TypeOf((*MockChainVM)(nil).CreateHandlers), arg0) } @@ -151,7 +156,7 @@ func (m *MockChainVM) CrossChainAppRequest(arg0 context.Context, arg1 ids.ID, ar } // CrossChainAppRequest indicates an expected call of CrossChainAppRequest. -func (mr *MockChainVMMockRecorder) CrossChainAppRequest(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) CrossChainAppRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequest", reflect.TypeOf((*MockChainVM)(nil).CrossChainAppRequest), arg0, arg1, arg2, arg3, arg4) } @@ -165,7 +170,7 @@ func (m *MockChainVM) CrossChainAppRequestFailed(arg0 context.Context, arg1 ids. } // CrossChainAppRequestFailed indicates an expected call of CrossChainAppRequestFailed. -func (mr *MockChainVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) CrossChainAppRequestFailed(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppRequestFailed", reflect.TypeOf((*MockChainVM)(nil).CrossChainAppRequestFailed), arg0, arg1, arg2, arg3) } @@ -179,7 +184,7 @@ func (m *MockChainVM) CrossChainAppResponse(arg0 context.Context, arg1 ids.ID, a } // CrossChainAppResponse indicates an expected call of CrossChainAppResponse. -func (mr *MockChainVMMockRecorder) CrossChainAppResponse(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) CrossChainAppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CrossChainAppResponse", reflect.TypeOf((*MockChainVM)(nil).CrossChainAppResponse), arg0, arg1, arg2, arg3) } @@ -193,7 +198,7 @@ func (m *MockChainVM) Disconnected(arg0 context.Context, arg1 ids.NodeID) error } // Disconnected indicates an expected call of Disconnected. -func (mr *MockChainVMMockRecorder) Disconnected(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) Disconnected(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*MockChainVM)(nil).Disconnected), arg0, arg1) } @@ -208,7 +213,7 @@ func (m *MockChainVM) GetBlock(arg0 context.Context, arg1 ids.ID) (snowman.Block } // GetBlock indicates an expected call of GetBlock. -func (mr *MockChainVMMockRecorder) GetBlock(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) GetBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockChainVM)(nil).GetBlock), arg0, arg1) } @@ -223,22 +228,22 @@ func (m *MockChainVM) GetBlockIDAtHeight(arg0 context.Context, arg1 uint64) (ids } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *MockChainVMMockRecorder) GetBlockIDAtHeight(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) GetBlockIDAtHeight(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockChainVM)(nil).GetBlockIDAtHeight), arg0, arg1) } // HealthCheck mocks base method. -func (m *MockChainVM) HealthCheck(arg0 context.Context) (interface{}, error) { +func (m *MockChainVM) HealthCheck(arg0 context.Context) (any, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HealthCheck", arg0) - ret0, _ := ret[0].(interface{}) + ret0, _ := ret[0].(any) ret1, _ := ret[1].(error) return ret0, ret1 } // HealthCheck indicates an expected call of HealthCheck. -func (mr *MockChainVMMockRecorder) HealthCheck(arg0 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) HealthCheck(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockChainVM)(nil).HealthCheck), arg0) } @@ -252,7 +257,7 @@ func (m *MockChainVM) Initialize(arg0 context.Context, arg1 *snow.Context, arg2 } // Initialize indicates an expected call of Initialize. -func (mr *MockChainVMMockRecorder) Initialize(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) Initialize(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*MockChainVM)(nil).Initialize), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } @@ -267,7 +272,7 @@ func (m *MockChainVM) LastAccepted(arg0 context.Context) (ids.ID, error) { } // LastAccepted indicates an expected call of LastAccepted. -func (mr *MockChainVMMockRecorder) LastAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) LastAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastAccepted", reflect.TypeOf((*MockChainVM)(nil).LastAccepted), arg0) } @@ -282,7 +287,7 @@ func (m *MockChainVM) ParseBlock(arg0 context.Context, arg1 []byte) (snowman.Blo } // ParseBlock indicates an expected call of ParseBlock. -func (mr *MockChainVMMockRecorder) ParseBlock(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) ParseBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseBlock", reflect.TypeOf((*MockChainVM)(nil).ParseBlock), arg0, arg1) } @@ -296,7 +301,7 @@ func (m *MockChainVM) SetPreference(arg0 context.Context, arg1 ids.ID) error { } // SetPreference indicates an expected call of SetPreference. -func (mr *MockChainVMMockRecorder) SetPreference(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) SetPreference(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockChainVM)(nil).SetPreference), arg0, arg1) } @@ -310,7 +315,7 @@ func (m *MockChainVM) SetState(arg0 context.Context, arg1 snow.State) error { } // SetState indicates an expected call of SetState. -func (mr *MockChainVMMockRecorder) SetState(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) SetState(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*MockChainVM)(nil).SetState), arg0, arg1) } @@ -324,7 +329,7 @@ func (m *MockChainVM) Shutdown(arg0 context.Context) error { } // Shutdown indicates an expected call of Shutdown. -func (mr *MockChainVMMockRecorder) Shutdown(arg0 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) Shutdown(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*MockChainVM)(nil).Shutdown), arg0) } @@ -338,7 +343,7 @@ func (m *MockChainVM) VerifyHeightIndex(arg0 context.Context) error { } // VerifyHeightIndex indicates an expected call of VerifyHeightIndex. -func (mr *MockChainVMMockRecorder) VerifyHeightIndex(arg0 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) VerifyHeightIndex(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyHeightIndex", reflect.TypeOf((*MockChainVM)(nil).VerifyHeightIndex), arg0) } @@ -353,7 +358,7 @@ func (m *MockChainVM) Version(arg0 context.Context) (string, error) { } // Version indicates an expected call of Version. -func (mr *MockChainVMMockRecorder) Version(arg0 interface{}) *gomock.Call { +func (mr *MockChainVMMockRecorder) Version(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Version", reflect.TypeOf((*MockChainVM)(nil).Version), arg0) } diff --git a/snow/engine/snowman/block/mock_state_syncable_vm.go b/snow/engine/snowman/block/mock_state_syncable_vm.go index f728b9b5a7a7..8d8abca53a0c 100644 --- a/snow/engine/snowman/block/mock_state_syncable_vm.go +++ b/snow/engine/snowman/block/mock_state_syncable_vm.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/snowman/block (interfaces: StateSyncableVM) +// +// Generated by this command: +// +// mockgen -package=block -destination=snow/engine/snowman/block/mock_state_syncable_vm.go github.com/ava-labs/avalanchego/snow/engine/snowman/block StateSyncableVM +// // Package block is a generated GoMock package. package block @@ -44,7 +49,7 @@ func (m *MockStateSyncableVM) GetLastStateSummary(arg0 context.Context) (StateSu } // GetLastStateSummary indicates an expected call of GetLastStateSummary. -func (mr *MockStateSyncableVMMockRecorder) GetLastStateSummary(arg0 interface{}) *gomock.Call { +func (mr *MockStateSyncableVMMockRecorder) GetLastStateSummary(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastStateSummary", reflect.TypeOf((*MockStateSyncableVM)(nil).GetLastStateSummary), arg0) } @@ -59,7 +64,7 @@ func (m *MockStateSyncableVM) GetOngoingSyncStateSummary(arg0 context.Context) ( } // GetOngoingSyncStateSummary indicates an expected call of GetOngoingSyncStateSummary. -func (mr *MockStateSyncableVMMockRecorder) GetOngoingSyncStateSummary(arg0 interface{}) *gomock.Call { +func (mr *MockStateSyncableVMMockRecorder) GetOngoingSyncStateSummary(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOngoingSyncStateSummary", reflect.TypeOf((*MockStateSyncableVM)(nil).GetOngoingSyncStateSummary), arg0) } @@ -74,7 +79,7 @@ func (m *MockStateSyncableVM) GetStateSummary(arg0 context.Context, arg1 uint64) } // GetStateSummary indicates an expected call of GetStateSummary. -func (mr *MockStateSyncableVMMockRecorder) GetStateSummary(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateSyncableVMMockRecorder) GetStateSummary(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateSummary", reflect.TypeOf((*MockStateSyncableVM)(nil).GetStateSummary), arg0, arg1) } @@ -89,7 +94,7 @@ func (m *MockStateSyncableVM) ParseStateSummary(arg0 context.Context, arg1 []byt } // ParseStateSummary indicates an expected call of ParseStateSummary. -func (mr *MockStateSyncableVMMockRecorder) ParseStateSummary(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateSyncableVMMockRecorder) ParseStateSummary(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseStateSummary", reflect.TypeOf((*MockStateSyncableVM)(nil).ParseStateSummary), arg0, arg1) } @@ -104,7 +109,7 @@ func (m *MockStateSyncableVM) StateSyncEnabled(arg0 context.Context) (bool, erro } // StateSyncEnabled indicates an expected call of StateSyncEnabled. -func (mr *MockStateSyncableVMMockRecorder) StateSyncEnabled(arg0 interface{}) *gomock.Call { +func (mr *MockStateSyncableVMMockRecorder) StateSyncEnabled(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSyncEnabled", reflect.TypeOf((*MockStateSyncableVM)(nil).StateSyncEnabled), arg0) } diff --git a/snow/engine/snowman/block/mock_with_verify_context.go b/snow/engine/snowman/block/mock_with_verify_context.go index 23ce5a2fd4d5..1c18e3e9f6cb 100644 --- a/snow/engine/snowman/block/mock_with_verify_context.go +++ b/snow/engine/snowman/block/mock_with_verify_context.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/engine/snowman/block (interfaces: WithVerifyContext) +// +// Generated by this command: +// +// mockgen -package=block -destination=snow/engine/snowman/block/mock_with_verify_context.go github.com/ava-labs/avalanchego/snow/engine/snowman/block WithVerifyContext +// // Package block is a generated GoMock package. package block @@ -44,7 +49,7 @@ func (m *MockWithVerifyContext) ShouldVerifyWithContext(arg0 context.Context) (b } // ShouldVerifyWithContext indicates an expected call of ShouldVerifyWithContext. -func (mr *MockWithVerifyContextMockRecorder) ShouldVerifyWithContext(arg0 interface{}) *gomock.Call { +func (mr *MockWithVerifyContextMockRecorder) ShouldVerifyWithContext(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldVerifyWithContext", reflect.TypeOf((*MockWithVerifyContext)(nil).ShouldVerifyWithContext), arg0) } @@ -58,7 +63,7 @@ func (m *MockWithVerifyContext) VerifyWithContext(arg0 context.Context, arg1 *Co } // VerifyWithContext indicates an expected call of VerifyWithContext. -func (mr *MockWithVerifyContextMockRecorder) VerifyWithContext(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockWithVerifyContextMockRecorder) VerifyWithContext(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyWithContext", reflect.TypeOf((*MockWithVerifyContext)(nil).VerifyWithContext), arg0, arg1) } diff --git a/snow/networking/handler/mock_handler.go b/snow/networking/handler/mock_handler.go index 3346da7960d8..517fbcd85537 100644 --- a/snow/networking/handler/mock_handler.go +++ b/snow/networking/handler/mock_handler.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/networking/handler (interfaces: Handler) +// +// Generated by this command: +// +// mockgen -package=handler -destination=snow/networking/handler/mock_handler.go github.com/ava-labs/avalanchego/snow/networking/handler Handler +// // Package handler is a generated GoMock package. package handler @@ -47,7 +52,7 @@ func (m *MockHandler) AwaitStopped(arg0 context.Context) (time.Duration, error) } // AwaitStopped indicates an expected call of AwaitStopped. -func (mr *MockHandlerMockRecorder) AwaitStopped(arg0 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) AwaitStopped(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AwaitStopped", reflect.TypeOf((*MockHandler)(nil).AwaitStopped), arg0) } @@ -81,16 +86,16 @@ func (mr *MockHandlerMockRecorder) GetEngineManager() *gomock.Call { } // HealthCheck mocks base method. -func (m *MockHandler) HealthCheck(arg0 context.Context) (interface{}, error) { +func (m *MockHandler) HealthCheck(arg0 context.Context) (any, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HealthCheck", arg0) - ret0, _ := ret[0].(interface{}) + ret0, _ := ret[0].(any) ret1, _ := ret[1].(error) return ret0, ret1 } // HealthCheck indicates an expected call of HealthCheck. -func (mr *MockHandlerMockRecorder) HealthCheck(arg0 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) HealthCheck(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockHandler)(nil).HealthCheck), arg0) } @@ -116,7 +121,7 @@ func (m *MockHandler) Push(arg0 context.Context, arg1 Message) { } // Push indicates an expected call of Push. -func (mr *MockHandlerMockRecorder) Push(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) Push(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Push", reflect.TypeOf((*MockHandler)(nil).Push), arg0, arg1) } @@ -128,7 +133,7 @@ func (m *MockHandler) RegisterTimeout(arg0 time.Duration) { } // RegisterTimeout indicates an expected call of RegisterTimeout. -func (mr *MockHandlerMockRecorder) RegisterTimeout(arg0 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) RegisterTimeout(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterTimeout", reflect.TypeOf((*MockHandler)(nil).RegisterTimeout), arg0) } @@ -140,7 +145,7 @@ func (m *MockHandler) SetEngineManager(arg0 *EngineManager) { } // SetEngineManager indicates an expected call of SetEngineManager. -func (mr *MockHandlerMockRecorder) SetEngineManager(arg0 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) SetEngineManager(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetEngineManager", reflect.TypeOf((*MockHandler)(nil).SetEngineManager), arg0) } @@ -152,7 +157,7 @@ func (m *MockHandler) SetOnStopped(arg0 func()) { } // SetOnStopped indicates an expected call of SetOnStopped. -func (mr *MockHandlerMockRecorder) SetOnStopped(arg0 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) SetOnStopped(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOnStopped", reflect.TypeOf((*MockHandler)(nil).SetOnStopped), arg0) } @@ -166,7 +171,7 @@ func (m *MockHandler) ShouldHandle(arg0 ids.NodeID) bool { } // ShouldHandle indicates an expected call of ShouldHandle. -func (mr *MockHandlerMockRecorder) ShouldHandle(arg0 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) ShouldHandle(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldHandle", reflect.TypeOf((*MockHandler)(nil).ShouldHandle), arg0) } @@ -178,7 +183,7 @@ func (m *MockHandler) Start(arg0 context.Context, arg1 bool) { } // Start indicates an expected call of Start. -func (mr *MockHandlerMockRecorder) Start(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) Start(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockHandler)(nil).Start), arg0, arg1) } @@ -190,7 +195,7 @@ func (m *MockHandler) Stop(arg0 context.Context) { } // Stop indicates an expected call of Stop. -func (mr *MockHandlerMockRecorder) Stop(arg0 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) Stop(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockHandler)(nil).Stop), arg0) } @@ -202,7 +207,7 @@ func (m *MockHandler) StopWithError(arg0 context.Context, arg1 error) { } // StopWithError indicates an expected call of StopWithError. -func (mr *MockHandlerMockRecorder) StopWithError(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockHandlerMockRecorder) StopWithError(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StopWithError", reflect.TypeOf((*MockHandler)(nil).StopWithError), arg0, arg1) } diff --git a/snow/networking/timeout/mock_manager.go b/snow/networking/timeout/mock_manager.go index 1033ad335afe..8eeac4c6f8dc 100644 --- a/snow/networking/timeout/mock_manager.go +++ b/snow/networking/timeout/mock_manager.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/networking/timeout (interfaces: Manager) +// +// Generated by this command: +// +// mockgen -package=timeout -destination=snow/networking/timeout/mock_manager.go github.com/ava-labs/avalanchego/snow/networking/timeout Manager +// // Package timeout is a generated GoMock package. package timeout @@ -58,7 +63,7 @@ func (m *MockManager) IsBenched(arg0 ids.NodeID, arg1 ids.ID) bool { } // IsBenched indicates an expected call of IsBenched. -func (mr *MockManagerMockRecorder) IsBenched(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) IsBenched(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsBenched", reflect.TypeOf((*MockManager)(nil).IsBenched), arg0, arg1) } @@ -72,7 +77,7 @@ func (m *MockManager) RegisterChain(arg0 *snow.ConsensusContext) error { } // RegisterChain indicates an expected call of RegisterChain. -func (mr *MockManagerMockRecorder) RegisterChain(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RegisterChain(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterChain", reflect.TypeOf((*MockManager)(nil).RegisterChain), arg0) } @@ -84,7 +89,7 @@ func (m *MockManager) RegisterRequest(arg0 ids.NodeID, arg1 ids.ID, arg2 bool, a } // RegisterRequest indicates an expected call of RegisterRequest. -func (mr *MockManagerMockRecorder) RegisterRequest(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RegisterRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterRequest", reflect.TypeOf((*MockManager)(nil).RegisterRequest), arg0, arg1, arg2, arg3, arg4) } @@ -108,7 +113,7 @@ func (m *MockManager) RegisterResponse(arg0 ids.NodeID, arg1 ids.ID, arg2 ids.Re } // RegisterResponse indicates an expected call of RegisterResponse. -func (mr *MockManagerMockRecorder) RegisterResponse(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RegisterResponse(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterResponse", reflect.TypeOf((*MockManager)(nil).RegisterResponse), arg0, arg1, arg2, arg3, arg4) } @@ -120,7 +125,7 @@ func (m *MockManager) RemoveRequest(arg0 ids.RequestID) { } // RemoveRequest indicates an expected call of RemoveRequest. -func (mr *MockManagerMockRecorder) RemoveRequest(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RemoveRequest(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveRequest", reflect.TypeOf((*MockManager)(nil).RemoveRequest), arg0) } diff --git a/snow/networking/tracker/mock_resource_tracker.go b/snow/networking/tracker/mock_resource_tracker.go index cfe8d59bdcd0..438bd44d9b4f 100644 --- a/snow/networking/tracker/mock_resource_tracker.go +++ b/snow/networking/tracker/mock_resource_tracker.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/networking/tracker (interfaces: Tracker) +// +// Generated by this command: +// +// mockgen -package=tracker -destination=snow/networking/tracker/mock_resource_tracker.go github.com/ava-labs/avalanchego/snow/networking/tracker Tracker +// // Package tracker is a generated GoMock package. package tracker @@ -44,7 +49,7 @@ func (m *MockTracker) TimeUntilUsage(arg0 ids.NodeID, arg1 time.Time, arg2 float } // TimeUntilUsage indicates an expected call of TimeUntilUsage. -func (mr *MockTrackerMockRecorder) TimeUntilUsage(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockTrackerMockRecorder) TimeUntilUsage(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TimeUntilUsage", reflect.TypeOf((*MockTracker)(nil).TimeUntilUsage), arg0, arg1, arg2) } @@ -72,7 +77,7 @@ func (m *MockTracker) Usage(arg0 ids.NodeID, arg1 time.Time) float64 { } // Usage indicates an expected call of Usage. -func (mr *MockTrackerMockRecorder) Usage(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockTrackerMockRecorder) Usage(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Usage", reflect.TypeOf((*MockTracker)(nil).Usage), arg0, arg1) } diff --git a/snow/networking/tracker/mock_targeter.go b/snow/networking/tracker/mock_targeter.go index 165bf7a95c59..7e260fe69d6d 100644 --- a/snow/networking/tracker/mock_targeter.go +++ b/snow/networking/tracker/mock_targeter.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/networking/tracker (interfaces: Targeter) +// +// Generated by this command: +// +// mockgen -package=tracker -destination=snow/networking/tracker/mock_targeter.go github.com/ava-labs/avalanchego/snow/networking/tracker Targeter +// // Package tracker is a generated GoMock package. package tracker @@ -43,7 +48,7 @@ func (m *MockTargeter) TargetUsage(arg0 ids.NodeID) float64 { } // TargetUsage indicates an expected call of TargetUsage. -func (mr *MockTargeterMockRecorder) TargetUsage(arg0 interface{}) *gomock.Call { +func (mr *MockTargeterMockRecorder) TargetUsage(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TargetUsage", reflect.TypeOf((*MockTargeter)(nil).TargetUsage), arg0) } diff --git a/snow/uptime/mock_calculator.go b/snow/uptime/mock_calculator.go index f0ece236f88c..cc5b5942e639 100644 --- a/snow/uptime/mock_calculator.go +++ b/snow/uptime/mock_calculator.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/uptime (interfaces: Calculator) +// +// Generated by this command: +// +// mockgen -package=uptime -destination=snow/uptime/mock_calculator.go github.com/ava-labs/avalanchego/snow/uptime Calculator +// // Package uptime is a generated GoMock package. package uptime @@ -46,7 +51,7 @@ func (m *MockCalculator) CalculateUptime(arg0 ids.NodeID, arg1 ids.ID) (time.Dur } // CalculateUptime indicates an expected call of CalculateUptime. -func (mr *MockCalculatorMockRecorder) CalculateUptime(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockCalculatorMockRecorder) CalculateUptime(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptime", reflect.TypeOf((*MockCalculator)(nil).CalculateUptime), arg0, arg1) } @@ -61,7 +66,7 @@ func (m *MockCalculator) CalculateUptimePercent(arg0 ids.NodeID, arg1 ids.ID) (f } // CalculateUptimePercent indicates an expected call of CalculateUptimePercent. -func (mr *MockCalculatorMockRecorder) CalculateUptimePercent(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockCalculatorMockRecorder) CalculateUptimePercent(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptimePercent", reflect.TypeOf((*MockCalculator)(nil).CalculateUptimePercent), arg0, arg1) } @@ -76,7 +81,7 @@ func (m *MockCalculator) CalculateUptimePercentFrom(arg0 ids.NodeID, arg1 ids.ID } // CalculateUptimePercentFrom indicates an expected call of CalculateUptimePercentFrom. -func (mr *MockCalculatorMockRecorder) CalculateUptimePercentFrom(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockCalculatorMockRecorder) CalculateUptimePercentFrom(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateUptimePercentFrom", reflect.TypeOf((*MockCalculator)(nil).CalculateUptimePercentFrom), arg0, arg1, arg2) } diff --git a/snow/validators/mock_state.go b/snow/validators/mock_state.go index 07447721c28c..6bed638becd8 100644 --- a/snow/validators/mock_state.go +++ b/snow/validators/mock_state.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/validators (interfaces: State) +// +// Generated by this command: +// +// mockgen -package=validators -destination=snow/validators/mock_state.go github.com/ava-labs/avalanchego/snow/validators State +// // Package validators is a generated GoMock package. package validators @@ -45,7 +50,7 @@ func (m *MockState) GetCurrentHeight(arg0 context.Context) (uint64, error) { } // GetCurrentHeight indicates an expected call of GetCurrentHeight. -func (mr *MockStateMockRecorder) GetCurrentHeight(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetCurrentHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentHeight", reflect.TypeOf((*MockState)(nil).GetCurrentHeight), arg0) } @@ -60,7 +65,7 @@ func (m *MockState) GetMinimumHeight(arg0 context.Context) (uint64, error) { } // GetMinimumHeight indicates an expected call of GetMinimumHeight. -func (mr *MockStateMockRecorder) GetMinimumHeight(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetMinimumHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMinimumHeight", reflect.TypeOf((*MockState)(nil).GetMinimumHeight), arg0) } @@ -75,7 +80,7 @@ func (m *MockState) GetSubnetID(arg0 context.Context, arg1 ids.ID) (ids.ID, erro } // GetSubnetID indicates an expected call of GetSubnetID. -func (mr *MockStateMockRecorder) GetSubnetID(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetSubnetID(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetID", reflect.TypeOf((*MockState)(nil).GetSubnetID), arg0, arg1) } @@ -90,7 +95,7 @@ func (m *MockState) GetValidatorSet(arg0 context.Context, arg1 uint64, arg2 ids. } // GetValidatorSet indicates an expected call of GetValidatorSet. -func (mr *MockStateMockRecorder) GetValidatorSet(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetValidatorSet(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorSet", reflect.TypeOf((*MockState)(nil).GetValidatorSet), arg0, arg1, arg2) } diff --git a/snow/validators/mock_subnet_connector.go b/snow/validators/mock_subnet_connector.go index 4719be84ef88..b9f3ee0519b8 100644 --- a/snow/validators/mock_subnet_connector.go +++ b/snow/validators/mock_subnet_connector.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/snow/validators (interfaces: SubnetConnector) +// +// Generated by this command: +// +// mockgen -package=validators -destination=snow/validators/mock_subnet_connector.go github.com/ava-labs/avalanchego/snow/validators SubnetConnector +// // Package validators is a generated GoMock package. package validators @@ -44,7 +49,7 @@ func (m *MockSubnetConnector) ConnectedSubnet(arg0 context.Context, arg1 ids.Nod } // ConnectedSubnet indicates an expected call of ConnectedSubnet. -func (mr *MockSubnetConnectorMockRecorder) ConnectedSubnet(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSubnetConnectorMockRecorder) ConnectedSubnet(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectedSubnet", reflect.TypeOf((*MockSubnetConnector)(nil).ConnectedSubnet), arg0, arg1, arg2) } diff --git a/utils/crypto/keychain/mock_ledger.go b/utils/crypto/keychain/mock_ledger.go index d17500564097..b082631c416e 100644 --- a/utils/crypto/keychain/mock_ledger.go +++ b/utils/crypto/keychain/mock_ledger.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/utils/crypto/keychain (interfaces: Ledger) +// +// Generated by this command: +// +// mockgen -package=keychain -destination=utils/crypto/keychain/mock_ledger.go github.com/ava-labs/avalanchego/utils/crypto/keychain Ledger +// // Package keychain is a generated GoMock package. package keychain @@ -45,7 +50,7 @@ func (m *MockLedger) Address(arg0 string, arg1 uint32) (ids.ShortID, error) { } // Address indicates an expected call of Address. -func (mr *MockLedgerMockRecorder) Address(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLedgerMockRecorder) Address(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Address", reflect.TypeOf((*MockLedger)(nil).Address), arg0, arg1) } @@ -60,7 +65,7 @@ func (m *MockLedger) Addresses(arg0 []uint32) ([]ids.ShortID, error) { } // Addresses indicates an expected call of Addresses. -func (mr *MockLedgerMockRecorder) Addresses(arg0 interface{}) *gomock.Call { +func (mr *MockLedgerMockRecorder) Addresses(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addresses", reflect.TypeOf((*MockLedger)(nil).Addresses), arg0) } @@ -89,7 +94,7 @@ func (m *MockLedger) Sign(arg0 []byte, arg1 []uint32) ([][]byte, error) { } // Sign indicates an expected call of Sign. -func (mr *MockLedgerMockRecorder) Sign(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLedgerMockRecorder) Sign(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sign", reflect.TypeOf((*MockLedger)(nil).Sign), arg0, arg1) } @@ -104,7 +109,7 @@ func (m *MockLedger) SignHash(arg0 []byte, arg1 []uint32) ([][]byte, error) { } // SignHash indicates an expected call of SignHash. -func (mr *MockLedgerMockRecorder) SignHash(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockLedgerMockRecorder) SignHash(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignHash", reflect.TypeOf((*MockLedger)(nil).SignHash), arg0, arg1) } diff --git a/utils/filesystem/mock_io.go b/utils/filesystem/mock_io.go index 43f28011cbfb..06b27dd18dd0 100644 --- a/utils/filesystem/mock_io.go +++ b/utils/filesystem/mock_io.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/utils/filesystem (interfaces: Reader) +// +// Generated by this command: +// +// mockgen -package=filesystem -destination=utils/filesystem/mock_io.go github.com/ava-labs/avalanchego/utils/filesystem Reader +// // Package filesystem is a generated GoMock package. package filesystem @@ -44,7 +49,7 @@ func (m *MockReader) ReadDir(arg0 string) ([]fs.DirEntry, error) { } // ReadDir indicates an expected call of ReadDir. -func (mr *MockReaderMockRecorder) ReadDir(arg0 interface{}) *gomock.Call { +func (mr *MockReaderMockRecorder) ReadDir(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadDir", reflect.TypeOf((*MockReader)(nil).ReadDir), arg0) } diff --git a/utils/hashing/consistent/ring_test.go b/utils/hashing/consistent/ring_test.go index 4a8f3ca5b71b..a53e166657b6 100644 --- a/utils/hashing/consistent/ring_test.go +++ b/utils/hashing/consistent/ring_test.go @@ -181,7 +181,7 @@ func TestGetMapsToClockwiseNode(t *testing.T) { ring, hasher := setupTest(t, 1) // setup expected calls - calls := make([]*gomock.Call, len(test.ringNodes)+1) + calls := make([]any, len(test.ringNodes)+1) for i, key := range test.ringNodes { calls[i] = hasher.EXPECT().Hash(getHashKey(key.ConsistentHashKey(), 0)).Return(key.hash).Times(1) diff --git a/utils/hashing/mock_hasher.go b/utils/hashing/mock_hasher.go index bc9a0abed2d0..c2d5ea4b3918 100644 --- a/utils/hashing/mock_hasher.go +++ b/utils/hashing/mock_hasher.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/utils/hashing (interfaces: Hasher) +// +// Generated by this command: +// +// mockgen -package=hashing -destination=utils/hashing/mock_hasher.go github.com/ava-labs/avalanchego/utils/hashing Hasher +// // Package hashing is a generated GoMock package. package hashing @@ -42,7 +47,7 @@ func (m *MockHasher) Hash(arg0 []byte) uint64 { } // Hash indicates an expected call of Hash. -func (mr *MockHasherMockRecorder) Hash(arg0 interface{}) *gomock.Call { +func (mr *MockHasherMockRecorder) Hash(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Hash", reflect.TypeOf((*MockHasher)(nil).Hash), arg0) } diff --git a/utils/resource/mock_user.go b/utils/resource/mock_user.go index 28f0059e1c88..d333f2c58e4b 100644 --- a/utils/resource/mock_user.go +++ b/utils/resource/mock_user.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/utils/resource (interfaces: User) +// +// Generated by this command: +// +// mockgen -package=resource -destination=utils/resource/mock_user.go github.com/ava-labs/avalanchego/utils/resource User +// // Package resource is a generated GoMock package. package resource diff --git a/vms/avm/block/mock_block.go b/vms/avm/block/mock_block.go index 296fc149f253..bc332e88590c 100644 --- a/vms/avm/block/mock_block.go +++ b/vms/avm/block/mock_block.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/avm/block (interfaces: Block) +// +// Generated by this command: +// +// mockgen -package=block -destination=vms/avm/block/mock_block.go github.com/ava-labs/avalanchego/vms/avm/block Block +// // Package block is a generated GoMock package. package block @@ -87,7 +92,7 @@ func (m *MockBlock) InitCtx(arg0 *snow.Context) { } // InitCtx indicates an expected call of InitCtx. -func (mr *MockBlockMockRecorder) InitCtx(arg0 interface{}) *gomock.Call { +func (mr *MockBlockMockRecorder) InitCtx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockBlock)(nil).InitCtx), arg0) } @@ -157,7 +162,7 @@ func (m *MockBlock) initialize(arg0 []byte, arg1 codec.Manager) error { } // initialize indicates an expected call of initialize. -func (mr *MockBlockMockRecorder) initialize(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockBlockMockRecorder) initialize(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "initialize", reflect.TypeOf((*MockBlock)(nil).initialize), arg0, arg1) } diff --git a/vms/avm/metrics/mock_metrics.go b/vms/avm/metrics/mock_metrics.go index 25ae52fef2d0..2ae4a0786bf0 100644 --- a/vms/avm/metrics/mock_metrics.go +++ b/vms/avm/metrics/mock_metrics.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/avm/metrics (interfaces: Metrics) +// +// Generated by this command: +// +// mockgen -package=metrics -destination=vms/avm/metrics/mock_metrics.go github.com/ava-labs/avalanchego/vms/avm/metrics Metrics +// // Package metrics is a generated GoMock package. package metrics @@ -44,7 +49,7 @@ func (m *MockMetrics) AfterRequest(arg0 *rpc.RequestInfo) { } // AfterRequest indicates an expected call of AfterRequest. -func (mr *MockMetricsMockRecorder) AfterRequest(arg0 interface{}) *gomock.Call { +func (mr *MockMetricsMockRecorder) AfterRequest(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterRequest", reflect.TypeOf((*MockMetrics)(nil).AfterRequest), arg0) } @@ -94,7 +99,7 @@ func (m *MockMetrics) InterceptRequest(arg0 *rpc.RequestInfo) *http.Request { } // InterceptRequest indicates an expected call of InterceptRequest. -func (mr *MockMetricsMockRecorder) InterceptRequest(arg0 interface{}) *gomock.Call { +func (mr *MockMetricsMockRecorder) InterceptRequest(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InterceptRequest", reflect.TypeOf((*MockMetrics)(nil).InterceptRequest), arg0) } @@ -108,7 +113,7 @@ func (m *MockMetrics) MarkBlockAccepted(arg0 block.Block) error { } // MarkBlockAccepted indicates an expected call of MarkBlockAccepted. -func (mr *MockMetricsMockRecorder) MarkBlockAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockMetricsMockRecorder) MarkBlockAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkBlockAccepted", reflect.TypeOf((*MockMetrics)(nil).MarkBlockAccepted), arg0) } @@ -122,7 +127,7 @@ func (m *MockMetrics) MarkTxAccepted(arg0 *txs.Tx) error { } // MarkTxAccepted indicates an expected call of MarkTxAccepted. -func (mr *MockMetricsMockRecorder) MarkTxAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockMetricsMockRecorder) MarkTxAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkTxAccepted", reflect.TypeOf((*MockMetrics)(nil).MarkTxAccepted), arg0) } diff --git a/vms/avm/state/mock_state.go b/vms/avm/state/mock_state.go index 162f6328ccdb..cb5138c90369 100644 --- a/vms/avm/state/mock_state.go +++ b/vms/avm/state/mock_state.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/avm/state (interfaces: Chain,State,Diff) +// +// Generated by this command: +// +// mockgen -package=state -destination=vms/avm/state/mock_state.go github.com/ava-labs/avalanchego/vms/avm/state Chain,State,Diff +// // Package state is a generated GoMock package. package state @@ -48,7 +53,7 @@ func (m *MockChain) AddBlock(arg0 block.Block) { } // AddBlock indicates an expected call of AddBlock. -func (mr *MockChainMockRecorder) AddBlock(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBlock", reflect.TypeOf((*MockChain)(nil).AddBlock), arg0) } @@ -60,7 +65,7 @@ func (m *MockChain) AddTx(arg0 *txs.Tx) { } // AddTx indicates an expected call of AddTx. -func (mr *MockChainMockRecorder) AddTx(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockChain)(nil).AddTx), arg0) } @@ -72,7 +77,7 @@ func (m *MockChain) AddUTXO(arg0 *avax.UTXO) { } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockChainMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockChain)(nil).AddUTXO), arg0) } @@ -84,7 +89,7 @@ func (m *MockChain) DeleteUTXO(arg0 ids.ID) { } // DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockChainMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), arg0) } @@ -99,7 +104,7 @@ func (m *MockChain) GetBlock(arg0 ids.ID) (block.Block, error) { } // GetBlock indicates an expected call of GetBlock. -func (mr *MockChainMockRecorder) GetBlock(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockChain)(nil).GetBlock), arg0) } @@ -114,7 +119,7 @@ func (m *MockChain) GetBlockIDAtHeight(arg0 uint64) (ids.ID, error) { } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *MockChainMockRecorder) GetBlockIDAtHeight(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetBlockIDAtHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockChain)(nil).GetBlockIDAtHeight), arg0) } @@ -157,7 +162,7 @@ func (m *MockChain) GetTx(arg0 ids.ID) (*txs.Tx, error) { } // GetTx indicates an expected call of GetTx. -func (mr *MockChainMockRecorder) GetTx(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), arg0) } @@ -172,7 +177,7 @@ func (m *MockChain) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { } // GetUTXO indicates an expected call of GetUTXO. -func (mr *MockChainMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), arg0) } @@ -184,7 +189,7 @@ func (m *MockChain) SetLastAccepted(arg0 ids.ID) { } // SetLastAccepted indicates an expected call of SetLastAccepted. -func (mr *MockChainMockRecorder) SetLastAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) SetLastAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastAccepted", reflect.TypeOf((*MockChain)(nil).SetLastAccepted), arg0) } @@ -196,7 +201,7 @@ func (m *MockChain) SetTimestamp(arg0 time.Time) { } // SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockChainMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) SetTimestamp(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), arg0) } @@ -243,7 +248,7 @@ func (m *MockState) AddBlock(arg0 block.Block) { } // AddBlock indicates an expected call of AddBlock. -func (mr *MockStateMockRecorder) AddBlock(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBlock", reflect.TypeOf((*MockState)(nil).AddBlock), arg0) } @@ -255,7 +260,7 @@ func (m *MockState) AddTx(arg0 *txs.Tx) { } // AddTx indicates an expected call of AddTx. -func (mr *MockStateMockRecorder) AddTx(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockState)(nil).AddTx), arg0) } @@ -267,7 +272,7 @@ func (m *MockState) AddUTXO(arg0 *avax.UTXO) { } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockStateMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockState)(nil).AddUTXO), arg0) } @@ -337,7 +342,7 @@ func (m *MockState) DeleteUTXO(arg0 ids.ID) { } // DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockStateMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockState)(nil).DeleteUTXO), arg0) } @@ -352,7 +357,7 @@ func (m *MockState) GetBlock(arg0 ids.ID) (block.Block, error) { } // GetBlock indicates an expected call of GetBlock. -func (mr *MockStateMockRecorder) GetBlock(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockState)(nil).GetBlock), arg0) } @@ -367,7 +372,7 @@ func (m *MockState) GetBlockIDAtHeight(arg0 uint64) (ids.ID, error) { } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *MockStateMockRecorder) GetBlockIDAtHeight(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetBlockIDAtHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockState)(nil).GetBlockIDAtHeight), arg0) } @@ -410,7 +415,7 @@ func (m *MockState) GetTx(arg0 ids.ID) (*txs.Tx, error) { } // GetTx indicates an expected call of GetTx. -func (mr *MockStateMockRecorder) GetTx(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockState)(nil).GetTx), arg0) } @@ -425,7 +430,7 @@ func (m *MockState) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { } // GetUTXO indicates an expected call of GetUTXO. -func (mr *MockStateMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockState)(nil).GetUTXO), arg0) } @@ -439,7 +444,7 @@ func (m *MockState) InitializeChainState(arg0 ids.ID, arg1 time.Time) error { } // InitializeChainState indicates an expected call of InitializeChainState. -func (mr *MockStateMockRecorder) InitializeChainState(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) InitializeChainState(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitializeChainState", reflect.TypeOf((*MockState)(nil).InitializeChainState), arg0, arg1) } @@ -468,7 +473,7 @@ func (m *MockState) Prune(arg0 sync.Locker, arg1 logging.Logger) error { } // Prune indicates an expected call of Prune. -func (mr *MockStateMockRecorder) Prune(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) Prune(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Prune", reflect.TypeOf((*MockState)(nil).Prune), arg0, arg1) } @@ -494,7 +499,7 @@ func (m *MockState) SetLastAccepted(arg0 ids.ID) { } // SetLastAccepted indicates an expected call of SetLastAccepted. -func (mr *MockStateMockRecorder) SetLastAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetLastAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastAccepted", reflect.TypeOf((*MockState)(nil).SetLastAccepted), arg0) } @@ -506,7 +511,7 @@ func (m *MockState) SetTimestamp(arg0 time.Time) { } // SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockStateMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetTimestamp(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockState)(nil).SetTimestamp), arg0) } @@ -521,7 +526,7 @@ func (m *MockState) UTXOIDs(arg0 []byte, arg1 ids.ID, arg2 int) ([]ids.ID, error } // UTXOIDs indicates an expected call of UTXOIDs. -func (mr *MockStateMockRecorder) UTXOIDs(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) UTXOIDs(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UTXOIDs", reflect.TypeOf((*MockState)(nil).UTXOIDs), arg0, arg1, arg2) } @@ -556,7 +561,7 @@ func (m *MockDiff) AddBlock(arg0 block.Block) { } // AddBlock indicates an expected call of AddBlock. -func (mr *MockDiffMockRecorder) AddBlock(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBlock", reflect.TypeOf((*MockDiff)(nil).AddBlock), arg0) } @@ -568,7 +573,7 @@ func (m *MockDiff) AddTx(arg0 *txs.Tx) { } // AddTx indicates an expected call of AddTx. -func (mr *MockDiffMockRecorder) AddTx(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), arg0) } @@ -580,7 +585,7 @@ func (m *MockDiff) AddUTXO(arg0 *avax.UTXO) { } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockDiffMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), arg0) } @@ -592,7 +597,7 @@ func (m *MockDiff) Apply(arg0 Chain) { } // Apply indicates an expected call of Apply. -func (mr *MockDiffMockRecorder) Apply(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) Apply(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) } @@ -604,7 +609,7 @@ func (m *MockDiff) DeleteUTXO(arg0 ids.ID) { } // DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) } @@ -619,7 +624,7 @@ func (m *MockDiff) GetBlock(arg0 ids.ID) (block.Block, error) { } // GetBlock indicates an expected call of GetBlock. -func (mr *MockDiffMockRecorder) GetBlock(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockDiff)(nil).GetBlock), arg0) } @@ -634,7 +639,7 @@ func (m *MockDiff) GetBlockIDAtHeight(arg0 uint64) (ids.ID, error) { } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *MockDiffMockRecorder) GetBlockIDAtHeight(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetBlockIDAtHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockDiff)(nil).GetBlockIDAtHeight), arg0) } @@ -677,7 +682,7 @@ func (m *MockDiff) GetTx(arg0 ids.ID) (*txs.Tx, error) { } // GetTx indicates an expected call of GetTx. -func (mr *MockDiffMockRecorder) GetTx(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockDiff)(nil).GetTx), arg0) } @@ -692,7 +697,7 @@ func (m *MockDiff) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { } // GetUTXO indicates an expected call of GetUTXO. -func (mr *MockDiffMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockDiff)(nil).GetUTXO), arg0) } @@ -704,7 +709,7 @@ func (m *MockDiff) SetLastAccepted(arg0 ids.ID) { } // SetLastAccepted indicates an expected call of SetLastAccepted. -func (mr *MockDiffMockRecorder) SetLastAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) SetLastAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastAccepted", reflect.TypeOf((*MockDiff)(nil).SetLastAccepted), arg0) } @@ -716,7 +721,7 @@ func (m *MockDiff) SetTimestamp(arg0 time.Time) { } // SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockDiffMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) SetTimestamp(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockDiff)(nil).SetTimestamp), arg0) } diff --git a/vms/avm/txs/mempool/mock_mempool.go b/vms/avm/txs/mempool/mock_mempool.go index c82758bac51f..69860c38d5d3 100644 --- a/vms/avm/txs/mempool/mock_mempool.go +++ b/vms/avm/txs/mempool/mock_mempool.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/avm/txs/mempool (interfaces: Mempool) +// +// Generated by this command: +// +// mockgen -package=mempool -destination=vms/avm/txs/mempool/mock_mempool.go github.com/ava-labs/avalanchego/vms/avm/txs/mempool Mempool +// // Package mempool is a generated GoMock package. package mempool @@ -44,7 +49,7 @@ func (m *MockMempool) Add(arg0 *txs.Tx) error { } // Add indicates an expected call of Add. -func (mr *MockMempoolMockRecorder) Add(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Add(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockMempool)(nil).Add), arg0) } @@ -59,7 +64,7 @@ func (m *MockMempool) Get(arg0 ids.ID) (*txs.Tx, bool) { } // Get indicates an expected call of Get. -func (mr *MockMempoolMockRecorder) Get(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Get(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMempool)(nil).Get), arg0) } @@ -73,7 +78,7 @@ func (m *MockMempool) GetDropReason(arg0 ids.ID) error { } // GetDropReason indicates an expected call of GetDropReason. -func (mr *MockMempoolMockRecorder) GetDropReason(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) GetDropReason(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDropReason", reflect.TypeOf((*MockMempool)(nil).GetDropReason), arg0) } @@ -85,7 +90,7 @@ func (m *MockMempool) Iterate(arg0 func(*txs.Tx) bool) { } // Iterate indicates an expected call of Iterate. -func (mr *MockMempoolMockRecorder) Iterate(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Iterate(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockMempool)(nil).Iterate), arg0) } @@ -111,7 +116,7 @@ func (m *MockMempool) MarkDropped(arg0 ids.ID, arg1 error) { } // MarkDropped indicates an expected call of MarkDropped. -func (mr *MockMempoolMockRecorder) MarkDropped(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) MarkDropped(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkDropped", reflect.TypeOf((*MockMempool)(nil).MarkDropped), arg0, arg1) } @@ -134,7 +139,7 @@ func (mr *MockMempoolMockRecorder) Peek() *gomock.Call { // Remove mocks base method. func (m *MockMempool) Remove(arg0 ...*txs.Tx) { m.ctrl.T.Helper() - varargs := []interface{}{} + varargs := []any{} for _, a := range arg0 { varargs = append(varargs, a) } @@ -142,7 +147,7 @@ func (m *MockMempool) Remove(arg0 ...*txs.Tx) { } // Remove indicates an expected call of Remove. -func (mr *MockMempoolMockRecorder) Remove(arg0 ...interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Remove(arg0 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockMempool)(nil).Remove), arg0...) } diff --git a/vms/components/avax/mock_transferable_in.go b/vms/components/avax/mock_transferable_in.go index cbe350801e3b..b4db89933057 100644 --- a/vms/components/avax/mock_transferable_in.go +++ b/vms/components/avax/mock_transferable_in.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/components/avax (interfaces: TransferableIn) +// +// Generated by this command: +// +// mockgen -package=avax -destination=vms/components/avax/mock_transferable_in.go github.com/ava-labs/avalanchego/vms/components/avax TransferableIn +// // Package avax is a generated GoMock package. package avax @@ -70,7 +75,7 @@ func (m *MockTransferableIn) InitCtx(arg0 *snow.Context) { } // InitCtx indicates an expected call of InitCtx. -func (mr *MockTransferableInMockRecorder) InitCtx(arg0 interface{}) *gomock.Call { +func (mr *MockTransferableInMockRecorder) InitCtx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockTransferableIn)(nil).InitCtx), arg0) } diff --git a/vms/components/verify/mock_verifiable.go b/vms/components/verify/mock_verifiable.go index 3b2609f6eb0f..fe0e5770500c 100644 --- a/vms/components/verify/mock_verifiable.go +++ b/vms/components/verify/mock_verifiable.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/components/verify (interfaces: Verifiable) +// +// Generated by this command: +// +// mockgen -package=verify -destination=vms/components/verify/mock_verifiable.go github.com/ava-labs/avalanchego/vms/components/verify Verifiable +// // Package verify is a generated GoMock package. package verify diff --git a/vms/mock_manager.go b/vms/mock_manager.go index 70f3dc5ca840..cea232ba2a7d 100644 --- a/vms/mock_manager.go +++ b/vms/mock_manager.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms (interfaces: Factory,Manager) +// +// Generated by this command: +// +// mockgen -package=vms -destination=vms/mock_manager.go github.com/ava-labs/avalanchego/vms Factory,Manager +// // Package vms is a generated GoMock package. package vms @@ -37,16 +42,16 @@ func (m *MockFactory) EXPECT() *MockFactoryMockRecorder { } // New mocks base method. -func (m *MockFactory) New(arg0 logging.Logger) (interface{}, error) { +func (m *MockFactory) New(arg0 logging.Logger) (any, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "New", arg0) - ret0, _ := ret[0].(interface{}) + ret0, _ := ret[0].(any) ret1, _ := ret[1].(error) return ret0, ret1 } // New indicates an expected call of New. -func (mr *MockFactoryMockRecorder) New(arg0 interface{}) *gomock.Call { +func (mr *MockFactoryMockRecorder) New(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "New", reflect.TypeOf((*MockFactory)(nil).New), arg0) } @@ -83,7 +88,7 @@ func (m *MockManager) Alias(arg0 ids.ID, arg1 string) error { } // Alias indicates an expected call of Alias. -func (mr *MockManagerMockRecorder) Alias(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) Alias(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Alias", reflect.TypeOf((*MockManager)(nil).Alias), arg0, arg1) } @@ -98,7 +103,7 @@ func (m *MockManager) Aliases(arg0 ids.ID) ([]string, error) { } // Aliases indicates an expected call of Aliases. -func (mr *MockManagerMockRecorder) Aliases(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) Aliases(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Aliases", reflect.TypeOf((*MockManager)(nil).Aliases), arg0) } @@ -113,7 +118,7 @@ func (m *MockManager) GetFactory(arg0 ids.ID) (Factory, error) { } // GetFactory indicates an expected call of GetFactory. -func (mr *MockManagerMockRecorder) GetFactory(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetFactory(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFactory", reflect.TypeOf((*MockManager)(nil).GetFactory), arg0) } @@ -143,7 +148,7 @@ func (m *MockManager) Lookup(arg0 string) (ids.ID, error) { } // Lookup indicates an expected call of Lookup. -func (mr *MockManagerMockRecorder) Lookup(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) Lookup(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lookup", reflect.TypeOf((*MockManager)(nil).Lookup), arg0) } @@ -158,7 +163,7 @@ func (m *MockManager) PrimaryAlias(arg0 ids.ID) (string, error) { } // PrimaryAlias indicates an expected call of PrimaryAlias. -func (mr *MockManagerMockRecorder) PrimaryAlias(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) PrimaryAlias(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryAlias", reflect.TypeOf((*MockManager)(nil).PrimaryAlias), arg0) } @@ -172,7 +177,7 @@ func (m *MockManager) PrimaryAliasOrDefault(arg0 ids.ID) string { } // PrimaryAliasOrDefault indicates an expected call of PrimaryAliasOrDefault. -func (mr *MockManagerMockRecorder) PrimaryAliasOrDefault(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) PrimaryAliasOrDefault(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryAliasOrDefault", reflect.TypeOf((*MockManager)(nil).PrimaryAliasOrDefault), arg0) } @@ -186,7 +191,7 @@ func (m *MockManager) RegisterFactory(arg0 context.Context, arg1 ids.ID, arg2 Fa } // RegisterFactory indicates an expected call of RegisterFactory. -func (mr *MockManagerMockRecorder) RegisterFactory(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RegisterFactory(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterFactory", reflect.TypeOf((*MockManager)(nil).RegisterFactory), arg0, arg1, arg2) } @@ -198,7 +203,7 @@ func (m *MockManager) RemoveAliases(arg0 ids.ID) { } // RemoveAliases indicates an expected call of RemoveAliases. -func (mr *MockManagerMockRecorder) RemoveAliases(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RemoveAliases(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveAliases", reflect.TypeOf((*MockManager)(nil).RemoveAliases), arg0) } diff --git a/vms/platformvm/block/mock_block.go b/vms/platformvm/block/mock_block.go index fde27ecbdc04..7bd281192253 100644 --- a/vms/platformvm/block/mock_block.go +++ b/vms/platformvm/block/mock_block.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/block (interfaces: Block) +// +// Generated by this command: +// +// mockgen -package=block -destination=vms/platformvm/block/mock_block.go github.com/ava-labs/avalanchego/vms/platformvm/block Block +// // Package block is a generated GoMock package. package block @@ -85,7 +90,7 @@ func (m *MockBlock) InitCtx(arg0 *snow.Context) { } // InitCtx indicates an expected call of InitCtx. -func (mr *MockBlockMockRecorder) InitCtx(arg0 interface{}) *gomock.Call { +func (mr *MockBlockMockRecorder) InitCtx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockBlock)(nil).InitCtx), arg0) } @@ -127,7 +132,7 @@ func (m *MockBlock) Visit(arg0 Visitor) error { } // Visit indicates an expected call of Visit. -func (mr *MockBlockMockRecorder) Visit(arg0 interface{}) *gomock.Call { +func (mr *MockBlockMockRecorder) Visit(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Visit", reflect.TypeOf((*MockBlock)(nil).Visit), arg0) } @@ -141,7 +146,7 @@ func (m *MockBlock) initialize(arg0 []byte) error { } // initialize indicates an expected call of initialize. -func (mr *MockBlockMockRecorder) initialize(arg0 interface{}) *gomock.Call { +func (mr *MockBlockMockRecorder) initialize(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "initialize", reflect.TypeOf((*MockBlock)(nil).initialize), arg0) } diff --git a/vms/platformvm/state/mock_staker_iterator.go b/vms/platformvm/state/mock_staker_iterator.go index a04f79c628da..62ba31d8b1c6 100644 --- a/vms/platformvm/state/mock_staker_iterator.go +++ b/vms/platformvm/state/mock_staker_iterator.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: StakerIterator) +// +// Generated by this command: +// +// mockgen -package=state -destination=vms/platformvm/state/mock_staker_iterator.go github.com/ava-labs/avalanchego/vms/platformvm/state StakerIterator +// // Package state is a generated GoMock package. package state diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index 051bc729ac21..cfb9dd16944a 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Chain,Diff,State,Versions) +// +// Generated by this command: +// +// mockgen -package=state -destination=vms/platformvm/state/mock_state.go github.com/ava-labs/avalanchego/vms/platformvm/state Chain,Diff,State,Versions +// // Package state is a generated GoMock package. package state @@ -52,7 +57,7 @@ func (m *MockChain) AddChain(arg0 *txs.Tx) { } // AddChain indicates an expected call of AddChain. -func (mr *MockChainMockRecorder) AddChain(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddChain(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockChain)(nil).AddChain), arg0) } @@ -64,7 +69,7 @@ func (m *MockChain) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { } // AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockChainMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddRewardUTXO(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockChain)(nil).AddRewardUTXO), arg0, arg1) } @@ -76,7 +81,7 @@ func (m *MockChain) AddSubnet(arg0 *txs.Tx) { } // AddSubnet indicates an expected call of AddSubnet. -func (mr *MockChainMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddSubnet(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockChain)(nil).AddSubnet), arg0) } @@ -88,7 +93,7 @@ func (m *MockChain) AddSubnetTransformation(arg0 *txs.Tx) { } // AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockChainMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddSubnetTransformation(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockChain)(nil).AddSubnetTransformation), arg0) } @@ -100,7 +105,7 @@ func (m *MockChain) AddTx(arg0 *txs.Tx, arg1 status.Status) { } // AddTx indicates an expected call of AddTx. -func (mr *MockChainMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddTx(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockChain)(nil).AddTx), arg0, arg1) } @@ -112,7 +117,7 @@ func (m *MockChain) AddUTXO(arg0 *avax.UTXO) { } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockChainMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) AddUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockChain)(nil).AddUTXO), arg0) } @@ -124,7 +129,7 @@ func (m *MockChain) DeleteCurrentDelegator(arg0 *Staker) { } // DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockChainMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) DeleteCurrentDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentDelegator), arg0) } @@ -136,7 +141,7 @@ func (m *MockChain) DeleteCurrentValidator(arg0 *Staker) { } // DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockChainMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) DeleteCurrentValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentValidator), arg0) } @@ -148,7 +153,7 @@ func (m *MockChain) DeletePendingDelegator(arg0 *Staker) { } // DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockChainMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) DeletePendingDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockChain)(nil).DeletePendingDelegator), arg0) } @@ -160,7 +165,7 @@ func (m *MockChain) DeletePendingValidator(arg0 *Staker) { } // DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockChainMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) DeletePendingValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockChain)(nil).DeletePendingValidator), arg0) } @@ -172,7 +177,7 @@ func (m *MockChain) DeleteUTXO(arg0 ids.ID) { } // DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockChainMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), arg0) } @@ -187,7 +192,7 @@ func (m *MockChain) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (S } // GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), arg0, arg1) } @@ -217,7 +222,7 @@ func (m *MockChain) GetCurrentSupply(arg0 ids.ID) (uint64, error) { } // GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockChainMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetCurrentSupply(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockChain)(nil).GetCurrentSupply), arg0) } @@ -232,7 +237,7 @@ func (m *MockChain) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, } // GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockChainMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetCurrentValidator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockChain)(nil).GetCurrentValidator), arg0, arg1) } @@ -247,7 +252,7 @@ func (m *MockChain) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, er } // GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockChainMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetDelegateeReward(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockChain)(nil).GetDelegateeReward), arg0, arg1) } @@ -262,7 +267,7 @@ func (m *MockChain) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (S } // GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetPendingDelegatorIterator), arg0, arg1) } @@ -292,7 +297,7 @@ func (m *MockChain) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, } // GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), arg0, arg1) } @@ -307,7 +312,7 @@ func (m *MockChain) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { } // GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockChainMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetSubnetOwner(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockChain)(nil).GetSubnetOwner), arg0) } @@ -322,7 +327,7 @@ func (m *MockChain) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { } // GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), arg0) } @@ -352,7 +357,7 @@ func (m *MockChain) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { } // GetTx indicates an expected call of GetTx. -func (mr *MockChainMockRecorder) GetTx(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), arg0) } @@ -367,7 +372,7 @@ func (m *MockChain) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { } // GetUTXO indicates an expected call of GetUTXO. -func (mr *MockChainMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) GetUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), arg0) } @@ -379,7 +384,7 @@ func (m *MockChain) PutCurrentDelegator(arg0 *Staker) { } // PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockChainMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) PutCurrentDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockChain)(nil).PutCurrentDelegator), arg0) } @@ -391,7 +396,7 @@ func (m *MockChain) PutCurrentValidator(arg0 *Staker) { } // PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockChainMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) PutCurrentValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockChain)(nil).PutCurrentValidator), arg0) } @@ -403,7 +408,7 @@ func (m *MockChain) PutPendingDelegator(arg0 *Staker) { } // PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockChainMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) PutPendingDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockChain)(nil).PutPendingDelegator), arg0) } @@ -415,7 +420,7 @@ func (m *MockChain) PutPendingValidator(arg0 *Staker) { } // PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockChainMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), arg0) } @@ -427,7 +432,7 @@ func (m *MockChain) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { } // SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockChainMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) SetCurrentSupply(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockChain)(nil).SetCurrentSupply), arg0, arg1) } @@ -441,7 +446,7 @@ func (m *MockChain) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64 } // SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockChainMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) SetDelegateeReward(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockChain)(nil).SetDelegateeReward), arg0, arg1, arg2) } @@ -453,7 +458,7 @@ func (m *MockChain) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { } // SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockChainMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) SetSubnetOwner(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockChain)(nil).SetSubnetOwner), arg0, arg1) } @@ -465,7 +470,7 @@ func (m *MockChain) SetTimestamp(arg0 time.Time) { } // SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockChainMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { +func (mr *MockChainMockRecorder) SetTimestamp(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), arg0) } @@ -500,7 +505,7 @@ func (m *MockDiff) AddChain(arg0 *txs.Tx) { } // AddChain indicates an expected call of AddChain. -func (mr *MockDiffMockRecorder) AddChain(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddChain(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockDiff)(nil).AddChain), arg0) } @@ -512,7 +517,7 @@ func (m *MockDiff) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { } // AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockDiffMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddRewardUTXO(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockDiff)(nil).AddRewardUTXO), arg0, arg1) } @@ -524,7 +529,7 @@ func (m *MockDiff) AddSubnet(arg0 *txs.Tx) { } // AddSubnet indicates an expected call of AddSubnet. -func (mr *MockDiffMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddSubnet(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockDiff)(nil).AddSubnet), arg0) } @@ -536,7 +541,7 @@ func (m *MockDiff) AddSubnetTransformation(arg0 *txs.Tx) { } // AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockDiffMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddSubnetTransformation(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).AddSubnetTransformation), arg0) } @@ -548,7 +553,7 @@ func (m *MockDiff) AddTx(arg0 *txs.Tx, arg1 status.Status) { } // AddTx indicates an expected call of AddTx. -func (mr *MockDiffMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddTx(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), arg0, arg1) } @@ -560,7 +565,7 @@ func (m *MockDiff) AddUTXO(arg0 *avax.UTXO) { } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockDiffMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) AddUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), arg0) } @@ -574,7 +579,7 @@ func (m *MockDiff) Apply(arg0 Chain) error { } // Apply indicates an expected call of Apply. -func (mr *MockDiffMockRecorder) Apply(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) Apply(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) } @@ -586,7 +591,7 @@ func (m *MockDiff) DeleteCurrentDelegator(arg0 *Staker) { } // DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentDelegator), arg0) } @@ -598,7 +603,7 @@ func (m *MockDiff) DeleteCurrentValidator(arg0 *Staker) { } // DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockDiffMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) DeleteCurrentValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentValidator), arg0) } @@ -610,7 +615,7 @@ func (m *MockDiff) DeletePendingDelegator(arg0 *Staker) { } // DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockDiffMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) DeletePendingDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockDiff)(nil).DeletePendingDelegator), arg0) } @@ -622,7 +627,7 @@ func (m *MockDiff) DeletePendingValidator(arg0 *Staker) { } // DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockDiffMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) DeletePendingValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockDiff)(nil).DeletePendingValidator), arg0) } @@ -634,7 +639,7 @@ func (m *MockDiff) DeleteUTXO(arg0 ids.ID) { } // DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) } @@ -649,7 +654,7 @@ func (m *MockDiff) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (St } // GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentDelegatorIterator), arg0, arg1) } @@ -679,7 +684,7 @@ func (m *MockDiff) GetCurrentSupply(arg0 ids.ID) (uint64, error) { } // GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockDiffMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetCurrentSupply(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).GetCurrentSupply), arg0) } @@ -694,7 +699,7 @@ func (m *MockDiff) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, e } // GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockDiffMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetCurrentValidator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockDiff)(nil).GetCurrentValidator), arg0, arg1) } @@ -709,7 +714,7 @@ func (m *MockDiff) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, err } // GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockDiffMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetDelegateeReward(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).GetDelegateeReward), arg0, arg1) } @@ -724,7 +729,7 @@ func (m *MockDiff) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (St } // GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockDiffMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetPendingDelegatorIterator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingDelegatorIterator), arg0, arg1) } @@ -754,7 +759,7 @@ func (m *MockDiff) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, e } // GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockDiffMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetPendingValidator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockDiff)(nil).GetPendingValidator), arg0, arg1) } @@ -769,7 +774,7 @@ func (m *MockDiff) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { } // GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockDiffMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetSubnetOwner(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).GetSubnetOwner), arg0) } @@ -784,7 +789,7 @@ func (m *MockDiff) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { } // GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockDiffMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetSubnetTransformation(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).GetSubnetTransformation), arg0) } @@ -814,7 +819,7 @@ func (m *MockDiff) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { } // GetTx indicates an expected call of GetTx. -func (mr *MockDiffMockRecorder) GetTx(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockDiff)(nil).GetTx), arg0) } @@ -829,7 +834,7 @@ func (m *MockDiff) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { } // GetUTXO indicates an expected call of GetUTXO. -func (mr *MockDiffMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockDiff)(nil).GetUTXO), arg0) } @@ -841,7 +846,7 @@ func (m *MockDiff) PutCurrentDelegator(arg0 *Staker) { } // PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockDiffMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) PutCurrentDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).PutCurrentDelegator), arg0) } @@ -853,7 +858,7 @@ func (m *MockDiff) PutCurrentValidator(arg0 *Staker) { } // PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockDiffMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) PutCurrentValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockDiff)(nil).PutCurrentValidator), arg0) } @@ -865,7 +870,7 @@ func (m *MockDiff) PutPendingDelegator(arg0 *Staker) { } // PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockDiffMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) PutPendingDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockDiff)(nil).PutPendingDelegator), arg0) } @@ -877,7 +882,7 @@ func (m *MockDiff) PutPendingValidator(arg0 *Staker) { } // PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockDiffMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockDiff)(nil).PutPendingValidator), arg0) } @@ -889,7 +894,7 @@ func (m *MockDiff) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { } // SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockDiffMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) SetCurrentSupply(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).SetCurrentSupply), arg0, arg1) } @@ -903,7 +908,7 @@ func (m *MockDiff) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) } // SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockDiffMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) SetDelegateeReward(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).SetDelegateeReward), arg0, arg1, arg2) } @@ -915,7 +920,7 @@ func (m *MockDiff) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { } // SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockDiffMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) SetSubnetOwner(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).SetSubnetOwner), arg0, arg1) } @@ -927,7 +932,7 @@ func (m *MockDiff) SetTimestamp(arg0 time.Time) { } // SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockDiffMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) SetTimestamp(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockDiff)(nil).SetTimestamp), arg0) } @@ -974,7 +979,7 @@ func (m *MockState) AddChain(arg0 *txs.Tx) { } // AddChain indicates an expected call of AddChain. -func (mr *MockStateMockRecorder) AddChain(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddChain(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockState)(nil).AddChain), arg0) } @@ -986,7 +991,7 @@ func (m *MockState) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { } // AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockStateMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddRewardUTXO(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockState)(nil).AddRewardUTXO), arg0, arg1) } @@ -998,7 +1003,7 @@ func (m *MockState) AddStatelessBlock(arg0 block.Block) { } // AddStatelessBlock indicates an expected call of AddStatelessBlock. -func (mr *MockStateMockRecorder) AddStatelessBlock(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddStatelessBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddStatelessBlock", reflect.TypeOf((*MockState)(nil).AddStatelessBlock), arg0) } @@ -1010,7 +1015,7 @@ func (m *MockState) AddSubnet(arg0 *txs.Tx) { } // AddSubnet indicates an expected call of AddSubnet. -func (mr *MockStateMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddSubnet(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockState)(nil).AddSubnet), arg0) } @@ -1022,7 +1027,7 @@ func (m *MockState) AddSubnetTransformation(arg0 *txs.Tx) { } // AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockStateMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddSubnetTransformation(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockState)(nil).AddSubnetTransformation), arg0) } @@ -1034,7 +1039,7 @@ func (m *MockState) AddTx(arg0 *txs.Tx, arg1 status.Status) { } // AddTx indicates an expected call of AddTx. -func (mr *MockStateMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddTx(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockState)(nil).AddTx), arg0, arg1) } @@ -1046,7 +1051,7 @@ func (m *MockState) AddUTXO(arg0 *avax.UTXO) { } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockStateMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) AddUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockState)(nil).AddUTXO), arg0) } @@ -1060,7 +1065,7 @@ func (m *MockState) ApplyValidatorPublicKeyDiffs(arg0 context.Context, arg1 map[ } // ApplyValidatorPublicKeyDiffs indicates an expected call of ApplyValidatorPublicKeyDiffs. -func (mr *MockStateMockRecorder) ApplyValidatorPublicKeyDiffs(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) ApplyValidatorPublicKeyDiffs(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyValidatorPublicKeyDiffs", reflect.TypeOf((*MockState)(nil).ApplyValidatorPublicKeyDiffs), arg0, arg1, arg2, arg3) } @@ -1074,7 +1079,7 @@ func (m *MockState) ApplyValidatorWeightDiffs(arg0 context.Context, arg1 map[ids } // ApplyValidatorWeightDiffs indicates an expected call of ApplyValidatorWeightDiffs. -func (mr *MockStateMockRecorder) ApplyValidatorWeightDiffs(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) ApplyValidatorWeightDiffs(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyValidatorWeightDiffs", reflect.TypeOf((*MockState)(nil).ApplyValidatorWeightDiffs), arg0, arg1, arg2, arg3, arg4) } @@ -1143,7 +1148,7 @@ func (m *MockState) DeleteCurrentDelegator(arg0 *Staker) { } // DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockStateMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) DeleteCurrentDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockState)(nil).DeleteCurrentDelegator), arg0) } @@ -1155,7 +1160,7 @@ func (m *MockState) DeleteCurrentValidator(arg0 *Staker) { } // DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockStateMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) DeleteCurrentValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockState)(nil).DeleteCurrentValidator), arg0) } @@ -1167,7 +1172,7 @@ func (m *MockState) DeletePendingDelegator(arg0 *Staker) { } // DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockStateMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) DeletePendingDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockState)(nil).DeletePendingDelegator), arg0) } @@ -1179,7 +1184,7 @@ func (m *MockState) DeletePendingValidator(arg0 *Staker) { } // DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockStateMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) DeletePendingValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockState)(nil).DeletePendingValidator), arg0) } @@ -1191,7 +1196,7 @@ func (m *MockState) DeleteUTXO(arg0 ids.ID) { } // DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockStateMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockState)(nil).DeleteUTXO), arg0) } @@ -1206,7 +1211,7 @@ func (m *MockState) GetBlockIDAtHeight(arg0 uint64) (ids.ID, error) { } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *MockStateMockRecorder) GetBlockIDAtHeight(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetBlockIDAtHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockState)(nil).GetBlockIDAtHeight), arg0) } @@ -1221,7 +1226,7 @@ func (m *MockState) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { } // GetChains indicates an expected call of GetChains. -func (mr *MockStateMockRecorder) GetChains(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetChains(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockState)(nil).GetChains), arg0) } @@ -1236,7 +1241,7 @@ func (m *MockState) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (S } // GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockStateMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockState)(nil).GetCurrentDelegatorIterator), arg0, arg1) } @@ -1266,7 +1271,7 @@ func (m *MockState) GetCurrentSupply(arg0 ids.ID) (uint64, error) { } // GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockStateMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetCurrentSupply(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockState)(nil).GetCurrentSupply), arg0) } @@ -1281,7 +1286,7 @@ func (m *MockState) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, } // GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockStateMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetCurrentValidator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockState)(nil).GetCurrentValidator), arg0, arg1) } @@ -1296,7 +1301,7 @@ func (m *MockState) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, er } // GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockStateMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetDelegateeReward(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockState)(nil).GetDelegateeReward), arg0, arg1) } @@ -1325,7 +1330,7 @@ func (m *MockState) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (S } // GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockStateMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetPendingDelegatorIterator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockState)(nil).GetPendingDelegatorIterator), arg0, arg1) } @@ -1355,7 +1360,7 @@ func (m *MockState) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, } // GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockStateMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetPendingValidator(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockState)(nil).GetPendingValidator), arg0, arg1) } @@ -1370,7 +1375,7 @@ func (m *MockState) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { } // GetRewardUTXOs indicates an expected call of GetRewardUTXOs. -func (mr *MockStateMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetRewardUTXOs(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockState)(nil).GetRewardUTXOs), arg0) } @@ -1385,7 +1390,7 @@ func (m *MockState) GetStartTime(arg0 ids.NodeID, arg1 ids.ID) (time.Time, error } // GetStartTime indicates an expected call of GetStartTime. -func (mr *MockStateMockRecorder) GetStartTime(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetStartTime(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStartTime", reflect.TypeOf((*MockState)(nil).GetStartTime), arg0, arg1) } @@ -1400,7 +1405,7 @@ func (m *MockState) GetStatelessBlock(arg0 ids.ID) (block.Block, error) { } // GetStatelessBlock indicates an expected call of GetStatelessBlock. -func (mr *MockStateMockRecorder) GetStatelessBlock(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetStatelessBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessBlock", reflect.TypeOf((*MockState)(nil).GetStatelessBlock), arg0) } @@ -1415,7 +1420,7 @@ func (m *MockState) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { } // GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockStateMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetSubnetOwner(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockState)(nil).GetSubnetOwner), arg0) } @@ -1430,7 +1435,7 @@ func (m *MockState) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { } // GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockStateMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetSubnetTransformation(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockState)(nil).GetSubnetTransformation), arg0) } @@ -1475,7 +1480,7 @@ func (m *MockState) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { } // GetTx indicates an expected call of GetTx. -func (mr *MockStateMockRecorder) GetTx(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetTx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockState)(nil).GetTx), arg0) } @@ -1490,7 +1495,7 @@ func (m *MockState) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { } // GetUTXO indicates an expected call of GetUTXO. -func (mr *MockStateMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetUTXO(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockState)(nil).GetUTXO), arg0) } @@ -1506,7 +1511,7 @@ func (m *MockState) GetUptime(arg0 ids.NodeID, arg1 ids.ID) (time.Duration, time } // GetUptime indicates an expected call of GetUptime. -func (mr *MockStateMockRecorder) GetUptime(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetUptime(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUptime", reflect.TypeOf((*MockState)(nil).GetUptime), arg0, arg1) } @@ -1520,7 +1525,7 @@ func (m *MockState) PruneAndIndex(arg0 sync.Locker, arg1 logging.Logger) error { } // PruneAndIndex indicates an expected call of PruneAndIndex. -func (mr *MockStateMockRecorder) PruneAndIndex(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) PruneAndIndex(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PruneAndIndex", reflect.TypeOf((*MockState)(nil).PruneAndIndex), arg0, arg1) } @@ -1532,7 +1537,7 @@ func (m *MockState) PutCurrentDelegator(arg0 *Staker) { } // PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockStateMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) PutCurrentDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockState)(nil).PutCurrentDelegator), arg0) } @@ -1544,7 +1549,7 @@ func (m *MockState) PutCurrentValidator(arg0 *Staker) { } // PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockStateMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) PutCurrentValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockState)(nil).PutCurrentValidator), arg0) } @@ -1556,7 +1561,7 @@ func (m *MockState) PutPendingDelegator(arg0 *Staker) { } // PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockStateMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) PutPendingDelegator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockState)(nil).PutPendingDelegator), arg0) } @@ -1568,7 +1573,7 @@ func (m *MockState) PutPendingValidator(arg0 *Staker) { } // PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockStateMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockState)(nil).PutPendingValidator), arg0) } @@ -1580,7 +1585,7 @@ func (m *MockState) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { } // SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockStateMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetCurrentSupply(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockState)(nil).SetCurrentSupply), arg0, arg1) } @@ -1594,7 +1599,7 @@ func (m *MockState) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64 } // SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockStateMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetDelegateeReward(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockState)(nil).SetDelegateeReward), arg0, arg1, arg2) } @@ -1606,7 +1611,7 @@ func (m *MockState) SetHeight(arg0 uint64) { } // SetHeight indicates an expected call of SetHeight. -func (mr *MockStateMockRecorder) SetHeight(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeight", reflect.TypeOf((*MockState)(nil).SetHeight), arg0) } @@ -1618,7 +1623,7 @@ func (m *MockState) SetLastAccepted(arg0 ids.ID) { } // SetLastAccepted indicates an expected call of SetLastAccepted. -func (mr *MockStateMockRecorder) SetLastAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetLastAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastAccepted", reflect.TypeOf((*MockState)(nil).SetLastAccepted), arg0) } @@ -1630,7 +1635,7 @@ func (m *MockState) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { } // SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockStateMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetSubnetOwner(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockState)(nil).SetSubnetOwner), arg0, arg1) } @@ -1642,7 +1647,7 @@ func (m *MockState) SetTimestamp(arg0 time.Time) { } // SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockStateMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetTimestamp(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockState)(nil).SetTimestamp), arg0) } @@ -1656,7 +1661,7 @@ func (m *MockState) SetUptime(arg0 ids.NodeID, arg1 ids.ID, arg2 time.Duration, } // SetUptime indicates an expected call of SetUptime. -func (mr *MockStateMockRecorder) SetUptime(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetUptime(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUptime", reflect.TypeOf((*MockState)(nil).SetUptime), arg0, arg1, arg2, arg3) } @@ -1686,7 +1691,7 @@ func (m *MockState) UTXOIDs(arg0 []byte, arg1 ids.ID, arg2 int) ([]ids.ID, error } // UTXOIDs indicates an expected call of UTXOIDs. -func (mr *MockStateMockRecorder) UTXOIDs(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) UTXOIDs(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UTXOIDs", reflect.TypeOf((*MockState)(nil).UTXOIDs), arg0, arg1, arg2) } @@ -1724,7 +1729,7 @@ func (m *MockVersions) GetState(arg0 ids.ID) (Chain, bool) { } // GetState indicates an expected call of GetState. -func (mr *MockVersionsMockRecorder) GetState(arg0 interface{}) *gomock.Call { +func (mr *MockVersionsMockRecorder) GetState(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockVersions)(nil).GetState), arg0) } diff --git a/vms/platformvm/txs/mempool/mock_mempool.go b/vms/platformvm/txs/mempool/mock_mempool.go index d88f0592571a..c47f42e92718 100644 --- a/vms/platformvm/txs/mempool/mock_mempool.go +++ b/vms/platformvm/txs/mempool/mock_mempool.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool (interfaces: Mempool) +// +// Generated by this command: +// +// mockgen -package=mempool -destination=vms/platformvm/txs/mempool/mock_mempool.go github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool Mempool +// // Package mempool is a generated GoMock package. package mempool @@ -44,7 +49,7 @@ func (m *MockMempool) Add(arg0 *txs.Tx) error { } // Add indicates an expected call of Add. -func (mr *MockMempoolMockRecorder) Add(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Add(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockMempool)(nil).Add), arg0) } @@ -59,7 +64,7 @@ func (m *MockMempool) Get(arg0 ids.ID) (*txs.Tx, bool) { } // Get indicates an expected call of Get. -func (mr *MockMempoolMockRecorder) Get(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Get(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMempool)(nil).Get), arg0) } @@ -73,7 +78,7 @@ func (m *MockMempool) GetDropReason(arg0 ids.ID) error { } // GetDropReason indicates an expected call of GetDropReason. -func (mr *MockMempoolMockRecorder) GetDropReason(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) GetDropReason(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDropReason", reflect.TypeOf((*MockMempool)(nil).GetDropReason), arg0) } @@ -85,7 +90,7 @@ func (m *MockMempool) Iterate(arg0 func(*txs.Tx) bool) { } // Iterate indicates an expected call of Iterate. -func (mr *MockMempoolMockRecorder) Iterate(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Iterate(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterate", reflect.TypeOf((*MockMempool)(nil).Iterate), arg0) } @@ -111,7 +116,7 @@ func (m *MockMempool) MarkDropped(arg0 ids.ID, arg1 error) { } // MarkDropped indicates an expected call of MarkDropped. -func (mr *MockMempoolMockRecorder) MarkDropped(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) MarkDropped(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkDropped", reflect.TypeOf((*MockMempool)(nil).MarkDropped), arg0, arg1) } @@ -134,7 +139,7 @@ func (mr *MockMempoolMockRecorder) Peek() *gomock.Call { // Remove mocks base method. func (m *MockMempool) Remove(arg0 ...*txs.Tx) { m.ctrl.T.Helper() - varargs := []interface{}{} + varargs := []any{} for _, a := range arg0 { varargs = append(varargs, a) } @@ -142,7 +147,7 @@ func (m *MockMempool) Remove(arg0 ...*txs.Tx) { } // Remove indicates an expected call of Remove. -func (mr *MockMempoolMockRecorder) Remove(arg0 ...interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) Remove(arg0 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockMempool)(nil).Remove), arg0...) } @@ -154,7 +159,7 @@ func (m *MockMempool) RequestBuildBlock(arg0 bool) { } // RequestBuildBlock indicates an expected call of RequestBuildBlock. -func (mr *MockMempoolMockRecorder) RequestBuildBlock(arg0 interface{}) *gomock.Call { +func (mr *MockMempoolMockRecorder) RequestBuildBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestBuildBlock", reflect.TypeOf((*MockMempool)(nil).RequestBuildBlock), arg0) } diff --git a/vms/platformvm/utxo/mock_verifier.go b/vms/platformvm/utxo/mock_verifier.go index 15766981f685..0447806cb7ae 100644 --- a/vms/platformvm/utxo/mock_verifier.go +++ b/vms/platformvm/utxo/mock_verifier.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/utxo (interfaces: Verifier) +// +// Generated by this command: +// +// mockgen -package=utxo -destination=vms/platformvm/utxo/mock_verifier.go github.com/ava-labs/avalanchego/vms/platformvm/utxo Verifier +// // Package utxo is a generated GoMock package. package utxo @@ -46,7 +51,7 @@ func (m *MockVerifier) VerifySpend(arg0 txs.UnsignedTx, arg1 avax.UTXOGetter, ar } // VerifySpend indicates an expected call of VerifySpend. -func (mr *MockVerifierMockRecorder) VerifySpend(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockVerifierMockRecorder) VerifySpend(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifySpend", reflect.TypeOf((*MockVerifier)(nil).VerifySpend), arg0, arg1, arg2, arg3, arg4, arg5) } @@ -60,7 +65,7 @@ func (m *MockVerifier) VerifySpendUTXOs(arg0 txs.UnsignedTx, arg1 []*avax.UTXO, } // VerifySpendUTXOs indicates an expected call of VerifySpendUTXOs. -func (mr *MockVerifierMockRecorder) VerifySpendUTXOs(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockVerifierMockRecorder) VerifySpendUTXOs(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifySpendUTXOs", reflect.TypeOf((*MockVerifier)(nil).VerifySpendUTXOs), arg0, arg1, arg2, arg3, arg4, arg5) } diff --git a/vms/proposervm/mock_post_fork_block.go b/vms/proposervm/mock_post_fork_block.go index 23c87ea5fa00..ab449b6363bf 100644 --- a/vms/proposervm/mock_post_fork_block.go +++ b/vms/proposervm/mock_post_fork_block.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/proposervm (interfaces: PostForkBlock) +// +// Generated by this command: +// +// mockgen -package=proposervm -destination=vms/proposervm/mock_post_fork_block.go github.com/ava-labs/avalanchego/vms/proposervm PostForkBlock +// // Package proposervm is a generated GoMock package. package proposervm @@ -48,7 +53,7 @@ func (m *MockPostForkBlock) Accept(arg0 context.Context) error { } // Accept indicates an expected call of Accept. -func (mr *MockPostForkBlockMockRecorder) Accept(arg0 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) Accept(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockPostForkBlock)(nil).Accept), arg0) } @@ -118,7 +123,7 @@ func (m *MockPostForkBlock) Reject(arg0 context.Context) error { } // Reject indicates an expected call of Reject. -func (mr *MockPostForkBlockMockRecorder) Reject(arg0 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) Reject(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reject", reflect.TypeOf((*MockPostForkBlock)(nil).Reject), arg0) } @@ -160,7 +165,7 @@ func (m *MockPostForkBlock) Verify(arg0 context.Context) error { } // Verify indicates an expected call of Verify. -func (mr *MockPostForkBlockMockRecorder) Verify(arg0 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) Verify(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verify", reflect.TypeOf((*MockPostForkBlock)(nil).Verify), arg0) } @@ -174,7 +179,7 @@ func (m *MockPostForkBlock) acceptInnerBlk(arg0 context.Context) error { } // acceptInnerBlk indicates an expected call of acceptInnerBlk. -func (mr *MockPostForkBlockMockRecorder) acceptInnerBlk(arg0 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) acceptInnerBlk(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "acceptInnerBlk", reflect.TypeOf((*MockPostForkBlock)(nil).acceptInnerBlk), arg0) } @@ -203,7 +208,7 @@ func (m *MockPostForkBlock) buildChild(arg0 context.Context) (Block, error) { } // buildChild indicates an expected call of buildChild. -func (mr *MockPostForkBlockMockRecorder) buildChild(arg0 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) buildChild(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "buildChild", reflect.TypeOf((*MockPostForkBlock)(nil).buildChild), arg0) } @@ -246,7 +251,7 @@ func (m *MockPostForkBlock) pChainHeight(arg0 context.Context) (uint64, error) { } // pChainHeight indicates an expected call of pChainHeight. -func (mr *MockPostForkBlockMockRecorder) pChainHeight(arg0 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) pChainHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "pChainHeight", reflect.TypeOf((*MockPostForkBlock)(nil).pChainHeight), arg0) } @@ -258,7 +263,7 @@ func (m *MockPostForkBlock) setInnerBlk(arg0 snowman.Block) { } // setInnerBlk indicates an expected call of setInnerBlk. -func (mr *MockPostForkBlockMockRecorder) setInnerBlk(arg0 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) setInnerBlk(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "setInnerBlk", reflect.TypeOf((*MockPostForkBlock)(nil).setInnerBlk), arg0) } @@ -270,7 +275,7 @@ func (m *MockPostForkBlock) setStatus(arg0 choices.Status) { } // setStatus indicates an expected call of setStatus. -func (mr *MockPostForkBlockMockRecorder) setStatus(arg0 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) setStatus(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "setStatus", reflect.TypeOf((*MockPostForkBlock)(nil).setStatus), arg0) } @@ -284,7 +289,7 @@ func (m *MockPostForkBlock) verifyPostForkChild(arg0 context.Context, arg1 *post } // verifyPostForkChild indicates an expected call of verifyPostForkChild. -func (mr *MockPostForkBlockMockRecorder) verifyPostForkChild(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) verifyPostForkChild(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "verifyPostForkChild", reflect.TypeOf((*MockPostForkBlock)(nil).verifyPostForkChild), arg0, arg1) } @@ -298,7 +303,7 @@ func (m *MockPostForkBlock) verifyPostForkOption(arg0 context.Context, arg1 *pos } // verifyPostForkOption indicates an expected call of verifyPostForkOption. -func (mr *MockPostForkBlockMockRecorder) verifyPostForkOption(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) verifyPostForkOption(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "verifyPostForkOption", reflect.TypeOf((*MockPostForkBlock)(nil).verifyPostForkOption), arg0, arg1) } @@ -312,7 +317,7 @@ func (m *MockPostForkBlock) verifyPreForkChild(arg0 context.Context, arg1 *preFo } // verifyPreForkChild indicates an expected call of verifyPreForkChild. -func (mr *MockPostForkBlockMockRecorder) verifyPreForkChild(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPostForkBlockMockRecorder) verifyPreForkChild(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "verifyPreForkChild", reflect.TypeOf((*MockPostForkBlock)(nil).verifyPreForkChild), arg0, arg1) } diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index d5e142b93791..5384da8ccf80 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/proposervm/proposer (interfaces: Windower) +// +// Generated by this command: +// +// mockgen -package=proposer -destination=vms/proposervm/proposer/mock_windower.go github.com/ava-labs/avalanchego/vms/proposervm/proposer Windower +// // Package proposer is a generated GoMock package. package proposer @@ -46,7 +51,7 @@ func (m *MockWindower) Delay(arg0 context.Context, arg1, arg2 uint64, arg3 ids.N } // Delay indicates an expected call of Delay. -func (mr *MockWindowerMockRecorder) Delay(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockWindowerMockRecorder) Delay(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delay", reflect.TypeOf((*MockWindower)(nil).Delay), arg0, arg1, arg2, arg3, arg4) } @@ -61,7 +66,7 @@ func (m *MockWindower) ExpectedProposer(arg0 context.Context, arg1, arg2, arg3 u } // ExpectedProposer indicates an expected call of ExpectedProposer. -func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExpectedProposer", reflect.TypeOf((*MockWindower)(nil).ExpectedProposer), arg0, arg1, arg2, arg3) } @@ -76,7 +81,7 @@ func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint } // MinDelayForProposer indicates an expected call of MinDelayForProposer. -func (mr *MockWindowerMockRecorder) MinDelayForProposer(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockWindowerMockRecorder) MinDelayForProposer(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinDelayForProposer", reflect.TypeOf((*MockWindower)(nil).MinDelayForProposer), arg0, arg1, arg2, arg3, arg4) } @@ -91,7 +96,7 @@ func (m *MockWindower) Proposers(arg0 context.Context, arg1, arg2 uint64, arg3 i } // Proposers indicates an expected call of Proposers. -func (mr *MockWindowerMockRecorder) Proposers(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockWindowerMockRecorder) Proposers(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Proposers", reflect.TypeOf((*MockWindower)(nil).Proposers), arg0, arg1, arg2, arg3) } diff --git a/vms/proposervm/scheduler/mock_scheduler.go b/vms/proposervm/scheduler/mock_scheduler.go index 9018cad9b5ff..f4a8f1e62197 100644 --- a/vms/proposervm/scheduler/mock_scheduler.go +++ b/vms/proposervm/scheduler/mock_scheduler.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/proposervm/scheduler (interfaces: Scheduler) +// +// Generated by this command: +// +// mockgen -package=scheduler -destination=vms/proposervm/scheduler/mock_scheduler.go github.com/ava-labs/avalanchego/vms/proposervm/scheduler Scheduler +// // Package scheduler is a generated GoMock package. package scheduler @@ -53,7 +58,7 @@ func (m *MockScheduler) Dispatch(arg0 time.Time) { } // Dispatch indicates an expected call of Dispatch. -func (mr *MockSchedulerMockRecorder) Dispatch(arg0 interface{}) *gomock.Call { +func (mr *MockSchedulerMockRecorder) Dispatch(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Dispatch", reflect.TypeOf((*MockScheduler)(nil).Dispatch), arg0) } @@ -65,7 +70,7 @@ func (m *MockScheduler) SetBuildBlockTime(arg0 time.Time) { } // SetBuildBlockTime indicates an expected call of SetBuildBlockTime. -func (mr *MockSchedulerMockRecorder) SetBuildBlockTime(arg0 interface{}) *gomock.Call { +func (mr *MockSchedulerMockRecorder) SetBuildBlockTime(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBuildBlockTime", reflect.TypeOf((*MockScheduler)(nil).SetBuildBlockTime), arg0) } diff --git a/vms/proposervm/state/mock_state.go b/vms/proposervm/state/mock_state.go index fcd266f2d790..6384528a61dd 100644 --- a/vms/proposervm/state/mock_state.go +++ b/vms/proposervm/state/mock_state.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/proposervm/state (interfaces: State) +// +// Generated by this command: +// +// mockgen -package=state -destination=vms/proposervm/state/mock_state.go github.com/ava-labs/avalanchego/vms/proposervm/state State +// // Package state is a generated GoMock package. package state @@ -59,7 +64,7 @@ func (m *MockState) DeleteBlock(arg0 ids.ID) error { } // DeleteBlock indicates an expected call of DeleteBlock. -func (mr *MockStateMockRecorder) DeleteBlock(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) DeleteBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBlock", reflect.TypeOf((*MockState)(nil).DeleteBlock), arg0) } @@ -73,7 +78,7 @@ func (m *MockState) DeleteBlockIDAtHeight(arg0 uint64) error { } // DeleteBlockIDAtHeight indicates an expected call of DeleteBlockIDAtHeight. -func (mr *MockStateMockRecorder) DeleteBlockIDAtHeight(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) DeleteBlockIDAtHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBlockIDAtHeight", reflect.TypeOf((*MockState)(nil).DeleteBlockIDAtHeight), arg0) } @@ -117,7 +122,7 @@ func (m *MockState) GetBlock(arg0 ids.ID) (block.Block, choices.Status, error) { } // GetBlock indicates an expected call of GetBlock. -func (mr *MockStateMockRecorder) GetBlock(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockState)(nil).GetBlock), arg0) } @@ -132,7 +137,7 @@ func (m *MockState) GetBlockIDAtHeight(arg0 uint64) (ids.ID, error) { } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *MockStateMockRecorder) GetBlockIDAtHeight(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetBlockIDAtHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockState)(nil).GetBlockIDAtHeight), arg0) } @@ -206,7 +211,7 @@ func (m *MockState) PutBlock(arg0 block.Block, arg1 choices.Status) error { } // PutBlock indicates an expected call of PutBlock. -func (mr *MockStateMockRecorder) PutBlock(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) PutBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutBlock", reflect.TypeOf((*MockState)(nil).PutBlock), arg0, arg1) } @@ -220,7 +225,7 @@ func (m *MockState) SetBlockIDAtHeight(arg0 uint64, arg1 ids.ID) error { } // SetBlockIDAtHeight indicates an expected call of SetBlockIDAtHeight. -func (mr *MockStateMockRecorder) SetBlockIDAtHeight(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetBlockIDAtHeight(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBlockIDAtHeight", reflect.TypeOf((*MockState)(nil).SetBlockIDAtHeight), arg0, arg1) } @@ -234,7 +239,7 @@ func (m *MockState) SetCheckpoint(arg0 ids.ID) error { } // SetCheckpoint indicates an expected call of SetCheckpoint. -func (mr *MockStateMockRecorder) SetCheckpoint(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetCheckpoint(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCheckpoint", reflect.TypeOf((*MockState)(nil).SetCheckpoint), arg0) } @@ -248,7 +253,7 @@ func (m *MockState) SetForkHeight(arg0 uint64) error { } // SetForkHeight indicates an expected call of SetForkHeight. -func (mr *MockStateMockRecorder) SetForkHeight(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetForkHeight(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetForkHeight", reflect.TypeOf((*MockState)(nil).SetForkHeight), arg0) } @@ -262,7 +267,7 @@ func (m *MockState) SetLastAccepted(arg0 ids.ID) error { } // SetLastAccepted indicates an expected call of SetLastAccepted. -func (mr *MockStateMockRecorder) SetLastAccepted(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetLastAccepted(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastAccepted", reflect.TypeOf((*MockState)(nil).SetLastAccepted), arg0) } diff --git a/vms/registry/mock_vm_getter.go b/vms/registry/mock_vm_getter.go index 1645c521c518..30c38f1b6a74 100644 --- a/vms/registry/mock_vm_getter.go +++ b/vms/registry/mock_vm_getter.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/registry (interfaces: VMGetter) +// +// Generated by this command: +// +// mockgen -package=registry -destination=vms/registry/mock_vm_getter.go github.com/ava-labs/avalanchego/vms/registry VMGetter +// // Package registry is a generated GoMock package. package registry diff --git a/vms/registry/mock_vm_registry.go b/vms/registry/mock_vm_registry.go index 4febab38fc5e..43efd85a6015 100644 --- a/vms/registry/mock_vm_registry.go +++ b/vms/registry/mock_vm_registry.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/registry (interfaces: VMRegistry) +// +// Generated by this command: +// +// mockgen -package=registry -destination=vms/registry/mock_vm_registry.go github.com/ava-labs/avalanchego/vms/registry VMRegistry +// // Package registry is a generated GoMock package. package registry @@ -46,7 +51,7 @@ func (m *MockVMRegistry) Reload(arg0 context.Context) ([]ids.ID, map[ids.ID]erro } // Reload indicates an expected call of Reload. -func (mr *MockVMRegistryMockRecorder) Reload(arg0 interface{}) *gomock.Call { +func (mr *MockVMRegistryMockRecorder) Reload(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reload", reflect.TypeOf((*MockVMRegistry)(nil).Reload), arg0) } diff --git a/x/sync/mock_client.go b/x/sync/mock_client.go index 9bbd81127e35..98fa6d69fd9f 100644 --- a/x/sync/mock_client.go +++ b/x/sync/mock_client.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/x/sync (interfaces: Client) +// +// Generated by this command: +// +// mockgen -package=sync -destination=x/sync/mock_client.go github.com/ava-labs/avalanchego/x/sync Client +// // Package sync is a generated GoMock package. package sync @@ -46,7 +51,7 @@ func (m *MockClient) GetChangeProof(arg0 context.Context, arg1 *sync.SyncGetChan } // GetChangeProof indicates an expected call of GetChangeProof. -func (mr *MockClientMockRecorder) GetChangeProof(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockClientMockRecorder) GetChangeProof(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChangeProof", reflect.TypeOf((*MockClient)(nil).GetChangeProof), arg0, arg1, arg2) } @@ -61,7 +66,7 @@ func (m *MockClient) GetRangeProof(arg0 context.Context, arg1 *sync.SyncGetRange } // GetRangeProof indicates an expected call of GetRangeProof. -func (mr *MockClientMockRecorder) GetRangeProof(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockClientMockRecorder) GetRangeProof(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProof", reflect.TypeOf((*MockClient)(nil).GetRangeProof), arg0, arg1) } diff --git a/x/sync/mock_network_client.go b/x/sync/mock_network_client.go index 027b4f549366..428191492c4d 100644 --- a/x/sync/mock_network_client.go +++ b/x/sync/mock_network_client.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/x/sync (interfaces: NetworkClient) +// +// Generated by this command: +// +// mockgen -package=sync -destination=x/sync/mock_network_client.go github.com/ava-labs/avalanchego/x/sync NetworkClient +// // Package sync is a generated GoMock package. package sync @@ -45,7 +50,7 @@ func (m *MockNetworkClient) AppRequestFailed(arg0 context.Context, arg1 ids.Node } // AppRequestFailed indicates an expected call of AppRequestFailed. -func (mr *MockNetworkClientMockRecorder) AppRequestFailed(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockNetworkClientMockRecorder) AppRequestFailed(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*MockNetworkClient)(nil).AppRequestFailed), arg0, arg1, arg2) } @@ -59,7 +64,7 @@ func (m *MockNetworkClient) AppResponse(arg0 context.Context, arg1 ids.NodeID, a } // AppResponse indicates an expected call of AppResponse. -func (mr *MockNetworkClientMockRecorder) AppResponse(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockNetworkClientMockRecorder) AppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*MockNetworkClient)(nil).AppResponse), arg0, arg1, arg2, arg3) } @@ -73,7 +78,7 @@ func (m *MockNetworkClient) Connected(arg0 context.Context, arg1 ids.NodeID, arg } // Connected indicates an expected call of Connected. -func (mr *MockNetworkClientMockRecorder) Connected(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockNetworkClientMockRecorder) Connected(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*MockNetworkClient)(nil).Connected), arg0, arg1, arg2) } @@ -87,7 +92,7 @@ func (m *MockNetworkClient) Disconnected(arg0 context.Context, arg1 ids.NodeID) } // Disconnected indicates an expected call of Disconnected. -func (mr *MockNetworkClientMockRecorder) Disconnected(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockNetworkClientMockRecorder) Disconnected(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*MockNetworkClient)(nil).Disconnected), arg0, arg1) } @@ -102,7 +107,7 @@ func (m *MockNetworkClient) Request(arg0 context.Context, arg1 ids.NodeID, arg2 } // Request indicates an expected call of Request. -func (mr *MockNetworkClientMockRecorder) Request(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockNetworkClientMockRecorder) Request(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Request", reflect.TypeOf((*MockNetworkClient)(nil).Request), arg0, arg1, arg2) } @@ -118,7 +123,7 @@ func (m *MockNetworkClient) RequestAny(arg0 context.Context, arg1 *version.Appli } // RequestAny indicates an expected call of RequestAny. -func (mr *MockNetworkClientMockRecorder) RequestAny(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockNetworkClientMockRecorder) RequestAny(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RequestAny", reflect.TypeOf((*MockNetworkClient)(nil).RequestAny), arg0, arg1, arg2) } From d23eecca9762e38eb86cdb97a86454bb95ae507c Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:18:59 -0500 Subject: [PATCH 253/267] Add `mockgen` source mode for generics + bls imports (#2615) --- scripts/mock.gen.sh | 16 ++ scripts/mocks.mockgen.source.txt | 10 + snow/engine/common/mock_sender.go | 194 +++++++------- snow/networking/router/mock_router.go | 78 +++--- .../networking/sender/mock_external_sender.go | 26 +- snow/validators/mock_manager.go | 130 +++++----- vms/avm/block/executor/mock_manager.go | 60 ++--- vms/avm/txs/mock_unsigned_tx.go | 34 +-- vms/platformvm/block/executor/mock_manager.go | 22 +- vms/platformvm/txs/mock_staker.go | 126 ---------- ..._scheduled_staker.go => mock_staker_tx.go} | 116 ++++++++- vms/platformvm/txs/mock_unsigned_tx.go | 42 ++-- x/merkledb/mock_db.go | 236 +++++++++--------- 13 files changed, 548 insertions(+), 542 deletions(-) create mode 100644 scripts/mocks.mockgen.source.txt delete mode 100644 vms/platformvm/txs/mock_staker.go rename vms/platformvm/txs/{mock_scheduled_staker.go => mock_staker_tx.go} (57%) diff --git a/scripts/mock.gen.sh b/scripts/mock.gen.sh index a4e74488c5df..e7eb04618016 100755 --- a/scripts/mock.gen.sh +++ b/scripts/mock.gen.sh @@ -27,4 +27,20 @@ do done < "$input" +# tuples of (source import path, comma-separated interface names to exclude, output file path) +input="scripts/mocks.mockgen.source.txt" +while IFS= read -r line +do + IFS='=' read source_path exclude_interfaces output_path <<< "${line}" + package_name=$(basename $(dirname $output_path)) + echo "Generating ${output_path}..." + + mockgen \ + -source=${source_path} \ + -destination=${output_path} \ + -package=${package_name} \ + -exclude_interfaces=${exclude_interfaces} + +done < "$input" + echo "SUCCESS" diff --git a/scripts/mocks.mockgen.source.txt b/scripts/mocks.mockgen.source.txt new file mode 100644 index 000000000000..02782a7b7d9c --- /dev/null +++ b/scripts/mocks.mockgen.source.txt @@ -0,0 +1,10 @@ +snow/engine/common/sender.go=StateSummarySender,AcceptedStateSummarySender,FrontierSender,AcceptedSender,FetchSender,AppSender,QuerySender,CrossChainAppSender,NetworkAppSender,Gossiper=snow/engine/common/mock_sender.go +snow/networking/router/router.go=InternalHandler=snow/networking/router/mock_router.go +snow/networking/sender/external_sender.go==snow/networking/sender/mock_external_sender.go +snow/validators/manager.go=SetCallbackListener=snow/validators/mock_manager.go +vms/avm/block/executor/manager.go==vms/avm/block/executor/mock_manager.go +vms/avm/txs/tx.go==vms/avm/txs/mock_unsigned_tx.go +vms/platformvm/block/executor/manager.go==vms/platformvm/block/executor/mock_manager.go +vms/platformvm/txs/staker_tx.go=ValidatorTx,DelegatorTx,StakerTx,PermissionlessStaker=vms/platformvm/txs/mock_staker_tx.go +vms/platformvm/txs/unsigned_tx.go==vms/platformvm/txs/mock_unsigned_tx.go +x/merkledb/db.go=ChangeProofer,RangeProofer,Clearer,Prefetcher=x/merkledb/mock_db.go diff --git a/snow/engine/common/mock_sender.go b/snow/engine/common/mock_sender.go index 3850c198a236..6ebeeb636675 100644 --- a/snow/engine/common/mock_sender.go +++ b/snow/engine/common/mock_sender.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/snow/engine/common (interfaces: Sender) +// Source: snow/engine/common/sender.go +// +// Generated by this command: +// +// mockgen -source=snow/engine/common/sender.go -destination=snow/engine/common/mock_sender.go -package=common -exclude_interfaces=StateSummarySender,AcceptedStateSummarySender,FrontierSender,AcceptedSender,FetchSender,AppSender,QuerySender,CrossChainAppSender,NetworkAppSender,Gossiper +// // Package common is a generated GoMock package. package common @@ -41,291 +43,291 @@ func (m *MockSender) EXPECT() *MockSenderMockRecorder { } // Accept mocks base method. -func (m *MockSender) Accept(arg0 *snow.ConsensusContext, arg1 ids.ID, arg2 []byte) error { +func (m *MockSender) Accept(ctx *snow.ConsensusContext, containerID ids.ID, container []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Accept", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "Accept", ctx, containerID, container) ret0, _ := ret[0].(error) return ret0 } // Accept indicates an expected call of Accept. -func (mr *MockSenderMockRecorder) Accept(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) Accept(ctx, containerID, container any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockSender)(nil).Accept), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accept", reflect.TypeOf((*MockSender)(nil).Accept), ctx, containerID, container) } // SendAccepted mocks base method. -func (m *MockSender) SendAccepted(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []ids.ID) { +func (m *MockSender) SendAccepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs []ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendAccepted", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendAccepted", ctx, nodeID, requestID, containerIDs) } // SendAccepted indicates an expected call of SendAccepted. -func (mr *MockSenderMockRecorder) SendAccepted(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendAccepted(ctx, nodeID, requestID, containerIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAccepted", reflect.TypeOf((*MockSender)(nil).SendAccepted), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAccepted", reflect.TypeOf((*MockSender)(nil).SendAccepted), ctx, nodeID, requestID, containerIDs) } // SendAcceptedFrontier mocks base method. -func (m *MockSender) SendAcceptedFrontier(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []ids.ID) { +func (m *MockSender) SendAcceptedFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendAcceptedFrontier", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendAcceptedFrontier", ctx, nodeID, requestID, containerID) } // SendAcceptedFrontier indicates an expected call of SendAcceptedFrontier. -func (mr *MockSenderMockRecorder) SendAcceptedFrontier(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendAcceptedFrontier(ctx, nodeID, requestID, containerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAcceptedFrontier", reflect.TypeOf((*MockSender)(nil).SendAcceptedFrontier), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAcceptedFrontier", reflect.TypeOf((*MockSender)(nil).SendAcceptedFrontier), ctx, nodeID, requestID, containerID) } // SendAcceptedStateSummary mocks base method. -func (m *MockSender) SendAcceptedStateSummary(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []ids.ID) { +func (m *MockSender) SendAcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs []ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendAcceptedStateSummary", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendAcceptedStateSummary", ctx, nodeID, requestID, summaryIDs) } // SendAcceptedStateSummary indicates an expected call of SendAcceptedStateSummary. -func (mr *MockSenderMockRecorder) SendAcceptedStateSummary(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendAcceptedStateSummary(ctx, nodeID, requestID, summaryIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAcceptedStateSummary", reflect.TypeOf((*MockSender)(nil).SendAcceptedStateSummary), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAcceptedStateSummary", reflect.TypeOf((*MockSender)(nil).SendAcceptedStateSummary), ctx, nodeID, requestID, summaryIDs) } // SendAncestors mocks base method. -func (m *MockSender) SendAncestors(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 [][]byte) { +func (m *MockSender) SendAncestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, containers [][]byte) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendAncestors", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendAncestors", ctx, nodeID, requestID, containers) } // SendAncestors indicates an expected call of SendAncestors. -func (mr *MockSenderMockRecorder) SendAncestors(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendAncestors(ctx, nodeID, requestID, containers any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAncestors", reflect.TypeOf((*MockSender)(nil).SendAncestors), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAncestors", reflect.TypeOf((*MockSender)(nil).SendAncestors), ctx, nodeID, requestID, containers) } // SendAppGossip mocks base method. -func (m *MockSender) SendAppGossip(arg0 context.Context, arg1 []byte) error { +func (m *MockSender) SendAppGossip(ctx context.Context, appGossipBytes []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendAppGossip", arg0, arg1) + ret := m.ctrl.Call(m, "SendAppGossip", ctx, appGossipBytes) ret0, _ := ret[0].(error) return ret0 } // SendAppGossip indicates an expected call of SendAppGossip. -func (mr *MockSenderMockRecorder) SendAppGossip(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendAppGossip(ctx, appGossipBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAppGossip", reflect.TypeOf((*MockSender)(nil).SendAppGossip), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAppGossip", reflect.TypeOf((*MockSender)(nil).SendAppGossip), ctx, appGossipBytes) } // SendAppGossipSpecific mocks base method. -func (m *MockSender) SendAppGossipSpecific(arg0 context.Context, arg1 set.Set[ids.NodeID], arg2 []byte) error { +func (m *MockSender) SendAppGossipSpecific(ctx context.Context, nodeIDs set.Set[ids.NodeID], appGossipBytes []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendAppGossipSpecific", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "SendAppGossipSpecific", ctx, nodeIDs, appGossipBytes) ret0, _ := ret[0].(error) return ret0 } // SendAppGossipSpecific indicates an expected call of SendAppGossipSpecific. -func (mr *MockSenderMockRecorder) SendAppGossipSpecific(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendAppGossipSpecific(ctx, nodeIDs, appGossipBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAppGossipSpecific", reflect.TypeOf((*MockSender)(nil).SendAppGossipSpecific), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAppGossipSpecific", reflect.TypeOf((*MockSender)(nil).SendAppGossipSpecific), ctx, nodeIDs, appGossipBytes) } // SendAppRequest mocks base method. -func (m *MockSender) SendAppRequest(arg0 context.Context, arg1 set.Set[ids.NodeID], arg2 uint32, arg3 []byte) error { +func (m *MockSender) SendAppRequest(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, appRequestBytes []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendAppRequest", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "SendAppRequest", ctx, nodeIDs, requestID, appRequestBytes) ret0, _ := ret[0].(error) return ret0 } // SendAppRequest indicates an expected call of SendAppRequest. -func (mr *MockSenderMockRecorder) SendAppRequest(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendAppRequest(ctx, nodeIDs, requestID, appRequestBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAppRequest", reflect.TypeOf((*MockSender)(nil).SendAppRequest), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAppRequest", reflect.TypeOf((*MockSender)(nil).SendAppRequest), ctx, nodeIDs, requestID, appRequestBytes) } // SendAppResponse mocks base method. -func (m *MockSender) SendAppResponse(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []byte) error { +func (m *MockSender) SendAppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, appResponseBytes []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendAppResponse", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "SendAppResponse", ctx, nodeID, requestID, appResponseBytes) ret0, _ := ret[0].(error) return ret0 } // SendAppResponse indicates an expected call of SendAppResponse. -func (mr *MockSenderMockRecorder) SendAppResponse(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendAppResponse(ctx, nodeID, requestID, appResponseBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAppResponse", reflect.TypeOf((*MockSender)(nil).SendAppResponse), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAppResponse", reflect.TypeOf((*MockSender)(nil).SendAppResponse), ctx, nodeID, requestID, appResponseBytes) } // SendChits mocks base method. -func (m *MockSender) SendChits(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3, arg4 ids.ID) { +func (m *MockSender) SendChits(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID, preferredIDAtHeight, acceptedID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendChits", arg0, arg1, arg2, arg3, arg4) + m.ctrl.Call(m, "SendChits", ctx, nodeID, requestID, preferredID, preferredIDAtHeight, acceptedID) } // SendChits indicates an expected call of SendChits. -func (mr *MockSenderMockRecorder) SendChits(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendChits(ctx, nodeID, requestID, preferredID, preferredIDAtHeight, acceptedID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendChits", reflect.TypeOf((*MockSender)(nil).SendChits), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendChits", reflect.TypeOf((*MockSender)(nil).SendChits), ctx, nodeID, requestID, preferredID, preferredIDAtHeight, acceptedID) } // SendCrossChainAppRequest mocks base method. -func (m *MockSender) SendCrossChainAppRequest(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 []byte) error { +func (m *MockSender) SendCrossChainAppRequest(ctx context.Context, chainID ids.ID, requestID uint32, appRequestBytes []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendCrossChainAppRequest", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "SendCrossChainAppRequest", ctx, chainID, requestID, appRequestBytes) ret0, _ := ret[0].(error) return ret0 } // SendCrossChainAppRequest indicates an expected call of SendCrossChainAppRequest. -func (mr *MockSenderMockRecorder) SendCrossChainAppRequest(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendCrossChainAppRequest(ctx, chainID, requestID, appRequestBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCrossChainAppRequest", reflect.TypeOf((*MockSender)(nil).SendCrossChainAppRequest), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCrossChainAppRequest", reflect.TypeOf((*MockSender)(nil).SendCrossChainAppRequest), ctx, chainID, requestID, appRequestBytes) } // SendCrossChainAppResponse mocks base method. -func (m *MockSender) SendCrossChainAppResponse(arg0 context.Context, arg1 ids.ID, arg2 uint32, arg3 []byte) error { +func (m *MockSender) SendCrossChainAppResponse(ctx context.Context, chainID ids.ID, requestID uint32, appResponseBytes []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SendCrossChainAppResponse", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "SendCrossChainAppResponse", ctx, chainID, requestID, appResponseBytes) ret0, _ := ret[0].(error) return ret0 } // SendCrossChainAppResponse indicates an expected call of SendCrossChainAppResponse. -func (mr *MockSenderMockRecorder) SendCrossChainAppResponse(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendCrossChainAppResponse(ctx, chainID, requestID, appResponseBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCrossChainAppResponse", reflect.TypeOf((*MockSender)(nil).SendCrossChainAppResponse), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCrossChainAppResponse", reflect.TypeOf((*MockSender)(nil).SendCrossChainAppResponse), ctx, chainID, requestID, appResponseBytes) } // SendGet mocks base method. -func (m *MockSender) SendGet(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 ids.ID) { +func (m *MockSender) SendGet(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendGet", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendGet", ctx, nodeID, requestID, containerID) } // SendGet indicates an expected call of SendGet. -func (mr *MockSenderMockRecorder) SendGet(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendGet(ctx, nodeID, requestID, containerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGet", reflect.TypeOf((*MockSender)(nil).SendGet), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGet", reflect.TypeOf((*MockSender)(nil).SendGet), ctx, nodeID, requestID, containerID) } // SendGetAccepted mocks base method. -func (m *MockSender) SendGetAccepted(arg0 context.Context, arg1 set.Set[ids.NodeID], arg2 uint32, arg3 []ids.ID) { +func (m *MockSender) SendGetAccepted(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, containerIDs []ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendGetAccepted", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendGetAccepted", ctx, nodeIDs, requestID, containerIDs) } // SendGetAccepted indicates an expected call of SendGetAccepted. -func (mr *MockSenderMockRecorder) SendGetAccepted(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendGetAccepted(ctx, nodeIDs, requestID, containerIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetAccepted", reflect.TypeOf((*MockSender)(nil).SendGetAccepted), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetAccepted", reflect.TypeOf((*MockSender)(nil).SendGetAccepted), ctx, nodeIDs, requestID, containerIDs) } // SendGetAcceptedFrontier mocks base method. -func (m *MockSender) SendGetAcceptedFrontier(arg0 context.Context, arg1 set.Set[ids.NodeID], arg2 uint32) { +func (m *MockSender) SendGetAcceptedFrontier(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendGetAcceptedFrontier", arg0, arg1, arg2) + m.ctrl.Call(m, "SendGetAcceptedFrontier", ctx, nodeIDs, requestID) } // SendGetAcceptedFrontier indicates an expected call of SendGetAcceptedFrontier. -func (mr *MockSenderMockRecorder) SendGetAcceptedFrontier(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendGetAcceptedFrontier(ctx, nodeIDs, requestID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetAcceptedFrontier", reflect.TypeOf((*MockSender)(nil).SendGetAcceptedFrontier), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetAcceptedFrontier", reflect.TypeOf((*MockSender)(nil).SendGetAcceptedFrontier), ctx, nodeIDs, requestID) } // SendGetAcceptedStateSummary mocks base method. -func (m *MockSender) SendGetAcceptedStateSummary(arg0 context.Context, arg1 set.Set[ids.NodeID], arg2 uint32, arg3 []uint64) { +func (m *MockSender) SendGetAcceptedStateSummary(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, heights []uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendGetAcceptedStateSummary", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendGetAcceptedStateSummary", ctx, nodeIDs, requestID, heights) } // SendGetAcceptedStateSummary indicates an expected call of SendGetAcceptedStateSummary. -func (mr *MockSenderMockRecorder) SendGetAcceptedStateSummary(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendGetAcceptedStateSummary(ctx, nodeIDs, requestID, heights any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetAcceptedStateSummary", reflect.TypeOf((*MockSender)(nil).SendGetAcceptedStateSummary), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetAcceptedStateSummary", reflect.TypeOf((*MockSender)(nil).SendGetAcceptedStateSummary), ctx, nodeIDs, requestID, heights) } // SendGetAncestors mocks base method. -func (m *MockSender) SendGetAncestors(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 ids.ID) { +func (m *MockSender) SendGetAncestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendGetAncestors", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendGetAncestors", ctx, nodeID, requestID, containerID) } // SendGetAncestors indicates an expected call of SendGetAncestors. -func (mr *MockSenderMockRecorder) SendGetAncestors(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendGetAncestors(ctx, nodeID, requestID, containerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetAncestors", reflect.TypeOf((*MockSender)(nil).SendGetAncestors), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetAncestors", reflect.TypeOf((*MockSender)(nil).SendGetAncestors), ctx, nodeID, requestID, containerID) } // SendGetStateSummaryFrontier mocks base method. -func (m *MockSender) SendGetStateSummaryFrontier(arg0 context.Context, arg1 set.Set[ids.NodeID], arg2 uint32) { +func (m *MockSender) SendGetStateSummaryFrontier(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendGetStateSummaryFrontier", arg0, arg1, arg2) + m.ctrl.Call(m, "SendGetStateSummaryFrontier", ctx, nodeIDs, requestID) } // SendGetStateSummaryFrontier indicates an expected call of SendGetStateSummaryFrontier. -func (mr *MockSenderMockRecorder) SendGetStateSummaryFrontier(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendGetStateSummaryFrontier(ctx, nodeIDs, requestID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetStateSummaryFrontier", reflect.TypeOf((*MockSender)(nil).SendGetStateSummaryFrontier), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGetStateSummaryFrontier", reflect.TypeOf((*MockSender)(nil).SendGetStateSummaryFrontier), ctx, nodeIDs, requestID) } // SendGossip mocks base method. -func (m *MockSender) SendGossip(arg0 context.Context, arg1 []byte) { +func (m *MockSender) SendGossip(ctx context.Context, container []byte) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendGossip", arg0, arg1) + m.ctrl.Call(m, "SendGossip", ctx, container) } // SendGossip indicates an expected call of SendGossip. -func (mr *MockSenderMockRecorder) SendGossip(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendGossip(ctx, container any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGossip", reflect.TypeOf((*MockSender)(nil).SendGossip), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendGossip", reflect.TypeOf((*MockSender)(nil).SendGossip), ctx, container) } // SendPullQuery mocks base method. -func (m *MockSender) SendPullQuery(arg0 context.Context, arg1 set.Set[ids.NodeID], arg2 uint32, arg3 ids.ID) { +func (m *MockSender) SendPullQuery(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, containerID ids.ID, requestedHeight uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendPullQuery", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendPullQuery", ctx, nodeIDs, requestID, containerID, requestedHeight) } // SendPullQuery indicates an expected call of SendPullQuery. -func (mr *MockSenderMockRecorder) SendPullQuery(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendPullQuery(ctx, nodeIDs, requestID, containerID, requestedHeight any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPullQuery", reflect.TypeOf((*MockSender)(nil).SendPullQuery), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPullQuery", reflect.TypeOf((*MockSender)(nil).SendPullQuery), ctx, nodeIDs, requestID, containerID, requestedHeight) } // SendPushQuery mocks base method. -func (m *MockSender) SendPushQuery(arg0 context.Context, arg1 set.Set[ids.NodeID], arg2 uint32, arg3 []byte) { +func (m *MockSender) SendPushQuery(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, container []byte, requestedHeight uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendPushQuery", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendPushQuery", ctx, nodeIDs, requestID, container, requestedHeight) } // SendPushQuery indicates an expected call of SendPushQuery. -func (mr *MockSenderMockRecorder) SendPushQuery(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendPushQuery(ctx, nodeIDs, requestID, container, requestedHeight any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPushQuery", reflect.TypeOf((*MockSender)(nil).SendPushQuery), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPushQuery", reflect.TypeOf((*MockSender)(nil).SendPushQuery), ctx, nodeIDs, requestID, container, requestedHeight) } // SendPut mocks base method. -func (m *MockSender) SendPut(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []byte) { +func (m *MockSender) SendPut(ctx context.Context, nodeID ids.NodeID, requestID uint32, container []byte) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendPut", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendPut", ctx, nodeID, requestID, container) } // SendPut indicates an expected call of SendPut. -func (mr *MockSenderMockRecorder) SendPut(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendPut(ctx, nodeID, requestID, container any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPut", reflect.TypeOf((*MockSender)(nil).SendPut), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPut", reflect.TypeOf((*MockSender)(nil).SendPut), ctx, nodeID, requestID, container) } // SendStateSummaryFrontier mocks base method. -func (m *MockSender) SendStateSummaryFrontier(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []byte) { +func (m *MockSender) SendStateSummaryFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, summary []byte) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendStateSummaryFrontier", arg0, arg1, arg2, arg3) + m.ctrl.Call(m, "SendStateSummaryFrontier", ctx, nodeID, requestID, summary) } // SendStateSummaryFrontier indicates an expected call of SendStateSummaryFrontier. -func (mr *MockSenderMockRecorder) SendStateSummaryFrontier(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockSenderMockRecorder) SendStateSummaryFrontier(ctx, nodeID, requestID, summary any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendStateSummaryFrontier", reflect.TypeOf((*MockSender)(nil).SendStateSummaryFrontier), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendStateSummaryFrontier", reflect.TypeOf((*MockSender)(nil).SendStateSummaryFrontier), ctx, nodeID, requestID, summary) } diff --git a/snow/networking/router/mock_router.go b/snow/networking/router/mock_router.go index e644edd2d6b2..c9146a777138 100644 --- a/snow/networking/router/mock_router.go +++ b/snow/networking/router/mock_router.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/snow/networking/router (interfaces: Router) +// Source: snow/networking/router/router.go +// +// Generated by this command: +// +// mockgen -source=snow/networking/router/router.go -destination=snow/networking/router/mock_router.go -package=router -exclude_interfaces=InternalHandler +// // Package router is a generated GoMock package. package router @@ -20,8 +22,8 @@ import ( logging "github.com/ava-labs/avalanchego/utils/logging" set "github.com/ava-labs/avalanchego/utils/set" version "github.com/ava-labs/avalanchego/version" - gomock "go.uber.org/mock/gomock" prometheus "github.com/prometheus/client_golang/prometheus" + gomock "go.uber.org/mock/gomock" ) // MockRouter is a mock of Router interface. @@ -48,51 +50,51 @@ func (m *MockRouter) EXPECT() *MockRouterMockRecorder { } // AddChain mocks base method. -func (m *MockRouter) AddChain(arg0 context.Context, arg1 handler.Handler) { +func (m *MockRouter) AddChain(ctx context.Context, chain handler.Handler) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0, arg1) + m.ctrl.Call(m, "AddChain", ctx, chain) } // AddChain indicates an expected call of AddChain. -func (mr *MockRouterMockRecorder) AddChain(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) AddChain(ctx, chain any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockRouter)(nil).AddChain), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockRouter)(nil).AddChain), ctx, chain) } // Benched mocks base method. -func (m *MockRouter) Benched(arg0 ids.ID, arg1 ids.NodeID) { +func (m *MockRouter) Benched(chainID ids.ID, validatorID ids.NodeID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Benched", arg0, arg1) + m.ctrl.Call(m, "Benched", chainID, validatorID) } // Benched indicates an expected call of Benched. -func (mr *MockRouterMockRecorder) Benched(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) Benched(chainID, validatorID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Benched", reflect.TypeOf((*MockRouter)(nil).Benched), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Benched", reflect.TypeOf((*MockRouter)(nil).Benched), chainID, validatorID) } // Connected mocks base method. -func (m *MockRouter) Connected(arg0 ids.NodeID, arg1 *version.Application, arg2 ids.ID) { +func (m *MockRouter) Connected(nodeID ids.NodeID, nodeVersion *version.Application, subnetID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Connected", arg0, arg1, arg2) + m.ctrl.Call(m, "Connected", nodeID, nodeVersion, subnetID) } // Connected indicates an expected call of Connected. -func (mr *MockRouterMockRecorder) Connected(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) Connected(nodeID, nodeVersion, subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*MockRouter)(nil).Connected), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*MockRouter)(nil).Connected), nodeID, nodeVersion, subnetID) } // Disconnected mocks base method. -func (m *MockRouter) Disconnected(arg0 ids.NodeID) { +func (m *MockRouter) Disconnected(nodeID ids.NodeID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Disconnected", arg0) + m.ctrl.Call(m, "Disconnected", nodeID) } // Disconnected indicates an expected call of Disconnected. -func (mr *MockRouterMockRecorder) Disconnected(arg0 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) Disconnected(nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*MockRouter)(nil).Disconnected), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*MockRouter)(nil).Disconnected), nodeID) } // HandleInbound mocks base method. @@ -102,50 +104,50 @@ func (m *MockRouter) HandleInbound(arg0 context.Context, arg1 message.InboundMes } // HandleInbound indicates an expected call of HandleInbound. -func (mr *MockRouterMockRecorder) HandleInbound(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) HandleInbound(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleInbound", reflect.TypeOf((*MockRouter)(nil).HandleInbound), arg0, arg1) } // HealthCheck mocks base method. -func (m *MockRouter) HealthCheck(arg0 context.Context) (interface{}, error) { +func (m *MockRouter) HealthCheck(arg0 context.Context) (any, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HealthCheck", arg0) - ret0, _ := ret[0].(interface{}) + ret0, _ := ret[0].(any) ret1, _ := ret[1].(error) return ret0, ret1 } // HealthCheck indicates an expected call of HealthCheck. -func (mr *MockRouterMockRecorder) HealthCheck(arg0 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) HealthCheck(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockRouter)(nil).HealthCheck), arg0) } // Initialize mocks base method. -func (m *MockRouter) Initialize(arg0 ids.NodeID, arg1 logging.Logger, arg2 timeout.Manager, arg3 time.Duration, arg4 set.Set[ids.ID], arg5 bool, arg6 set.Set[ids.ID], arg7 func(int), arg8 HealthConfig, arg9 string, arg10 prometheus.Registerer) error { +func (m *MockRouter) Initialize(nodeID ids.NodeID, log logging.Logger, timeouts timeout.Manager, shutdownTimeout time.Duration, criticalChains set.Set[ids.ID], sybilProtectionEnabled bool, trackedSubnets set.Set[ids.ID], onFatal func(int), healthConfig HealthConfig, metricsNamespace string, metricsRegisterer prometheus.Registerer) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Initialize", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) + ret := m.ctrl.Call(m, "Initialize", nodeID, log, timeouts, shutdownTimeout, criticalChains, sybilProtectionEnabled, trackedSubnets, onFatal, healthConfig, metricsNamespace, metricsRegisterer) ret0, _ := ret[0].(error) return ret0 } // Initialize indicates an expected call of Initialize. -func (mr *MockRouterMockRecorder) Initialize(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) Initialize(nodeID, log, timeouts, shutdownTimeout, criticalChains, sybilProtectionEnabled, trackedSubnets, onFatal, healthConfig, metricsNamespace, metricsRegisterer any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*MockRouter)(nil).Initialize), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*MockRouter)(nil).Initialize), nodeID, log, timeouts, shutdownTimeout, criticalChains, sybilProtectionEnabled, trackedSubnets, onFatal, healthConfig, metricsNamespace, metricsRegisterer) } // RegisterRequest mocks base method. -func (m *MockRouter) RegisterRequest(arg0 context.Context, arg1 ids.NodeID, arg2, arg3 ids.ID, arg4 uint32, arg5 message.Op, arg6 message.InboundMessage, arg7 p2p.EngineType) { +func (m *MockRouter) RegisterRequest(ctx context.Context, nodeID ids.NodeID, sourceChainID, destinationChainID ids.ID, requestID uint32, op message.Op, failedMsg message.InboundMessage, engineType p2p.EngineType) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RegisterRequest", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + m.ctrl.Call(m, "RegisterRequest", ctx, nodeID, sourceChainID, destinationChainID, requestID, op, failedMsg, engineType) } // RegisterRequest indicates an expected call of RegisterRequest. -func (mr *MockRouterMockRecorder) RegisterRequest(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) RegisterRequest(ctx, nodeID, sourceChainID, destinationChainID, requestID, op, failedMsg, engineType any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterRequest", reflect.TypeOf((*MockRouter)(nil).RegisterRequest), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterRequest", reflect.TypeOf((*MockRouter)(nil).RegisterRequest), ctx, nodeID, sourceChainID, destinationChainID, requestID, op, failedMsg, engineType) } // Shutdown mocks base method. @@ -155,19 +157,19 @@ func (m *MockRouter) Shutdown(arg0 context.Context) { } // Shutdown indicates an expected call of Shutdown. -func (mr *MockRouterMockRecorder) Shutdown(arg0 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) Shutdown(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*MockRouter)(nil).Shutdown), arg0) } // Unbenched mocks base method. -func (m *MockRouter) Unbenched(arg0 ids.ID, arg1 ids.NodeID) { +func (m *MockRouter) Unbenched(chainID ids.ID, validatorID ids.NodeID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Unbenched", arg0, arg1) + m.ctrl.Call(m, "Unbenched", chainID, validatorID) } // Unbenched indicates an expected call of Unbenched. -func (mr *MockRouterMockRecorder) Unbenched(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRouterMockRecorder) Unbenched(chainID, validatorID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unbenched", reflect.TypeOf((*MockRouter)(nil).Unbenched), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unbenched", reflect.TypeOf((*MockRouter)(nil).Unbenched), chainID, validatorID) } diff --git a/snow/networking/sender/mock_external_sender.go b/snow/networking/sender/mock_external_sender.go index d3d4717b2959..9dc0a50d1af9 100644 --- a/snow/networking/sender/mock_external_sender.go +++ b/snow/networking/sender/mock_external_sender.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/snow/networking/sender (interfaces: ExternalSender) +// Source: snow/networking/sender/external_sender.go +// +// Generated by this command: +// +// mockgen -source=snow/networking/sender/external_sender.go -destination=snow/networking/sender/mock_external_sender.go -package=sender -exclude_interfaces= +// // Package sender is a generated GoMock package. package sender @@ -41,29 +43,29 @@ func (m *MockExternalSender) EXPECT() *MockExternalSenderMockRecorder { } // Gossip mocks base method. -func (m *MockExternalSender) Gossip(arg0 message.OutboundMessage, arg1 ids.ID, arg2, arg3, arg4 int, arg5 subnets.Allower) set.Set[ids.NodeID] { +func (m *MockExternalSender) Gossip(msg message.OutboundMessage, subnetID ids.ID, numValidatorsToSend, numNonValidatorsToSend, numPeersToSend int, allower subnets.Allower) set.Set[ids.NodeID] { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Gossip", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "Gossip", msg, subnetID, numValidatorsToSend, numNonValidatorsToSend, numPeersToSend, allower) ret0, _ := ret[0].(set.Set[ids.NodeID]) return ret0 } // Gossip indicates an expected call of Gossip. -func (mr *MockExternalSenderMockRecorder) Gossip(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockExternalSenderMockRecorder) Gossip(msg, subnetID, numValidatorsToSend, numNonValidatorsToSend, numPeersToSend, allower any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Gossip", reflect.TypeOf((*MockExternalSender)(nil).Gossip), arg0, arg1, arg2, arg3, arg4, arg5) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Gossip", reflect.TypeOf((*MockExternalSender)(nil).Gossip), msg, subnetID, numValidatorsToSend, numNonValidatorsToSend, numPeersToSend, allower) } // Send mocks base method. -func (m *MockExternalSender) Send(arg0 message.OutboundMessage, arg1 set.Set[ids.NodeID], arg2 ids.ID, arg3 subnets.Allower) set.Set[ids.NodeID] { +func (m *MockExternalSender) Send(msg message.OutboundMessage, nodeIDs set.Set[ids.NodeID], subnetID ids.ID, allower subnets.Allower) set.Set[ids.NodeID] { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Send", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "Send", msg, nodeIDs, subnetID, allower) ret0, _ := ret[0].(set.Set[ids.NodeID]) return ret0 } // Send indicates an expected call of Send. -func (mr *MockExternalSenderMockRecorder) Send(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockExternalSenderMockRecorder) Send(msg, nodeIDs, subnetID, allower any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockExternalSender)(nil).Send), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockExternalSender)(nil).Send), msg, nodeIDs, subnetID, allower) } diff --git a/snow/validators/mock_manager.go b/snow/validators/mock_manager.go index 2b99245710fb..b622ba11223a 100644 --- a/snow/validators/mock_manager.go +++ b/snow/validators/mock_manager.go @@ -1,9 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Do not include this in mocks.mockgen.txt as bls package won't be available. // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/snow/validators (interfaces: Manager) +// Source: snow/validators/manager.go +// +// Generated by this command: +// +// mockgen -source=snow/validators/manager.go -destination=snow/validators/mock_manager.go -package=validators -exclude_interfaces=SetCallbackListener +// // Package validators is a generated GoMock package. package validators @@ -41,158 +42,143 @@ func (m *MockManager) EXPECT() *MockManagerMockRecorder { } // AddStaker mocks base method. -func (m *MockManager) AddStaker(arg0 ids.ID, arg1 ids.NodeID, arg2 *bls.PublicKey, arg3 ids.ID, arg4 uint64) error { +func (m *MockManager) AddStaker(subnetID ids.ID, nodeID ids.NodeID, pk *bls.PublicKey, txID ids.ID, weight uint64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddStaker", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "AddStaker", subnetID, nodeID, pk, txID, weight) ret0, _ := ret[0].(error) return ret0 } // AddStaker indicates an expected call of AddStaker. -func (mr *MockManagerMockRecorder) AddStaker(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) AddStaker(subnetID, nodeID, pk, txID, weight any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddStaker", reflect.TypeOf((*MockManager)(nil).AddStaker), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddStaker", reflect.TypeOf((*MockManager)(nil).AddStaker), subnetID, nodeID, pk, txID, weight) } // AddWeight mocks base method. -func (m *MockManager) AddWeight(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { +func (m *MockManager) AddWeight(subnetID ids.ID, nodeID ids.NodeID, weight uint64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddWeight", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "AddWeight", subnetID, nodeID, weight) ret0, _ := ret[0].(error) return ret0 } // AddWeight indicates an expected call of AddWeight. -func (mr *MockManagerMockRecorder) AddWeight(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) AddWeight(subnetID, nodeID, weight any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWeight", reflect.TypeOf((*MockManager)(nil).AddWeight), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWeight", reflect.TypeOf((*MockManager)(nil).AddWeight), subnetID, nodeID, weight) } -// Contains mocks base method. -func (m *MockManager) Contains(arg0 ids.ID, arg1 ids.NodeID) bool { +// Count mocks base method. +func (m *MockManager) Count(subnetID ids.ID) int { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Contains", arg0, arg1) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "Count", subnetID) + ret0, _ := ret[0].(int) return ret0 } -// Contains indicates an expected call of Contains. -func (mr *MockManagerMockRecorder) Contains(arg0, arg1 interface{}) *gomock.Call { +// Count indicates an expected call of Count. +func (mr *MockManagerMockRecorder) Count(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Contains", reflect.TypeOf((*MockManager)(nil).Contains), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Count", reflect.TypeOf((*MockManager)(nil).Count), subnetID) } // GetMap mocks base method. -func (m *MockManager) GetMap(arg0 ids.ID) map[ids.NodeID]*GetValidatorOutput { +func (m *MockManager) GetMap(subnetID ids.ID) map[ids.NodeID]*GetValidatorOutput { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMap", arg0) + ret := m.ctrl.Call(m, "GetMap", subnetID) ret0, _ := ret[0].(map[ids.NodeID]*GetValidatorOutput) return ret0 } // GetMap indicates an expected call of GetMap. -func (mr *MockManagerMockRecorder) GetMap(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetMap(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMap", reflect.TypeOf((*MockManager)(nil).GetMap), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMap", reflect.TypeOf((*MockManager)(nil).GetMap), subnetID) } // GetValidator mocks base method. -func (m *MockManager) GetValidator(arg0 ids.ID, arg1 ids.NodeID) (*Validator, bool) { +func (m *MockManager) GetValidator(subnetID ids.ID, nodeID ids.NodeID) (*Validator, bool) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValidator", arg0, arg1) + ret := m.ctrl.Call(m, "GetValidator", subnetID, nodeID) ret0, _ := ret[0].(*Validator) ret1, _ := ret[1].(bool) return ret0, ret1 } // GetValidator indicates an expected call of GetValidator. -func (mr *MockManagerMockRecorder) GetValidator(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidator", reflect.TypeOf((*MockManager)(nil).GetValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidator", reflect.TypeOf((*MockManager)(nil).GetValidator), subnetID, nodeID) } // GetValidatorIDs mocks base method. -func (m *MockManager) GetValidatorIDs(arg0 ids.ID) ([]ids.NodeID, error) { +func (m *MockManager) GetValidatorIDs(subnetID ids.ID) []ids.NodeID { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValidatorIDs", arg0) + ret := m.ctrl.Call(m, "GetValidatorIDs", subnetID) ret0, _ := ret[0].([]ids.NodeID) - ret1, _ := ret[1].(error) - return ret0, ret1 + return ret0 } // GetValidatorIDs indicates an expected call of GetValidatorIDs. -func (mr *MockManagerMockRecorder) GetValidatorIDs(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetValidatorIDs(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorIDs", reflect.TypeOf((*MockManager)(nil).GetValidatorIDs), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorIDs", reflect.TypeOf((*MockManager)(nil).GetValidatorIDs), subnetID) } // GetWeight mocks base method. -func (m *MockManager) GetWeight(arg0 ids.ID, arg1 ids.NodeID) uint64 { +func (m *MockManager) GetWeight(subnetID ids.ID, nodeID ids.NodeID) uint64 { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetWeight", arg0, arg1) + ret := m.ctrl.Call(m, "GetWeight", subnetID, nodeID) ret0, _ := ret[0].(uint64) return ret0 } // GetWeight indicates an expected call of GetWeight. -func (mr *MockManagerMockRecorder) GetWeight(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWeight", reflect.TypeOf((*MockManager)(nil).GetWeight), arg0, arg1) -} - -// Len mocks base method. -func (m *MockManager) Len(arg0 ids.ID) int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Len", arg0) - ret0, _ := ret[0].(int) - return ret0 -} - -// Len indicates an expected call of Len. -func (mr *MockManagerMockRecorder) Len(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetWeight(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Len", reflect.TypeOf((*MockManager)(nil).Len), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWeight", reflect.TypeOf((*MockManager)(nil).GetWeight), subnetID, nodeID) } // RegisterCallbackListener mocks base method. -func (m *MockManager) RegisterCallbackListener(arg0 ids.ID, arg1 SetCallbackListener) { +func (m *MockManager) RegisterCallbackListener(subnetID ids.ID, listener SetCallbackListener) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RegisterCallbackListener", arg0, arg1) + m.ctrl.Call(m, "RegisterCallbackListener", subnetID, listener) } // RegisterCallbackListener indicates an expected call of RegisterCallbackListener. -func (mr *MockManagerMockRecorder) RegisterCallbackListener(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RegisterCallbackListener(subnetID, listener any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterCallbackListener", reflect.TypeOf((*MockManager)(nil).RegisterCallbackListener), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterCallbackListener", reflect.TypeOf((*MockManager)(nil).RegisterCallbackListener), subnetID, listener) } // RemoveWeight mocks base method. -func (m *MockManager) RemoveWeight(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { +func (m *MockManager) RemoveWeight(subnetID ids.ID, nodeID ids.NodeID, weight uint64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RemoveWeight", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "RemoveWeight", subnetID, nodeID, weight) ret0, _ := ret[0].(error) return ret0 } // RemoveWeight indicates an expected call of RemoveWeight. -func (mr *MockManagerMockRecorder) RemoveWeight(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) RemoveWeight(subnetID, nodeID, weight any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveWeight", reflect.TypeOf((*MockManager)(nil).RemoveWeight), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveWeight", reflect.TypeOf((*MockManager)(nil).RemoveWeight), subnetID, nodeID, weight) } // Sample mocks base method. -func (m *MockManager) Sample(arg0 ids.ID, arg1 int) ([]ids.NodeID, error) { +func (m *MockManager) Sample(subnetID ids.ID, size int) ([]ids.NodeID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Sample", arg0, arg1) + ret := m.ctrl.Call(m, "Sample", subnetID, size) ret0, _ := ret[0].([]ids.NodeID) ret1, _ := ret[1].(error) return ret0, ret1 } // Sample indicates an expected call of Sample. -func (mr *MockManagerMockRecorder) Sample(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) Sample(subnetID, size any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sample", reflect.TypeOf((*MockManager)(nil).Sample), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sample", reflect.TypeOf((*MockManager)(nil).Sample), subnetID, size) } // String mocks base method. @@ -210,31 +196,31 @@ func (mr *MockManagerMockRecorder) String() *gomock.Call { } // SubsetWeight mocks base method. -func (m *MockManager) SubsetWeight(arg0 ids.ID, arg1 set.Set[ids.NodeID]) (uint64, error) { +func (m *MockManager) SubsetWeight(subnetID ids.ID, validatorIDs set.Set[ids.NodeID]) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SubsetWeight", arg0, arg1) + ret := m.ctrl.Call(m, "SubsetWeight", subnetID, validatorIDs) ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } // SubsetWeight indicates an expected call of SubsetWeight. -func (mr *MockManagerMockRecorder) SubsetWeight(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) SubsetWeight(subnetID, validatorIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubsetWeight", reflect.TypeOf((*MockManager)(nil).SubsetWeight), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubsetWeight", reflect.TypeOf((*MockManager)(nil).SubsetWeight), subnetID, validatorIDs) } // TotalWeight mocks base method. -func (m *MockManager) TotalWeight(arg0 ids.ID) (uint64, error) { +func (m *MockManager) TotalWeight(subnetID ids.ID) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TotalWeight", arg0) + ret := m.ctrl.Call(m, "TotalWeight", subnetID) ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } // TotalWeight indicates an expected call of TotalWeight. -func (mr *MockManagerMockRecorder) TotalWeight(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) TotalWeight(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TotalWeight", reflect.TypeOf((*MockManager)(nil).TotalWeight), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TotalWeight", reflect.TypeOf((*MockManager)(nil).TotalWeight), subnetID) } diff --git a/vms/avm/block/executor/mock_manager.go b/vms/avm/block/executor/mock_manager.go index 5e27089b19fa..a882ec519fba 100644 --- a/vms/avm/block/executor/mock_manager.go +++ b/vms/avm/block/executor/mock_manager.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/avm/block/executor (interfaces: Manager) +// Source: vms/avm/block/executor/manager.go +// +// Generated by this command: +// +// mockgen -source=vms/avm/block/executor/manager.go -destination=vms/avm/block/executor/mock_manager.go -package=executor -exclude_interfaces= +// // Package executor is a generated GoMock package. package executor @@ -43,48 +45,48 @@ func (m *MockManager) EXPECT() *MockManagerMockRecorder { } // GetBlock mocks base method. -func (m *MockManager) GetBlock(arg0 ids.ID) (snowman.Block, error) { +func (m *MockManager) GetBlock(blkID ids.ID) (snowman.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlock", arg0) + ret := m.ctrl.Call(m, "GetBlock", blkID) ret0, _ := ret[0].(snowman.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlock indicates an expected call of GetBlock. -func (mr *MockManagerMockRecorder) GetBlock(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetBlock(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockManager)(nil).GetBlock), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockManager)(nil).GetBlock), blkID) } // GetState mocks base method. -func (m *MockManager) GetState(arg0 ids.ID) (state.Chain, bool) { +func (m *MockManager) GetState(blkID ids.ID) (state.Chain, bool) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetState", arg0) + ret := m.ctrl.Call(m, "GetState", blkID) ret0, _ := ret[0].(state.Chain) ret1, _ := ret[1].(bool) return ret0, ret1 } // GetState indicates an expected call of GetState. -func (mr *MockManagerMockRecorder) GetState(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetState(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockManager)(nil).GetState), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockManager)(nil).GetState), blkID) } // GetStatelessBlock mocks base method. -func (m *MockManager) GetStatelessBlock(arg0 ids.ID) (block.Block, error) { +func (m *MockManager) GetStatelessBlock(blkID ids.ID) (block.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStatelessBlock", arg0) + ret := m.ctrl.Call(m, "GetStatelessBlock", blkID) ret0, _ := ret[0].(block.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStatelessBlock indicates an expected call of GetStatelessBlock. -func (mr *MockManagerMockRecorder) GetStatelessBlock(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetStatelessBlock(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessBlock", reflect.TypeOf((*MockManager)(nil).GetStatelessBlock), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessBlock", reflect.TypeOf((*MockManager)(nil).GetStatelessBlock), blkID) } // LastAccepted mocks base method. @@ -110,7 +112,7 @@ func (m *MockManager) NewBlock(arg0 block.Block) snowman.Block { } // NewBlock indicates an expected call of NewBlock. -func (mr *MockManagerMockRecorder) NewBlock(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) NewBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBlock", reflect.TypeOf((*MockManager)(nil).NewBlock), arg0) } @@ -130,41 +132,41 @@ func (mr *MockManagerMockRecorder) Preferred() *gomock.Call { } // SetPreference mocks base method. -func (m *MockManager) SetPreference(arg0 ids.ID) { +func (m *MockManager) SetPreference(blkID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetPreference", arg0) + m.ctrl.Call(m, "SetPreference", blkID) } // SetPreference indicates an expected call of SetPreference. -func (mr *MockManagerMockRecorder) SetPreference(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) SetPreference(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockManager)(nil).SetPreference), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockManager)(nil).SetPreference), blkID) } // VerifyTx mocks base method. -func (m *MockManager) VerifyTx(arg0 *txs.Tx) error { +func (m *MockManager) VerifyTx(tx *txs.Tx) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VerifyTx", arg0) + ret := m.ctrl.Call(m, "VerifyTx", tx) ret0, _ := ret[0].(error) return ret0 } // VerifyTx indicates an expected call of VerifyTx. -func (mr *MockManagerMockRecorder) VerifyTx(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) VerifyTx(tx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyTx", reflect.TypeOf((*MockManager)(nil).VerifyTx), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyTx", reflect.TypeOf((*MockManager)(nil).VerifyTx), tx) } // VerifyUniqueInputs mocks base method. -func (m *MockManager) VerifyUniqueInputs(arg0 ids.ID, arg1 set.Set[ids.ID]) error { +func (m *MockManager) VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VerifyUniqueInputs", arg0, arg1) + ret := m.ctrl.Call(m, "VerifyUniqueInputs", blkID, inputs) ret0, _ := ret[0].(error) return ret0 } // VerifyUniqueInputs indicates an expected call of VerifyUniqueInputs. -func (mr *MockManagerMockRecorder) VerifyUniqueInputs(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) VerifyUniqueInputs(blkID, inputs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyUniqueInputs", reflect.TypeOf((*MockManager)(nil).VerifyUniqueInputs), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyUniqueInputs", reflect.TypeOf((*MockManager)(nil).VerifyUniqueInputs), blkID, inputs) } diff --git a/vms/avm/txs/mock_unsigned_tx.go b/vms/avm/txs/mock_unsigned_tx.go index c6504c7855a0..25bc9d501a16 100644 --- a/vms/avm/txs/mock_unsigned_tx.go +++ b/vms/avm/txs/mock_unsigned_tx.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/avm/txs (interfaces: UnsignedTx) +// Source: vms/avm/txs/tx.go +// +// Generated by this command: +// +// mockgen -source=vms/avm/txs/tx.go -destination=vms/avm/txs/mock_unsigned_tx.go -package=txs -exclude_interfaces= +// // Package txs is a generated GoMock package. package txs @@ -55,15 +57,15 @@ func (mr *MockUnsignedTxMockRecorder) Bytes() *gomock.Call { } // InitCtx mocks base method. -func (m *MockUnsignedTx) InitCtx(arg0 *snow.Context) { +func (m *MockUnsignedTx) InitCtx(ctx *snow.Context) { m.ctrl.T.Helper() - m.ctrl.Call(m, "InitCtx", arg0) + m.ctrl.Call(m, "InitCtx", ctx) } // InitCtx indicates an expected call of InitCtx. -func (mr *MockUnsignedTxMockRecorder) InitCtx(arg0 interface{}) *gomock.Call { +func (mr *MockUnsignedTxMockRecorder) InitCtx(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockUnsignedTx)(nil).InitCtx), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockUnsignedTx)(nil).InitCtx), ctx) } // InputIDs mocks base method. @@ -109,27 +111,27 @@ func (mr *MockUnsignedTxMockRecorder) NumCredentials() *gomock.Call { } // SetBytes mocks base method. -func (m *MockUnsignedTx) SetBytes(arg0 []byte) { +func (m *MockUnsignedTx) SetBytes(unsignedBytes []byte) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetBytes", arg0) + m.ctrl.Call(m, "SetBytes", unsignedBytes) } // SetBytes indicates an expected call of SetBytes. -func (mr *MockUnsignedTxMockRecorder) SetBytes(arg0 interface{}) *gomock.Call { +func (mr *MockUnsignedTxMockRecorder) SetBytes(unsignedBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBytes", reflect.TypeOf((*MockUnsignedTx)(nil).SetBytes), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBytes", reflect.TypeOf((*MockUnsignedTx)(nil).SetBytes), unsignedBytes) } // Visit mocks base method. -func (m *MockUnsignedTx) Visit(arg0 Visitor) error { +func (m *MockUnsignedTx) Visit(visitor Visitor) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Visit", arg0) + ret := m.ctrl.Call(m, "Visit", visitor) ret0, _ := ret[0].(error) return ret0 } // Visit indicates an expected call of Visit. -func (mr *MockUnsignedTxMockRecorder) Visit(arg0 interface{}) *gomock.Call { +func (mr *MockUnsignedTxMockRecorder) Visit(visitor any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Visit", reflect.TypeOf((*MockUnsignedTx)(nil).Visit), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Visit", reflect.TypeOf((*MockUnsignedTx)(nil).Visit), visitor) } diff --git a/vms/platformvm/block/executor/mock_manager.go b/vms/platformvm/block/executor/mock_manager.go index a6a7a9c95bcf..5e8222383071 100644 --- a/vms/platformvm/block/executor/mock_manager.go +++ b/vms/platformvm/block/executor/mock_manager.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: vms/platformvm/block/executor/manager.go +// +// Generated by this command: +// +// mockgen -source=vms/platformvm/block/executor/manager.go -destination=vms/platformvm/block/executor/mock_manager.go -package=executor -exclude_interfaces= +// // Package executor is a generated GoMock package. package executor @@ -52,7 +54,7 @@ func (m *MockManager) GetBlock(blkID ids.ID) (snowman.Block, error) { } // GetBlock indicates an expected call of GetBlock. -func (mr *MockManagerMockRecorder) GetBlock(blkID interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetBlock(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockManager)(nil).GetBlock), blkID) } @@ -67,7 +69,7 @@ func (m *MockManager) GetState(blkID ids.ID) (state.Chain, bool) { } // GetState indicates an expected call of GetState. -func (mr *MockManagerMockRecorder) GetState(blkID interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetState(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockManager)(nil).GetState), blkID) } @@ -82,7 +84,7 @@ func (m *MockManager) GetStatelessBlock(blkID ids.ID) (block.Block, error) { } // GetStatelessBlock indicates an expected call of GetStatelessBlock. -func (mr *MockManagerMockRecorder) GetStatelessBlock(blkID interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) GetStatelessBlock(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessBlock", reflect.TypeOf((*MockManager)(nil).GetStatelessBlock), blkID) } @@ -110,7 +112,7 @@ func (m *MockManager) NewBlock(arg0 block.Block) snowman.Block { } // NewBlock indicates an expected call of NewBlock. -func (mr *MockManagerMockRecorder) NewBlock(arg0 interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) NewBlock(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBlock", reflect.TypeOf((*MockManager)(nil).NewBlock), arg0) } @@ -138,7 +140,7 @@ func (m *MockManager) SetPreference(blkID ids.ID) bool { } // SetPreference indicates an expected call of SetPreference. -func (mr *MockManagerMockRecorder) SetPreference(blkID interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) SetPreference(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*MockManager)(nil).SetPreference), blkID) } @@ -152,7 +154,7 @@ func (m *MockManager) VerifyTx(tx *txs.Tx) error { } // VerifyTx indicates an expected call of VerifyTx. -func (mr *MockManagerMockRecorder) VerifyTx(tx interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) VerifyTx(tx any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyTx", reflect.TypeOf((*MockManager)(nil).VerifyTx), tx) } @@ -166,7 +168,7 @@ func (m *MockManager) VerifyUniqueInputs(blkID ids.ID, inputs set.Set[ids.ID]) e } // VerifyUniqueInputs indicates an expected call of VerifyUniqueInputs. -func (mr *MockManagerMockRecorder) VerifyUniqueInputs(blkID, inputs interface{}) *gomock.Call { +func (mr *MockManagerMockRecorder) VerifyUniqueInputs(blkID, inputs any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyUniqueInputs", reflect.TypeOf((*MockManager)(nil).VerifyUniqueInputs), blkID, inputs) } diff --git a/vms/platformvm/txs/mock_staker.go b/vms/platformvm/txs/mock_staker.go deleted file mode 100644 index f74c2534ca39..000000000000 --- a/vms/platformvm/txs/mock_staker.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/txs (interfaces: Staker) - -// Package txs is a generated GoMock package. -package txs - -import ( - reflect "reflect" - time "time" - - ids "github.com/ava-labs/avalanchego/ids" - bls "github.com/ava-labs/avalanchego/utils/crypto/bls" - gomock "go.uber.org/mock/gomock" -) - -// MockStaker is a mock of Staker interface. -type MockStaker struct { - ctrl *gomock.Controller - recorder *MockStakerMockRecorder -} - -// MockStakerMockRecorder is the mock recorder for MockStaker. -type MockStakerMockRecorder struct { - mock *MockStaker -} - -// NewMockStaker creates a new mock instance. -func NewMockStaker(ctrl *gomock.Controller) *MockStaker { - mock := &MockStaker{ctrl: ctrl} - mock.recorder = &MockStakerMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockStaker) EXPECT() *MockStakerMockRecorder { - return m.recorder -} - -// CurrentPriority mocks base method. -func (m *MockStaker) CurrentPriority() Priority { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CurrentPriority") - ret0, _ := ret[0].(Priority) - return ret0 -} - -// CurrentPriority indicates an expected call of CurrentPriority. -func (mr *MockStakerMockRecorder) CurrentPriority() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentPriority", reflect.TypeOf((*MockStaker)(nil).CurrentPriority)) -} - -// EndTime mocks base method. -func (m *MockStaker) EndTime() time.Time { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EndTime") - ret0, _ := ret[0].(time.Time) - return ret0 -} - -// EndTime indicates an expected call of EndTime. -func (mr *MockStakerMockRecorder) EndTime() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EndTime", reflect.TypeOf((*MockStaker)(nil).EndTime)) -} - -// NodeID mocks base method. -func (m *MockStaker) NodeID() ids.NodeID { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NodeID") - ret0, _ := ret[0].(ids.NodeID) - return ret0 -} - -// NodeID indicates an expected call of NodeID. -func (mr *MockStakerMockRecorder) NodeID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeID", reflect.TypeOf((*MockStaker)(nil).NodeID)) -} - -// PublicKey mocks base method. -func (m *MockStaker) PublicKey() (*bls.PublicKey, bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PublicKey") - ret0, _ := ret[0].(*bls.PublicKey) - ret1, _ := ret[1].(bool) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// PublicKey indicates an expected call of PublicKey. -func (mr *MockStakerMockRecorder) PublicKey() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublicKey", reflect.TypeOf((*MockStaker)(nil).PublicKey)) -} - -// SubnetID mocks base method. -func (m *MockStaker) SubnetID() ids.ID { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SubnetID") - ret0, _ := ret[0].(ids.ID) - return ret0 -} - -// SubnetID indicates an expected call of SubnetID. -func (mr *MockStakerMockRecorder) SubnetID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubnetID", reflect.TypeOf((*MockStaker)(nil).SubnetID)) -} - -// Weight mocks base method. -func (m *MockStaker) Weight() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Weight") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// Weight indicates an expected call of Weight. -func (mr *MockStakerMockRecorder) Weight() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Weight", reflect.TypeOf((*MockStaker)(nil).Weight)) -} diff --git a/vms/platformvm/txs/mock_scheduled_staker.go b/vms/platformvm/txs/mock_staker_tx.go similarity index 57% rename from vms/platformvm/txs/mock_scheduled_staker.go rename to vms/platformvm/txs/mock_staker_tx.go index ce1a22b4eda0..2e01b15b3813 100644 --- a/vms/platformvm/txs/mock_scheduled_staker.go +++ b/vms/platformvm/txs/mock_staker_tx.go @@ -1,5 +1,10 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/txs (interfaces: ScheduledStaker) +// Source: vms/platformvm/txs/staker_tx.go +// +// Generated by this command: +// +// mockgen -source=vms/platformvm/txs/staker_tx.go -destination=vms/platformvm/txs/mock_staker_tx.go -package=txs -exclude_interfaces=ValidatorTx,DelegatorTx,StakerTx,PermissionlessStaker +// // Package txs is a generated GoMock package. package txs @@ -13,6 +18,115 @@ import ( gomock "go.uber.org/mock/gomock" ) +// MockStaker is a mock of Staker interface. +type MockStaker struct { + ctrl *gomock.Controller + recorder *MockStakerMockRecorder +} + +// MockStakerMockRecorder is the mock recorder for MockStaker. +type MockStakerMockRecorder struct { + mock *MockStaker +} + +// NewMockStaker creates a new mock instance. +func NewMockStaker(ctrl *gomock.Controller) *MockStaker { + mock := &MockStaker{ctrl: ctrl} + mock.recorder = &MockStakerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockStaker) EXPECT() *MockStakerMockRecorder { + return m.recorder +} + +// CurrentPriority mocks base method. +func (m *MockStaker) CurrentPriority() Priority { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CurrentPriority") + ret0, _ := ret[0].(Priority) + return ret0 +} + +// CurrentPriority indicates an expected call of CurrentPriority. +func (mr *MockStakerMockRecorder) CurrentPriority() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentPriority", reflect.TypeOf((*MockStaker)(nil).CurrentPriority)) +} + +// EndTime mocks base method. +func (m *MockStaker) EndTime() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EndTime") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// EndTime indicates an expected call of EndTime. +func (mr *MockStakerMockRecorder) EndTime() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EndTime", reflect.TypeOf((*MockStaker)(nil).EndTime)) +} + +// NodeID mocks base method. +func (m *MockStaker) NodeID() ids.NodeID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NodeID") + ret0, _ := ret[0].(ids.NodeID) + return ret0 +} + +// NodeID indicates an expected call of NodeID. +func (mr *MockStakerMockRecorder) NodeID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NodeID", reflect.TypeOf((*MockStaker)(nil).NodeID)) +} + +// PublicKey mocks base method. +func (m *MockStaker) PublicKey() (*bls.PublicKey, bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PublicKey") + ret0, _ := ret[0].(*bls.PublicKey) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// PublicKey indicates an expected call of PublicKey. +func (mr *MockStakerMockRecorder) PublicKey() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PublicKey", reflect.TypeOf((*MockStaker)(nil).PublicKey)) +} + +// SubnetID mocks base method. +func (m *MockStaker) SubnetID() ids.ID { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SubnetID") + ret0, _ := ret[0].(ids.ID) + return ret0 +} + +// SubnetID indicates an expected call of SubnetID. +func (mr *MockStakerMockRecorder) SubnetID() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubnetID", reflect.TypeOf((*MockStaker)(nil).SubnetID)) +} + +// Weight mocks base method. +func (m *MockStaker) Weight() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Weight") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// Weight indicates an expected call of Weight. +func (mr *MockStakerMockRecorder) Weight() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Weight", reflect.TypeOf((*MockStaker)(nil).Weight)) +} + // MockScheduledStaker is a mock of ScheduledStaker interface. type MockScheduledStaker struct { ctrl *gomock.Controller diff --git a/vms/platformvm/txs/mock_unsigned_tx.go b/vms/platformvm/txs/mock_unsigned_tx.go index 9d9ec6c94dd4..f775c5203a4f 100644 --- a/vms/platformvm/txs/mock_unsigned_tx.go +++ b/vms/platformvm/txs/mock_unsigned_tx.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/txs (interfaces: UnsignedTx) +// Source: vms/platformvm/txs/unsigned_tx.go +// +// Generated by this command: +// +// mockgen -source=vms/platformvm/txs/unsigned_tx.go -destination=vms/platformvm/txs/mock_unsigned_tx.go -package=txs -exclude_interfaces= +// // Package txs is a generated GoMock package. package txs @@ -55,15 +57,15 @@ func (mr *MockUnsignedTxMockRecorder) Bytes() *gomock.Call { } // InitCtx mocks base method. -func (m *MockUnsignedTx) InitCtx(arg0 *snow.Context) { +func (m *MockUnsignedTx) InitCtx(ctx *snow.Context) { m.ctrl.T.Helper() - m.ctrl.Call(m, "InitCtx", arg0) + m.ctrl.Call(m, "InitCtx", ctx) } // InitCtx indicates an expected call of InitCtx. -func (mr *MockUnsignedTxMockRecorder) InitCtx(arg0 interface{}) *gomock.Call { +func (mr *MockUnsignedTxMockRecorder) InitCtx(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockUnsignedTx)(nil).InitCtx), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockUnsignedTx)(nil).InitCtx), ctx) } // InputIDs mocks base method. @@ -95,41 +97,41 @@ func (mr *MockUnsignedTxMockRecorder) Outputs() *gomock.Call { } // SetBytes mocks base method. -func (m *MockUnsignedTx) SetBytes(arg0 []byte) { +func (m *MockUnsignedTx) SetBytes(unsignedBytes []byte) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetBytes", arg0) + m.ctrl.Call(m, "SetBytes", unsignedBytes) } // SetBytes indicates an expected call of SetBytes. -func (mr *MockUnsignedTxMockRecorder) SetBytes(arg0 interface{}) *gomock.Call { +func (mr *MockUnsignedTxMockRecorder) SetBytes(unsignedBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBytes", reflect.TypeOf((*MockUnsignedTx)(nil).SetBytes), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBytes", reflect.TypeOf((*MockUnsignedTx)(nil).SetBytes), unsignedBytes) } // SyntacticVerify mocks base method. -func (m *MockUnsignedTx) SyntacticVerify(arg0 *snow.Context) error { +func (m *MockUnsignedTx) SyntacticVerify(ctx *snow.Context) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SyntacticVerify", arg0) + ret := m.ctrl.Call(m, "SyntacticVerify", ctx) ret0, _ := ret[0].(error) return ret0 } // SyntacticVerify indicates an expected call of SyntacticVerify. -func (mr *MockUnsignedTxMockRecorder) SyntacticVerify(arg0 interface{}) *gomock.Call { +func (mr *MockUnsignedTxMockRecorder) SyntacticVerify(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyntacticVerify", reflect.TypeOf((*MockUnsignedTx)(nil).SyntacticVerify), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SyntacticVerify", reflect.TypeOf((*MockUnsignedTx)(nil).SyntacticVerify), ctx) } // Visit mocks base method. -func (m *MockUnsignedTx) Visit(arg0 Visitor) error { +func (m *MockUnsignedTx) Visit(visitor Visitor) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Visit", arg0) + ret := m.ctrl.Call(m, "Visit", visitor) ret0, _ := ret[0].(error) return ret0 } // Visit indicates an expected call of Visit. -func (mr *MockUnsignedTxMockRecorder) Visit(arg0 interface{}) *gomock.Call { +func (mr *MockUnsignedTxMockRecorder) Visit(visitor any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Visit", reflect.TypeOf((*MockUnsignedTx)(nil).Visit), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Visit", reflect.TypeOf((*MockUnsignedTx)(nil).Visit), visitor) } diff --git a/x/merkledb/mock_db.go b/x/merkledb/mock_db.go index faca3d9c00cf..d43e276103f7 100644 --- a/x/merkledb/mock_db.go +++ b/x/merkledb/mock_db.go @@ -1,16 +1,22 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/x/merkledb (interfaces: MerkleDB) +// Source: x/merkledb/db.go +// +// Generated by this command: +// +// mockgen -source=x/merkledb/db.go -destination=x/merkledb/mock_db.go -package=merkledb -exclude_interfaces=ChangeProofer,RangeProofer,Clearer,Prefetcher +// // Package merkledb is a generated GoMock package. package merkledb import ( context "context" + reflect "reflect" + database "github.com/ava-labs/avalanchego/database" ids "github.com/ava-labs/avalanchego/ids" maybe "github.com/ava-labs/avalanchego/utils/maybe" gomock "go.uber.org/mock/gomock" - reflect "reflect" ) // MockMerkleDB is a mock of MerkleDB interface. @@ -65,207 +71,207 @@ func (mr *MockMerkleDBMockRecorder) Close() *gomock.Call { } // CommitChangeProof mocks base method. -func (m *MockMerkleDB) CommitChangeProof(arg0 context.Context, arg1 *ChangeProof) error { +func (m *MockMerkleDB) CommitChangeProof(ctx context.Context, proof *ChangeProof) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CommitChangeProof", arg0, arg1) + ret := m.ctrl.Call(m, "CommitChangeProof", ctx, proof) ret0, _ := ret[0].(error) return ret0 } // CommitChangeProof indicates an expected call of CommitChangeProof. -func (mr *MockMerkleDBMockRecorder) CommitChangeProof(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) CommitChangeProof(ctx, proof any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitChangeProof), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitChangeProof), ctx, proof) } // CommitRangeProof mocks base method. -func (m *MockMerkleDB) CommitRangeProof(arg0 context.Context, arg1, arg2 maybe.Maybe[[]uint8], arg3 *RangeProof) error { +func (m *MockMerkleDB) CommitRangeProof(ctx context.Context, start, end maybe.Maybe[[]byte], proof *RangeProof) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CommitRangeProof", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "CommitRangeProof", ctx, start, end, proof) ret0, _ := ret[0].(error) return ret0 } // CommitRangeProof indicates an expected call of CommitRangeProof. -func (mr *MockMerkleDBMockRecorder) CommitRangeProof(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) CommitRangeProof(ctx, start, end, proof any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitRangeProof), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).CommitRangeProof), ctx, start, end, proof) } // Compact mocks base method. -func (m *MockMerkleDB) Compact(arg0, arg1 []byte) error { +func (m *MockMerkleDB) Compact(start, limit []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Compact", arg0, arg1) + ret := m.ctrl.Call(m, "Compact", start, limit) ret0, _ := ret[0].(error) return ret0 } // Compact indicates an expected call of Compact. -func (mr *MockMerkleDBMockRecorder) Compact(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) Compact(start, limit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Compact", reflect.TypeOf((*MockMerkleDB)(nil).Compact), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Compact", reflect.TypeOf((*MockMerkleDB)(nil).Compact), start, limit) } // Delete mocks base method. -func (m *MockMerkleDB) Delete(arg0 []byte) error { +func (m *MockMerkleDB) Delete(key []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Delete", arg0) + ret := m.ctrl.Call(m, "Delete", key) ret0, _ := ret[0].(error) return ret0 } // Delete indicates an expected call of Delete. -func (mr *MockMerkleDBMockRecorder) Delete(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) Delete(key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockMerkleDB)(nil).Delete), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockMerkleDB)(nil).Delete), key) } // Get mocks base method. -func (m *MockMerkleDB) Get(arg0 []byte) ([]byte, error) { +func (m *MockMerkleDB) Get(key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0) + ret := m.ctrl.Call(m, "Get", key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockMerkleDBMockRecorder) Get(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) Get(key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMerkleDB)(nil).Get), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockMerkleDB)(nil).Get), key) } // GetChangeProof mocks base method. -func (m *MockMerkleDB) GetChangeProof(arg0 context.Context, arg1, arg2 ids.ID, arg3, arg4 maybe.Maybe[[]uint8], arg5 int) (*ChangeProof, error) { +func (m *MockMerkleDB) GetChangeProof(ctx context.Context, startRootID, endRootID ids.ID, start, end maybe.Maybe[[]byte], maxLength int) (*ChangeProof, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChangeProof", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "GetChangeProof", ctx, startRootID, endRootID, start, end, maxLength) ret0, _ := ret[0].(*ChangeProof) ret1, _ := ret[1].(error) return ret0, ret1 } // GetChangeProof indicates an expected call of GetChangeProof. -func (mr *MockMerkleDBMockRecorder) GetChangeProof(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) GetChangeProof(ctx, startRootID, endRootID, start, end, maxLength any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetChangeProof), arg0, arg1, arg2, arg3, arg4, arg5) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetChangeProof), ctx, startRootID, endRootID, start, end, maxLength) } // GetMerkleRoot mocks base method. -func (m *MockMerkleDB) GetMerkleRoot(arg0 context.Context) (ids.ID, error) { +func (m *MockMerkleDB) GetMerkleRoot(ctx context.Context) (ids.ID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMerkleRoot", arg0) + ret := m.ctrl.Call(m, "GetMerkleRoot", ctx) ret0, _ := ret[0].(ids.ID) ret1, _ := ret[1].(error) return ret0, ret1 } // GetMerkleRoot indicates an expected call of GetMerkleRoot. -func (mr *MockMerkleDBMockRecorder) GetMerkleRoot(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) GetMerkleRoot(ctx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMerkleRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetMerkleRoot), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMerkleRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetMerkleRoot), ctx) } // GetProof mocks base method. -func (m *MockMerkleDB) GetProof(arg0 context.Context, arg1 []byte) (*Proof, error) { +func (m *MockMerkleDB) GetProof(ctx context.Context, keyBytes []byte) (*Proof, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProof", arg0, arg1) + ret := m.ctrl.Call(m, "GetProof", ctx, keyBytes) ret0, _ := ret[0].(*Proof) ret1, _ := ret[1].(error) return ret0, ret1 } // GetProof indicates an expected call of GetProof. -func (mr *MockMerkleDBMockRecorder) GetProof(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) GetProof(ctx, keyBytes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProof", reflect.TypeOf((*MockMerkleDB)(nil).GetProof), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProof", reflect.TypeOf((*MockMerkleDB)(nil).GetProof), ctx, keyBytes) } // GetRangeProof mocks base method. -func (m *MockMerkleDB) GetRangeProof(arg0 context.Context, arg1, arg2 maybe.Maybe[[]uint8], arg3 int) (*RangeProof, error) { +func (m *MockMerkleDB) GetRangeProof(ctx context.Context, start, end maybe.Maybe[[]byte], maxLength int) (*RangeProof, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRangeProof", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "GetRangeProof", ctx, start, end, maxLength) ret0, _ := ret[0].(*RangeProof) ret1, _ := ret[1].(error) return ret0, ret1 } // GetRangeProof indicates an expected call of GetRangeProof. -func (mr *MockMerkleDBMockRecorder) GetRangeProof(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) GetRangeProof(ctx, start, end, maxLength any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProof), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProof", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProof), ctx, start, end, maxLength) } // GetRangeProofAtRoot mocks base method. -func (m *MockMerkleDB) GetRangeProofAtRoot(arg0 context.Context, arg1 ids.ID, arg2, arg3 maybe.Maybe[[]uint8], arg4 int) (*RangeProof, error) { +func (m *MockMerkleDB) GetRangeProofAtRoot(ctx context.Context, rootID ids.ID, start, end maybe.Maybe[[]byte], maxLength int) (*RangeProof, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRangeProofAtRoot", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "GetRangeProofAtRoot", ctx, rootID, start, end, maxLength) ret0, _ := ret[0].(*RangeProof) ret1, _ := ret[1].(error) return ret0, ret1 } // GetRangeProofAtRoot indicates an expected call of GetRangeProofAtRoot. -func (mr *MockMerkleDBMockRecorder) GetRangeProofAtRoot(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) GetRangeProofAtRoot(ctx, rootID, start, end, maxLength any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProofAtRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProofAtRoot), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRangeProofAtRoot", reflect.TypeOf((*MockMerkleDB)(nil).GetRangeProofAtRoot), ctx, rootID, start, end, maxLength) } // GetValue mocks base method. -func (m *MockMerkleDB) GetValue(arg0 context.Context, arg1 []byte) ([]byte, error) { +func (m *MockMerkleDB) GetValue(ctx context.Context, key []byte) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValue", arg0, arg1) + ret := m.ctrl.Call(m, "GetValue", ctx, key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // GetValue indicates an expected call of GetValue. -func (mr *MockMerkleDBMockRecorder) GetValue(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) GetValue(ctx, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValue", reflect.TypeOf((*MockMerkleDB)(nil).GetValue), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValue", reflect.TypeOf((*MockMerkleDB)(nil).GetValue), ctx, key) } // GetValues mocks base method. -func (m *MockMerkleDB) GetValues(arg0 context.Context, arg1 [][]byte) ([][]byte, []error) { +func (m *MockMerkleDB) GetValues(ctx context.Context, keys [][]byte) ([][]byte, []error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValues", arg0, arg1) + ret := m.ctrl.Call(m, "GetValues", ctx, keys) ret0, _ := ret[0].([][]byte) ret1, _ := ret[1].([]error) return ret0, ret1 } // GetValues indicates an expected call of GetValues. -func (mr *MockMerkleDBMockRecorder) GetValues(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) GetValues(ctx, keys any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValues", reflect.TypeOf((*MockMerkleDB)(nil).GetValues), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValues", reflect.TypeOf((*MockMerkleDB)(nil).GetValues), ctx, keys) } // Has mocks base method. -func (m *MockMerkleDB) Has(arg0 []byte) (bool, error) { +func (m *MockMerkleDB) Has(key []byte) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Has", arg0) + ret := m.ctrl.Call(m, "Has", key) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } // Has indicates an expected call of Has. -func (mr *MockMerkleDBMockRecorder) Has(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) Has(key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMerkleDB)(nil).Has), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockMerkleDB)(nil).Has), key) } // HealthCheck mocks base method. -func (m *MockMerkleDB) HealthCheck(arg0 context.Context) (interface{}, error) { +func (m *MockMerkleDB) HealthCheck(arg0 context.Context) (any, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HealthCheck", arg0) - ret0, _ := ret[0].(interface{}) + ret0, _ := ret[0].(any) ret1, _ := ret[1].(error) return ret0, ret1 } // HealthCheck indicates an expected call of HealthCheck. -func (mr *MockMerkleDBMockRecorder) HealthCheck(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) HealthCheck(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockMerkleDB)(nil).HealthCheck), arg0) } @@ -299,174 +305,160 @@ func (mr *MockMerkleDBMockRecorder) NewIterator() *gomock.Call { } // NewIteratorWithPrefix mocks base method. -func (m *MockMerkleDB) NewIteratorWithPrefix(arg0 []byte) database.Iterator { +func (m *MockMerkleDB) NewIteratorWithPrefix(prefix []byte) database.Iterator { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithPrefix", arg0) + ret := m.ctrl.Call(m, "NewIteratorWithPrefix", prefix) ret0, _ := ret[0].(database.Iterator) return ret0 } // NewIteratorWithPrefix indicates an expected call of NewIteratorWithPrefix. -func (mr *MockMerkleDBMockRecorder) NewIteratorWithPrefix(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) NewIteratorWithPrefix(prefix any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithPrefix), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithPrefix), prefix) } // NewIteratorWithStart mocks base method. -func (m *MockMerkleDB) NewIteratorWithStart(arg0 []byte) database.Iterator { +func (m *MockMerkleDB) NewIteratorWithStart(start []byte) database.Iterator { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithStart", arg0) + ret := m.ctrl.Call(m, "NewIteratorWithStart", start) ret0, _ := ret[0].(database.Iterator) return ret0 } // NewIteratorWithStart indicates an expected call of NewIteratorWithStart. -func (mr *MockMerkleDBMockRecorder) NewIteratorWithStart(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) NewIteratorWithStart(start any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStart", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStart), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStart", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStart), start) } // NewIteratorWithStartAndPrefix mocks base method. -func (m *MockMerkleDB) NewIteratorWithStartAndPrefix(arg0, arg1 []byte) database.Iterator { +func (m *MockMerkleDB) NewIteratorWithStartAndPrefix(start, prefix []byte) database.Iterator { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewIteratorWithStartAndPrefix", arg0, arg1) + ret := m.ctrl.Call(m, "NewIteratorWithStartAndPrefix", start, prefix) ret0, _ := ret[0].(database.Iterator) return ret0 } // NewIteratorWithStartAndPrefix indicates an expected call of NewIteratorWithStartAndPrefix. -func (mr *MockMerkleDBMockRecorder) NewIteratorWithStartAndPrefix(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) NewIteratorWithStartAndPrefix(start, prefix any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStartAndPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStartAndPrefix), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStartAndPrefix", reflect.TypeOf((*MockMerkleDB)(nil).NewIteratorWithStartAndPrefix), start, prefix) } // NewView mocks base method. -func (m *MockMerkleDB) NewView(arg0 context.Context, arg1 ViewChanges) (View, error) { +func (m *MockMerkleDB) NewView(ctx context.Context, changes ViewChanges) (View, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewView", arg0, arg1) + ret := m.ctrl.Call(m, "NewView", ctx, changes) ret0, _ := ret[0].(View) ret1, _ := ret[1].(error) return ret0, ret1 } // NewView indicates an expected call of NewView. -func (mr *MockMerkleDBMockRecorder) NewView(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) NewView(ctx, changes any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewView", reflect.TypeOf((*MockMerkleDB)(nil).NewView), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewView", reflect.TypeOf((*MockMerkleDB)(nil).NewView), ctx, changes) } // PrefetchPath mocks base method. -func (m *MockMerkleDB) PrefetchPath(arg0 []byte) error { +func (m *MockMerkleDB) PrefetchPath(key []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PrefetchPath", arg0) + ret := m.ctrl.Call(m, "PrefetchPath", key) ret0, _ := ret[0].(error) return ret0 } // PrefetchPath indicates an expected call of PrefetchPath. -func (mr *MockMerkleDBMockRecorder) PrefetchPath(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) PrefetchPath(key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPath", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPath), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPath", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPath), key) } // PrefetchPaths mocks base method. -func (m *MockMerkleDB) PrefetchPaths(arg0 [][]byte) error { +func (m *MockMerkleDB) PrefetchPaths(keys [][]byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PrefetchPaths", arg0) + ret := m.ctrl.Call(m, "PrefetchPaths", keys) ret0, _ := ret[0].(error) return ret0 } // PrefetchPaths indicates an expected call of PrefetchPaths. -func (mr *MockMerkleDBMockRecorder) PrefetchPaths(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) PrefetchPaths(keys any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPaths", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPaths), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrefetchPaths", reflect.TypeOf((*MockMerkleDB)(nil).PrefetchPaths), keys) } // Put mocks base method. -func (m *MockMerkleDB) Put(arg0, arg1 []byte) error { +func (m *MockMerkleDB) Put(key, value []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Put", arg0, arg1) + ret := m.ctrl.Call(m, "Put", key, value) ret0, _ := ret[0].(error) return ret0 } // Put indicates an expected call of Put. -func (mr *MockMerkleDBMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) Put(key, value any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockMerkleDB)(nil).Put), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockMerkleDB)(nil).Put), key, value) } // VerifyChangeProof mocks base method. -func (m *MockMerkleDB) VerifyChangeProof(arg0 context.Context, arg1 *ChangeProof, arg2, arg3 maybe.Maybe[[]uint8], arg4 ids.ID) error { +func (m *MockMerkleDB) VerifyChangeProof(ctx context.Context, proof *ChangeProof, start, end maybe.Maybe[[]byte], expectedEndRootID ids.ID) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VerifyChangeProof", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "VerifyChangeProof", ctx, proof, start, end, expectedEndRootID) ret0, _ := ret[0].(error) return ret0 } // VerifyChangeProof indicates an expected call of VerifyChangeProof. -func (mr *MockMerkleDBMockRecorder) VerifyChangeProof(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) VerifyChangeProof(ctx, proof, start, end, expectedEndRootID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).VerifyChangeProof), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyChangeProof", reflect.TypeOf((*MockMerkleDB)(nil).VerifyChangeProof), ctx, proof, start, end, expectedEndRootID) } // getEditableNode mocks base method. -func (m *MockMerkleDB) getEditableNode(arg0 Key, arg1 bool) (*node, error) { +func (m *MockMerkleDB) getEditableNode(key Key, hasValue bool) (*node, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getEditableNode", arg0, arg1) + ret := m.ctrl.Call(m, "getEditableNode", key, hasValue) ret0, _ := ret[0].(*node) ret1, _ := ret[1].(error) return ret0, ret1 } // getEditableNode indicates an expected call of getEditableNode. -func (mr *MockMerkleDBMockRecorder) getEditableNode(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) getEditableNode(key, hasValue any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getEditableNode", reflect.TypeOf((*MockMerkleDB)(nil).getEditableNode), arg0, arg1) -} - -// getRoot mocks base method. -func (m *MockMerkleDB) getRoot() maybe.Maybe[*node] { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getRoot") - ret0, _ := ret[0].(maybe.Maybe[*node]) - return ret0 -} - -// getRoot indicates an expected call of getRoot. -func (mr *MockMerkleDBMockRecorder) getRoot() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getRoot", reflect.TypeOf((*MockMerkleDB)(nil).getRoot)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getEditableNode", reflect.TypeOf((*MockMerkleDB)(nil).getEditableNode), key, hasValue) } // getNode mocks base method. -func (m *MockMerkleDB) getNode(arg0 Key, arg1 bool) (*node, error) { +func (m *MockMerkleDB) getNode(key Key, hasValue bool) (*node, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getNode", arg0, arg1) + ret := m.ctrl.Call(m, "getNode", key, hasValue) ret0, _ := ret[0].(*node) ret1, _ := ret[1].(error) return ret0, ret1 } // getNode indicates an expected call of getNode. -func (mr *MockMerkleDBMockRecorder) getNode(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) getNode(key, hasValue any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getNode", reflect.TypeOf((*MockMerkleDB)(nil).getNode), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getNode", reflect.TypeOf((*MockMerkleDB)(nil).getNode), key, hasValue) } -// getSentinelNode mocks base method. -func (m *MockMerkleDB) getSentinelNode() *node { +// getRoot mocks base method. +func (m *MockMerkleDB) getRoot() maybe.Maybe[*node] { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getSentinelNode") - ret0, _ := ret[0].(*node) + ret := m.ctrl.Call(m, "getRoot") + ret0, _ := ret[0].(maybe.Maybe[*node]) return ret0 } -// getSentinelNode indicates an expected call of getSentinelNode. -func (mr *MockMerkleDBMockRecorder) getSentinelNode() *gomock.Call { +// getRoot indicates an expected call of getRoot. +func (mr *MockMerkleDBMockRecorder) getRoot() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getSentinelNode", reflect.TypeOf((*MockMerkleDB)(nil).getSentinelNode)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getRoot", reflect.TypeOf((*MockMerkleDB)(nil).getRoot)) } // getTokenSize mocks base method. @@ -484,16 +476,16 @@ func (mr *MockMerkleDBMockRecorder) getTokenSize() *gomock.Call { } // getValue mocks base method. -func (m *MockMerkleDB) getValue(arg0 Key) ([]byte, error) { +func (m *MockMerkleDB) getValue(key Key) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "getValue", arg0) + ret := m.ctrl.Call(m, "getValue", key) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // getValue indicates an expected call of getValue. -func (mr *MockMerkleDBMockRecorder) getValue(arg0 interface{}) *gomock.Call { +func (mr *MockMerkleDBMockRecorder) getValue(key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getValue", reflect.TypeOf((*MockMerkleDB)(nil).getValue), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "getValue", reflect.TypeOf((*MockMerkleDB)(nil).getValue), key) } From cde054f7cecc7a54f1143e9166a78173ee40f2e3 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:50:21 -0500 Subject: [PATCH 254/267] Verify all MockGen generated files are re-generated in CI (#2616) --- scripts/mock.gen.sh | 20 ++++++++++ vms/components/avax/mock_transferable_out.go | 22 ++++++++-- vms/platformvm/fx/mock_fx.go | 42 ++++++++++++++------ 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/scripts/mock.gen.sh b/scripts/mock.gen.sh index e7eb04618016..75997d18b86e 100755 --- a/scripts/mock.gen.sh +++ b/scripts/mock.gen.sh @@ -16,6 +16,8 @@ fi source ./scripts/constants.sh +outputted_files=() + # tuples of (source interface import path, comma-separated interface names, output file path) input="scripts/mocks.mockgen.txt" while IFS= read -r line @@ -23,6 +25,7 @@ do IFS='=' read src_import_path interface_name output_path <<< "${line}" package_name=$(basename $(dirname $output_path)) echo "Generating ${output_path}..." + outputted_files+=(${output_path}) mockgen -package=${package_name} -destination=${output_path} ${src_import_path} ${interface_name} done < "$input" @@ -33,6 +36,7 @@ while IFS= read -r line do IFS='=' read source_path exclude_interfaces output_path <<< "${line}" package_name=$(basename $(dirname $output_path)) + outputted_files+=(${output_path}) echo "Generating ${output_path}..." mockgen \ @@ -43,4 +47,20 @@ do done < "$input" +all_generated_files=( $(grep -Rl 'Code generated by MockGen. DO NOT EDIT.') ) + +# Exclude certain files +outputted_files+=('scripts/mock.gen.sh') # This file +outputted_files+=('vms/components/avax/mock_transferable_out.go') # Embedded verify.IsState +outputted_files+=('vms/platformvm/fx/mock_fx.go') # Embedded verify.IsNotState + +diff_files=(`echo ${all_generated_files[@]} ${outputted_files[@]} | tr ' ' '\n' | sort | uniq -u`) + +if (( ${#diff_files[@]} )); then + printf "\nFAILURE\n" + echo "Detected MockGen generated files that are not in scripts/mocks.mockgen.source.txt or scripts/mocks.mockgen.txt:" + printf "%s\n" "${diff_files[@]}" + exit 255 +fi + echo "SUCCESS" diff --git a/vms/components/avax/mock_transferable_out.go b/vms/components/avax/mock_transferable_out.go index bf1836002214..b518b86302d4 100644 --- a/vms/components/avax/mock_transferable_out.go +++ b/vms/components/avax/mock_transferable_out.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/components/avax (interfaces: TransferableOut) +// +// Generated by this command: +// +// mockgen -package=avax -destination=vms/components/avax/mock_transferable_out.go github.com/ava-labs/avalanchego/vms/components/avax TransferableOut +// // Package avax is a generated GoMock package. package avax @@ -61,7 +63,7 @@ func (m *MockTransferableOut) InitCtx(arg0 *snow.Context) { } // InitCtx indicates an expected call of InitCtx. -func (mr *MockTransferableOutMockRecorder) InitCtx(arg0 interface{}) *gomock.Call { +func (mr *MockTransferableOutMockRecorder) InitCtx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockTransferableOut)(nil).InitCtx), arg0) } @@ -79,3 +81,15 @@ func (mr *MockTransferableOutMockRecorder) Verify() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verify", reflect.TypeOf((*MockTransferableOut)(nil).Verify)) } + +// isState mocks base method. +func (m *MockTransferableOut) isState() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "isState") +} + +// isState indicates an expected call of isState. +func (mr *MockTransferableOutMockRecorder) isState() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "isState", reflect.TypeOf((*MockTransferableOut)(nil).isState)) +} diff --git a/vms/platformvm/fx/mock_fx.go b/vms/platformvm/fx/mock_fx.go index b0a2d761c7b2..6878c124b822 100644 --- a/vms/platformvm/fx/mock_fx.go +++ b/vms/platformvm/fx/mock_fx.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/fx (interfaces: Fx,Owner) +// +// Generated by this command: +// +// mockgen -package=fx -destination=vms/platformvm/fx/mock_fx.go github.com/ava-labs/avalanchego/vms/platformvm/fx Fx,Owner +// // Package fx is a generated GoMock package. package fx @@ -67,22 +69,22 @@ func (mr *MockFxMockRecorder) Bootstrapping() *gomock.Call { } // CreateOutput mocks base method. -func (m *MockFx) CreateOutput(arg0 uint64, arg1 interface{}) (interface{}, error) { +func (m *MockFx) CreateOutput(arg0 uint64, arg1 any) (any, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateOutput", arg0, arg1) - ret0, _ := ret[0].(interface{}) + ret0, _ := ret[0].(any) ret1, _ := ret[1].(error) return ret0, ret1 } // CreateOutput indicates an expected call of CreateOutput. -func (mr *MockFxMockRecorder) CreateOutput(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockFxMockRecorder) CreateOutput(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOutput", reflect.TypeOf((*MockFx)(nil).CreateOutput), arg0, arg1) } // Initialize mocks base method. -func (m *MockFx) Initialize(arg0 interface{}) error { +func (m *MockFx) Initialize(arg0 any) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Initialize", arg0) ret0, _ := ret[0].(error) @@ -90,13 +92,13 @@ func (m *MockFx) Initialize(arg0 interface{}) error { } // Initialize indicates an expected call of Initialize. -func (mr *MockFxMockRecorder) Initialize(arg0 interface{}) *gomock.Call { +func (mr *MockFxMockRecorder) Initialize(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*MockFx)(nil).Initialize), arg0) } // VerifyPermission mocks base method. -func (m *MockFx) VerifyPermission(arg0, arg1, arg2, arg3 interface{}) error { +func (m *MockFx) VerifyPermission(arg0, arg1, arg2, arg3 any) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "VerifyPermission", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) @@ -104,13 +106,13 @@ func (m *MockFx) VerifyPermission(arg0, arg1, arg2, arg3 interface{}) error { } // VerifyPermission indicates an expected call of VerifyPermission. -func (mr *MockFxMockRecorder) VerifyPermission(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockFxMockRecorder) VerifyPermission(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyPermission", reflect.TypeOf((*MockFx)(nil).VerifyPermission), arg0, arg1, arg2, arg3) } // VerifyTransfer mocks base method. -func (m *MockFx) VerifyTransfer(arg0, arg1, arg2, arg3 interface{}) error { +func (m *MockFx) VerifyTransfer(arg0, arg1, arg2, arg3 any) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "VerifyTransfer", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) @@ -118,7 +120,7 @@ func (m *MockFx) VerifyTransfer(arg0, arg1, arg2, arg3 interface{}) error { } // VerifyTransfer indicates an expected call of VerifyTransfer. -func (mr *MockFxMockRecorder) VerifyTransfer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockFxMockRecorder) VerifyTransfer(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyTransfer", reflect.TypeOf((*MockFx)(nil).VerifyTransfer), arg0, arg1, arg2, arg3) } @@ -155,7 +157,7 @@ func (m *MockOwner) InitCtx(arg0 *snow.Context) { } // InitCtx indicates an expected call of InitCtx. -func (mr *MockOwnerMockRecorder) InitCtx(arg0 interface{}) *gomock.Call { +func (mr *MockOwnerMockRecorder) InitCtx(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitCtx", reflect.TypeOf((*MockOwner)(nil).InitCtx), arg0) } @@ -173,3 +175,17 @@ func (mr *MockOwnerMockRecorder) Verify() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Verify", reflect.TypeOf((*MockOwner)(nil).Verify)) } + +// isState mocks base method. +func (m *MockOwner) isState() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "isState") + ret0, _ := ret[0].(error) + return ret0 +} + +// isState indicates an expected call of isState. +func (mr *MockOwnerMockRecorder) isState() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "isState", reflect.TypeOf((*MockOwner)(nil).isState)) +} From fee76e8539915e21d44c51dff336c30bf1f68a82 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 17 Jan 2024 14:40:44 -0500 Subject: [PATCH 255/267] Move division by 0 check out of the bloom loops (#2622) --- utils/bloom/filter.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/bloom/filter.go b/utils/bloom/filter.go index 761ebfad12e1..7a0e3026087e 100644 --- a/utils/bloom/filter.go +++ b/utils/bloom/filter.go @@ -63,6 +63,7 @@ func (f *Filter) Add(hash uint64) { f.lock.Lock() defer f.lock.Unlock() + _ = 1 % f.numBits // hint to the compiler that numBits is not 0 for _, seed := range f.hashSeeds { hash = bits.RotateLeft64(hash, hashRotation) ^ seed index := hash % f.numBits @@ -119,6 +120,7 @@ func newHashSeeds(count int) ([]uint64, error) { func contains(hashSeeds []uint64, entries []byte, hash uint64) bool { var ( numBits = bitsPerByte * uint64(len(entries)) + _ = 1 % numBits // hint to the compiler that numBits is not 0 accumulator byte = 1 ) for seedIndex := 0; seedIndex < len(hashSeeds) && accumulator != 0; seedIndex++ { From 4819bb90babb06a684279d2ba77c30f0cd5525e0 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 17 Jan 2024 13:33:20 -0700 Subject: [PATCH 256/267] P-chain Add UTs around stakers persistence in platformvm state (#2505) --- vms/platformvm/state/diff_test.go | 14 +- vms/platformvm/state/state_test.go | 776 ++++++++++++++++++++++++++++- 2 files changed, 771 insertions(+), 19 deletions(-) diff --git a/vms/platformvm/state/diff_test.go b/vms/platformvm/state/diff_test.go index c4698603855e..e8d51039bdba 100644 --- a/vms/platformvm/state/diff_test.go +++ b/vms/platformvm/state/diff_test.go @@ -38,7 +38,7 @@ func TestDiffCreation(t *testing.T) { ctrl := gomock.NewController(t) lastAcceptedID := ids.GenerateTestID() - state, _ := newInitializedState(require) + state := newInitializedState(require) versions := NewMockVersions(ctrl) versions.EXPECT().GetState(lastAcceptedID).AnyTimes().Return(state, true) @@ -52,7 +52,7 @@ func TestDiffCurrentSupply(t *testing.T) { ctrl := gomock.NewController(t) lastAcceptedID := ids.GenerateTestID() - state, _ := newInitializedState(require) + state := newInitializedState(require) versions := NewMockVersions(ctrl) versions.EXPECT().GetState(lastAcceptedID).AnyTimes().Return(state, true) @@ -250,7 +250,7 @@ func TestDiffSubnet(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state, _ := newInitializedState(require) + state := newInitializedState(require) // Initialize parent with one subnet parentStateCreateSubnetTx := &txs.Tx{ @@ -298,7 +298,7 @@ func TestDiffChain(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state, _ := newInitializedState(require) + state := newInitializedState(require) subnetID := ids.GenerateTestID() // Initialize parent with one chain @@ -397,7 +397,7 @@ func TestDiffRewardUTXO(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state, _ := newInitializedState(require) + state := newInitializedState(require) txID := ids.GenerateTestID() @@ -523,7 +523,7 @@ func TestDiffSubnetOwner(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state, _ := newInitializedState(require) + state := newInitializedState(require) states := NewMockVersions(ctrl) lastAcceptedID := ids.GenerateTestID() @@ -585,7 +585,7 @@ func TestDiffStacking(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - state, _ := newInitializedState(require) + state := newInitializedState(require) states := NewMockVersions(ctrl) lastAcceptedID := ids.GenerateTestID() diff --git a/vms/platformvm/state/state_test.go b/vms/platformvm/state/state_test.go index 6986f15a0aa0..c0fdb1e60269 100644 --- a/vms/platformvm/state/state_test.go +++ b/vms/platformvm/state/state_test.go @@ -5,6 +5,7 @@ package state import ( "context" + "fmt" "math" "testing" "time" @@ -32,8 +33,11 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/genesis" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" + "github.com/ava-labs/avalanchego/vms/platformvm/status" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/vms/types" safemath "github.com/ava-labs/avalanchego/utils/math" ) @@ -49,23 +53,23 @@ func TestStateInitialization(t *testing.T) { require := require.New(t) s, db := newUninitializedState(require) - shouldInit, err := s.(*state).shouldInit() + shouldInit, err := s.shouldInit() require.NoError(err) require.True(shouldInit) - require.NoError(s.(*state).doneInit()) + require.NoError(s.doneInit()) require.NoError(s.Commit()) s = newStateFromDB(require, db) - shouldInit, err = s.(*state).shouldInit() + shouldInit, err = s.shouldInit() require.NoError(err) require.False(shouldInit) } func TestStateSyncGenesis(t *testing.T) { require := require.New(t) - state, _ := newInitializedState(require) + state := newInitializedState(require) staker, err := state.GetCurrentValidator(constants.PrimaryNetworkID, initialNodeID) require.NoError(err) @@ -88,8 +92,626 @@ func TestStateSyncGenesis(t *testing.T) { assertIteratorsEqual(t, EmptyIterator, delegatorIterator) } -func newInitializedState(require *require.Assertions) (State, database.Database) { - s, db := newUninitializedState(require) +// Whenever we store a staker, a whole bunch a data structures are updated +// This test is meant to capture which updates are carried out +func TestPersistStakers(t *testing.T) { + tests := map[string]struct { + // Insert or delete a staker to state and store it + storeStaker func(*require.Assertions, ids.ID /*=subnetID*/, *state) *Staker + + // Check that the staker is duly stored/removed in P-chain state + checkStakerInState func(*require.Assertions, *state, *Staker) + + // Check whether validators are duly reported in the validator set, + // with the right weight and showing the BLS key + checkValidatorsSet func(*require.Assertions, *state, *Staker) + + // Check that node duly track stakers uptimes + checkValidatorUptimes func(*require.Assertions, *state, *Staker) + + // Check whether weight/bls keys diffs are duly stored + checkDiffs func(*require.Assertions, *state, *Staker, uint64) + }{ + "add current validator": { + storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { + var ( + startTime = time.Now().Unix() + endTime = time.Now().Add(14 * 24 * time.Hour).Unix() + + validatorsData = txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(endTime), + Wght: 1234, + } + validatorReward uint64 = 5678 + ) + + utx := createPermissionlessValidatorTx(r, subnetID, validatorsData) + addPermValTx := &txs.Tx{Unsigned: utx} + r.NoError(addPermValTx.Initialize(txs.Codec)) + + staker, err := NewCurrentStaker( + addPermValTx.ID(), + utx, + time.Unix(startTime, 0), + validatorReward, + ) + r.NoError(err) + + s.PutCurrentValidator(staker) + s.AddTx(addPermValTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + return staker + }, + checkStakerInState: func(r *require.Assertions, s *state, staker *Staker) { + retrievedStaker, err := s.GetCurrentValidator(staker.SubnetID, staker.NodeID) + r.NoError(err) + r.Equal(staker, retrievedStaker) + }, + checkValidatorsSet: func(r *require.Assertions, s *state, staker *Staker) { + valsMap := s.cfg.Validators.GetMap(staker.SubnetID) + r.Len(valsMap, 1) + valOut, found := valsMap[staker.NodeID] + r.True(found) + r.Equal(valOut, &validators.GetValidatorOutput{ + NodeID: staker.NodeID, + PublicKey: staker.PublicKey, + Weight: staker.Weight, + }) + }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + upDuration, lastUpdated, err := s.GetUptime(staker.NodeID, staker.SubnetID) + r.NoError(err) + r.Equal(upDuration, time.Duration(0)) + r.Equal(lastUpdated, staker.StartTime) + }, + checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { + weightDiffBytes, err := s.flatValidatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + r.NoError(err) + weightDiff, err := unmarshalWeightDiff(weightDiffBytes) + r.NoError(err) + r.Equal(weightDiff, &ValidatorWeightDiff{ + Decrease: false, + Amount: staker.Weight, + }) + + blsDiffBytes, err := s.flatValidatorPublicKeyDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + if staker.SubnetID == constants.PrimaryNetworkID { + r.NoError(err) + r.Nil(blsDiffBytes) + } else { + r.ErrorIs(err, database.ErrNotFound) + } + }, + }, + "add current delegator": { + storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { + // insert the delegator and its validator + var ( + valStartTime = time.Now().Truncate(time.Second).Unix() + delStartTime = time.Unix(valStartTime, 0).Add(time.Hour).Unix() + delEndTime = time.Unix(delStartTime, 0).Add(30 * 24 * time.Hour).Unix() + valEndTime = time.Unix(valStartTime, 0).Add(365 * 24 * time.Hour).Unix() + + validatorsData = txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(valEndTime), + Wght: 1234, + } + validatorReward uint64 = 5678 + + delegatorData = txs.Validator{ + NodeID: validatorsData.NodeID, + End: uint64(delEndTime), + Wght: validatorsData.Wght / 2, + } + delegatorReward uint64 = 5432 + ) + + utxVal := createPermissionlessValidatorTx(r, subnetID, validatorsData) + addPermValTx := &txs.Tx{Unsigned: utxVal} + r.NoError(addPermValTx.Initialize(txs.Codec)) + + val, err := NewCurrentStaker( + addPermValTx.ID(), + utxVal, + time.Unix(valStartTime, 0), + validatorReward, + ) + r.NoError(err) + + utxDel := createPermissionlessDelegatorTx(subnetID, delegatorData) + addPermDelTx := &txs.Tx{Unsigned: utxDel} + r.NoError(addPermDelTx.Initialize(txs.Codec)) + + del, err := NewCurrentStaker( + addPermDelTx.ID(), + utxDel, + time.Unix(delStartTime, 0), + delegatorReward, + ) + r.NoError(err) + + s.PutCurrentValidator(val) + s.AddTx(addPermValTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + + s.PutCurrentDelegator(del) + s.AddTx(addPermDelTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + return del + }, + checkStakerInState: func(r *require.Assertions, s *state, staker *Staker) { + delIt, err := s.GetCurrentDelegatorIterator(staker.SubnetID, staker.NodeID) + r.NoError(err) + r.True(delIt.Next()) + retrievedDelegator := delIt.Value() + r.False(delIt.Next()) + delIt.Release() + r.Equal(staker, retrievedDelegator) + }, + checkValidatorsSet: func(r *require.Assertions, s *state, staker *Staker) { + val, err := s.GetCurrentValidator(staker.SubnetID, staker.NodeID) + r.NoError(err) + + valsMap := s.cfg.Validators.GetMap(staker.SubnetID) + r.Len(valsMap, 1) + valOut, found := valsMap[staker.NodeID] + r.True(found) + r.Equal(valOut.NodeID, staker.NodeID) + r.Equal(valOut.Weight, val.Weight+staker.Weight) + }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + }, + checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { + // validator's weight must increase of delegator's weight amount + weightDiffBytes, err := s.flatValidatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + r.NoError(err) + weightDiff, err := unmarshalWeightDiff(weightDiffBytes) + r.NoError(err) + r.Equal(weightDiff, &ValidatorWeightDiff{ + Decrease: false, + Amount: staker.Weight, + }) + }, + }, + "add pending validator": { + storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { + var ( + startTime = time.Now().Unix() + endTime = time.Now().Add(14 * 24 * time.Hour).Unix() + + validatorsData = txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(startTime), + End: uint64(endTime), + Wght: 1234, + } + ) + + utx := createPermissionlessValidatorTx(r, subnetID, validatorsData) + addPermValTx := &txs.Tx{Unsigned: utx} + r.NoError(addPermValTx.Initialize(txs.Codec)) + + staker, err := NewPendingStaker( + addPermValTx.ID(), + utx, + ) + r.NoError(err) + + s.PutPendingValidator(staker) + s.AddTx(addPermValTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + return staker + }, + checkStakerInState: func(r *require.Assertions, s *state, staker *Staker) { + retrievedStaker, err := s.GetPendingValidator(staker.SubnetID, staker.NodeID) + r.NoError(err) + r.Equal(staker, retrievedStaker) + }, + checkValidatorsSet: func(r *require.Assertions, s *state, staker *Staker) { + // pending validators are not showed in validators set + valsMap := s.cfg.Validators.GetMap(staker.SubnetID) + r.Len(valsMap, 0) + }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + // pending validators uptime is not tracked + _, _, err := s.GetUptime(staker.NodeID, staker.SubnetID) + r.ErrorIs(err, database.ErrNotFound) + }, + checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { + // pending validators weight diff and bls diffs are not stored + _, err := s.flatValidatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + r.ErrorIs(err, database.ErrNotFound) + + _, err = s.flatValidatorPublicKeyDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + r.ErrorIs(err, database.ErrNotFound) + }, + }, + "add pending delegator": { + storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { + // insert the delegator and its validator + var ( + valStartTime = time.Now().Truncate(time.Second).Unix() + delStartTime = time.Unix(valStartTime, 0).Add(time.Hour).Unix() + delEndTime = time.Unix(delStartTime, 0).Add(30 * 24 * time.Hour).Unix() + valEndTime = time.Unix(valStartTime, 0).Add(365 * 24 * time.Hour).Unix() + + validatorsData = txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(valStartTime), + End: uint64(valEndTime), + Wght: 1234, + } + + delegatorData = txs.Validator{ + NodeID: validatorsData.NodeID, + Start: uint64(delStartTime), + End: uint64(delEndTime), + Wght: validatorsData.Wght / 2, + } + ) + + utxVal := createPermissionlessValidatorTx(r, subnetID, validatorsData) + addPermValTx := &txs.Tx{Unsigned: utxVal} + r.NoError(addPermValTx.Initialize(txs.Codec)) + + val, err := NewPendingStaker(addPermValTx.ID(), utxVal) + r.NoError(err) + + utxDel := createPermissionlessDelegatorTx(subnetID, delegatorData) + addPermDelTx := &txs.Tx{Unsigned: utxDel} + r.NoError(addPermDelTx.Initialize(txs.Codec)) + + del, err := NewPendingStaker(addPermDelTx.ID(), utxDel) + r.NoError(err) + + s.PutPendingValidator(val) + s.AddTx(addPermValTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + + s.PutPendingDelegator(del) + s.AddTx(addPermDelTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + + return del + }, + checkStakerInState: func(r *require.Assertions, s *state, staker *Staker) { + delIt, err := s.GetPendingDelegatorIterator(staker.SubnetID, staker.NodeID) + r.NoError(err) + r.True(delIt.Next()) + retrievedDelegator := delIt.Value() + r.False(delIt.Next()) + delIt.Release() + r.Equal(staker, retrievedDelegator) + }, + checkValidatorsSet: func(r *require.Assertions, s *state, staker *Staker) { + valsMap := s.cfg.Validators.GetMap(staker.SubnetID) + r.Len(valsMap, 0) + }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + // nothing to do here + }, + checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { + // nothing to do here + }, + }, + "delete current validator": { + storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { + // add them remove the validator + var ( + startTime = time.Now().Unix() + endTime = time.Now().Add(14 * 24 * time.Hour).Unix() + + validatorsData = txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(endTime), + Wght: 1234, + } + validatorReward uint64 = 5678 + ) + + utx := createPermissionlessValidatorTx(r, subnetID, validatorsData) + addPermValTx := &txs.Tx{Unsigned: utx} + r.NoError(addPermValTx.Initialize(txs.Codec)) + + staker, err := NewCurrentStaker( + addPermValTx.ID(), + utx, + time.Unix(startTime, 0), + validatorReward, + ) + r.NoError(err) + + s.PutCurrentValidator(staker) + s.AddTx(addPermValTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + + s.DeleteCurrentValidator(staker) + r.NoError(s.Commit()) + return staker + }, + checkStakerInState: func(r *require.Assertions, s *state, staker *Staker) { + _, err := s.GetCurrentValidator(staker.SubnetID, staker.NodeID) + r.ErrorIs(err, database.ErrNotFound) + }, + checkValidatorsSet: func(r *require.Assertions, s *state, staker *Staker) { + // deleted validators are not showed in the validators set anymore + valsMap := s.cfg.Validators.GetMap(staker.SubnetID) + r.Len(valsMap, 0) + }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + // uptimes of delete validators are dropped + _, _, err := s.GetUptime(staker.NodeID, staker.SubnetID) + r.ErrorIs(err, database.ErrNotFound) + }, + checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { + weightDiffBytes, err := s.flatValidatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + r.NoError(err) + weightDiff, err := unmarshalWeightDiff(weightDiffBytes) + r.NoError(err) + r.Equal(weightDiff, &ValidatorWeightDiff{ + Decrease: true, + Amount: staker.Weight, + }) + + blsDiffBytes, err := s.flatValidatorPublicKeyDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + if staker.SubnetID == constants.PrimaryNetworkID { + r.NoError(err) + r.Equal(bls.DeserializePublicKey(blsDiffBytes), staker.PublicKey) + } else { + r.ErrorIs(err, database.ErrNotFound) + } + }, + }, + "delete current delegator": { + storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { + // insert validator and delegator, then remove the delegator + var ( + valStartTime = time.Now().Truncate(time.Second).Unix() + delStartTime = time.Unix(valStartTime, 0).Add(time.Hour).Unix() + delEndTime = time.Unix(delStartTime, 0).Add(30 * 24 * time.Hour).Unix() + valEndTime = time.Unix(valStartTime, 0).Add(365 * 24 * time.Hour).Unix() + + validatorsData = txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + End: uint64(valEndTime), + Wght: 1234, + } + validatorReward uint64 = 5678 + + delegatorData = txs.Validator{ + NodeID: validatorsData.NodeID, + End: uint64(delEndTime), + Wght: validatorsData.Wght / 2, + } + delegatorReward uint64 = 5432 + ) + + utxVal := createPermissionlessValidatorTx(r, subnetID, validatorsData) + addPermValTx := &txs.Tx{Unsigned: utxVal} + r.NoError(addPermValTx.Initialize(txs.Codec)) + + val, err := NewCurrentStaker( + addPermValTx.ID(), + utxVal, + time.Unix(valStartTime, 0), + validatorReward, + ) + r.NoError(err) + + utxDel := createPermissionlessDelegatorTx(subnetID, delegatorData) + addPermDelTx := &txs.Tx{Unsigned: utxDel} + r.NoError(addPermDelTx.Initialize(txs.Codec)) + + del, err := NewCurrentStaker( + addPermDelTx.ID(), + utxDel, + time.Unix(delStartTime, 0), + delegatorReward, + ) + r.NoError(err) + + s.PutCurrentValidator(val) + s.AddTx(addPermValTx, status.Committed) // this is currently needed to reload the staker + + s.PutCurrentDelegator(del) + s.AddTx(addPermDelTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + + s.DeleteCurrentDelegator(del) + r.NoError(s.Commit()) + + return del + }, + checkStakerInState: func(r *require.Assertions, s *state, staker *Staker) { + delIt, err := s.GetCurrentDelegatorIterator(staker.SubnetID, staker.NodeID) + r.NoError(err) + r.False(delIt.Next()) + delIt.Release() + }, + checkValidatorsSet: func(r *require.Assertions, s *state, staker *Staker) { + val, err := s.GetCurrentValidator(staker.SubnetID, staker.NodeID) + r.NoError(err) + + valsMap := s.cfg.Validators.GetMap(staker.SubnetID) + r.Len(valsMap, 1) + valOut, found := valsMap[staker.NodeID] + r.True(found) + r.Equal(valOut.NodeID, staker.NodeID) + r.Equal(valOut.Weight, val.Weight) + }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + // nothing to do here + }, + checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { + // validator's weight must decrease of delegator's weight amount + weightDiffBytes, err := s.flatValidatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + r.NoError(err) + weightDiff, err := unmarshalWeightDiff(weightDiffBytes) + r.NoError(err) + r.Equal(weightDiff, &ValidatorWeightDiff{ + Decrease: true, + Amount: staker.Weight, + }) + }, + }, + "delete pending validator": { + storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { + var ( + startTime = time.Now().Unix() + endTime = time.Now().Add(14 * 24 * time.Hour).Unix() + + validatorsData = txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(startTime), + End: uint64(endTime), + Wght: 1234, + } + ) + + utx := createPermissionlessValidatorTx(r, subnetID, validatorsData) + addPermValTx := &txs.Tx{Unsigned: utx} + r.NoError(addPermValTx.Initialize(txs.Codec)) + + staker, err := NewPendingStaker( + addPermValTx.ID(), + utx, + ) + r.NoError(err) + + s.PutPendingValidator(staker) + s.AddTx(addPermValTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + + s.DeletePendingValidator(staker) + r.NoError(s.Commit()) + + return staker + }, + checkStakerInState: func(r *require.Assertions, s *state, staker *Staker) { + _, err := s.GetPendingValidator(staker.SubnetID, staker.NodeID) + r.ErrorIs(err, database.ErrNotFound) + }, + checkValidatorsSet: func(r *require.Assertions, s *state, staker *Staker) { + valsMap := s.cfg.Validators.GetMap(staker.SubnetID) + r.Len(valsMap, 0) + }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + _, _, err := s.GetUptime(staker.NodeID, staker.SubnetID) + r.ErrorIs(err, database.ErrNotFound) + }, + checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { + _, err := s.flatValidatorWeightDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + r.ErrorIs(err, database.ErrNotFound) + + _, err = s.flatValidatorPublicKeyDiffsDB.Get(marshalDiffKey(staker.SubnetID, height, staker.NodeID)) + r.ErrorIs(err, database.ErrNotFound) + }, + }, + "delete pending delegator": { + storeStaker: func(r *require.Assertions, subnetID ids.ID, s *state) *Staker { + // insert validator and delegator the remove the validator + var ( + valStartTime = time.Now().Truncate(time.Second).Unix() + delStartTime = time.Unix(valStartTime, 0).Add(time.Hour).Unix() + delEndTime = time.Unix(delStartTime, 0).Add(30 * 24 * time.Hour).Unix() + valEndTime = time.Unix(valStartTime, 0).Add(365 * 24 * time.Hour).Unix() + + validatorsData = txs.Validator{ + NodeID: ids.GenerateTestNodeID(), + Start: uint64(valStartTime), + End: uint64(valEndTime), + Wght: 1234, + } + + delegatorData = txs.Validator{ + NodeID: validatorsData.NodeID, + Start: uint64(delStartTime), + End: uint64(delEndTime), + Wght: validatorsData.Wght / 2, + } + ) + + utxVal := createPermissionlessValidatorTx(r, subnetID, validatorsData) + addPermValTx := &txs.Tx{Unsigned: utxVal} + r.NoError(addPermValTx.Initialize(txs.Codec)) + + val, err := NewPendingStaker(addPermValTx.ID(), utxVal) + r.NoError(err) + + utxDel := createPermissionlessDelegatorTx(subnetID, delegatorData) + addPermDelTx := &txs.Tx{Unsigned: utxDel} + r.NoError(addPermDelTx.Initialize(txs.Codec)) + + del, err := NewPendingStaker(addPermDelTx.ID(), utxDel) + r.NoError(err) + + s.PutPendingValidator(val) + s.AddTx(addPermValTx, status.Committed) // this is currently needed to reload the staker + + s.PutPendingDelegator(del) + s.AddTx(addPermDelTx, status.Committed) // this is currently needed to reload the staker + r.NoError(s.Commit()) + + s.DeletePendingDelegator(del) + r.NoError(s.Commit()) + return del + }, + checkStakerInState: func(r *require.Assertions, s *state, staker *Staker) { + delIt, err := s.GetPendingDelegatorIterator(staker.SubnetID, staker.NodeID) + r.NoError(err) + r.False(delIt.Next()) + delIt.Release() + }, + checkValidatorsSet: func(r *require.Assertions, s *state, staker *Staker) { + valsMap := s.cfg.Validators.GetMap(staker.SubnetID) + r.Len(valsMap, 0) + }, + checkValidatorUptimes: func(r *require.Assertions, s *state, staker *Staker) { + }, + checkDiffs: func(r *require.Assertions, s *state, staker *Staker, height uint64) { + }, + }, + } + + subnetIDs := []ids.ID{constants.PrimaryNetworkID, ids.GenerateTestID()} + for _, subnetID := range subnetIDs { + for name, test := range tests { + t.Run(fmt.Sprintf("%s - subnetID %s", name, subnetID), func(t *testing.T) { + require := require.New(t) + + state, db := newUninitializedState(require) + + // create and store the staker + staker := test.storeStaker(require, subnetID, state) + + // check all relevant data are stored + test.checkStakerInState(require, state, staker) + test.checkValidatorsSet(require, state, staker) + test.checkValidatorUptimes(require, state, staker) + test.checkDiffs(require, state, staker, 0 /*height*/) + + // rebuild the state + rebuiltState := newStateFromDB(require, db) + + // load relevant quantities + require.NoError(rebuiltState.loadCurrentValidators()) + require.NoError(rebuiltState.loadPendingValidators()) + require.NoError(rebuiltState.initValidatorSets()) + + // check again that all relevant data are still available in rebuilt state + test.checkStakerInState(require, state, staker) + test.checkValidatorsSet(require, state, staker) + test.checkValidatorUptimes(require, state, staker) + test.checkDiffs(require, state, staker, 0 /*height*/) + }) + } + } +} + +func newInitializedState(require *require.Assertions) State { + s, _ := newUninitializedState(require) initialValidator := &txs.AddValidatorTx{ Validator: txs.Validator{ @@ -150,17 +772,17 @@ func newInitializedState(require *require.Assertions) (State, database.Database) genesisBlk, err := block.NewApricotCommitBlock(genesisBlkID, 0) require.NoError(err) - require.NoError(s.(*state).syncGenesis(genesisBlk, genesisState)) + require.NoError(s.syncGenesis(genesisBlk, genesisState)) - return s, db + return s } -func newUninitializedState(require *require.Assertions) (State, database.Database) { +func newUninitializedState(require *require.Assertions) (*state, database.Database) { db := memdb.New() return newStateFromDB(require, db), db } -func newStateFromDB(require *require.Assertions, db database.Database) State { +func newStateFromDB(require *require.Assertions, db database.Database) *state { execCfg, _ := config.GetExecutionConfig(nil) state, err := newState( db, @@ -183,6 +805,136 @@ func newStateFromDB(require *require.Assertions, db database.Database) State { return state } +func createPermissionlessValidatorTx(r *require.Assertions, subnetID ids.ID, validatorsData txs.Validator) *txs.AddPermissionlessValidatorTx { + var sig signer.Signer = &signer.Empty{} + if subnetID == constants.PrimaryNetworkID { + sk, err := bls.NewSecretKey() + r.NoError(err) + sig = signer.NewProofOfPossession(sk) + } + + return &txs.AddPermissionlessValidatorTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: constants.MainnetID, + BlockchainID: constants.PlatformChainID, + Outs: []*avax.TransferableOutput{}, + Ins: []*avax.TransferableInput{ + { + UTXOID: avax.UTXOID{ + TxID: ids.GenerateTestID(), + OutputIndex: 1, + }, + Asset: avax.Asset{ + ID: ids.GenerateTestID(), + }, + In: &secp256k1fx.TransferInput{ + Amt: 2 * units.KiloAvax, + Input: secp256k1fx.Input{ + SigIndices: []uint32{1}, + }, + }, + }, + }, + Memo: types.JSONByteSlice{}, + }, + }, + Validator: validatorsData, + Subnet: subnetID, + Signer: sig, + + StakeOuts: []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: ids.GenerateTestID(), + }, + Out: &secp256k1fx.TransferOutput{ + Amt: 2 * units.KiloAvax, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + }, + }, + }, + ValidatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + DelegatorRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + DelegationShares: reward.PercentDenominator, + } +} + +func createPermissionlessDelegatorTx(subnetID ids.ID, delegatorData txs.Validator) *txs.AddPermissionlessDelegatorTx { + return &txs.AddPermissionlessDelegatorTx{ + BaseTx: txs.BaseTx{ + BaseTx: avax.BaseTx{ + NetworkID: constants.MainnetID, + BlockchainID: constants.PlatformChainID, + Outs: []*avax.TransferableOutput{}, + Ins: []*avax.TransferableInput{ + { + UTXOID: avax.UTXOID{ + TxID: ids.GenerateTestID(), + OutputIndex: 1, + }, + Asset: avax.Asset{ + ID: ids.GenerateTestID(), + }, + In: &secp256k1fx.TransferInput{ + Amt: 2 * units.KiloAvax, + Input: secp256k1fx.Input{ + SigIndices: []uint32{1}, + }, + }, + }, + }, + Memo: types.JSONByteSlice{}, + }, + }, + Validator: delegatorData, + Subnet: subnetID, + + StakeOuts: []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: ids.GenerateTestID(), + }, + Out: &secp256k1fx.TransferOutput{ + Amt: 2 * units.KiloAvax, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + }, + }, + }, + DelegationRewardsOwner: &secp256k1fx.OutputOwners{ + Locktime: 0, + Threshold: 1, + Addrs: []ids.ShortID{ + ids.GenerateTestShortID(), + }, + }, + } +} + func TestValidatorWeightDiff(t *testing.T) { type test struct { name string @@ -328,7 +1080,7 @@ func TestValidatorWeightDiff(t *testing.T) { func TestStateAddRemoveValidator(t *testing.T) { require := require.New(t) - state, _ := newInitializedState(require) + state := newInitializedState(require) var ( numNodes = 3 @@ -667,7 +1419,7 @@ func TestParsedStateBlock(t *testing.T) { func TestStateSubnetOwner(t *testing.T) { require := require.New(t) - state, _ := newInitializedState(require) + state := newInitializedState(require) ctrl := gomock.NewController(t) var ( From fe2ded6a8237801c2c49597dc2099f9ec759f574 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:58:44 -0500 Subject: [PATCH 257/267] Revert "Set dependabot target branch to `dev` (#2553)" (#2623) --- .github/dependabot.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 39bc8b683ea0..b444581e62d0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,4 +9,3 @@ updates: directory: "/" # Location of package manifests schedule: interval: "daily" - target-branch: "dev" From a120693004de47838a171121827f77af5467e385 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:09:54 -0500 Subject: [PATCH 258/267] Remove remaining 2023 remnants (#2624) --- LICENSE | 2 +- header.yml | 2 +- network/ip_tracker.go | 2 +- tests/fixture/tmpnet/network_config.go | 2 +- tests/fixture/tmpnet/subnet.go | 2 +- utils/filesystem/mock_file.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/LICENSE b/LICENSE index c9be72c59aa5..6178f77a85af 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (C) 2019-2023, Ava Labs, Inc. +Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/header.yml b/header.yml index 19229afa4a64..c15feba2713b 100644 --- a/header.yml +++ b/header.yml @@ -1,4 +1,4 @@ header: | - // Copyright (C) 2019-{{YEAR}}, Ava Labs, Inc. All rights reserved. + // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. \ No newline at end of file diff --git a/network/ip_tracker.go b/network/ip_tracker.go index eb8dcddb6e76..60502dbbf4df 100644 --- a/network/ip_tracker.go +++ b/network/ip_tracker.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package network diff --git a/tests/fixture/tmpnet/network_config.go b/tests/fixture/tmpnet/network_config.go index 4c68af240e98..c5bb603ed3e5 100644 --- a/tests/fixture/tmpnet/network_config.go +++ b/tests/fixture/tmpnet/network_config.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/tests/fixture/tmpnet/subnet.go b/tests/fixture/tmpnet/subnet.go index 0eb1feab5f38..1cfa0dc12aa0 100644 --- a/tests/fixture/tmpnet/subnet.go +++ b/tests/fixture/tmpnet/subnet.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package tmpnet diff --git a/utils/filesystem/mock_file.go b/utils/filesystem/mock_file.go index 92b219393765..7b133025621b 100644 --- a/utils/filesystem/mock_file.go +++ b/utils/filesystem/mock_file.go @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. package filesystem From 6647ef6bf7d3e5451e4131148d98d2c5a5ba0ace Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 17 Jan 2024 16:50:58 -0500 Subject: [PATCH 259/267] Deprecate push-based peerlist gossip flags (#2625) --- config/config.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/config/config.go b/config/config.go index 5de3e70777b4..eb27ac1021d2 100644 --- a/config/config.go +++ b/config/config.go @@ -58,16 +58,20 @@ const ( ipcDeprecationMsg = "IPC API is deprecated" keystoreDeprecationMsg = "keystore API is deprecated" acceptedFrontierGossipDeprecationMsg = "push-based accepted frontier gossip is deprecated" + peerListPushGossipDeprecationMsg = "push-based peer list gossip is deprecated" ) var ( // Deprecated key --> deprecation message (i.e. which key replaces it) // TODO: deprecate "BootstrapIDsKey" and "BootstrapIPsKey" - deprecatedKeys = map[string]string{ - IpcAPIEnabledKey: ipcDeprecationMsg, - IpcsChainIDsKey: ipcDeprecationMsg, - IpcsPathKey: ipcDeprecationMsg, + commitThresholdDeprecationMsg = fmt.Sprintf("use --%s instead", SnowCommitThresholdKey) + deprecatedKeys = map[string]string{ + IpcAPIEnabledKey: ipcDeprecationMsg, + IpcsChainIDsKey: ipcDeprecationMsg, + IpcsPathKey: ipcDeprecationMsg, + KeystoreAPIEnabledKey: keystoreDeprecationMsg, + ConsensusGossipAcceptedFrontierValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, ConsensusGossipAcceptedFrontierNonValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, ConsensusGossipAcceptedFrontierPeerSizeKey: acceptedFrontierGossipDeprecationMsg, @@ -75,8 +79,13 @@ var ( ConsensusGossipOnAcceptNonValidatorSizeKey: acceptedFrontierGossipDeprecationMsg, ConsensusGossipOnAcceptPeerSizeKey: acceptedFrontierGossipDeprecationMsg, - SnowRogueCommitThresholdKey: fmt.Sprintf("use --%s instead", SnowCommitThresholdKey), - SnowVirtuousCommitThresholdKey: fmt.Sprintf("use --%s instead", SnowCommitThresholdKey), + NetworkPeerListValidatorGossipSizeKey: peerListPushGossipDeprecationMsg, + NetworkPeerListNonValidatorGossipSizeKey: peerListPushGossipDeprecationMsg, + NetworkPeerListPeersGossipSizeKey: peerListPushGossipDeprecationMsg, + NetworkPeerListGossipFreqKey: peerListPushGossipDeprecationMsg, + + SnowRogueCommitThresholdKey: commitThresholdDeprecationMsg, + SnowVirtuousCommitThresholdKey: commitThresholdDeprecationMsg, } errConflictingACPOpinion = errors.New("supporting and objecting to the same ACP") From f3561f4f82028927296006e7dc4bee058fabb681 Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:00:39 -0500 Subject: [PATCH 260/267] Remove support for compressing gzip messages (#2627) --- config/config.go | 4 + config/flags.go | 2 +- message/messages.go | 21 +-- message/messages_test.go | 187 --------------------------- message/outbound_msg_builder_test.go | 1 - utils/compression/gzip_compressor.go | 1 + utils/compression/type.go | 2 +- 7 files changed, 8 insertions(+), 210 deletions(-) diff --git a/config/config.go b/config/config.go index eb27ac1021d2..09cc32d286b5 100644 --- a/config/config.go +++ b/config/config.go @@ -109,6 +109,7 @@ var ( errCannotReadDirectory = errors.New("cannot read directory") errUnmarshalling = errors.New("unmarshalling failed") errFileDoesNotExist = errors.New("file does not exist") + errGzipDeprecatedMsg = errors.New("gzip compression is not supported, use zstd or no compression") ) func getConsensusConfig(v *viper.Viper) snowball.Parameters { @@ -346,6 +347,9 @@ func getNetworkConfig( if err != nil { return network.Config{}, err } + if compressionType == compression.TypeGzip { + return network.Config{}, errGzipDeprecatedMsg + } allowPrivateIPs := !constants.ProductionNetworkIDs.Contains(networkID) if v.IsSet(NetworkAllowPrivateIPsKey) { diff --git a/config/flags.go b/config/flags.go index 6f85fedfd33c..1cbd89dfcf8c 100644 --- a/config/flags.go +++ b/config/flags.go @@ -157,7 +157,7 @@ func addNodeFlags(fs *pflag.FlagSet) { fs.Duration(NetworkPingTimeoutKey, constants.DefaultPingPongTimeout, "Timeout value for Ping-Pong with a peer") fs.Duration(NetworkPingFrequencyKey, constants.DefaultPingFrequency, "Frequency of pinging other peers") - fs.String(NetworkCompressionTypeKey, constants.DefaultNetworkCompressionType.String(), fmt.Sprintf("Compression type for outbound messages. Must be one of [%s, %s, %s]", compression.TypeGzip, compression.TypeZstd, compression.TypeNone)) + fs.String(NetworkCompressionTypeKey, constants.DefaultNetworkCompressionType.String(), fmt.Sprintf("Compression type for outbound messages. Must be one of [%s, %s]", compression.TypeZstd, compression.TypeNone)) fs.Duration(NetworkMaxClockDifferenceKey, constants.DefaultNetworkMaxClockDifference, "Max allowed clock difference value between this node and peers") // Note: The default value is set to false here because the default diff --git a/message/messages.go b/message/messages.go index fbd3519de30d..b8b5db69e958 100644 --- a/message/messages.go +++ b/message/messages.go @@ -134,8 +134,8 @@ func (m *outboundMessage) BytesSavedCompression() int { type msgBuilder struct { log logging.Logger + // TODO: Remove gzip once v1.11.x is out. gzipCompressor compression.Compressor - gzipCompressTimeMetrics map[Op]metric.Averager gzipDecompressTimeMetrics map[Op]metric.Averager zstdCompressor compression.Compressor @@ -164,7 +164,6 @@ func newMsgBuilder( log: log, gzipCompressor: gzipCompressor, - gzipCompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), gzipDecompressTimeMetrics: make(map[Op]metric.Averager, len(ExternalOps)), zstdCompressor: zstdCompressor, @@ -176,13 +175,6 @@ func newMsgBuilder( errs := wrappers.Errs{} for _, op := range ExternalOps { - mb.gzipCompressTimeMetrics[op] = metric.NewAveragerWithErrs( - namespace, - fmt.Sprintf("gzip_%s_compress_time", op), - fmt.Sprintf("time (in ns) to compress %s messages with gzip", op), - metrics, - &errs, - ) mb.gzipDecompressTimeMetrics[op] = metric.NewAveragerWithErrs( namespace, fmt.Sprintf("gzip_%s_decompress_time", op), @@ -236,17 +228,6 @@ func (mb *msgBuilder) marshal( switch compressionType { case compression.TypeNone: return uncompressedMsgBytes, 0, op, nil - case compression.TypeGzip: - compressedBytes, err := mb.gzipCompressor.Compress(uncompressedMsgBytes) - if err != nil { - return nil, 0, 0, err - } - compressedMsg = p2p.Message{ - Message: &p2p.Message_CompressedGzip{ - CompressedGzip: compressedBytes, - }, - } - opToCompressTimeMetrics = mb.gzipCompressTimeMetrics case compression.TypeZstd: compressedBytes, err := mb.zstdCompressor.Compress(uncompressedMsgBytes) if err != nil { diff --git a/message/messages_test.go b/message/messages_test.go index b259cefa341e..27c0fb5fb646 100644 --- a/message/messages_test.go +++ b/message/messages_test.go @@ -159,23 +159,6 @@ func TestMessage(t *testing.T) { bypassThrottling: false, bytesSaved: false, }, - { - desc: "get_peer_list message with gzip compression", - op: GetPeerListOp, - msg: &p2p.Message{ - Message: &p2p.Message_GetPeerList{ - GetPeerList: &p2p.GetPeerList{ - KnownPeers: &p2p.BloomFilter{ - Filter: make([]byte, 2048), - Salt: make([]byte, 32), - }, - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: false, - bytesSaved: true, - }, { desc: "get_peer_list message with zstd compression", op: GetPeerListOp, @@ -215,28 +198,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "peer_list message with gzip compression", - op: PeerListOp, - msg: &p2p.Message{ - Message: &p2p.Message_PeerList_{ - PeerList_: &p2p.PeerList{ - ClaimedIpPorts: []*p2p.ClaimedIpPort{ - { - X509Certificate: testTLSCert.Certificate[0], - IpAddr: []byte(net.IPv6zero), - IpPort: 9651, - Timestamp: uint64(nowUnix), - Signature: compressibleContainers[0], - }, - }, - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "peer_list message with zstd compression", op: PeerListOp, @@ -291,22 +252,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "state_summary_frontier message with gzip compression", - op: StateSummaryFrontierOp, - msg: &p2p.Message{ - Message: &p2p.Message_StateSummaryFrontier_{ - StateSummaryFrontier_: &p2p.StateSummaryFrontier{ - ChainId: testID[:], - RequestId: 1, - Summary: compressibleContainers[0], - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "state_summary_frontier message with zstd compression", op: StateSummaryFrontierOp, @@ -340,23 +285,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "get_accepted_state_summary message with gzip compression", - op: GetAcceptedStateSummaryOp, - msg: &p2p.Message{ - Message: &p2p.Message_GetAcceptedStateSummary{ - GetAcceptedStateSummary: &p2p.GetAcceptedStateSummary{ - ChainId: testID[:], - RequestId: 1, - Deadline: 1, - Heights: []uint64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: false, - }, { desc: "get_accepted_state_summary message with zstd compression", op: GetAcceptedStateSummaryOp, @@ -390,22 +318,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "accepted_state_summary message with gzip compression", - op: AcceptedStateSummaryOp, - msg: &p2p.Message{ - Message: &p2p.Message_AcceptedStateSummary_{ - AcceptedStateSummary_: &p2p.AcceptedStateSummary{ - ChainId: testID[:], - RequestId: 1, - SummaryIds: [][]byte{testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:], testID[:]}, - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "accepted_state_summary message with zstd compression", op: AcceptedStateSummaryOp, @@ -523,22 +435,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "ancestors message with gzip compression", - op: AncestorsOp, - msg: &p2p.Message{ - Message: &p2p.Message_Ancestors_{ - Ancestors_: &p2p.Ancestors{ - ChainId: testID[:], - RequestId: 12345, - Containers: compressibleContainers, - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "ancestors message with zstd compression", op: AncestorsOp, @@ -590,23 +486,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "put message with gzip compression", - op: PutOp, - msg: &p2p.Message{ - Message: &p2p.Message_Put{ - Put: &p2p.Put{ - ChainId: testID[:], - RequestId: 1, - Container: compressibleContainers[0], - EngineType: p2p.EngineType_ENGINE_TYPE_AVALANCHE, - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "put message with zstd compression", op: PutOp, @@ -642,24 +521,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "push_query message with gzip compression", - op: PushQueryOp, - msg: &p2p.Message{ - Message: &p2p.Message_PushQuery{ - PushQuery: &p2p.PushQuery{ - ChainId: testID[:], - RequestId: 1, - Deadline: 1, - Container: compressibleContainers[0], - EngineType: p2p.EngineType_ENGINE_TYPE_AVALANCHE, - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "push_query message with zstd compression", op: PushQueryOp, @@ -729,23 +590,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "app_request message with gzip compression", - op: AppRequestOp, - msg: &p2p.Message{ - Message: &p2p.Message_AppRequest{ - AppRequest: &p2p.AppRequest{ - ChainId: testID[:], - RequestId: 1, - Deadline: 1, - AppBytes: compressibleContainers[0], - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "app_request message with zstd compression", op: AppRequestOp, @@ -779,22 +623,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "app_response message with gzip compression", - op: AppResponseOp, - msg: &p2p.Message{ - Message: &p2p.Message_AppResponse{ - AppResponse: &p2p.AppResponse{ - ChainId: testID[:], - RequestId: 1, - AppBytes: compressibleContainers[0], - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "app_response message with zstd compression", op: AppResponseOp, @@ -826,21 +654,6 @@ func TestMessage(t *testing.T) { bypassThrottling: true, bytesSaved: false, }, - { - desc: "app_gossip message with gzip compression", - op: AppGossipOp, - msg: &p2p.Message{ - Message: &p2p.Message_AppGossip{ - AppGossip: &p2p.AppGossip{ - ChainId: testID[:], - AppBytes: compressibleContainers[0], - }, - }, - }, - compressionType: compression.TypeGzip, - bypassThrottling: true, - bytesSaved: true, - }, { desc: "app_gossip message with zstd compression", op: AppGossipOp, diff --git a/message/outbound_msg_builder_test.go b/message/outbound_msg_builder_test.go index 1b6895f3f52c..39d22442b0a4 100644 --- a/message/outbound_msg_builder_test.go +++ b/message/outbound_msg_builder_test.go @@ -29,7 +29,6 @@ func Test_newOutboundBuilder(t *testing.T) { for _, compressionType := range []compression.Type{ compression.TypeNone, - compression.TypeGzip, compression.TypeZstd, } { t.Run(compressionType.String(), func(t *testing.T) { diff --git a/utils/compression/gzip_compressor.go b/utils/compression/gzip_compressor.go index 90067512a771..da0b941a47a1 100644 --- a/utils/compression/gzip_compressor.go +++ b/utils/compression/gzip_compressor.go @@ -21,6 +21,7 @@ var ( ErrMsgTooLarge = errors.New("msg too large to be compressed") ) +// TODO: Remove once v1.11.x is out. type gzipCompressor struct { maxSize int64 gzipWriterPool sync.Pool diff --git a/utils/compression/type.go b/utils/compression/type.go index 6af0cf75407d..09b4d64c33ea 100644 --- a/utils/compression/type.go +++ b/utils/compression/type.go @@ -14,7 +14,7 @@ type Type byte const ( TypeNone Type = iota + 1 - TypeGzip + TypeGzip // Remove once v1.11.x is out. TypeZstd ) From d3d1b114cebd2d675adb81720431707b467fa40f Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:17:13 -0500 Subject: [PATCH 261/267] Always attempt to install mockgen `v0.4.0` before execution (#2628) --- scripts/mock.gen.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/scripts/mock.gen.sh b/scripts/mock.gen.sh index 75997d18b86e..16b00a42a569 100755 --- a/scripts/mock.gen.sh +++ b/scripts/mock.gen.sh @@ -7,12 +7,8 @@ if ! [[ "$0" =~ scripts/mock.gen.sh ]]; then exit 255 fi -if ! command -v mockgen &> /dev/null -then - echo "mockgen not found, installing..." - # https://github.com/uber-go/mock - go install -v go.uber.org/mock/mockgen@v0.4.0 -fi +# https://github.com/uber-go/mock +go install -v go.uber.org/mock/mockgen@v0.4.0 source ./scripts/constants.sh From f5884bb413ffa19987302df44cfe34f738d93fdf Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jan 2024 13:34:21 -0500 Subject: [PATCH 262/267] Modify TLS parsing rules for Durango (#2458) Signed-off-by: Stephen Buttolph Co-authored-by: Filippo Valsorda --- indexer/examples/p-chain/main.go | 3 +- indexer/examples/x-chain-blocks/main.go | 3 +- network/network.go | 10 +- network/peer/peer.go | 18 ++- network/peer/test_peer.go | 1 + network/peer/upgrader.go | 36 ++--- staking/asn1.go | 28 +++- staking/certificate.go | 10 +- staking/large_rsa_key.sig | Bin 2048 -> 0 bytes staking/parse.go | 172 +++++++++++++++++++++++- staking/parse_test.go | 89 ++++++++++++ staking/verify.go | 39 ++---- staking/verify_test.go | 30 ----- vms/proposervm/batched_vm.go | 2 +- vms/proposervm/block/block.go | 15 ++- vms/proposervm/block/build.go | 9 +- vms/proposervm/block/option.go | 4 +- vms/proposervm/block/parse.go | 9 +- vms/proposervm/block/parse_test.go | 56 +++++--- vms/proposervm/state/block_state.go | 7 +- vms/proposervm/vm.go | 2 +- 21 files changed, 422 insertions(+), 121 deletions(-) delete mode 100644 staking/large_rsa_key.sig create mode 100644 staking/parse_test.go delete mode 100644 staking/verify_test.go diff --git a/indexer/examples/p-chain/main.go b/indexer/examples/p-chain/main.go index 9f8966d21546..80f0e1aeed8e 100644 --- a/indexer/examples/p-chain/main.go +++ b/indexer/examples/p-chain/main.go @@ -10,6 +10,7 @@ import ( "time" "github.com/ava-labs/avalanchego/indexer" + "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/wallet/subnet/primary" platformvmblock "github.com/ava-labs/avalanchego/vms/platformvm/block" @@ -34,7 +35,7 @@ func main() { } platformvmBlockBytes := container.Bytes - proposerVMBlock, err := proposervmblock.Parse(container.Bytes) + proposerVMBlock, err := proposervmblock.Parse(container.Bytes, version.DefaultUpgradeTime) if err == nil { platformvmBlockBytes = proposerVMBlock.Block() } diff --git a/indexer/examples/x-chain-blocks/main.go b/indexer/examples/x-chain-blocks/main.go index 92c5f7ad34e7..e25693b62998 100644 --- a/indexer/examples/x-chain-blocks/main.go +++ b/indexer/examples/x-chain-blocks/main.go @@ -10,6 +10,7 @@ import ( "time" "github.com/ava-labs/avalanchego/indexer" + "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary" @@ -32,7 +33,7 @@ func main() { continue } - proposerVMBlock, err := block.Parse(container.Bytes) + proposerVMBlock, err := block.Parse(container.Bytes, version.DefaultUpgradeTime) if err != nil { log.Fatalf("failed to parse proposervm block: %s\n", err) } diff --git a/network/network.go b/network/network.go index 51c2d223829e..1e13ed45b9c2 100644 --- a/network/network.go +++ b/network/network.go @@ -273,6 +273,12 @@ func NewNetwork( IPSigner: peer.NewIPSigner(config.MyIPPort, config.TLSKey), } + // Invariant: We delay the activation of durango during the TLS handshake to + // avoid gossiping any TLS certs that anyone else in the network may + // consider invalid. Recall that if a peer gossips an invalid cert, the + // connection is terminated. + durangoTime := version.GetDurangoTime(config.NetworkID) + durangoTimeWithClockSkew := durangoTime.Add(config.MaxClockDifference) onCloseCtx, cancel := context.WithCancel(context.Background()) n := &network{ config: config, @@ -283,8 +289,8 @@ func NewNetwork( inboundConnUpgradeThrottler: throttling.NewInboundConnUpgradeThrottler(log, config.ThrottlerConfig.InboundConnUpgradeThrottlerConfig), listener: listener, dialer: dialer, - serverUpgrader: peer.NewTLSServerUpgrader(config.TLSConfig, metrics.tlsConnRejected), - clientUpgrader: peer.NewTLSClientUpgrader(config.TLSConfig, metrics.tlsConnRejected), + serverUpgrader: peer.NewTLSServerUpgrader(config.TLSConfig, metrics.tlsConnRejected, durangoTimeWithClockSkew), + clientUpgrader: peer.NewTLSClientUpgrader(config.TLSConfig, metrics.tlsConnRejected, durangoTimeWithClockSkew), onCloseCtx: onCloseCtx, onCloseCtxCancel: cancel, diff --git a/network/peer/peer.go b/network/peer/peer.go index db2cb5485b04..403bea5220ba 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -1194,10 +1194,22 @@ func (p *peer) handlePeerList(msg *p2p.PeerList) { close(p.onFinishHandshake) } - // the peers this peer told us about - discoveredIPs := make([]*ips.ClaimedIPPort, len(msg.ClaimedIpPorts)) + // Invariant: We do not account for clock skew here, as the sender of the + // certificate is expected to account for clock skew during the activation + // of Durango. + durangoTime := version.GetDurangoTime(p.NetworkID) + beforeDurango := time.Now().Before(durangoTime) + discoveredIPs := make([]*ips.ClaimedIPPort, len(msg.ClaimedIpPorts)) // the peers this peer told us about for i, claimedIPPort := range msg.ClaimedIpPorts { - tlsCert, err := staking.ParseCertificate(claimedIPPort.X509Certificate) + var ( + tlsCert *staking.Certificate + err error + ) + if beforeDurango { + tlsCert, err = staking.ParseCertificate(claimedIPPort.X509Certificate) + } else { + tlsCert, err = staking.ParseCertificatePermissive(claimedIPPort.X509Certificate) + } if err != nil { p.Log.Debug("message with invalid field", zap.Stringer("nodeID", p.id), diff --git a/network/peer/test_peer.go b/network/peer/test_peer.go index 7bd58344ab86..04cfd93aaa7a 100644 --- a/network/peer/test_peer.go +++ b/network/peer/test_peer.go @@ -65,6 +65,7 @@ func StartTestPeer( clientUpgrader := NewTLSClientUpgrader( tlsConfg, prometheus.NewCounter(prometheus.CounterOpts{}), + version.GetDurangoTime(networkID), ) peerID, conn, cert, err := clientUpgrader.Upgrade(conn) diff --git a/network/peer/upgrader.go b/network/peer/upgrader.go index dd973af1b825..9341922175cd 100644 --- a/network/peer/upgrader.go +++ b/network/peer/upgrader.go @@ -7,6 +7,7 @@ import ( "crypto/tls" "errors" "net" + "time" "github.com/prometheus/client_golang/prometheus" @@ -29,36 +30,40 @@ type Upgrader interface { type tlsServerUpgrader struct { config *tls.Config invalidCerts prometheus.Counter + durangoTime time.Time } -func NewTLSServerUpgrader(config *tls.Config, invalidCerts prometheus.Counter) Upgrader { +func NewTLSServerUpgrader(config *tls.Config, invalidCerts prometheus.Counter, durangoTime time.Time) Upgrader { return &tlsServerUpgrader{ config: config, invalidCerts: invalidCerts, + durangoTime: durangoTime, } } func (t *tlsServerUpgrader) Upgrade(conn net.Conn) (ids.NodeID, net.Conn, *staking.Certificate, error) { - return connToIDAndCert(tls.Server(conn, t.config), t.invalidCerts) + return connToIDAndCert(tls.Server(conn, t.config), t.invalidCerts, t.durangoTime) } type tlsClientUpgrader struct { config *tls.Config invalidCerts prometheus.Counter + durangoTime time.Time } -func NewTLSClientUpgrader(config *tls.Config, invalidCerts prometheus.Counter) Upgrader { +func NewTLSClientUpgrader(config *tls.Config, invalidCerts prometheus.Counter, durangoTime time.Time) Upgrader { return &tlsClientUpgrader{ config: config, invalidCerts: invalidCerts, + durangoTime: durangoTime, } } func (t *tlsClientUpgrader) Upgrade(conn net.Conn) (ids.NodeID, net.Conn, *staking.Certificate, error) { - return connToIDAndCert(tls.Client(conn, t.config), t.invalidCerts) + return connToIDAndCert(tls.Client(conn, t.config), t.invalidCerts, t.durangoTime) } -func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter) (ids.NodeID, net.Conn, *staking.Certificate, error) { +func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter, durangoTime time.Time) (ids.NodeID, net.Conn, *staking.Certificate, error) { if err := conn.Handshake(); err != nil { return ids.EmptyNodeID, nil, nil, err } @@ -72,17 +77,18 @@ func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter) (ids.NodeI // Invariant: ParseCertificate is used rather than CertificateFromX509 to // ensure that signature verification can assume the certificate was // parseable according the staking package's parser. - peerCert, err := staking.ParseCertificate(tlsCert.Raw) - if err != nil { - invalidCerts.Inc() - return ids.EmptyNodeID, nil, nil, err + // + // TODO: Remove pre-Durango parsing after v1.11.x has activated. + var ( + peerCert *staking.Certificate + err error + ) + if time.Now().Before(durangoTime) { + peerCert, err = staking.ParseCertificate(tlsCert.Raw) + } else { + peerCert, err = staking.ParseCertificatePermissive(tlsCert.Raw) } - - // We validate the certificate here to attempt to make the validity of the - // peer certificate as clear as possible. Specifically, a node running a - // prior version using an invalid certificate should not be able to report - // healthy. - if err := staking.ValidateCertificate(peerCert); err != nil { + if err != nil { invalidCerts.Inc() return ids.EmptyNodeID, nil, nil, err } diff --git a/staking/asn1.go b/staking/asn1.go index a21ebc7ff88c..afd817a95cd6 100644 --- a/staking/asn1.go +++ b/staking/asn1.go @@ -6,6 +6,7 @@ package staking import ( "crypto" "crypto/x509" + "encoding/asn1" "fmt" // Explicitly import for the crypto.RegisterHash init side-effects. @@ -14,11 +15,28 @@ import ( _ "crypto/sha256" ) -// Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/x509.go#L326-L350 -var signatureAlgorithmVerificationDetails = map[x509.SignatureAlgorithm]x509.PublicKeyAlgorithm{ - x509.SHA256WithRSA: x509.RSA, - x509.ECDSAWithSHA256: x509.ECDSA, -} +var ( + // Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/x509.go#L433-L452 + // + // RFC 3279, 2.3 Public Key Algorithms + // + // pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840) + // rsadsi(113549) pkcs(1) 1 } + // + // rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 } + oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} + // RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters + // + // id-ecPublicKey OBJECT IDENTIFIER ::= { + // iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } + oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} + + // Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/x509.go#L326-L350 + signatureAlgorithmVerificationDetails = map[x509.SignatureAlgorithm]x509.PublicKeyAlgorithm{ + x509.SHA256WithRSA: x509.RSA, + x509.ECDSAWithSHA256: x509.ECDSA, + } +) func init() { if !crypto.SHA256.Available() { diff --git a/staking/certificate.go b/staking/certificate.go index 53d86a748b97..b3e1a511f63f 100644 --- a/staking/certificate.go +++ b/staking/certificate.go @@ -3,11 +3,15 @@ package staking -import "crypto/x509" +import ( + "crypto" + "crypto/x509" +) type Certificate struct { - Raw []byte - PublicKey any + Raw []byte + PublicKey crypto.PublicKey + // TODO: Remove after v1.11.x activates. SignatureAlgorithm x509.SignatureAlgorithm } diff --git a/staking/large_rsa_key.sig b/staking/large_rsa_key.sig deleted file mode 100644 index 61000a9903cfd642fa3130da4f85881ebfb8f43e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2048 zcmV+b2>kPMVuz>0LLX_JB4Rxwmf~~%Xw^SRfM5v=gT;&2{tAvS z&O$y_2aS0G99O-y1k5Oec>Hu<7Hr$#jb;mzA1H*Tf4k27Ev;(6qmT-SH(^6Q_Rk6z za}FHoL|idFRi1%V;NVb3Pw&?fyV8L= zpJT}YinNNgD5NY-jR|!}ppH2C+koCkaRDk}84mQlqWbEedTv@Udl~=c3rtg3QBipd zO;?M=oD2#x+u!QAbN_SPi3ZyBmKVkuJHig+Sn$gL%tvK&GLu`LlK(Lsis@}aQotXM zJFI6KjfN~!1-w8xW~|rYd*Xw5 zOQ<6&uxML+s!3(bhh%zz5>21CjDNc#=Wo0?{2e|Hx=2&ukrrW1EinylkOg&Q(8N4W zNNgD9PRI+aEtCqBvS2>5B6=UOdEc7BQ!X50UN4N;V2XHg-$}Z;9CqrB~`69czr#EWp_Rr+)}^Z zOT-#SO|l<-5PA5xXnr0-7i*pWW_!l$I6W#`Q1u_)C-vh*Gq6?OnUW=6+4Sdg!0m1p zO0HNtA;#%ar=DojUB$IyFh zrAw;&iB=z>{af@Z91`)tR>MbeQ)y^00_l{y4|kga2`Bwb;5WcZfJ{BvU!J+zXIRrz znLfmeoQ+t+-$=t9v!hZlI2Q{{spvAv^Aq|oW7#omms1(2P$m^_RPkm+Mt1E=7DOk2 zEb$Yzw6k5Su6%piX!4bfEwdI3N zC9)q2)-y&+X#sA0FnmkNB0oJK^_0SeKmeDpq)^xJgx+t8=T*R+FY-jL$KJeme z3}71OA6zNg*&_`IMpZ&8-kZ25k-o$6q_n@J@spb~ndhKwAf$W)&vJUA&W_fENvMDE z29}#=&0WV z2Z|Uh0804pu1`6n?POSXz?11Wwmhe9XKl8^ZUZ@j^9@)fo5+x~L$+884XR#C_rwZ2Gt{fQaD%fjffSd=gCrrn^eOsJ5gyGUruECTQB^=-NC z6L_kjWzC=4Og%E!&qy6_tE5W3o)LQd^)8*xs#0|6Axrjgdr@`h53JLtete6HgXedgfeNn^pEmpQmj%aWDM-(9HVO-O!vX|nY;E-?GJ_z zjyI_@2>FR-Fq~+4?>jB0LWc#vBREpe`6lF|j@E`s1!KI!MO> zwJhKbDjyXke`W(QSn7fUYB1+nEzI${6V@!+>q%^+>0>cT{z+2}=XLmnG+IJc z)|QdFLS+EHJ6aPWVcHd#$O(tD_agBWyO@()+RA83UfBv`rR@=fk;tw@2fcGCq(PUb zAQE__HZY{qUY)-JR8i|~nmL6AU0r%sg5B8CSVTvH_djo`?-%2lOqzZdraAWkBCHJw~;aftx{U6XvSYt1J7r%)if*DY7KNOnzkHw4v*$<0>}NpL4k zE{hUQVd=u9V41E9g(IKQIoycing7Jwiv6^MbKFb3$o0$yMuKc_OWAIXUdgF>-KNo| zULv0~ufVqWpRYe?{OSG969^}SAxiSe1dEtakosm;HM8L+>DDqkxOf#zW0EV$5ErJQ za&IPh-{VBqh6@iKN%0}LFlfpsFswL|HjC)~irI)~A6XpCq^2rZz}EByGCir^JRWhL zp>IJoXw4`PZa$iEds?lDuEC@Zc0+lnhlFT>2q4(c?B%2F12a0)0FuNNSBcKcae5zjO%6nkiYI|L0=Y1j-^{G)NdIeBu|MWA+Rg)7Ef& zwWza$ZE`(uO{e4FmFvA652$jt~!iDqGxkW$v8C*27U$419&Ufyx=Fx?; z3)rUcLQpTw&9@if5fbkgc$Y1GI)h=3&b7hhTFv&fl0U-4IhZb#78{iDrA(U`kGhc5 eShhHiq3tib1FXJZIB*UCvmaBS&ZT&-Cn|XI>E;#y diff --git a/staking/parse.go b/staking/parse.go index 6de6b63dd4dd..fd21c3cbe38e 100644 --- a/staking/parse.go +++ b/staking/parse.go @@ -3,13 +3,179 @@ package staking -import "crypto/x509" +import ( + "crypto" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rsa" + "crypto/x509" + "encoding/asn1" + "errors" + "fmt" + "math/big" + + "golang.org/x/crypto/cryptobyte" + + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" + + "github.com/ava-labs/avalanchego/utils/units" +) + +const ( + MaxCertificateLen = 2 * units.KiB + + allowedRSASmallModulusLen = 2048 + allowedRSALargeModulusLen = 4096 + allowedRSAPublicExponentValue = 65537 +) + +var ( + ErrCertificateTooLarge = fmt.Errorf("staking: certificate length is greater than %d", MaxCertificateLen) + ErrMalformedCertificate = errors.New("staking: malformed certificate") + ErrMalformedTBSCertificate = errors.New("staking: malformed tbs certificate") + ErrMalformedVersion = errors.New("staking: malformed version") + ErrMalformedSerialNumber = errors.New("staking: malformed serial number") + ErrMalformedSignatureAlgorithmIdentifier = errors.New("staking: malformed signature algorithm identifier") + ErrMalformedIssuer = errors.New("staking: malformed issuer") + ErrMalformedValidity = errors.New("staking: malformed validity") + ErrMalformedSPKI = errors.New("staking: malformed spki") + ErrMalformedPublicKeyAlgorithmIdentifier = errors.New("staking: malformed public key algorithm identifier") + ErrMalformedSubjectPublicKey = errors.New("staking: malformed subject public key") + ErrMalformedOID = errors.New("staking: malformed oid") + ErrInvalidRSAPublicKey = errors.New("staking: invalid RSA public key") + ErrInvalidRSAModulus = errors.New("staking: invalid RSA modulus") + ErrInvalidRSAPublicExponent = errors.New("staking: invalid RSA public exponent") + ErrRSAModulusNotPositive = errors.New("staking: RSA modulus is not a positive number") + ErrUnsupportedRSAModulusBitLen = errors.New("staking: unsupported RSA modulus bitlen") + ErrRSAModulusIsEven = errors.New("staking: RSA modulus is an even number") + ErrUnsupportedRSAPublicExponent = errors.New("staking: unsupported RSA public exponent") + ErrFailedUnmarshallingEllipticCurvePoint = errors.New("staking: failed to unmarshal elliptic curve point") + ErrUnknownPublicKeyAlgorithm = errors.New("staking: unknown public key algorithm") +) // ParseCertificate parses a single certificate from the given ASN.1 DER data. +// +// TODO: Remove after v1.11.x activates. func ParseCertificate(der []byte) (*Certificate, error) { - cert, err := x509.ParseCertificate(der) + x509Cert, err := x509.ParseCertificate(der) if err != nil { return nil, err } - return CertificateFromX509(cert), nil + stakingCert := CertificateFromX509(x509Cert) + return stakingCert, ValidateCertificate(stakingCert) +} + +// ParseCertificatePermissive parses a single certificate from the given ASN.1. +// +// This function does not validate that the certificate is valid to be used +// against normal TLS implementations. +// +// Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/parser.go#L789-L968 +func ParseCertificatePermissive(bytes []byte) (*Certificate, error) { + if len(bytes) > MaxCertificateLen { + return nil, ErrCertificateTooLarge + } + + input := cryptobyte.String(bytes) + // Consume the length and tag bytes. + if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) { + return nil, ErrMalformedCertificate + } + + // Read the "to be signed" certificate into input. + if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) { + return nil, ErrMalformedTBSCertificate + } + if !input.SkipOptionalASN1(cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) { + return nil, ErrMalformedVersion + } + if !input.SkipASN1(cryptobyte_asn1.INTEGER) { + return nil, ErrMalformedSerialNumber + } + if !input.SkipASN1(cryptobyte_asn1.SEQUENCE) { + return nil, ErrMalformedSignatureAlgorithmIdentifier + } + if !input.SkipASN1(cryptobyte_asn1.SEQUENCE) { + return nil, ErrMalformedIssuer + } + if !input.SkipASN1(cryptobyte_asn1.SEQUENCE) { + return nil, ErrMalformedValidity + } + if !input.SkipASN1(cryptobyte_asn1.SEQUENCE) { + return nil, ErrMalformedIssuer + } + + // Read the "subject public key info" into input. + if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) { + return nil, ErrMalformedSPKI + } + + // Read the public key algorithm identifier. + var pkAISeq cryptobyte.String + if !input.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) { + return nil, ErrMalformedPublicKeyAlgorithmIdentifier + } + var pkAI asn1.ObjectIdentifier + if !pkAISeq.ReadASN1ObjectIdentifier(&pkAI) { + return nil, ErrMalformedOID + } + + // Note: Unlike the x509 package, we require parsing the public key. + + var spk asn1.BitString + if !input.ReadASN1BitString(&spk) { + return nil, ErrMalformedSubjectPublicKey + } + publicKey, signatureAlgorithm, err := parsePublicKey(pkAI, spk) + return &Certificate{ + Raw: bytes, + SignatureAlgorithm: signatureAlgorithm, + PublicKey: publicKey, + }, err +} + +// Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/parser.go#L215-L306 +func parsePublicKey(oid asn1.ObjectIdentifier, publicKey asn1.BitString) (crypto.PublicKey, x509.SignatureAlgorithm, error) { + der := cryptobyte.String(publicKey.RightAlign()) + switch { + case oid.Equal(oidPublicKeyRSA): + pub := &rsa.PublicKey{N: new(big.Int)} + if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) { + return nil, 0, ErrInvalidRSAPublicKey + } + if !der.ReadASN1Integer(pub.N) { + return nil, 0, ErrInvalidRSAModulus + } + if !der.ReadASN1Integer(&pub.E) { + return nil, 0, ErrInvalidRSAPublicExponent + } + + if pub.N.Sign() <= 0 { + return nil, 0, ErrRSAModulusNotPositive + } + + if bitLen := pub.N.BitLen(); bitLen != allowedRSALargeModulusLen && bitLen != allowedRSASmallModulusLen { + return nil, 0, fmt.Errorf("%w: %d", ErrUnsupportedRSAModulusBitLen, bitLen) + } + if pub.N.Bit(0) == 0 { + return nil, 0, ErrRSAModulusIsEven + } + if pub.E != allowedRSAPublicExponentValue { + return nil, 0, fmt.Errorf("%w: %d", ErrUnsupportedRSAPublicExponent, pub.E) + } + return pub, x509.SHA256WithRSA, nil + case oid.Equal(oidPublicKeyECDSA): + namedCurve := elliptic.P256() + x, y := elliptic.Unmarshal(namedCurve, der) + if x == nil { + return nil, 0, ErrFailedUnmarshallingEllipticCurvePoint + } + return &ecdsa.PublicKey{ + Curve: namedCurve, + X: x, + Y: y, + }, x509.ECDSAWithSHA256, nil + default: + return nil, 0, ErrUnknownPublicKeyAlgorithm + } } diff --git a/staking/parse_test.go b/staking/parse_test.go new file mode 100644 index 000000000000..e9006e4ddcc0 --- /dev/null +++ b/staking/parse_test.go @@ -0,0 +1,89 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package staking + +import ( + "testing" + + _ "embed" + + "github.com/stretchr/testify/require" +) + +var ( + //go:embed large_rsa_key.cert + largeRSAKeyCert []byte + + parsers = []struct { + name string + parse func([]byte) (*Certificate, error) + }{ + { + name: "ParseCertificate", + parse: ParseCertificate, + }, + { + name: "ParseCertificatePermissive", + parse: ParseCertificatePermissive, + }, + } +) + +func TestParseCheckLargeCert(t *testing.T) { + for _, parser := range parsers { + t.Run(parser.name, func(t *testing.T) { + _, err := parser.parse(largeRSAKeyCert) + require.ErrorIs(t, err, ErrCertificateTooLarge) + }) + } +} + +func BenchmarkParse(b *testing.B) { + tlsCert, err := NewTLSCert() + require.NoError(b, err) + + bytes := tlsCert.Leaf.Raw + for _, parser := range parsers { + b.Run(parser.name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, err = parser.parse(bytes) + require.NoError(b, err) + } + }) + } +} + +func FuzzParseCertificate(f *testing.F) { + tlsCert, err := NewTLSCert() + require.NoError(f, err) + + f.Add(tlsCert.Leaf.Raw) + f.Add(largeRSAKeyCert) + f.Fuzz(func(t *testing.T, certBytes []byte) { + require := require.New(t) + + // Verify that any certificate that can be parsed by ParseCertificate + // can also be parsed by ParseCertificatePermissive. + { + strictCert, err := ParseCertificate(certBytes) + if err == nil { + permissiveCert, err := ParseCertificatePermissive(certBytes) + require.NoError(err) + require.Equal(strictCert, permissiveCert) + } + } + + // Verify that any certificate that can't be parsed by + // ParseCertificatePermissive also can't be parsed by ParseCertificate. + { + cert, err := ParseCertificatePermissive(certBytes) + if err == nil { + require.NoError(ValidateCertificate(cert)) + } else { + _, err = ParseCertificate(certBytes) + require.Error(err) //nolint:forbidigo + } + } + }) +} diff --git a/staking/verify.go b/staking/verify.go index 5fc8d77278e1..dd4255455ff0 100644 --- a/staking/verify.go +++ b/staking/verify.go @@ -11,28 +11,13 @@ import ( "crypto/x509" "errors" "fmt" - - "github.com/ava-labs/avalanchego/utils/units" -) - -// MaxRSAKeyBitLen is the maximum RSA key size in bits that we are willing to -// parse. -// -// https://github.com/golang/go/blob/go1.19.12/src/crypto/tls/handshake_client.go#L860-L862 -const ( - MaxCertificateLen = 16 * units.KiB - MaxRSAKeyByteLen = units.KiB - MaxRSAKeyBitLen = 8 * MaxRSAKeyByteLen ) var ( - ErrCertificateTooLarge = fmt.Errorf("staking: certificate length is greater than %d", MaxCertificateLen) - ErrUnsupportedAlgorithm = errors.New("staking: cannot verify signature: unsupported algorithm") - ErrPublicKeyAlgoMismatch = errors.New("staking: signature algorithm specified different public key type") - ErrInvalidRSAPublicKey = errors.New("staking: invalid RSA public key") - ErrInvalidECDSAPublicKey = errors.New("staking: invalid ECDSA public key") - ErrECDSAVerificationFailure = errors.New("staking: ECDSA verification failure") - ErrED25519VerificationFailure = errors.New("staking: Ed25519 verification failure") + ErrUnsupportedAlgorithm = errors.New("staking: cannot verify signature: unsupported algorithm") + ErrPublicKeyAlgoMismatch = errors.New("staking: signature algorithm specified different public key type") + ErrInvalidECDSAPublicKey = errors.New("staking: invalid ECDSA public key") + ErrECDSAVerificationFailure = errors.New("staking: ECDSA verification failure") ) // CheckSignature verifies that the signature is a valid signature over signed @@ -41,10 +26,6 @@ var ( // Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/x509.go#L793-L797 // Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/x509.go#L816-L879 func CheckSignature(cert *Certificate, msg []byte, signature []byte) error { - if err := ValidateCertificate(cert); err != nil { - return err - } - hasher := crypto.SHA256.New() _, err := hasher.Write(msg) if err != nil { @@ -67,6 +48,8 @@ func CheckSignature(cert *Certificate, msg []byte, signature []byte) error { // ValidateCertificate verifies that this certificate conforms to the required // staking format assuming that it was already able to be parsed. +// +// TODO: Remove after v1.11.x activates. func ValidateCertificate(cert *Certificate) error { if len(cert.Raw) > MaxCertificateLen { return ErrCertificateTooLarge @@ -82,8 +65,14 @@ func ValidateCertificate(cert *Certificate) error { if pubkeyAlgo != x509.RSA { return signaturePublicKeyAlgoMismatchError(pubkeyAlgo, pub) } - if bitLen := pub.N.BitLen(); bitLen > MaxRSAKeyBitLen { - return fmt.Errorf("%w: bitLen=%d > maxBitLen=%d", ErrInvalidRSAPublicKey, bitLen, MaxRSAKeyBitLen) + if bitLen := pub.N.BitLen(); bitLen != allowedRSALargeModulusLen && bitLen != allowedRSASmallModulusLen { + return fmt.Errorf("%w: %d", ErrUnsupportedRSAModulusBitLen, bitLen) + } + if pub.N.Bit(0) == 0 { + return ErrRSAModulusIsEven + } + if pub.E != allowedRSAPublicExponentValue { + return fmt.Errorf("%w: %d", ErrUnsupportedRSAPublicExponent, pub.E) } return nil case *ecdsa.PublicKey: diff --git a/staking/verify_test.go b/staking/verify_test.go deleted file mode 100644 index 7fcf0ba8d624..000000000000 --- a/staking/verify_test.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package staking - -import ( - "testing" - - _ "embed" - - "github.com/stretchr/testify/require" -) - -var ( - //go:embed large_rsa_key.cert - largeRSAKeyCert []byte - //go:embed large_rsa_key.sig - largeRSAKeySig []byte -) - -func TestCheckSignatureLargePublicKey(t *testing.T) { - require := require.New(t) - - cert, err := ParseCertificate(largeRSAKeyCert) - require.NoError(err) - - msg := []byte("TODO: put something clever") - err = CheckSignature(cert, msg, largeRSAKeySig) - require.ErrorIs(err, ErrInvalidRSAPublicKey) -} diff --git a/vms/proposervm/batched_vm.go b/vms/proposervm/batched_vm.go index ff1ce6a597a0..0bf514827193 100644 --- a/vms/proposervm/batched_vm.go +++ b/vms/proposervm/batched_vm.go @@ -101,7 +101,7 @@ func (vm *VM) BatchedParseBlock(ctx context.Context, blks [][]byte) ([]snowman.B ) for ; blocksIndex < len(blks); blocksIndex++ { blkBytes := blks[blocksIndex] - statelessBlock, err := statelessblock.Parse(blkBytes) + statelessBlock, err := statelessblock.Parse(blkBytes, vm.DurangoTime) if err != nil { break } diff --git a/vms/proposervm/block/block.go b/vms/proposervm/block/block.go index fccbbe2e3718..0f5b374391f7 100644 --- a/vms/proposervm/block/block.go +++ b/vms/proposervm/block/block.go @@ -28,7 +28,7 @@ type Block interface { Block() []byte Bytes() []byte - initialize(bytes []byte) error + initialize(bytes []byte, durangoTime time.Time) error } type SignedBlock interface { @@ -76,7 +76,7 @@ func (b *statelessBlock) Bytes() []byte { return b.bytes } -func (b *statelessBlock) initialize(bytes []byte) error { +func (b *statelessBlock) initialize(bytes []byte, durangoTime time.Time) error { b.bytes = bytes // The serialized form of the block is the unsignedBytes followed by the @@ -91,13 +91,18 @@ func (b *statelessBlock) initialize(bytes []byte) error { return nil } - cert, err := staking.ParseCertificate(b.StatelessBlock.Certificate) + // TODO: Remove durangoTime after v1.11.x has activated. + var err error + if b.timestamp.Before(durangoTime) { + b.cert, err = staking.ParseCertificate(b.StatelessBlock.Certificate) + } else { + b.cert, err = staking.ParseCertificatePermissive(b.StatelessBlock.Certificate) + } if err != nil { return fmt.Errorf("%w: %w", errInvalidCertificate, err) } - b.cert = cert - b.proposer = ids.NodeIDFromCert(cert) + b.proposer = ids.NodeIDFromCert(b.cert) return nil } diff --git a/vms/proposervm/block/build.go b/vms/proposervm/block/build.go index 7baa89205342..b13255c91dd1 100644 --- a/vms/proposervm/block/build.go +++ b/vms/proposervm/block/build.go @@ -35,7 +35,10 @@ func BuildUnsigned( if err != nil { return nil, err } - return block, block.initialize(bytes) + + // Invariant: The durango timestamp isn't used here because the certificate + // is empty. + return block, block.initialize(bytes, time.Time{}) } func Build( @@ -121,5 +124,7 @@ func BuildOption( if err != nil { return nil, err } - return block, block.initialize(bytes) + + // Invariant: The durango timestamp isn't used. + return block, block.initialize(bytes, time.Time{}) } diff --git a/vms/proposervm/block/option.go b/vms/proposervm/block/option.go index c80651b621fc..7edb39bd429f 100644 --- a/vms/proposervm/block/option.go +++ b/vms/proposervm/block/option.go @@ -4,6 +4,8 @@ package block import ( + "time" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/hashing" ) @@ -32,7 +34,7 @@ func (b *option) Bytes() []byte { return b.bytes } -func (b *option) initialize(bytes []byte) error { +func (b *option) initialize(bytes []byte, _ time.Time) error { b.id = hashing.ComputeHash256Array(bytes) b.bytes = bytes return nil diff --git a/vms/proposervm/block/parse.go b/vms/proposervm/block/parse.go index cf275134d888..bf9b44adf1f4 100644 --- a/vms/proposervm/block/parse.go +++ b/vms/proposervm/block/parse.go @@ -3,9 +3,12 @@ package block -import "fmt" +import ( + "fmt" + "time" +) -func Parse(bytes []byte) (Block, error) { +func Parse(bytes []byte, durangoTime time.Time) (Block, error) { var block Block parsedVersion, err := Codec.Unmarshal(bytes, &block) if err != nil { @@ -14,7 +17,7 @@ func Parse(bytes []byte) (Block, error) { if parsedVersion != CodecVersion { return nil, fmt.Errorf("expected codec version %d but got %d", CodecVersion, parsedVersion) } - return block, block.initialize(bytes) + return block, block.initialize(bytes, durangoTime) } func ParseHeader(bytes []byte) (Header, error) { diff --git a/vms/proposervm/block/parse_test.go b/vms/proposervm/block/parse_test.go index 1d04271c9fec..148bac82c0a6 100644 --- a/vms/proposervm/block/parse_test.go +++ b/vms/proposervm/block/parse_test.go @@ -43,14 +43,19 @@ func TestParse(t *testing.T) { require.NoError(err) builtBlockBytes := builtBlock.Bytes() - - parsedBlockIntf, err := Parse(builtBlockBytes) - require.NoError(err) - - parsedBlock, ok := parsedBlockIntf.(SignedBlock) - require.True(ok) - - equal(require, chainID, builtBlock, parsedBlock) + durangoTimes := []time.Time{ + timestamp.Add(time.Second), // Durango not activated yet + timestamp.Add(-time.Second), // Durango activated + } + for _, durangoTime := range durangoTimes { + parsedBlockIntf, err := Parse(builtBlockBytes, durangoTime) + require.NoError(err) + + parsedBlock, ok := parsedBlockIntf.(SignedBlock) + require.True(ok) + + equal(require, chainID, builtBlock, parsedBlock) + } } func TestParseDuplicateExtension(t *testing.T) { @@ -60,8 +65,16 @@ func TestParseDuplicateExtension(t *testing.T) { blockBytes, err := hex.DecodeString(blockHex) require.NoError(err) - _, err = Parse(blockBytes) + // Note: The above blockHex specifies 123 as the block's timestamp. + timestamp := time.Unix(123, 0) + durangoNotYetActivatedTime := timestamp.Add(time.Second) + durangoAlreadyActivatedTime := timestamp.Add(-time.Second) + + _, err = Parse(blockBytes, durangoNotYetActivatedTime) require.ErrorIs(err, errInvalidCertificate) + + _, err = Parse(blockBytes, durangoAlreadyActivatedTime) + require.NoError(err) } func TestParseHeader(t *testing.T) { @@ -97,7 +110,7 @@ func TestParseOption(t *testing.T) { builtOptionBytes := builtOption.Bytes() - parsedOption, err := Parse(builtOptionBytes) + parsedOption, err := Parse(builtOptionBytes, time.Time{}) require.NoError(err) equalOption(require, builtOption, parsedOption) @@ -115,14 +128,19 @@ func TestParseUnsigned(t *testing.T) { require.NoError(err) builtBlockBytes := builtBlock.Bytes() - - parsedBlockIntf, err := Parse(builtBlockBytes) - require.NoError(err) - - parsedBlock, ok := parsedBlockIntf.(SignedBlock) - require.True(ok) - - equal(require, ids.Empty, builtBlock, parsedBlock) + durangoTimes := []time.Time{ + timestamp.Add(time.Second), // Durango not activated yet + timestamp.Add(-time.Second), // Durango activated + } + for _, durangoTime := range durangoTimes { + parsedBlockIntf, err := Parse(builtBlockBytes, durangoTime) + require.NoError(err) + + parsedBlock, ok := parsedBlockIntf.(SignedBlock) + require.True(ok) + + equal(require, ids.Empty, builtBlock, parsedBlock) + } } func TestParseGibberish(t *testing.T) { @@ -130,6 +148,6 @@ func TestParseGibberish(t *testing.T) { bytes := []byte{0, 1, 2, 3, 4, 5} - _, err := Parse(bytes) + _, err := Parse(bytes, time.Time{}) require.ErrorIs(err, codec.ErrUnknownVersion) } diff --git a/vms/proposervm/state/block_state.go b/vms/proposervm/state/block_state.go index 88382f0abc67..862d492b925b 100644 --- a/vms/proposervm/state/block_state.go +++ b/vms/proposervm/state/block_state.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/avalanchego/version" "github.com/ava-labs/avalanchego/vms/proposervm/block" ) @@ -109,7 +110,11 @@ func (s *blockState) GetBlock(blkID ids.ID) (block.Block, choices.Status, error) } // The key was in the database - blk, err := block.Parse(blkWrapper.Block) + // + // Invariant: Blocks stored on disk were previously accepted by this node. + // Because the durango activation relaxes TLS cert parsing rules, we assume + // it is always activated here. + blk, err := block.Parse(blkWrapper.Block, version.DefaultUpgradeTime) if err != nil { return nil, choices.Unknown, err } diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 99dc045be66d..9f77a658b55d 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -708,7 +708,7 @@ func (vm *VM) setLastAcceptedMetadata(ctx context.Context) error { } func (vm *VM) parsePostForkBlock(ctx context.Context, b []byte) (PostForkBlock, error) { - statelessBlock, err := statelessblock.Parse(b) + statelessBlock, err := statelessblock.Parse(b, vm.DurangoTime) if err != nil { return nil, err } From 20452c35e86e56dbdb3bf80e8aa6889c9a585b5e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 18 Jan 2024 14:32:32 -0500 Subject: [PATCH 263/267] Update versions for v1.10.18 (#2548) --- RELEASES.md | 254 ++++++++++++++++++++++ network/p2p/network_test.go | 1 + network/peer/peer.go | 4 +- network/peer/validator_id.go | 14 -- utils/sorting_test.go | 9 +- version/compatibility.json | 3 + version/constants.go | 9 +- vms/avm/network/network.go | 3 +- vms/platformvm/block/executor/verifier.go | 6 +- vms/platformvm/vm.go | 3 + 10 files changed, 273 insertions(+), 33 deletions(-) delete mode 100644 network/peer/validator_id.go diff --git a/RELEASES.md b/RELEASES.md index 743df32d471d..24d42b4d6027 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,259 @@ # Release Notes +## [v1.10.18](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.18) + +This version is backwards compatible to [v1.10.0](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0). It is optional, but encouraged. + +The plugin version is updated to `31` all plugins must update to be compatible. + +### APIs + +- Added `info.acps` API +- Added `supportedACPs` and `objectedACPs` for each peer returned by `info.peers` +- Added `txs` field to `BanffProposalBlock`'s json format +- Added metrics: + - `avalanche_network_validator_ips` + - `avalanche_network_gossipable_ips` + - `avalanche_network_ip_bloom_count` + - `avalanche_network_ip_bloom_entries` + - `avalanche_network_ip_bloom_hashes` + - `avalanche_network_ip_bloom_max_count` + - `avalanche_network_ip_bloom_reset_count` +- Added metrics related to `get_peer_list` message handling +- Added p2p SDK metrics to the P-chain and X-chain +- Renamed metrics related to message handling: + - `version` -> `handshake` + - `appRequestFailed` -> `appError` + - `crossChainAppRequestFailed` -> `crossChainAppError` +- Removed `gzip` compression time metrics +- Converted p2p SDK metrics to use vectors rather than independent metrics +- Converted client name reported over the p2p network from `avalanche` to `avalanchego` + + +### Configs + +- Added: + - `--acp-support` + - `--acp-object` + - `snow-commit-threshold` + - `network-peer-list-pull-gossip-frequency` + - `network-peer-list-bloom-reset-frequency` + - `network` to the X-chain and P-chain configs including: + - `max-validator-set-staleness` + - `target-gossip-size` + - `pull-gossip-poll-size` + - `pull-gossip-frequency` + - `pull-gossip-throttling-period` + - `pull-gossip-throttling-limit` + - `expected-bloom-filter-elements` + - `expected-bloom-filter-false-positive-probability` + - `max-bloom-filter-false-positive-probability` + - `legacy-push-gossip-cache-size` +- Deprecated: + - `snow-virtuous-commit-threshold` + - `snow-rogue-commit-threshold` + - `network-peer-list-validator-gossip-size` + - `network-peer-list-non-validator-gossip-size` + - `network-peer-list-peers-gossip-size` + - `network-peer-list-gossip-frequency` +- Removed: + - `gzip` as an option for `network-compression-type` + +### Fixes + +- Fixed `platformvm.SetPreference` to correctly reset the block building timer +- Fixed early bootstrapping termination +- Fixed duplicated transaction initialization in the X-chain and P-chain +- Fixed IP gossip when using dynamically allocated staking ports +- Updated `golang.org/x/exp` dependency to fix downstream compilation errors +- Updated `golang.org/x/crypto` dependency to address `CVE-2023-48795` +- Updated minimum golang version to address `CVE-2023-39326` +- Restricted `GOPROXY` during compilation to avoid `direct` version control fallbacks +- Fixed `merkledb` deletion of the empty key +- Fixed `merkledb` race condition when interacting with invalidated or closed trie views +- Fixed `json.Marshal` for `wallet` transactions +- Fixed duplicate outbound dialer for manually tracked nodes in the p2p network + +### What's Changed + +- testing: Update to latest version of ginkgo by @marun in https://github.com/ava-labs/avalanchego/pull/2390 +- `vms/platformvm`: Cleanup block builder tests by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2406 +- Drop Pending Stakers 0 - De-duplicate staking tx verification by @abi87 in https://github.com/ava-labs/avalanchego/pull/2335 +- `vms/platformvm`: Initialize txs in `Transactions` field for `BanffProposalBlock` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2419 +- `vms/platformvm`: Move `VerifyUniqueInputs` from `verifier` to `backend` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2410 +- Fix duplicated bootstrapper engine termination by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2334 +- allow user of `build_fuzz.sh` to specify a directory to fuzz in by @danlaine in https://github.com/ava-labs/avalanchego/pull/2414 +- Update slices dependency to use Compare by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2424 +- `vms/platformvm`: Cleanup some block tests by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2422 +- ProposerVM Extend windows 0 - Cleanup by @abi87 in https://github.com/ava-labs/avalanchego/pull/2404 +- `vms/platformvm`: Add `decisionTxs` parameter to `NewBanffProposalBlock` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2411 +- Update minimum golang version to v1.20.12 by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2427 +- Fix platformvm.SetPreference by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2429 +- Restrict GOPROXY by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2434 +- Drop Pending Stakers 1 - introduced ScheduledStaker txs by @abi87 in https://github.com/ava-labs/avalanchego/pull/2323 +- Run merkledb fuzz tests every 6 hours by @danlaine in https://github.com/ava-labs/avalanchego/pull/2415 +- Remove unused error by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2426 +- Make `messageQueue.msgAndCtxs` a circular buffer by @danlaine in https://github.com/ava-labs/avalanchego/pull/2433 +- ProposerVM Extend windows 1 - UTs Cleanup by @abi87 in https://github.com/ava-labs/avalanchego/pull/2412 +- Change seed from int64 to uint64 by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2438 +- Remove usage of timer.Timer in node by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2441 +- Remove staged timer again by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2440 +- `merkledb` / `sync` -- Disambiguate no end root from no start root by @danlaine in https://github.com/ava-labs/avalanchego/pull/2437 +- Drop Pending Stakers 2 - Replace txs.ScheduledStaker with txs.Staker by @abi87 in https://github.com/ava-labs/avalanchego/pull/2305 +- `vms/platformvm`: Remove double block building logic by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2380 +- Remove usage of timer.Timer in benchlist by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2446 +- `vms/avm`: Simplify `Peek` function in mempool by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2449 +- `vms/platformvm`: Remove `standardBlockState` struct by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2450 +- Refactor sampler seeding by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2456 +- Update tmpnet fixture to include Proof-of-Possession for initial stakers by @marun in https://github.com/ava-labs/avalanchego/pull/2391 +- `vms/platformvm`: Remove `EnableAdding` and `DisableAdding` from `Mempool` interface by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2463 +- `vms/avm`: Add `exists` bool to mempool `Peek` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2465 +- `vms/platformvm`: Remove `PeekTxs` from `Mempool` interface by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2378 +- `vms/platformvm`: Add `processStandardTxs` helper by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2461 +- `vms/platformvm`: Process `atomicRequests` and `onAcceptFunc` in option blocks by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2459 +- `e2e`: Rename 'funded key' to 'pre-funded key' for consistency by @marun in https://github.com/ava-labs/avalanchego/pull/2455 +- `vms/platformvm`: Surface `VerifyUniqueInputs` in the `Manager` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2467 +- `vms/platformvm`: Add `TestBuildBlockShouldReward` test by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2466 +- Switch client version to a proto type from a string by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2188 +- Remove stale TODO by @danlaine in https://github.com/ava-labs/avalanchego/pull/2468 +- `vms/platformvm`: Add `TestBuildBlockDoesNotBuildWithEmptyMempool` test by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2469 +- `vms/platformvm`: Add `TestBuildBlockShouldAdvanceTime` test by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2471 +- `vms/platformvm`: Permit usage of the `Transactions` field in `BanffProposalBlock` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2451 +- `vms/platformvm`: Add `TestBuildBlockForceAdvanceTime` test by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2472 +- P2P AppError handling by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2248 +- `vms/platformvm`: Verify txs before building a block by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2359 +- Refactor p2p unit tests by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2475 +- Add ACP signaling by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2476 +- Refactor SDK by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2452 +- Cleanup CI by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2480 +- Ensure upgrade test uses the correct binary on restart by @marun in https://github.com/ava-labs/avalanchego/pull/2478 +- Prefetch Improvement by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2435 +- ci: run each fuzz test for 10 seconds by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2483 +- Remove nullable options by @nytzuga in https://github.com/ava-labs/avalanchego/pull/2481 +- `merkledb` -- dynamic root by @danlaine in https://github.com/ava-labs/avalanchego/pull/2177 +- fix onEvictCache by @danlaine in https://github.com/ava-labs/avalanchego/pull/2484 +- Remove cached node bytes from merkle nodes by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2393 +- Fix race in view iteration by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2486 +- MerkleDB -- update readme by @danlaine in https://github.com/ava-labs/avalanchego/pull/2423 +- Drop Pending Stakers 3 - persist stakers' StartTime by @abi87 in https://github.com/ava-labs/avalanchego/pull/2306 +- SDK Push Gossiper implementation by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2428 +- `tmpnet`: Move tmpnet/local to tmpnet package by @marun in https://github.com/ava-labs/avalanchego/pull/2457 +- `merkledb` -- make tests use time as randomness seed by @danlaine in https://github.com/ava-labs/avalanchego/pull/2470 +- `tmpnet`: Break config.go up into coherent parts by @marun in https://github.com/ava-labs/avalanchego/pull/2462 +- Drop Pending Stakers 4 - minimal UT infra cleanup by @abi87 in https://github.com/ava-labs/avalanchego/pull/2332 +- ProposerVM Extend windows 2- extend windowing by @abi87 in https://github.com/ava-labs/avalanchego/pull/2401 +- Support json marshalling txs returned from the wallet by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2494 +- Avoid escaping to improve readability by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2496 +- Allow OutputOwners to be json marshalled without InitCtx by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2495 +- Drop Pending Stakers 5 - validated PostDurango StakerTxs by @abi87 in https://github.com/ava-labs/avalanchego/pull/2314 +- Bump golang.org/x/crypto from 0.14.0 to 0.17.0 by @dependabot in https://github.com/ava-labs/avalanchego/pull/2502 +- Remove unused `BuildGenesisTest` function by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2503 +- Remove unused `AcceptorTracker` struct by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2508 +- Dedupe secp256k1 key usage in tests by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2511 +- Merkledb readme updates by @danlaine in https://github.com/ava-labs/avalanchego/pull/2510 +- Gossip Test structs by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2514 +- `tmpnet`: Separate node into orchestration, config and process by @marun in https://github.com/ava-labs/avalanchego/pull/2460 +- Move `snow.DefaultConsensusContextTest` to `snowtest.ConsensusContext` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2507 +- Add gossip Marshaller interface by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2509 +- Include chain creation error in health check by @marun in https://github.com/ava-labs/avalanchego/pull/2519 +- Make X-chain mempool safe for concurrent use by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2520 +- Initialize transactions once by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2521 +- `vms/avm`: Remove usage of `require.Contains` from service tests by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2517 +- Move context lock into issueTx by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2524 +- Rework X-chain locking in tests by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2526 +- `vms/avm`: Simplify `mempool.Remove` signature by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2527 +- Remove unused mocks by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2528 +- Move `avm.newContext` to `snowtest.Context` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2513 +- Do not fail-fast Tests / Unit by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2530 +- Make P-Chain Mempool thread-safe by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2523 +- `vms/platformvm`: Use `snowtest.Context` helper by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2515 +- Export mempool errors by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2531 +- Move locking into issueTx by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2532 +- Fix merge in wallet service by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2534 +- Introduce TxVerifier interface to network by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2533 +- Export P-Chain Mempool Errors by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2535 +- Rename `Version` message to `Handshake` by @danlaine in https://github.com/ava-labs/avalanchego/pull/2479 +- Rename myVersionTime to ipSigningTime by @danlaine in https://github.com/ava-labs/avalanchego/pull/2537 +- Remove resolved TODO by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2540 +- Only initialize Txs once by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2538 +- JSON marshal the `Transactions` field in `BanffProposalBlocks` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2541 +- Enable `predeclared` linter by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2539 +- Move context lock into `network.issueTx` by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2525 +- Remove comment on treating failed sends as FATAL by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2544 +- Add TxVerifier interface to network by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2542 +- X-chain SDK gossip by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2490 +- Remove network context by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2543 +- Remove `snow.DefaultContextTest` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2518 +- Fix windowing when no validator is available by @abi87 in https://github.com/ava-labs/avalanchego/pull/2529 +- Unexport fields from gossip.BloomFilter by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2547 +- P-Chain SDK Gossip by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2487 +- Documentation Fixes: Grammatical Corrections and Typo Fixes Across Multiple Files by @joaolago1113 in https://github.com/ava-labs/avalanchego/pull/2550 +- Notify block builder of txs after reject by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2549 +- Set dependabot target branch to `dev` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2553 +- Remove `MockLogger` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2554 +- Clean up merkleDB interface and duplicate code by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2445 +- Do not mark txs as dropped when mempool is full by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2557 +- Update bug bounty program to immunefi by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2558 +- Fix p2p sdk metric labels by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2561 +- Suppress gossip warnings due to no sampled peers by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2562 +- Remove dead code and unnecessary lock from reflect codec by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2560 +- Remove unused index interface by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2564 +- Implement SetMap and use it in XP-chain mempools by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2555 +- `vms/platformvm`: Add `TestIterate` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2565 +- Cleanup codec usage by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2563 +- Remove `len` tag parsing from the reflect codec by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2559 +- Use more specific type by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2567 +- Standardize `onShutdownCtx` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2568 +- Verify avm mempool txs against the last accepted state by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2569 +- Update `CODEOWNERS` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2570 +- Remove license from mocks by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2574 +- Add missing import by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2573 +- `vms/platformvm`: Prune mempool periodically by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2566 +- Update license header to 2024 by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2572 +- [MerkleDB] Make intermediate node cache two layered by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2576 +- Fix merkledb rebuild iterator by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2581 +- Fix intermediate node caching by @dboehm-avalabs in https://github.com/ava-labs/avalanchego/pull/2585 +- Remove codec length check after Durango by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2586 +- `tmpnet`: Use AvalancheLocalChainConfig for cchain genesis by @marun in https://github.com/ava-labs/avalanchego/pull/2583 +- `testing`: Ensure CheckBootstrapIsPossible is safe for teardown by @marun in https://github.com/ava-labs/avalanchego/pull/2582 +- `tmpnet`: Separate network into orchestration and configuration by @marun in https://github.com/ava-labs/avalanchego/pull/2464 +- Update uintsize implementation by @danlaine in https://github.com/ava-labs/avalanchego/pull/2590 +- Optimize bloom filter by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2588 +- Remove TLS key gen from networking tests by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2596 +- [utils/bloom] Optionally Update Bloom Filter Size on Reset by @patrick-ogrady in https://github.com/ava-labs/avalanchego/pull/2591 +- [ci] Increase Fuzz Time in Periodic Runs by @patrick-ogrady in https://github.com/ava-labs/avalanchego/pull/2599 +- `tmpnet`: Save metrics snapshot to disk before node shutdown by @marun in https://github.com/ava-labs/avalanchego/pull/2601 +- chore: Fix typo s/useage/usage by @hugo-syn in https://github.com/ava-labs/avalanchego/pull/2602 +- Deprecate `SnowRogueCommitThresholdKey` and `SnowVirtuousCommitThresholdKey` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2600 +- Fix networking invalid field log by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2604 +- chore: Fix typo s/seperate/separate/ by @hugo-syn in https://github.com/ava-labs/avalanchego/pull/2605 +- Support dynamic port peerlist gossip by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2603 +- Replace `PeerListAck` with `GetPeerList` by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2580 +- Log critical consensus values during health checks by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2609 +- Update contributions branch to master by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2610 +- Add ip bloom metrics by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2614 +- `x/sync`: Auto-generate `MockNetworkClient` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2617 +- Remove CreateStaticHandlers from VM interface by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2589 +- `tmpnet`: Add support for subnets by @marun in https://github.com/ava-labs/avalanchego/pull/2492 +- Update `go.uber.org/mock/gomock` to `v0.4.0` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2618 +- Add `mockgen` source mode for generics + bls imports by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2615 +- Verify all MockGen generated files are re-generated in CI by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2616 +- Move division by 0 check out of the bloom loops by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2622 +- P-chain Add UTs around stakers persistence in platformvm state by @abi87 in https://github.com/ava-labs/avalanchego/pull/2505 +- Revert "Set dependabot target branch to `dev` (#2553)" by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2623 +- Remove remaining 2023 remnants by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2624 +- Deprecate push-based peerlist gossip flags by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2625 +- Remove support for compressing gzip messages by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2627 +- Always attempt to install mockgen `v0.4.0` before execution by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/2628 +- Modify TLS parsing rules for Durango by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/2458 + +### New Contributors + +- @joaolago1113 made their first contribution in https://github.com/ava-labs/avalanchego/pull/2550 +- @hugo-syn made their first contribution in https://github.com/ava-labs/avalanchego/pull/2602 + +**Full Changelog**: https://github.com/ava-labs/avalanchego/compare/v1.10.17...v1.10.18 + ## [v1.10.17](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.17) This version is backwards compatible to [v1.10.0](https://github.com/ava-labs/avalanchego/releases/tag/v1.10.0). It is optional, but encouraged. diff --git a/network/p2p/network_test.go b/network/p2p/network_test.go index 6aea3bc554d0..3bf902c38035 100644 --- a/network/p2p/network_test.go +++ b/network/p2p/network_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" diff --git a/network/peer/peer.go b/network/peer/peer.go index 403bea5220ba..255f13821f23 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -1102,8 +1102,8 @@ func (p *peer) handleHandshake(msg *p2p.Handshake) { peerIPs := p.Network.Peers(p.id, knownPeers, salt) - // We bypass throttling here to ensure that the peerlist message is - // acknowledged timely. + // We bypass throttling here to ensure that the handshake message is + // acknowledged correctly. peerListMsg, err := p.Config.MessageCreator.PeerList(peerIPs, true /*=bypassThrottling*/) if err != nil { p.Log.Error("failed to create peer list handshake message", diff --git a/network/peer/validator_id.go b/network/peer/validator_id.go deleted file mode 100644 index 078929d0f90a..000000000000 --- a/network/peer/validator_id.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package peer - -import "github.com/ava-labs/avalanchego/ids" - -// ValidatorID represents a validator that we gossip to other peers -type ValidatorID struct { - // The validator's ID - NodeID ids.NodeID - // The Tx that added this into the validator set - TxID ids.ID -} diff --git a/utils/sorting_test.go b/utils/sorting_test.go index 632629368518..acab335034ed 100644 --- a/utils/sorting_test.go +++ b/utils/sorting_test.go @@ -14,14 +14,7 @@ var _ Sortable[sortable] = sortable(0) type sortable int func (s sortable) Compare(other sortable) int { - switch { - case s < other: - return -1 - case s > other: - return 1 - default: - return 0 - } + return Compare(s, other) } func TestSortSliceSortable(t *testing.T) { diff --git a/version/compatibility.json b/version/compatibility.json index d34dfb1a5a28..e975f92c3698 100644 --- a/version/compatibility.json +++ b/version/compatibility.json @@ -1,4 +1,7 @@ { + "31": [ + "v1.10.18" + ], "30": [ "v1.10.15", "v1.10.16", diff --git a/version/constants.go b/version/constants.go index 053a57a4585b..55af70a4d89f 100644 --- a/version/constants.go +++ b/version/constants.go @@ -15,9 +15,10 @@ import ( const ( Client = "avalanchego" - // RPCChainVMProtocol should be bumped anytime changes are made which require - // the plugin vm to upgrade to latest avalanchego release to be compatible. - RPCChainVMProtocol uint = 30 + // RPCChainVMProtocol should be bumped anytime changes are made which + // require the plugin vm to upgrade to latest avalanchego release to be + // compatible. + RPCChainVMProtocol uint = 31 ) // These are globals that describe network upgrades and node versions @@ -25,7 +26,7 @@ var ( Current = &Semantic{ Major: 1, Minor: 10, - Patch: 17, + Patch: 18, } CurrentApp = &Application{ Name: Client, diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index d2920bc51af4..fbeed92a95a1 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -204,8 +204,7 @@ func (n *Network) AppGossip(ctx context.Context, nodeID ids.NodeID, msgBytes []b return nil } - err = n.mempool.Add(tx) - if err == nil { + if err := n.mempool.Add(tx); err == nil { txID := tx.ID() n.txPushGossiper.Add(tx) if err := n.txPushGossiper.Gossip(ctx); err != nil { diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index 2af7cb20912a..1f46ce132c47 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -51,7 +51,8 @@ func (v *verifier) BanffCommitBlock(b *block.BanffCommitBlock) error { } func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { - if !v.txExecutorBackend.Config.IsDurangoActivated(b.Timestamp()) && len(b.Transactions) != 0 { + nextChainTime := b.Timestamp() + if !v.txExecutorBackend.Config.IsDurangoActivated(nextChainTime) && len(b.Transactions) != 0 { return errBanffProposalBlockWithMultipleTransactions } @@ -66,7 +67,6 @@ func (v *verifier) BanffProposalBlock(b *block.BanffProposalBlock) error { } // Apply the changes, if any, from advancing the chain time. - nextChainTime := b.Timestamp() changes, err := executor.AdvanceTimeTo( v.txExecutorBackend, onDecisionState, @@ -219,7 +219,7 @@ func (v *verifier) ApricotAtomicBlock(b *block.ApricotAtomicBlock) error { atomicExecutor.OnAccept.AddTx(b.Tx, status.Committed) - if err := v.verifyUniqueInputs(b.Parent(), atomicExecutor.Inputs); err != nil { + if err := v.verifyUniqueInputs(parentID, atomicExecutor.Inputs); err != nil { return err } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 746826666c6d..8c4b527e4539 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -302,6 +302,9 @@ func (vm *VM) pruneMempool() error { vm.ctx.Lock.Lock() defer vm.ctx.Lock.Unlock() + // Packing all of the transactions in order performs additional checks that + // the MempoolTxVerifier doesn't include. So, evicting transactions from + // here is expected to happen occasionally. blockTxs, err := vm.Builder.PackBlockTxs(math.MaxInt) if err != nil { return err From 9d26ea95989cee5dbe152a958fdd1a66a7d82760 Mon Sep 17 00:00:00 2001 From: evlekht Date: Fri, 8 Mar 2024 16:58:20 +0400 Subject: [PATCH 264/267] [AVAX] Post Merge fixes for Cortina 16 (v1.10.16) --- genesis/camino_genesis.go | 4 +- go.mod | 3 +- go.sum | 6 +- node/node.go | 4 +- scripts/constants.sh | 4 +- vms/platformvm/api/camino.go | 2 +- vms/platformvm/api/camino_test.go | 22 +-- vms/platformvm/api/static_service.go | 18 +-- .../block/builder/camino_builder.go | 46 ------- vms/platformvm/camino_helpers_test.go | 2 +- vms/platformvm/camino_service.go | 30 ++--- vms/platformvm/camino_vm_test.go | 6 +- .../builder => network}/camino_network.go | 28 ++-- vms/platformvm/state/camino.go | 52 ++++---- vms/platformvm/state/camino_diff.go | 9 -- vms/platformvm/state/camino_diff_test.go | 57 -------- vms/platformvm/state/camino_helpers_test.go | 6 +- vms/platformvm/state/camino_state.go | 5 - vms/platformvm/state/camino_test.go | 12 +- .../state/test/camino_test_state.go | 7 +- vms/platformvm/test/camino_defaults.go | 6 +- .../txs/executor/camino_helpers_test.go | 4 +- .../txs/executor/camino_tx_executor.go | 46 +++++-- .../txs/executor/staker_tx_verification.go | 2 +- .../txs/executor/standard_tx_executor.go | 4 +- vms/platformvm/txs/mempool/camino_visitor.go | 125 ------------------ vms/platformvm/utxo/camino_locked_test.go | 2 +- vms/platformvm/vm.go | 5 +- 28 files changed, 147 insertions(+), 370 deletions(-) rename vms/platformvm/{block/builder => network}/camino_network.go (77%) delete mode 100644 vms/platformvm/txs/mempool/camino_visitor.go diff --git a/genesis/camino_genesis.go b/genesis/camino_genesis.go index ff29648bbb1b..12da7d88e29f 100644 --- a/genesis/camino_genesis.go +++ b/genesis/camino_genesis.go @@ -434,8 +434,8 @@ func buildPGenesis(config *Config, hrp string, xGenesisBytes []byte, xGenesisDat stakingOffset += time.Duration(config.InitialStakeDurationOffset) * time.Second platformvmArgs.Validators = append(platformvmArgs.Validators, - api.PermissionlessValidator{ - Staker: api.Staker{ + api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(startStakingTime.Unix()), EndTime: json.Uint64(endStakingTime.Unix()), NodeID: platformAllocation.NodeID, diff --git a/go.mod b/go.mod index 1a5d5b2a415a..860ced1ccd9d 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a github.com/thepudds/fzgen v0.4.2 github.com/tyler-smith/go-bip32 v1.0.0 + github.com/xuri/excelize/v2 v2.8.0 go.opentelemetry.io/otel v1.11.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.0 @@ -161,4 +162,4 @@ require ( replace github.com/ava-labs/avalanche-ledger-go => github.com/chain4travel/camino-ledger-go v0.0.13-c4t -replace github.com/ava-labs/coreth => github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114647-ffc063541f3f +replace github.com/ava-labs/coreth => github.com/chain4travel/caminoethvm v1.1.16-rc0 diff --git a/go.sum b/go.sum index 8edb97c40c50..9c2dfd6ea248 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,6 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.5 h1:xYBgNm1uOPfUdUNm8+fS8ellHnEd4qfFNb6uZHo9tqI= -github.com/ava-labs/coreth v0.12.9-rc.5/go.mod h1:rECKQfGFDeodrwGPlJSvFUJDbVr30jSMIVjQLi6pNX4= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -108,8 +106,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114647-ffc063541f3f h1:UXaMNZQQBLT8Fu3l6p8Fktr3NhYBHfjs5ZRi4UauP4I= -github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114647-ffc063541f3f/go.mod h1:aXs2X5y4BVp+fGUk4sR1rk1qHmrtTl6NxTJPhUVw3P0= +github.com/chain4travel/caminoethvm v1.1.16-rc0 h1:yu2vadc5xzsQ6gtK7oNYBwVw+CsAVFvDj0894In71/M= +github.com/chain4travel/caminoethvm v1.1.16-rc0/go.mod h1:PgnbVryuhwq5IS7lI+TciNyqVPEru4gMOj3lzEBVPEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= diff --git a/node/node.go b/node/node.go index ac122bbeffe8..2aaa33cc1b3a 100644 --- a/node/node.go +++ b/node/node.go @@ -122,11 +122,11 @@ func New( if err := staking.ValidateCertificate(stakingCert); err != nil { return nil, fmt.Errorf("invalid staking certificate: %w", err) } - + // Get the nodeID from certificate (secp256k1 public key) nodeID, err := peer.CertToID(tlsCert) if err != nil { - return fmt.Errorf("cannot extract nodeID from certificate: %w", err) + return nil, fmt.Errorf("cannot extract nodeID from certificate: %w", err) } n := &Node{ diff --git a/scripts/constants.sh b/scripts/constants.sh index 8429fdb0bf18..d016d18f7343 100755 --- a/scripts/constants.sh +++ b/scripts/constants.sh @@ -30,8 +30,8 @@ current_branch=${current_branch_temp////-} # caminogo and caminoethvm git tag and sha git_commit=${CAMINO_NODE_COMMIT:-$(git rev-parse --short HEAD)} git_tag=${CAMINO_NODE_TAG:-$(git describe --tags --abbrev=0 --always || echo unknown)} -caminoethvm_tag=${CAMINO_ETHVM_VERSION:-'v1.1.15-rc0'} -caminoethvm_commit=${CAMINOETHVM_COMMIT:-'ffc063541f3f645420b524fb367375adbf07ed7e'} +caminoethvm_tag=${CAMINO_ETHVM_VERSION:-'v1.1.16-rc0'} +caminoethvm_commit=${CAMINOETHVM_COMMIT:-'d258907cfd8a448ccb111e9e0f232980f85bb0da'} # Static compilation static_ld_flags='' diff --git a/vms/platformvm/api/camino.go b/vms/platformvm/api/camino.go index c4b9662ef5b3..debab84df10f 100644 --- a/vms/platformvm/api/camino.go +++ b/vms/platformvm/api/camino.go @@ -287,7 +287,7 @@ func buildCaminoGenesis(args *BuildGenesisArgs, reply *BuildGenesisReply) error } func makeValidator( - vdr *PermissionlessValidator, + vdr *GenesisPermissionlessValidator, avaxAssetID ids.ID, networkID uint32, ) (*txs.Tx, error) { diff --git a/vms/platformvm/api/camino_test.go b/vms/platformvm/api/camino_test.go index d9d391739589..21f33cda811e 100644 --- a/vms/platformvm/api/camino_test.go +++ b/vms/platformvm/api/camino_test.go @@ -62,8 +62,8 @@ func TestBuildCaminoGenesis(t *testing.T) { Address: addrStr, Amount: 10, }}, - Validators: []PermissionlessValidator{{ - Staker: Staker{ + Validators: []GenesisPermissionlessValidator{{ + GenesisValidator: GenesisValidator{ StartTime: 0, EndTime: 20, NodeID: nodeID, @@ -347,9 +347,9 @@ func TestBuildCaminoGenesis(t *testing.T) { Amount: 10, }, }, - Validators: []PermissionlessValidator{ + Validators: []GenesisPermissionlessValidator{ { - Staker: Staker{ + GenesisValidator: GenesisValidator{ StartTime: 0, EndTime: 20, NodeID: nodeID, @@ -407,7 +407,7 @@ func TestBuildCaminoGenesis(t *testing.T) { Amount: 0, }, }, - Validators: []PermissionlessValidator{}, + Validators: []GenesisPermissionlessValidator{}, Time: 5, Encoding: formatting.Hex, Camino: &Camino{ @@ -435,9 +435,9 @@ func TestBuildCaminoGenesis(t *testing.T) { "Wrong Validator Number": { args: BuildGenesisArgs{ UTXOs: []UTXO{}, - Validators: []PermissionlessValidator{ + Validators: []GenesisPermissionlessValidator{ { - Staker: Staker{ + GenesisValidator: GenesisValidator{ StartTime: 0, EndTime: 20, NodeID: nodeID, @@ -483,9 +483,9 @@ func TestBuildCaminoGenesis(t *testing.T) { "Deposits and Staked Misalignment": { args: BuildGenesisArgs{ UTXOs: []UTXO{}, - Validators: []PermissionlessValidator{ + Validators: []GenesisPermissionlessValidator{ { - Staker: Staker{ + GenesisValidator: GenesisValidator{ StartTime: 0, EndTime: 20, NodeID: nodeID, @@ -530,9 +530,9 @@ func TestBuildCaminoGenesis(t *testing.T) { Amount: 0, }, }, - Validators: []PermissionlessValidator{ + Validators: []GenesisPermissionlessValidator{ { - Staker: Staker{ + GenesisValidator: GenesisValidator{ StartTime: 0, EndTime: 20, NodeID: nodeID, diff --git a/vms/platformvm/api/static_service.go b/vms/platformvm/api/static_service.go index b3739ccdddfc..3ef6399a654e 100644 --- a/vms/platformvm/api/static_service.go +++ b/vms/platformvm/api/static_service.go @@ -193,16 +193,16 @@ type Chain struct { // [Camino] are the camino specific genesis args. // [Time] is the Platform Chain's time at network genesis. type BuildGenesisArgs struct { - AvaxAssetID ids.ID `json:"avaxAssetID"` - NetworkID json.Uint32 `json:"networkID"` - UTXOs []UTXO `json:"utxos"` + AvaxAssetID ids.ID `json:"avaxAssetID"` + NetworkID json.Uint32 `json:"networkID"` + UTXOs []UTXO `json:"utxos"` Validators []GenesisPermissionlessValidator `json:"validators"` - Chains []Chain `json:"chains"` - Camino *Camino `json:"camino"` - Time json.Uint64 `json:"time"` - InitialSupply json.Uint64 `json:"initialSupply"` - Message string `json:"message"` - Encoding formatting.Encoding `json:"encoding"` + Chains []Chain `json:"chains"` + Camino *Camino `json:"camino"` + Time json.Uint64 `json:"time"` + InitialSupply json.Uint64 `json:"initialSupply"` + Message string `json:"message"` + Encoding formatting.Encoding `json:"encoding"` } // BuildGenesisReply is the reply from BuildGenesis diff --git a/vms/platformvm/block/builder/camino_builder.go b/vms/platformvm/block/builder/camino_builder.go index c1ee081b7cd5..0cddf98dbb55 100644 --- a/vms/platformvm/block/builder/camino_builder.go +++ b/vms/platformvm/block/builder/camino_builder.go @@ -9,59 +9,13 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/utils/timer" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/platformvm/block" - blockexecutor "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/txs" txBuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" - txexecutor "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor" - "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) -// Overriding axax block builder methods with caminoBuilder methods -// must be done with consideration, that network uses reference to avax builder, -// not to camino builder. So it will actually call avax builder methods. - -type caminoBuilder struct { - builder - caminoTxBuilder txBuilder.CaminoBuilder -} - -func CaminoNew( - mempool mempool.Mempool, - txBuilder txBuilder.CaminoBuilder, - txExecutorBackend *txexecutor.Backend, - blkManager blockexecutor.Manager, - toEngine chan<- common.Message, - appSender common.AppSender, -) Builder { - builder := &caminoBuilder{ - builder: builder{ - Mempool: mempool, - txExecutorBackend: txExecutorBackend, - blkManager: blkManager, - toEngine: toEngine, - txBuilder: txBuilder, - }, - caminoTxBuilder: txBuilder, - } - - builder.timer = timer.NewTimer(builder.setNextBuildBlockTime) - - builder.Network = NewCaminoNetwork( - txExecutorBackend.Ctx, - builder, - appSender, - builder.caminoTxBuilder, - ) - - go txExecutorBackend.Ctx.Log.RecoverAndPanic(builder.timer.Dispatch) - return builder -} - func caminoBuildBlock( builder *builder, parentID ids.ID, diff --git a/vms/platformvm/camino_helpers_test.go b/vms/platformvm/camino_helpers_test.go index b4af4304317c..4256626e9653 100644 --- a/vms/platformvm/camino_helpers_test.go +++ b/vms/platformvm/camino_helpers_test.go @@ -99,7 +99,7 @@ func newCaminoVM(t *testing.T, genesisConfig api.Camino, phase test.Phase, genes ) require.NoError(err) - require.NoError(vm.Builder.AddUnverifiedTx(testSubnet1)) + require.NoError(vm.Network.IssueTx(context.Background(), testSubnet1)) blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) require.NoError(blk.Verify(context.Background())) diff --git a/vms/platformvm/camino_service.go b/vms/platformvm/camino_service.go index a7ce23a05224..c6c786bbd39c 100644 --- a/vms/platformvm/camino_service.go +++ b/vms/platformvm/camino_service.go @@ -267,7 +267,7 @@ type SetAddressStateArgs struct { } // AddAdressState issues an AddAdressStateTx -func (s *CaminoService) SetAddressState(_ *http.Request, args *SetAddressStateArgs, response *api.JSONTxID) error { +func (s *CaminoService) SetAddressState(req *http.Request, args *SetAddressStateArgs, response *api.JSONTxID) error { s.vm.ctx.Log.Debug("Platform: SetAddressState called") s.vm.ctx.Lock.Lock() @@ -303,10 +303,7 @@ func (s *CaminoService) SetAddressState(_ *http.Request, args *SetAddressStateAr response.TxID = tx.ID() - if err = s.vm.Builder.AddUnverifiedTx(tx); err != nil { - return err - } - return nil + return s.vm.Network.IssueTx(req.Context(), tx) } // GetAddressStates retrieves the state applied to an address (see setAddressState) @@ -477,7 +474,7 @@ type RegisterNodeArgs struct { } // RegisterNode issues an RegisterNodeTx -func (s *CaminoService) RegisterNode(_ *http.Request, args *RegisterNodeArgs, reply *api.JSONTxID) error { +func (s *CaminoService) RegisterNode(req *http.Request, args *RegisterNodeArgs, reply *api.JSONTxID) error { s.vm.ctx.Log.Debug("Platform: RegisterNode called") s.vm.ctx.Lock.Lock() @@ -513,10 +510,7 @@ func (s *CaminoService) RegisterNode(_ *http.Request, args *RegisterNodeArgs, re reply.TxID = tx.ID() - if err = s.vm.Builder.AddUnverifiedTx(tx); err != nil { - return err - } - return nil + return s.vm.Network.IssueTx(req.Context(), tx) } type ClaimedAmount struct { @@ -536,7 +530,7 @@ type ClaimArgs struct { } // Claim issues an ClaimTx -func (s *CaminoService) Claim(_ *http.Request, args *ClaimArgs, reply *api.JSONTxID) error { +func (s *CaminoService) Claim(req *http.Request, args *ClaimArgs, reply *api.JSONTxID) error { s.vm.ctx.Log.Debug("Platform: Claim called") s.vm.ctx.Lock.Lock() @@ -592,11 +586,7 @@ func (s *CaminoService) Claim(_ *http.Request, args *ClaimArgs, reply *api.JSONT reply.TxID = tx.ID() - if err := s.vm.Builder.AddUnverifiedTx(tx); err != nil { - return fmt.Errorf("couldn't create tx: %w", err) - } - - return nil + return s.vm.Network.IssueTx(req.Context(), tx) } type TransferArgs struct { @@ -608,7 +598,7 @@ type TransferArgs struct { } // Transfer issues an BaseTx -func (s *CaminoService) Transfer(_ *http.Request, args *TransferArgs, reply *api.JSONTxID) error { +func (s *CaminoService) Transfer(req *http.Request, args *TransferArgs, reply *api.JSONTxID) error { s.vm.ctx.Log.Debug("Platform: Transfer called") s.vm.ctx.Lock.Lock() @@ -642,11 +632,7 @@ func (s *CaminoService) Transfer(_ *http.Request, args *TransferArgs, reply *api reply.TxID = tx.ID() - if err := s.vm.Builder.AddUnverifiedTx(tx); err != nil { - return fmt.Errorf("couldn't create tx: %w", err) - } - - return nil + return s.vm.Network.IssueTx(req.Context(), tx) } func (s *CaminoService) GetRegisteredShortIDLink(_ *http.Request, args *api.JSONAddress, response *api.JSONAddress) error { diff --git a/vms/platformvm/camino_vm_test.go b/vms/platformvm/camino_vm_test.go index 756120268063..6109b34306dd 100644 --- a/vms/platformvm/camino_vm_test.go +++ b/vms/platformvm/camino_vm_test.go @@ -624,7 +624,7 @@ func TestProposals(t *testing.T) { // Try to vote on proposal, expect to fail vm.clock.Set(baseFeeProposalState.StartTime().Add(-time.Second)) addVoteTx := buildSimpleVoteTx(t, vm, proposerKey, fee, proposalTx.ID(), test.FundedKeys[0], 0) - err = vm.Builder.AddUnverifiedTx(addVoteTx) + err = vm.Network.IssueTx(context.Background(), addVoteTx) require.ErrorIs(err, txexecutor.ErrProposalInactive) vm.clock.Set(baseFeeProposalState.StartTime()) @@ -1168,7 +1168,7 @@ func TestExcludeMemberProposals(t *testing.T) { if tt.moreExclude { excludeMemberProposalTx := buildExcludeMemberProposalTx(t, vm, fundsKey, proposalBondAmount, fee, consortiumSecretaryKey, memberToExcludeAddr, proposalStartTime, proposalStartTime.Add(time.Duration(dac.ExcludeMemberProposalMinDuration)*time.Second), true) - err = vm.Builder.AddUnverifiedTx(excludeMemberProposalTx) + err = vm.Network.IssueTx(context.Background(), excludeMemberProposalTx) require.ErrorIs(err, txexecutor.ErrInvalidProposal) height, err = vm.GetCurrentHeight(context.Background()) require.NoError(err) @@ -1279,7 +1279,7 @@ func TestExcludeMemberProposals(t *testing.T) { func buildAndAcceptBlock(t *testing.T, vm *VM, tx *txs.Tx) block.Block { t.Helper() if tx != nil { - require.NoError(t, vm.Builder.AddUnverifiedTx(tx)) + require.NoError(t, vm.Network.IssueTx(context.Background(), tx)) } blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(t, err) diff --git a/vms/platformvm/block/builder/camino_network.go b/vms/platformvm/network/camino_network.go similarity index 77% rename from vms/platformvm/block/builder/camino_network.go rename to vms/platformvm/network/camino_network.go index 2ebef08754c8..c8536e361c82 100644 --- a/vms/platformvm/block/builder/camino_network.go +++ b/vms/platformvm/network/camino_network.go @@ -1,7 +1,7 @@ // Copyright (C) 2022-2024, Chain4Travel AG. All rights reserved. // See the file LICENSE for licensing terms. -package builder +package network import ( "context" @@ -16,8 +16,10 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/vms/components/message" + "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs" txBuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" + "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) var errUnknownCrossChainMessage = errors.New("unknown cross-chain message") @@ -27,18 +29,24 @@ type caminoNetwork struct { txBuilder txBuilder.CaminoBuilder } -func NewCaminoNetwork( +func NewCamino( ctx *snow.Context, - blkBuilder *caminoBuilder, + manager executor.Manager, + mempool mempool.Mempool, + partialSyncPrimaryNetwork bool, appSender common.AppSender, txBuilder txBuilder.CaminoBuilder, ) Network { return &caminoNetwork{ network: network{ - ctx: ctx, - blkBuilder: &blkBuilder.builder, - appSender: appSender, - recentTxs: &cache.LRU[ids.ID, struct{}]{Size: recentCacheSize}, + AppHandler: common.NewNoOpAppHandler(ctx.Log), + + ctx: ctx, + manager: manager, + mempool: mempool, + partialSyncPrimaryNetwork: partialSyncPrimaryNetwork, + appSender: appSender, + recentTxs: &cache.LRU[ids.ID, struct{}]{Size: recentCacheSize}, }, txBuilder: txBuilder, } @@ -88,9 +96,9 @@ func (n *caminoNetwork) caminoRewardMessage() string { n.ctx.Lock.Lock() defer n.ctx.Lock.Unlock() - if err := n.blkBuilder.AddUnverifiedTx(tx); err != nil { - n.ctx.Log.Error("caminoCrossChainAppRequest failed to add unverified rewardsImportTx to block builder", zap.Error(err)) - return fmt.Sprintf("caminoCrossChainAppRequest failed to add unverified rewardsImportTx to block builder: %s", err) + if err := n.issueTx(tx); err != nil { + n.ctx.Log.Error("caminoCrossChainAppRequest failed to issue rewardsImportTx", zap.Error(err)) + return fmt.Sprintf("caminoCrossChainAppRequest failed to issue rewardsImportTx: %s", err) } amounts := make([]uint64, len(utx.Ins)) diff --git a/vms/platformvm/state/camino.go b/vms/platformvm/state/camino.go index cc30238492d4..2a45ed5fc6f7 100644 --- a/vms/platformvm/state/camino.go +++ b/vms/platformvm/state/camino.go @@ -24,7 +24,6 @@ import ( "github.com/ava-labs/avalanchego/vms/components/multisig" as "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" "github.com/ava-labs/avalanchego/vms/platformvm/block" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/dac" "github.com/ava-labs/avalanchego/vms/platformvm/deposit" "github.com/ava-labs/avalanchego/vms/platformvm/genesis" @@ -152,7 +151,6 @@ type Camino interface { LockedUTXOs(set.Set[ids.ID], set.Set[ids.ShortID], locked.State) ([]*avax.UTXO, error) CaminoConfig() (*CaminoConfig, error) - Config() (*config.Config, error) } // For state only @@ -194,8 +192,8 @@ type caminoState struct { genesisSynced bool verifyNodeSignature bool lockModeBondDeposit bool - baseFee uint64 - feeDistribution [dac.FeeDistributionFractionsCount]uint64 + baseFee *uint64 + feeDistribution *[dac.FeeDistributionFractionsCount]uint64 // Deferred Stakers deferredStakers *baseStakers @@ -549,28 +547,20 @@ func (cs *caminoState) Load(s *state) error { cs.lockModeBondDeposit = mode baseFee, err := database.GetUInt64(cs.caminoDB, baseFeeKey) - if err == database.ErrNotFound { - // if baseFee is not in db yet, than its first time when we access it - // and it should be equal to config base fee - config, err := s.Config() - if err != nil { - return err - } - baseFee = config.TxFee - } else if err != nil { + switch { + case err == nil: + cs.baseFee = &baseFee + case err != database.ErrNotFound: return err } - cs.baseFee = baseFee feeDistribution, err := database.GetUInt64Slice(cs.caminoDB, feeDistributionKey) - if err == database.ErrNotFound { - // if fee distribution is not in db yet, than its first time when we access it - // and it should be equal to hardcoded fee distribution - feeDistribution = s.cfg.CaminoConfig.FeeDistribution[:] - } else if err != nil { + switch { + case err == nil: + cs.feeDistribution = (*[3]uint64)(feeDistribution) + case err != database.ErrNotFound: return err } - cs.feeDistribution = *(*[dac.FeeDistributionFractionsCount]uint64)(feeDistribution) // TODO @evlekht change when mod go is >= 1.20 errs := wrappers.Errs{} errs.Add( @@ -592,9 +582,13 @@ func (cs *caminoState) Write() error { database.PutBool(cs.caminoDB, depositBondModeKey, cs.lockModeBondDeposit), ) } + if cs.baseFee != nil { + errs.Add(database.PutUInt64(cs.caminoDB, baseFeeKey, *cs.baseFee)) + } + if cs.feeDistribution != nil { + errs.Add(database.PutUInt64Slice(cs.caminoDB, feeDistributionKey, cs.feeDistribution[:])) + } errs.Add( - database.PutUInt64(cs.caminoDB, baseFeeKey, cs.baseFee), - database.PutUInt64Slice(cs.caminoDB, feeDistributionKey, cs.feeDistribution[:]), cs.writeAddressStates(), cs.writeDepositOffers(), cs.writeDeposits(), @@ -627,17 +621,23 @@ func (cs *caminoState) Close() error { } func (cs *caminoState) GetBaseFee() (uint64, error) { - return cs.baseFee, nil + if cs.baseFee == nil { + return 0, database.ErrNotFound + } + return *cs.baseFee, nil } func (cs *caminoState) SetBaseFee(baseFee uint64) { - cs.baseFee = baseFee + cs.baseFee = &baseFee } func (cs *caminoState) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { - return cs.feeDistribution, nil + if cs.feeDistribution == nil { + return [3]uint64{}, database.ErrNotFound + } + return *cs.feeDistribution, nil } func (cs *caminoState) SetFeeDistribution(feeDistribution [dac.FeeDistributionFractionsCount]uint64) { - cs.feeDistribution = feeDistribution + cs.feeDistribution = &feeDistribution } diff --git a/vms/platformvm/state/camino_diff.go b/vms/platformvm/state/camino_diff.go index 3da77f0fd62e..fc6fa6586d58 100644 --- a/vms/platformvm/state/camino_diff.go +++ b/vms/platformvm/state/camino_diff.go @@ -15,7 +15,6 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/multisig" as "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/dac" "github.com/ava-labs/avalanchego/vms/platformvm/deposit" "github.com/ava-labs/avalanchego/vms/platformvm/locked" @@ -79,14 +78,6 @@ func (d *diff) LockedUTXOs(txIDs set.Set[ids.ID], addresses set.Set[ids.ShortID] return retUtxos, nil } -func (d *diff) Config() (*config.Config, error) { - parentState, ok := d.stateVersions.GetState(d.parentID) - if !ok { - return nil, fmt.Errorf("%w: %s", ErrMissingParentState, d.parentID) - } - return parentState.Config() -} - func (d *diff) CaminoConfig() (*CaminoConfig, error) { parentState, ok := d.stateVersions.GetState(d.parentID) if !ok { diff --git a/vms/platformvm/state/camino_diff_test.go b/vms/platformvm/state/camino_diff_test.go index ea470cc166d2..99dd96317828 100644 --- a/vms/platformvm/state/camino_diff_test.go +++ b/vms/platformvm/state/camino_diff_test.go @@ -18,7 +18,6 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/multisig" as "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/dac" "github.com/ava-labs/avalanchego/vms/platformvm/deposit" "github.com/ava-labs/avalanchego/vms/platformvm/locked" @@ -1896,62 +1895,6 @@ func TestDiffLockedUTXOs(t *testing.T) { } } -func TestDiffConfig(t *testing.T) { - parentStateID := ids.GenerateTestID() - testErr := errors.New("test err") - - tests := map[string]struct { - diff func(*gomock.Controller) *diff - expectedDiff func(*diff) *diff - expectedConfig *config.Config - expectedErr error - }{ - "OK": { - diff: func(c *gomock.Controller) *diff { - parentState := NewMockChain(c) - parentState.EXPECT().Config().Return(&config.Config{TxFee: 111}, nil) - return &diff{ - stateVersions: newMockStateVersions(c, parentStateID, parentState), - parentID: parentStateID, - } - }, - expectedDiff: func(actualDiff *diff) *diff { - return &diff{ - stateVersions: actualDiff.stateVersions, - parentID: actualDiff.parentID, - } - }, - expectedConfig: &config.Config{TxFee: 111}, - }, - "Fail: parent errored": { - diff: func(c *gomock.Controller) *diff { - parentState := NewMockChain(c) - parentState.EXPECT().Config().Return(nil, testErr) - return &diff{ - stateVersions: newMockStateVersions(c, parentStateID, parentState), - parentID: parentStateID, - } - }, - expectedDiff: func(actualDiff *diff) *diff { - return &diff{ - stateVersions: actualDiff.stateVersions, - parentID: actualDiff.parentID, - } - }, - expectedErr: testErr, - }, - } - for name, tt := range tests { - t.Run(name, func(t *testing.T) { - actualDiff := tt.diff(gomock.NewController(t)) - config, err := actualDiff.Config() - require.ErrorIs(t, err, tt.expectedErr) - require.Equal(t, tt.expectedConfig, config) - require.Equal(t, tt.expectedDiff(actualDiff), actualDiff) - }) - } -} - func TestDiffCaminoConfig(t *testing.T) { parentStateID := ids.GenerateTestID() testErr := errors.New("test err") diff --git a/vms/platformvm/state/camino_helpers_test.go b/vms/platformvm/state/camino_helpers_test.go index a4d007edf670..44f53090de01 100644 --- a/vms/platformvm/state/camino_helpers_test.go +++ b/vms/platformvm/state/camino_helpers_test.go @@ -15,7 +15,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/config" @@ -58,9 +57,7 @@ func newEmptyState(t *testing.T) *state { newState, err := newState( memdb.New(), metrics.Noop, - &config.Config{ - Validators: validators.NewManager(), - }, + validators.NewManager(), execCfg, &snow.Context{}, prometheus.NewRegistry(), @@ -70,7 +67,6 @@ func newEmptyState(t *testing.T) *state { MintingPeriod: 365 * 24 * time.Hour, SupplyCap: 720 * units.MegaAvax, }), - &utils.Atomic[bool]{}, ) require.NoError(t, err) require.NotNil(t, newState) diff --git a/vms/platformvm/state/camino_state.go b/vms/platformvm/state/camino_state.go index 22b8ef894127..129b3cc0d2a6 100644 --- a/vms/platformvm/state/camino_state.go +++ b/vms/platformvm/state/camino_state.go @@ -12,7 +12,6 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/multisig" as "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" - "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/dac" "github.com/ava-labs/avalanchego/vms/platformvm/deposit" "github.com/ava-labs/avalanchego/vms/platformvm/locked" @@ -42,10 +41,6 @@ func (s *state) LockedUTXOs(txIDs set.Set[ids.ID], addresses set.Set[ids.ShortID return retUtxos, nil } -func (s *state) Config() (*config.Config, error) { - return s.cfg, nil -} - func (s *state) CaminoConfig() (*CaminoConfig, error) { return s.caminoState.CaminoConfig(), nil } diff --git a/vms/platformvm/state/camino_test.go b/vms/platformvm/state/camino_test.go index 24a7e3966cde..d3ffc5089a57 100644 --- a/vms/platformvm/state/camino_test.go +++ b/vms/platformvm/state/camino_test.go @@ -449,6 +449,8 @@ func defaultGenesisState(addresses []pvm_genesis.AddressState, deposits []*txs.T } func TestGetBaseFee(t *testing.T) { + baseFee := uint64(123) + tests := map[string]struct { caminoState *caminoState expectedCaminoState *caminoState @@ -456,8 +458,8 @@ func TestGetBaseFee(t *testing.T) { expectedErr error }{ "OK": { - caminoState: &caminoState{baseFee: 123}, - expectedCaminoState: &caminoState{baseFee: 123}, + caminoState: &caminoState{baseFee: &baseFee}, + expectedCaminoState: &caminoState{baseFee: &baseFee}, expectedBaseFee: 123, }, } @@ -472,6 +474,8 @@ func TestGetBaseFee(t *testing.T) { } func TestSetBaseFee(t *testing.T) { + baseFee := uint64(123) + tests := map[string]struct { baseFee uint64 caminoState *caminoState @@ -479,8 +483,8 @@ func TestSetBaseFee(t *testing.T) { }{ "OK": { baseFee: 123, - caminoState: &caminoState{baseFee: 111}, - expectedCaminoState: &caminoState{baseFee: 123}, + caminoState: &caminoState{baseFee: &baseFee}, + expectedCaminoState: &caminoState{baseFee: &baseFee}, }, } for name, tt := range tests { diff --git a/vms/platformvm/state/test/camino_test_state.go b/vms/platformvm/state/test/camino_test_state.go index 40c3c305eeb9..5f9951b7c561 100644 --- a/vms/platformvm/state/test/camino_test_state.go +++ b/vms/platformvm/state/test/camino_test_state.go @@ -11,7 +11,7 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" @@ -21,7 +21,7 @@ import ( func State( t *testing.T, - cfg *config.Config, + validators validators.Manager, ctx *snow.Context, db database.Database, rewards reward.Calculator, @@ -34,12 +34,11 @@ func State( db, genesisBytes, prometheus.NewRegistry(), - cfg, + validators, execCfg, ctx, metrics.Noop, rewards, - &utils.Atomic[bool]{}, ) require.NoError(t, err) // persist and reload to init a bunch of in-memory stuff diff --git a/vms/platformvm/test/camino_defaults.go b/vms/platformvm/test/camino_defaults.go index 80180c29d5c2..851aef57eff9 100644 --- a/vms/platformvm/test/camino_defaults.go +++ b/vms/platformvm/test/camino_defaults.go @@ -151,10 +151,10 @@ func Genesis(t *testing.T, avaxAssetID ids.ID, caminoGenesisConfig api.Camino, a caminoGenesisConfig.ValidatorDeposits = make([][]api.UTXODeposit, len(FundedKeys)) caminoGenesisConfig.ValidatorConsortiumMembers = make([]ids.ShortID, len(FundedKeys)) - genesisValidators := make([]api.PermissionlessValidator, len(FundedKeys)) + genesisValidators := make([]api.GenesisPermissionlessValidator, len(FundedKeys)) for i, key := range FundedKeys { - genesisValidators[i] = api.PermissionlessValidator{ - Staker: api.Staker{ + genesisValidators[i] = api.GenesisPermissionlessValidator{ + GenesisValidator: api.GenesisValidator{ StartTime: json.Uint64(ValidatorStartTime.Unix()), EndTime: json.Uint64(ValidatorEndTime.Unix()), NodeID: FundedNodeIDs[i], diff --git a/vms/platformvm/txs/executor/camino_helpers_test.go b/vms/platformvm/txs/executor/camino_helpers_test.go index 2acbfb2f1e0d..33deb1afeaa1 100644 --- a/vms/platformvm/txs/executor/camino_helpers_test.go +++ b/vms/platformvm/txs/executor/camino_helpers_test.go @@ -53,7 +53,7 @@ func newCaminoEnvironment(t *testing.T, phase test.Phase, caminoGenesisConf api. rewards := reward.NewCalculator(config.RewardConfig) genesisBytes := test.Genesis(t, ctx.AVAXAssetID, caminoGenesisConf, nil) - baseState := testState.State(t, config, ctx, baseDB, rewards, genesisBytes) + baseState := testState.State(t, config.Validators, ctx, baseDB, rewards, genesisBytes) atomicUTXOs := avax.NewAtomicUTXOManager(ctx.SharedMemory, txs.Codec) uptimes := uptime.NewManager(baseState, clk) @@ -193,7 +193,7 @@ func newExecutorBackend( rewards := reward.NewCalculator(config.RewardConfig) genesisBytes := test.Genesis(t, ctx.AVAXAssetID, caminoGenesisConf, nil) - state := testState.State(t, config, ctx, baseDB, rewards, genesisBytes) + state := testState.State(t, config.Validators, ctx, baseDB, rewards, genesisBytes) if sharedMemory != nil { ctx.SharedMemory = &mutableSharedMemory{ diff --git a/vms/platformvm/txs/executor/camino_tx_executor.go b/vms/platformvm/txs/executor/camino_tx_executor.go index 086e873ee8ba..9a65974c0335 100644 --- a/vms/platformvm/txs/executor/camino_tx_executor.go +++ b/vms/platformvm/txs/executor/camino_tx_executor.go @@ -22,6 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/multisig" "github.com/ava-labs/avalanchego/vms/components/verify" as "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" + "github.com/ava-labs/avalanchego/vms/platformvm/config" dacProposals "github.com/ava-labs/avalanchego/vms/platformvm/dac" "github.com/ava-labs/avalanchego/vms/platformvm/locked" "github.com/ava-labs/avalanchego/vms/platformvm/state" @@ -757,7 +758,7 @@ func (e *CaminoStandardTxExecutor) DepositTx(tx *txs.DepositTx) error { return err } - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -888,7 +889,7 @@ func (e *CaminoStandardTxExecutor) UnlockDepositTx(tx *txs.UnlockDepositTx) erro amountToBurn := uint64(0) if !hasExpiredDeposits { - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -1137,7 +1138,7 @@ func (e *CaminoStandardTxExecutor) ClaimTx(tx *txs.ClaimTx) error { } // BaseTx check (fee, reward outs) - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -1244,7 +1245,7 @@ func (e *CaminoStandardTxExecutor) RegisterNodeTx(tx *txs.RegisterNodeTx) error } // verify the flowcheck - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -1502,7 +1503,7 @@ func (e *CaminoStandardTxExecutor) BaseTx(tx *txs.BaseTx) error { return err } - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -1593,7 +1594,7 @@ func (e *CaminoStandardTxExecutor) MultisigAliasTx(tx *txs.MultisigAliasTx) erro } // verify the flowcheck - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -1654,7 +1655,7 @@ func (e *CaminoStandardTxExecutor) AddDepositOfferTx(tx *txs.AddDepositOfferTx) } // verify the flowcheck - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -1812,7 +1813,7 @@ func (e *CaminoStandardTxExecutor) AddProposalTx(tx *txs.AddProposalTx) error { // verify the flowcheck lockState := locked.StateBonded - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -1947,7 +1948,7 @@ func (e *CaminoStandardTxExecutor) AddVoteTx(tx *txs.AddVoteTx) error { // verify the flowcheck - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -2274,7 +2275,7 @@ func (e *CaminoStandardTxExecutor) AddressStateTx(tx *txs.AddressStateTx) error } // Verify the flowcheck - baseFee, err := e.State.GetBaseFee() + baseFee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -2399,3 +2400,28 @@ func outputsAreEqual(outs1, outs2 []*avax.TransferableOutput) bool { return ok && out1.Asset == out2.Asset && outEq1.Equal(out2.Out) }) } + +func getBaseFee(s state.Chain, cfg *config.Config) (uint64, error) { + fee, err := s.GetBaseFee() + switch err { + case database.ErrNotFound: + return cfg.TxFee, nil + case nil: + return fee, nil + } + return 0, err +} + +// TODO@ remove nolint, when this func will be used. +// Currently its not used, cause we didn't implement P->C transport of proposal outcomes +// like new base fee or new fee distribution or at least api that will provide this info. +func getFeeDistribution(s state.Chain, cfg *config.Config) ([dacProposals.FeeDistributionFractionsCount]uint64, error) { //nolint:unused + feeDistribution, err := s.GetFeeDistribution() + switch err { + case database.ErrNotFound: + return cfg.CaminoConfig.FeeDistribution, nil + case nil: + return feeDistribution, nil + } + return [dacProposals.FeeDistributionFractionsCount]uint64{}, err +} diff --git a/vms/platformvm/txs/executor/staker_tx_verification.go b/vms/platformvm/txs/executor/staker_tx_verification.go index baa539410d75..882eee34fedd 100644 --- a/vms/platformvm/txs/executor/staker_tx_verification.go +++ b/vms/platformvm/txs/executor/staker_tx_verification.go @@ -325,7 +325,7 @@ func verifyRemoveSubnetValidatorTx( return nil, false, err } - fee, err := chainState.GetBaseFee() + fee, err := getBaseFee(chainState, backend.Config) if err != nil { return nil, false, err } diff --git a/vms/platformvm/txs/executor/standard_tx_executor.go b/vms/platformvm/txs/executor/standard_tx_executor.go index 85cab6d192ac..8fa65c185f30 100644 --- a/vms/platformvm/txs/executor/standard_tx_executor.go +++ b/vms/platformvm/txs/executor/standard_tx_executor.go @@ -181,7 +181,7 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error { copy(ins, tx.Ins) copy(ins[len(tx.Ins):], tx.ImportedInputs) - fee, err := e.State.GetBaseFee() + fee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } @@ -234,7 +234,7 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error { } } - fee, err := e.State.GetBaseFee() + fee, err := getBaseFee(e.State, e.Backend.Config) if err != nil { return err } diff --git a/vms/platformvm/txs/mempool/camino_visitor.go b/vms/platformvm/txs/mempool/camino_visitor.go deleted file mode 100644 index 5e87ab9ed296..000000000000 --- a/vms/platformvm/txs/mempool/camino_visitor.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2022-2024, Chain4Travel AG. All rights reserved. -// See the file LICENSE for licensing terms. - -package mempool - -import ( - "errors" - - "github.com/ava-labs/avalanchego/vms/platformvm/txs" -) - -var errUnsupportedTxType = errors.New("unsupported tx type") - -// Issuer - -func (i *issuer) AddressStateTx(*txs.AddressStateTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) DepositTx(*txs.DepositTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) UnlockDepositTx(*txs.UnlockDepositTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) ClaimTx(*txs.ClaimTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) RegisterNodeTx(*txs.RegisterNodeTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) RewardsImportTx(*txs.RewardsImportTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) MultisigAliasTx(*txs.MultisigAliasTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) AddDepositOfferTx(*txs.AddDepositOfferTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) AddProposalTx(*txs.AddProposalTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (i *issuer) AddVoteTx(*txs.AddVoteTx) error { - i.m.addDecisionTx(i.tx) - return nil -} - -func (*issuer) FinishProposalsTx(*txs.FinishProposalsTx) error { - return errUnsupportedTxType -} - -// Remover - -func (r *remover) AddressStateTx(*txs.AddressStateTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) DepositTx(*txs.DepositTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) UnlockDepositTx(*txs.UnlockDepositTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) ClaimTx(*txs.ClaimTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) RegisterNodeTx(*txs.RegisterNodeTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) RewardsImportTx(*txs.RewardsImportTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) MultisigAliasTx(*txs.MultisigAliasTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) AddDepositOfferTx(*txs.AddDepositOfferTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) AddProposalTx(*txs.AddProposalTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (r *remover) AddVoteTx(*txs.AddVoteTx) error { - r.m.removeDecisionTxs([]*txs.Tx{r.tx}) - return nil -} - -func (*remover) FinishProposalsTx(*txs.FinishProposalsTx) error { - // this tx is never in mempool - return nil -} diff --git a/vms/platformvm/utxo/camino_locked_test.go b/vms/platformvm/utxo/camino_locked_test.go index 18ddecced1e6..66acdb8a002c 100644 --- a/vms/platformvm/utxo/camino_locked_test.go +++ b/vms/platformvm/utxo/camino_locked_test.go @@ -160,7 +160,7 @@ func TestLock(t *testing.T) { rewardsCalc := reward.NewCalculator(config.RewardConfig) genesisBytes := test.Genesis(t, ctx.AVAXAssetID, api.Camino{}, nil) - testState := stateTest.State(t, config, ctx, baseDB, rewardsCalc, genesisBytes) + testState := stateTest.State(t, config.Validators, ctx, baseDB, rewardsCalc, genesisBytes) key, err := secp256k1.NewPrivateKey() require.NoError(t, err) diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 74d6a38d13c7..4957f564a41e 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -202,14 +202,15 @@ func (vm *VM) Initialize( txExecutorBackend, validatorManager, ) - vm.Network = network.New( + vm.Network = network.NewCamino( txExecutorBackend.Ctx, vm.manager, mempool, txExecutorBackend.Config.PartialSyncPrimaryNetwork, appSender, + vm.txBuilder, ) - vm.Builder = blockbuilder.CaminoNew( + vm.Builder = blockbuilder.New( mempool, vm.txBuilder, txExecutorBackend, From f4257b413197f2c3cf47df24310b2c70a847433c Mon Sep 17 00:00:00 2001 From: evlekht Date: Tue, 12 Mar 2024 14:52:38 +0400 Subject: [PATCH 265/267] [AVAX] Post Merge fixes for Cortina 17 (v1.10.17) --- .github/workflows/ci.yml | 2 +- codec/linearcodec/camino_codec.go | 14 +- go.mod | 2 +- go.sum | 4 +- scripts/build_tmpnetctl.sh | 4 +- scripts/camino_mocks.mockgen.txt | 4 +- scripts/mocks.mockgen.txt | 1 - scripts/tests.e2e.existing.sh | 8 +- scripts/tests.e2e.persistent.sh | 62 - scripts/tests.e2e.sh | 4 +- tests/fixture/tmpnet/local/config.go | 2 +- .../block/executor/proposal_block_test.go | 1 - .../block/executor/standard_block_test.go | 1 - vms/platformvm/state/camino.go | 2 +- vms/platformvm/state/camino_diff.go | 2 +- vms/platformvm/state/mock_chain.go | 1081 ----------- vms/platformvm/state/mock_diff.go | 1096 ----------- vms/platformvm/state/mock_state.go | 1621 ++++++++++++++--- vms/platformvm/state/state.go | 2 +- 19 files changed, 1373 insertions(+), 2540 deletions(-) delete mode 100755 scripts/tests.e2e.persistent.sh delete mode 100644 vms/platformvm/state/mock_chain.go delete mode 100644 vms/platformvm/state/mock_diff.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b4d4001147b..b5c78475b3b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,7 @@ jobs: run: ./scripts/build.sh -r - name: Run e2e tests with existing network shell: bash - run: E2E_SERIAL=1 ./scripts/tests.e2e.persistent.sh + run: E2E_SERIAL=1 ./scripts/tests.e2e.existing.sh Upgrade: runs-on: ubuntu-latest steps: diff --git a/codec/linearcodec/camino_codec.go b/codec/linearcodec/camino_codec.go index 462685276d03..4b38ee49ea7b 100644 --- a/codec/linearcodec/camino_codec.go +++ b/codec/linearcodec/camino_codec.go @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/reflectcodec" + "github.com/ava-labs/avalanchego/utils/bimap" ) const ( @@ -38,9 +39,8 @@ type caminoLinearCodec struct { func NewCamino(tagNames []string, maxSliceLen uint32) CaminoCodec { hCodec := &caminoLinearCodec{ linearCodec: linearCodec{ - nextTypeID: 0, - typeIDToType: map[uint32]reflect.Type{}, - typeToTypeID: map[reflect.Type]uint32{}, + nextTypeID: 0, + registeredTypes: bimap.New[uint32, reflect.Type](), }, nextCustomTypeID: firstCustomTypeID, } @@ -66,12 +66,10 @@ func (c *caminoLinearCodec) RegisterCustomType(val interface{}) error { defer c.lock.Unlock() valType := reflect.TypeOf(val) - if _, exists := c.typeToTypeID[valType]; exists { - return fmt.Errorf("type %v has already been registered", valType) + if c.registeredTypes.HasValue(valType) { + return fmt.Errorf("%w: %v", codec.ErrDuplicateType, valType) } - - c.typeIDToType[c.nextCustomTypeID] = valType - c.typeToTypeID[valType] = c.nextCustomTypeID + c.registeredTypes.Put(c.nextCustomTypeID, valType) c.nextCustomTypeID++ return nil } diff --git a/go.mod b/go.mod index fcdc317ff53a..a2c9afbedfe7 100644 --- a/go.mod +++ b/go.mod @@ -162,4 +162,4 @@ require ( replace github.com/ava-labs/avalanche-ledger-go => github.com/chain4travel/camino-ledger-go v0.0.13-c4t -replace github.com/ava-labs/coreth => github.com/chain4travel/caminoethvm v1.1.16-rc0 +replace github.com/ava-labs/coreth => github.com/chain4travel/caminoethvm v1.1.17-rc0 diff --git a/go.sum b/go.sum index 9c2dfd6ea248..96a31fa5df68 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chain4travel/caminoethvm v1.1.16-rc0 h1:yu2vadc5xzsQ6gtK7oNYBwVw+CsAVFvDj0894In71/M= -github.com/chain4travel/caminoethvm v1.1.16-rc0/go.mod h1:PgnbVryuhwq5IS7lI+TciNyqVPEru4gMOj3lzEBVPEE= +github.com/chain4travel/caminoethvm v1.1.17-rc0 h1:wA4Qds83AXP71w1XP1wlts7p6B8P70g14YRX3pnV9P8= +github.com/chain4travel/caminoethvm v1.1.17-rc0/go.mod h1:xSjZ76NJK1UUMaYl1mLrkdNbb1RDUhtBA71WXkJI50Y= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= diff --git a/scripts/build_tmpnetctl.sh b/scripts/build_tmpnetctl.sh index 5cbdb13a61e7..974e83efc467 100755 --- a/scripts/build_tmpnetctl.sh +++ b/scripts/build_tmpnetctl.sh @@ -15,5 +15,5 @@ LDFLAGS="$LDFLAGS $static_ld_flags" echo "Building tmpnetctl..." go build -ldflags "$LDFLAGS"\ - -o "$CAMINOGO_PATH/build/testnetctl"\ - "$CAMINOGO_PATH/tests/fixture/testnet/cmd/"*.go + -o "$CAMINOGO_PATH/build/tmpnetctl"\ + "$CAMINOGO_PATH/tests/fixture/tmpnet/cmd/"*.go diff --git a/scripts/camino_mocks.mockgen.txt b/scripts/camino_mocks.mockgen.txt index 287a9722c852..0eea8923cc3b 100644 --- a/scripts/camino_mocks.mockgen.txt +++ b/scripts/camino_mocks.mockgen.txt @@ -5,9 +5,7 @@ github.com/ava-labs/avalanchego/cache=Cacher=cache/mock_cacher.go github.com/ava-labs/avalanchego/vms/components/avax=AtomicUTXOManager=vms/components/avax/mock_atomic_utxos.go -github.com/ava-labs/avalanchego/vms/platformvm/state=Chain=vms/platformvm/state/mock_chain.go -github.com/ava-labs/avalanchego/vms/platformvm/state=Diff=vms/platformvm/state/mock_diff.go -github.com/ava-labs/avalanchego/vms/platformvm/state=State=vms/platformvm/state/mock_state.go +github.com/ava-labs/avalanchego/vms/platformvm/state=Chain,Diff,State,Versions=vms/platformvm/state/mock_state.go // avax also have their own mocks excluded from list, diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 248ed77f78dc..8f1766bc645a 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -33,7 +33,6 @@ github.com/ava-labs/avalanchego/vms/components/avax=TransferableIn=vms/component github.com/ava-labs/avalanchego/vms/components/verify=Verifiable=vms/components/verify/mock_verifiable.go github.com/ava-labs/avalanchego/vms/platformvm/block/executor=Manager=vms/platformvm/block/executor/mock_manager.go github.com/ava-labs/avalanchego/vms/platformvm/block=Block=vms/platformvm/block/mock_block.go -github.com/ava-labs/avalanchego/vms/platformvm/state=Versions=vms/platformvm/state/mock_versions.go github.com/ava-labs/avalanchego/vms/platformvm/state=StakerIterator=vms/platformvm/state/mock_staker_iterator.go github.com/ava-labs/avalanchego/vms/platformvm/txs/builder=Builder=vms/platformvm/txs/builder/mock_builder.go github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool=Mempool=vms/platformvm/txs/mempool/mock_mempool.go diff --git a/scripts/tests.e2e.existing.sh b/scripts/tests.e2e.existing.sh index bc1f8104977b..98f5e3f79482 100755 --- a/scripts/tests.e2e.existing.sh +++ b/scripts/tests.e2e.existing.sh @@ -14,7 +14,7 @@ set -euo pipefail # ./scripts/build.sh # ./scripts/tests.e2e.existing.sh --ginkgo.label-filter=x # All arguments are supplied to ginkgo # E2E_SERIAL=1 ./scripts/tests.e2e.sh # Run tests serially -# AVALANCHEGO_PATH=./build/avalanchego ./scripts/tests.e2e.existing.sh # Customization of avalanchego path +# CAMINOGO_BIN_PATH=./build/caminogo ./scripts/tests.e2e.existing.sh # Customization of caminogo path if ! [[ "$0" =~ scripts/tests.e2e.existing.sh ]]; then echo "must be run from repository root" exit 255 @@ -22,7 +22,8 @@ fi # Ensure an absolute path to avoid dependency on the working directory # of script execution. -export AVALANCHEGO_PATH="$(realpath ${AVALANCHEGO_PATH:-./build/avalanchego})" +CAMINOGO_BIN_PATH="$(realpath "${CAMINOGO_BIN_PATH:-./build/caminogo}")" +export CAMINOGO_BIN_PATH # Provide visual separation between testing and setup/teardown function print_separator { @@ -47,7 +48,8 @@ print_separator # Determine the network configuration path from the latest symlink LATEST_SYMLINK_PATH="${HOME}/.tmpnet/networks/latest" if [[ -h "${LATEST_SYMLINK_PATH}" ]]; then - export TMPNET_NETWORK_DIR="$(realpath ${LATEST_SYMLINK_PATH})" + TMPNET_NETWORK_DIR="$(realpath "${LATEST_SYMLINK_PATH}")" + export TMPNET_NETWORK_DIR else echo "failed to find configuration path: ${LATEST_SYMLINK_PATH} symlink not found" exit 255 diff --git a/scripts/tests.e2e.persistent.sh b/scripts/tests.e2e.persistent.sh deleted file mode 100755 index 35bdd74db98b..000000000000 --- a/scripts/tests.e2e.persistent.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -################################################################ -# This script deploys a persistent local network and configures -# tests.e2e.sh to execute the e2e suite against it. -################################################################ - -# e.g., -# ./scripts/build.sh -# ./scripts/tests.e2e.persistent.sh --ginkgo.label-filter=x # All arguments are supplied to ginkgo -# E2E_SERIAL=1 ./scripts/tests.e2e.sh # Run tests serially -# CAMINOGO_BIN_PATH=./build/caminogo ./scripts/tests.e2e.persistent.sh # Customization of caminogo path -if ! [[ "$0" =~ scripts/tests.e2e.persistent.sh ]]; then - echo "must be run from repository root" - exit 255 -fi - -# Ensure an absolute path to avoid dependency on the working directory -# of script execution. -CAMINOGO_BIN_PATH="$(realpath "${CAMINOGO_BIN_PATH:-./build/caminogo}")" -export CAMINOGO_BIN_PATH - -# Provide visual separation between testing and setup/teardown -function print_separator { - printf '%*s\n' "${COLUMNS:-80}" '' | tr ' ' ─ -} - -# Ensure network cleanup on teardown -function cleanup { - print_separator - echo "cleaning up persistent network" - if [[ -n "${TESTNETCTL_NETWORK_DIR:-}" ]]; then - ./build/testnetctl stop-network - fi -} -trap cleanup EXIT - -# Start a persistent network -./scripts/build_testnetctl.sh -print_separator -./build/testnetctl start-network - -# Determine the network configuration path from the latest symlink -LATEST_SYMLINK_PATH="${HOME}/.testnetctl/networks/latest" -if [[ -h "${LATEST_SYMLINK_PATH}" ]]; then - TESTNETCTL_NETWORK_DIR="$(realpath "${LATEST_SYMLINK_PATH}")" - export TESTNETCTL_NETWORK_DIR -else - echo "failed to find configuration path: ${LATEST_SYMLINK_PATH} symlink not found" - exit 255 -fi - -print_separator -# - Setting E2E_USE_PERSISTENT_NETWORK configures tests.e2e.sh to use -# the persistent network identified by TESTNETCTL_NETWORK_DIR. -# - Only a single test (selected with --ginkgo.focus-file) is required -# to validate that a persistent network can be used by an e2e test -# suite run. Executing more tests would be duplicative of the testing -# performed against an ephemeral test network. -E2E_USE_PERSISTENT_NETWORK=1 ./scripts/tests.e2e.sh --ginkgo.focus-file=permissionless_subnets.go diff --git a/scripts/tests.e2e.sh b/scripts/tests.e2e.sh index 6eaf30005671..9e4acfe18089 100755 --- a/scripts/tests.e2e.sh +++ b/scripts/tests.e2e.sh @@ -34,7 +34,7 @@ ACK_GINKGO_RC=true ginkgo build ./tests/e2e if [[ -n "${E2E_USE_EXISTING_NETWORK:-}" && -n "${TMPNET_NETWORK_DIR:-}" ]]; then E2E_ARGS="--use-existing-network" else - CAMINOGO_BIN_PATH="$(realpath ${CAMINOGO_BIN_PATH:-./build/caminogo})" + CAMINOGO_BIN_PATH="$(realpath "${CAMINOGO_BIN_PATH:-./build/caminogo}")" E2E_ARGS="--avalanchego-path=${CAMINOGO_BIN_PATH}" fi @@ -60,4 +60,4 @@ fi ################################# # - Execute in random order to identify unwanted dependency -ginkgo -p -v --randomize-all ./tests/e2e/e2e.test -- ${E2E_ARGS} "${@}" +ginkgo "${GINKGO_ARGS}" -v --randomize-all ./tests/e2e/e2e.test -- "${E2E_ARGS[@]}" "${@}" diff --git a/tests/fixture/tmpnet/local/config.go b/tests/fixture/tmpnet/local/config.go index 70ef9a443185..8d1d88494701 100644 --- a/tests/fixture/tmpnet/local/config.go +++ b/tests/fixture/tmpnet/local/config.go @@ -13,7 +13,7 @@ import ( const ( // Constants defining the names of shell variables whose value can // configure local network orchestration. - AvalancheGoPathEnvName = "AVALANCHEGO_PATH" + AvalancheGoPathEnvName = "CAMINOGO_BIN_PATH" NetworkDirEnvName = "TMPNET_NETWORK_DIR" RootDirEnvName = "TMPNET_ROOT_DIR" diff --git a/vms/platformvm/block/executor/proposal_block_test.go b/vms/platformvm/block/executor/proposal_block_test.go index a13c073bcd7a..35261f37d00a 100644 --- a/vms/platformvm/block/executor/proposal_block_test.go +++ b/vms/platformvm/block/executor/proposal_block_test.go @@ -199,7 +199,6 @@ func TestBanffProposalBlockTimeVerification(t *testing.T) { } return nil, database.ErrNotFound }).AnyTimes() - onParentAccept.EXPECT().Config().Return(env.config, nil).AnyTimes() // setup state to validate proposal block transaction nextStakerTime := chainTime.Add(executor.SyncBound).Add(-1 * time.Second) diff --git a/vms/platformvm/block/executor/standard_block_test.go b/vms/platformvm/block/executor/standard_block_test.go index 232cf025ff75..0b2be59c22c0 100644 --- a/vms/platformvm/block/executor/standard_block_test.go +++ b/vms/platformvm/block/executor/standard_block_test.go @@ -129,7 +129,6 @@ func TestBanffStandardBlockTimeVerification(t *testing.T) { env.blkManager.(*manager).lastAccepted = parentID env.mockedState.EXPECT().GetLastAccepted().Return(parentID).AnyTimes() env.mockedState.EXPECT().GetTimestamp().Return(chainTime).AnyTimes() - onParentAccept.EXPECT().Config().Return(env.config, nil).AnyTimes() nextStakerTime := chainTime.Add(executor.SyncBound).Add(-1 * time.Second) diff --git a/vms/platformvm/state/camino.go b/vms/platformvm/state/camino.go index 2a45ed5fc6f7..d9a4379122a9 100644 --- a/vms/platformvm/state/camino.go +++ b/vms/platformvm/state/camino.go @@ -71,7 +71,7 @@ var ( ) type CaminoApply interface { - ApplyCaminoState(State) error + ApplyCaminoState(Chain) error } type CaminoDiff interface { diff --git a/vms/platformvm/state/camino_diff.go b/vms/platformvm/state/camino_diff.go index fc6fa6586d58..fc5c89d4052b 100644 --- a/vms/platformvm/state/camino_diff.go +++ b/vms/platformvm/state/camino_diff.go @@ -643,7 +643,7 @@ func (d *diff) SetFeeDistribution(feeDistribution [dac.FeeDistributionFractionsC } // Finally apply all changes -func (d *diff) ApplyCaminoState(baseState State) error { +func (d *diff) ApplyCaminoState(baseState Chain) error { if d.caminoDiff.modifiedNotDistributedValidatorReward != nil { baseState.SetNotDistributedValidatorReward(*d.caminoDiff.modifiedNotDistributedValidatorReward) } diff --git a/vms/platformvm/state/mock_chain.go b/vms/platformvm/state/mock_chain.go deleted file mode 100644 index 3f35686b57d0..000000000000 --- a/vms/platformvm/state/mock_chain.go +++ /dev/null @@ -1,1081 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Chain) - -// Package state is a generated GoMock package. -package state - -import ( - reflect "reflect" - time "time" - - ids "github.com/ava-labs/avalanchego/ids" - set "github.com/ava-labs/avalanchego/utils/set" - avax "github.com/ava-labs/avalanchego/vms/components/avax" - multisig "github.com/ava-labs/avalanchego/vms/components/multisig" - addrstate "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" - config "github.com/ava-labs/avalanchego/vms/platformvm/config" - dac "github.com/ava-labs/avalanchego/vms/platformvm/dac" - deposit "github.com/ava-labs/avalanchego/vms/platformvm/deposit" - fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" - locked "github.com/ava-labs/avalanchego/vms/platformvm/locked" - status "github.com/ava-labs/avalanchego/vms/platformvm/status" - txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" - gomock "go.uber.org/mock/gomock" -) - -// MockChain is a mock of Chain interface. -type MockChain struct { - ctrl *gomock.Controller - recorder *MockChainMockRecorder -} - -// MockChainMockRecorder is the mock recorder for MockChain. -type MockChainMockRecorder struct { - mock *MockChain -} - -// NewMockChain creates a new mock instance. -func NewMockChain(ctrl *gomock.Controller) *MockChain { - mock := &MockChain{ctrl: ctrl} - mock.recorder = &MockChainMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockChain) EXPECT() *MockChainMockRecorder { - return m.recorder -} - -// AddChain mocks base method. -func (m *MockChain) AddChain(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0) -} - -// AddChain indicates an expected call of AddChain. -func (mr *MockChainMockRecorder) AddChain(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockChain)(nil).AddChain), arg0) -} - -// SetDepositOffer mocks base method. -func (m *MockChain) SetDepositOffer(arg0 *deposit.Offer) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetDepositOffer", arg0) -} - -// SetDepositOffer indicates an expected call of SetDepositOffer. -func (mr *MockChainMockRecorder) SetDepositOffer(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockChain)(nil).SetDepositOffer), arg0) -} - -// AddRewardUTXO mocks base method. -func (m *MockChain) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) -} - -// AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockChainMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockChain)(nil).AddRewardUTXO), arg0, arg1) -} - -// AddSubnet mocks base method. -func (m *MockChain) AddSubnet(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnet", arg0) -} - -// AddSubnet indicates an expected call of AddSubnet. -func (mr *MockChainMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockChain)(nil).AddSubnet), arg0) -} - -// AddSubnetTransformation mocks base method. -func (m *MockChain) AddSubnetTransformation(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnetTransformation", arg0) -} - -// AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockChainMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockChain)(nil).AddSubnetTransformation), arg0) -} - -// AddTx mocks base method. -func (m *MockChain) AddTx(arg0 *txs.Tx, arg1 status.Status) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddTx", arg0, arg1) -} - -// AddTx indicates an expected call of AddTx. -func (mr *MockChainMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockChain)(nil).AddTx), arg0, arg1) -} - -// AddUTXO mocks base method. -func (m *MockChain) AddUTXO(arg0 *avax.UTXO) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddUTXO", arg0) -} - -// AddUTXO indicates an expected call of AddUTXO. -func (mr *MockChainMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockChain)(nil).AddUTXO), arg0) -} - -// CaminoConfig mocks base method. -func (m *MockChain) CaminoConfig() (*CaminoConfig, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CaminoConfig") - ret0, _ := ret[0].(*CaminoConfig) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CaminoConfig indicates an expected call of CaminoConfig. -func (mr *MockChainMockRecorder) CaminoConfig() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockChain)(nil).CaminoConfig)) -} - -// Config mocks base method. -func (m *MockChain) Config() (*config.Config, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Config") - ret0, _ := ret[0].(*config.Config) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Config indicates an expected call of Config. -func (mr *MockChainMockRecorder) Config() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Config", reflect.TypeOf((*MockChain)(nil).Config)) -} - -// DeleteCurrentDelegator mocks base method. -func (m *MockChain) DeleteCurrentDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) -} - -// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockChainMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentDelegator), arg0) -} - -// DeleteCurrentValidator mocks base method. -func (m *MockChain) DeleteCurrentValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentValidator", arg0) -} - -// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockChainMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentValidator), arg0) -} - -// DeletePendingDelegator mocks base method. -func (m *MockChain) DeletePendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingDelegator", arg0) -} - -// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockChainMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockChain)(nil).DeletePendingDelegator), arg0) -} - -// DeletePendingValidator mocks base method. -func (m *MockChain) DeletePendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingValidator", arg0) -} - -// DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockChainMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockChain)(nil).DeletePendingValidator), arg0) -} - -// DeleteUTXO mocks base method. -func (m *MockChain) DeleteUTXO(arg0 ids.ID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteUTXO", arg0) -} - -// DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockChainMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), arg0) -} - -// GetAddressStates mocks base method. -func (m *MockChain) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAddressStates", arg0) - ret0, _ := ret[0].(addrstate.AddressState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAddressStates indicates an expected call of GetAddressStates. -func (mr *MockChainMockRecorder) GetAddressStates(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockChain)(nil).GetAddressStates), arg0) -} - -// GetAllDepositOffers mocks base method. -func (m *MockChain) GetAllDepositOffers() ([]*deposit.Offer, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAllDepositOffers") - ret0, _ := ret[0].([]*deposit.Offer) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAllDepositOffers indicates an expected call of GetAllDepositOffers. -func (mr *MockChainMockRecorder) GetAllDepositOffers() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockChain)(nil).GetAllDepositOffers)) -} - -// GetChains mocks base method. -func (m *MockChain) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChains", arg0) - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChains indicates an expected call of GetChains. -func (mr *MockChainMockRecorder) GetChains(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockChain)(nil).GetChains), arg0) -} - -// GetClaimable mocks base method. -func (m *MockChain) GetClaimable(arg0 ids.ID) (*Claimable, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetClaimable", arg0) - ret0, _ := ret[0].(*Claimable) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetClaimable indicates an expected call of GetClaimable. -func (mr *MockChainMockRecorder) GetClaimable(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockChain)(nil).GetClaimable), arg0) -} - -// GetProposal mocks base method. -func (m *MockChain) GetProposal(arg0 ids.ID) (dac.ProposalState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposal", arg0) - ret0, _ := ret[0].(dac.ProposalState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetProposal indicates an expected call of GetProposal. -func (mr *MockChainMockRecorder) GetProposal(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockChain)(nil).GetProposal), arg0) -} - -// GetBaseFee mocks base method. -func (m *MockChain) GetBaseFee() (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBaseFee") - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBaseFee indicates an expected call of GetBaseFee. -func (mr *MockChainMockRecorder) GetBaseFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockChain)(nil).GetBaseFee)) -} - -// GetFeeDistribution mocks base method. -func (m *MockChain) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetFeeDistribution") - ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetFeeDistribution indicates an expected call of GetFeeDistribution. -func (mr *MockChainMockRecorder) GetFeeDistribution() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockChain)(nil).GetFeeDistribution)) -} - -// GetCurrentDelegatorIterator mocks base method. -func (m *MockChain) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), arg0, arg1) -} - -// GetCurrentStakerIterator mocks base method. -func (m *MockChain) GetCurrentStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. -func (mr *MockChainMockRecorder) GetCurrentStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentStakerIterator)) -} - -// GetCurrentSupply mocks base method. -func (m *MockChain) GetCurrentSupply(arg0 ids.ID) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockChainMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockChain)(nil).GetCurrentSupply), arg0) -} - -// GetCurrentValidator mocks base method. -func (m *MockChain) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockChainMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockChain)(nil).GetCurrentValidator), arg0, arg1) -} - -// GetDelegateeReward mocks base method. -func (m *MockChain) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockChainMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockChain)(nil).GetDelegateeReward), arg0, arg1) -} - -// GetDeposit mocks base method. -func (m *MockChain) GetDeposit(arg0 ids.ID) (*deposit.Deposit, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeposit", arg0) - ret0, _ := ret[0].(*deposit.Deposit) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDeposit indicates an expected call of GetDeposit. -func (mr *MockChainMockRecorder) GetDeposit(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockChain)(nil).GetDeposit), arg0) -} - -// GetNextToUnlockDepositTime mocks base method. -func (m *MockChain) GetNextToUnlockDepositTime(arg0 set.Set[ids.ID]) (time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", arg0) - ret0, _ := ret[0].(time.Time) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. -func (mr *MockChainMockRecorder) GetNextToUnlockDepositTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockChain)(nil).GetNextToUnlockDepositTime), arg0) -} - -// GetNextToUnlockDepositIDsAndTime mocks base method. -func (m *MockChain) GetNextToUnlockDepositIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. -func (mr *MockChainMockRecorder) GetNextToUnlockDepositIDsAndTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockChain)(nil).GetNextToUnlockDepositIDsAndTime), arg0) -} - -// GetNextProposalExpirationTime mocks base method. -func (m *MockChain) GetNextProposalExpirationTime(arg0 set.Set[ids.ID]) (time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", arg0) - ret0, _ := ret[0].(time.Time) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. -func (mr *MockChainMockRecorder) GetNextProposalExpirationTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockChain)(nil).GetNextProposalExpirationTime), arg0) -} - -// GetNextToExpireProposalIDsAndTime mocks base method. -func (m *MockChain) GetNextToExpireProposalIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. -func (mr *MockChainMockRecorder) GetNextToExpireProposalIDsAndTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockChain)(nil).GetNextToExpireProposalIDsAndTime), arg0) -} - -// GetProposalIDsToFinish mocks base method. -func (m *MockChain) GetProposalIDsToFinish() ([]ids.ID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposalIDsToFinish") - ret0, _ := ret[0].([]ids.ID) - ret2, _ := ret[1].(error) - return ret0, ret2 -} - -// GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. -func (mr *MockChainMockRecorder) GetProposalIDsToFinish() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockChain)(nil).GetProposalIDsToFinish)) -} - -// GetProposalIterator mocks base method. -func (m *MockChain) GetProposalIterator() (ProposalsIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposalIterator") - ret0, _ := ret[0].(ProposalsIterator) - ret2, _ := ret[1].(error) - return ret0, ret2 -} - -// GetProposalIterator indicates an expected call of GetProposalIterator. -func (mr *MockChainMockRecorder) GetProposalIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockChain)(nil).GetProposalIterator)) -} - -// GetDepositOffer mocks base method. -func (m *MockChain) GetDepositOffer(arg0 ids.ID) (*deposit.Offer, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDepositOffer", arg0) - ret0, _ := ret[0].(*deposit.Offer) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDepositOffer indicates an expected call of GetDepositOffer. -func (mr *MockChainMockRecorder) GetDepositOffer(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockChain)(nil).GetDepositOffer), arg0) -} - -// GetMultisigAlias mocks base method. -func (m *MockChain) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) - ret0, _ := ret[0].(*multisig.AliasWithNonce) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetMultisigAlias indicates an expected call of GetMultisigAlias. -func (mr *MockChainMockRecorder) GetMultisigAlias(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockChain)(nil).GetMultisigAlias), arg0) -} - -// GetNotDistributedValidatorReward mocks base method. -func (m *MockChain) GetNotDistributedValidatorReward() (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. -func (mr *MockChainMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockChain)(nil).GetNotDistributedValidatorReward)) -} - -// GetPendingDelegatorIterator mocks base method. -func (m *MockChain) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetPendingDelegatorIterator), arg0, arg1) -} - -// GetPendingStakerIterator mocks base method. -func (m *MockChain) GetPendingStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. -func (mr *MockChainMockRecorder) GetPendingStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockChain)(nil).GetPendingStakerIterator)) -} - -// GetPendingValidator mocks base method. -func (m *MockChain) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), arg0, arg1) -} - -// GetDeferredStakerIterator mocks base method. -func (m *MockChain) GetDeferredStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. -func (mr *MockChainMockRecorder) GetDeferredStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockChain)(nil).GetDeferredStakerIterator)) -} - -// GetDeferredValidator mocks base method. -func (m *MockChain) GetDeferredValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDeferredValidator indicates an expected call of GetDeferredValidator. -func (mr *MockChainMockRecorder) GetDeferredValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockChain)(nil).GetDeferredValidator), arg0, arg1) -} - -// DeleteDeferredValidator mocks base method. -func (m *MockChain) DeleteDeferredValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteDeferredValidator", arg0) -} - -// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. -func (mr *MockChainMockRecorder) DeleteDeferredValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockChain)(nil).DeleteDeferredValidator), arg0) -} - -// PutDeferredValidator mocks base method. -func (m *MockChain) PutDeferredValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutDeferredValidator", arg0) -} - -// PutDeferredValidator indicates an expected call of PutDeferredValidator. -func (mr *MockChainMockRecorder) PutDeferredValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockChain)(nil).PutDeferredValidator), arg0) -} - -// GetRewardUTXOs mocks base method. -func (m *MockChain) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. -func (mr *MockChainMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockChain)(nil).GetRewardUTXOs), arg0) -} - -// GetSubnetOwner mocks base method. -func (m *MockChain) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockChainMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockChain)(nil).GetSubnetOwner), arg0) -} - -// GetShortIDLink mocks base method. -func (m *MockChain) GetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey) (ids.ShortID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetShortIDLink", arg0, arg1) - ret0, _ := ret[0].(ids.ShortID) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetShortIDLink indicates an expected call of GetShortIDLink. -func (mr *MockChainMockRecorder) GetShortIDLink(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockChain)(nil).GetShortIDLink), arg0, arg1) -} - -// GetSubnetTransformation mocks base method. -func (m *MockChain) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), arg0) -} - -// GetSubnets mocks base method. -func (m *MockChain) GetSubnets() ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnets") - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnets indicates an expected call of GetSubnets. -func (mr *MockChainMockRecorder) GetSubnets() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockChain)(nil).GetSubnets)) -} - -// GetTimestamp mocks base method. -func (m *MockChain) GetTimestamp() time.Time { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTimestamp") - ret0, _ := ret[0].(time.Time) - return ret0 -} - -// GetTimestamp indicates an expected call of GetTimestamp. -func (mr *MockChainMockRecorder) GetTimestamp() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockChain)(nil).GetTimestamp)) -} - -// GetTx mocks base method. -func (m *MockChain) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(status.Status) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetTx indicates an expected call of GetTx. -func (mr *MockChainMockRecorder) GetTx(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), arg0) -} - -// GetUTXO mocks base method. -func (m *MockChain) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0) - ret0, _ := ret[0].(*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetUTXO indicates an expected call of GetUTXO. -func (mr *MockChainMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), arg0) -} - -// LockedUTXOs mocks base method. -func (m *MockChain) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// LockedUTXOs indicates an expected call of LockedUTXOs. -func (mr *MockChainMockRecorder) LockedUTXOs(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockChain)(nil).LockedUTXOs), arg0, arg1, arg2) -} - -// PutCurrentDelegator mocks base method. -func (m *MockChain) PutCurrentDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentDelegator", arg0) -} - -// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockChainMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockChain)(nil).PutCurrentDelegator), arg0) -} - -// PutCurrentValidator mocks base method. -func (m *MockChain) PutCurrentValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentValidator", arg0) -} - -// PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockChainMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockChain)(nil).PutCurrentValidator), arg0) -} - -// PutPendingDelegator mocks base method. -func (m *MockChain) PutPendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingDelegator", arg0) -} - -// PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockChainMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockChain)(nil).PutPendingDelegator), arg0) -} - -// PutPendingValidator mocks base method. -func (m *MockChain) PutPendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingValidator", arg0) -} - -// PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockChainMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), arg0) -} - -// SetAddressStates mocks base method. -func (m *MockChain) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetAddressStates", arg0, arg1) -} - -// SetAddressStates indicates an expected call of SetAddressStates. -func (mr *MockChainMockRecorder) SetAddressStates(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockChain)(nil).SetAddressStates), arg0, arg1) -} - -// SetClaimable mocks base method. -func (m *MockChain) SetClaimable(arg0 ids.ID, arg1 *Claimable) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetClaimable", arg0, arg1) -} - -// SetClaimable indicates an expected call of SetClaimable. -func (mr *MockChainMockRecorder) SetClaimable(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockChain)(nil).SetClaimable), arg0, arg1) -} - -// AddProposal mocks base method. -func (m *MockChain) AddProposal(arg0 ids.ID, arg1 dac.ProposalState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposal", arg0, arg1) -} - -// AddProposal indicates an expected call of AddProposal. -func (mr *MockChainMockRecorder) AddProposal(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockChain)(nil).AddProposal), arg0, arg1) -} - -// ModifyProposal mocks base method. -func (m *MockChain) ModifyProposal(arg0 ids.ID, arg1 dac.ProposalState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyProposal", arg0, arg1) -} - -// ModifyProposal indicates an expected call of ModifyProposal. -func (mr *MockChainMockRecorder) ModifyProposal(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockChain)(nil).ModifyProposal), arg0, arg1) -} - -// RemoveProposal mocks base method. -func (m *MockChain) RemoveProposal(arg0 ids.ID, arg1 dac.ProposalState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposal", arg0, arg1) -} - -// RemoveProposal indicates an expected call of RemoveProposal. -func (mr *MockChainMockRecorder) RemoveProposal(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockChain)(nil).RemoveProposal), arg0, arg1) -} - -// AddProposalIDToFinish mocks base method. -func (m *MockChain) AddProposalIDToFinish(arg0 ids.ID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposalIDToFinish", arg0) -} - -// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. -func (mr *MockChainMockRecorder) AddProposalIDToFinish(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockChain)(nil).AddProposalIDToFinish), arg0) -} - -// RemoveProposalIDToFinish mocks base method. -func (m *MockChain) RemoveProposalIDToFinish(arg0 ids.ID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) -} - -// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. -func (mr *MockChainMockRecorder) RemoveProposalIDToFinish(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockChain)(nil).RemoveProposalIDToFinish), arg0) -} - -// SetBaseFee mocks base method. -func (m *MockChain) SetBaseFee(arg0 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetBaseFee", arg0) -} - -// SetBaseFee indicates an expected call of SetBaseFee. -func (mr *MockChainMockRecorder) SetBaseFee(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockChain)(nil).SetBaseFee), arg0) -} - -// SetFeeDistribution mocks base method. -func (m *MockChain) SetFeeDistribution(arg0 [dac.FeeDistributionFractionsCount]uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetFeeDistribution", arg0) -} - -// SetFeeDistribution indicates an expected call of SetFeeDistribution. -func (mr *MockChainMockRecorder) SetFeeDistribution(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockChain)(nil).SetFeeDistribution), arg0) -} - -// SetCurrentSupply mocks base method. -func (m *MockChain) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) -} - -// SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockChainMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockChain)(nil).SetCurrentSupply), arg0, arg1) -} - -// SetDelegateeReward mocks base method. -func (m *MockChain) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockChainMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockChain)(nil).SetDelegateeReward), arg0, arg1, arg2) -} - -// SetSubnetOwner mocks base method. -func (m *MockChain) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) -} - -// SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockChainMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockChain)(nil).SetSubnetOwner), arg0, arg1) -} - -// SetLastRewardImportTimestamp mocks base method. -func (m *MockChain) SetLastRewardImportTimestamp(arg0 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetLastRewardImportTimestamp", arg0) -} - -// SetLastRewardImportTimestamp indicates an expected call of SetLastRewardImportTimestamp. -func (mr *MockChainMockRecorder) SetLastRewardImportTimestamp(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastRewardImportTimestamp", reflect.TypeOf((*MockChain)(nil).SetLastRewardImportTimestamp), - arg0) -} - -// SetMultisigAlias mocks base method. -func (m *MockChain) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) -} - -// SetMultisigAlias indicates an expected call of SetMultisigAlias. -func (mr *MockChainMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockChain)(nil).SetMultisigAlias), arg0, arg1) -} - -// SetNotDistributedValidatorReward mocks base method. -func (m *MockChain) SetNotDistributedValidatorReward(arg0 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetNotDistributedValidatorReward", arg0) -} - -// SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. -func (mr *MockChainMockRecorder) SetNotDistributedValidatorReward(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockChain)(nil).SetNotDistributedValidatorReward), arg0) -} - -// SetShortIDLink mocks base method. -func (m *MockChain) SetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey, arg2 *ids.ShortID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetShortIDLink", arg0, arg1, arg2) -} - -// SetShortIDLink indicates an expected call of SetShortIDLink. -func (mr *MockChainMockRecorder) SetShortIDLink(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockChain)(nil).SetShortIDLink), arg0, arg1, arg2) -} - -// SetTimestamp mocks base method. -func (m *MockChain) SetTimestamp(arg0 time.Time) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetTimestamp", arg0) -} - -// SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockChainMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), arg0) -} - -// AddDeposit mocks base method. -func (m *MockChain) AddDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddDeposit", arg0, arg1) -} - -// AddDeposit indicates an expected call of AddDeposit. -func (mr *MockChainMockRecorder) AddDeposit(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockChain)(nil).AddDeposit), arg0, arg1) -} - -// ModifyDeposit mocks base method. -func (m *MockChain) ModifyDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyDeposit", arg0, arg1) -} - -// ModifyDeposit indicates an expected call of ModifyDeposit. -func (mr *MockChainMockRecorder) ModifyDeposit(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockChain)(nil).ModifyDeposit), arg0, arg1) -} - -// RemoveDeposit mocks base method. -func (m *MockChain) RemoveDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveDeposit", arg0, arg1) -} - -// RemoveDeposit indicates an expected call of RemoveDeposit. -func (mr *MockChainMockRecorder) RemoveDeposit(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockChain)(nil).RemoveDeposit), arg0, arg1) -} diff --git a/vms/platformvm/state/mock_diff.go b/vms/platformvm/state/mock_diff.go deleted file mode 100644 index a33660d98af6..000000000000 --- a/vms/platformvm/state/mock_diff.go +++ /dev/null @@ -1,1096 +0,0 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Diff) - -// Package state is a generated GoMock package. -package state - -import ( - reflect "reflect" - time "time" - - ids "github.com/ava-labs/avalanchego/ids" - set "github.com/ava-labs/avalanchego/utils/set" - avax "github.com/ava-labs/avalanchego/vms/components/avax" - multisig "github.com/ava-labs/avalanchego/vms/components/multisig" - addrstate "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" - config "github.com/ava-labs/avalanchego/vms/platformvm/config" - dac "github.com/ava-labs/avalanchego/vms/platformvm/dac" - deposit "github.com/ava-labs/avalanchego/vms/platformvm/deposit" - fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" - locked "github.com/ava-labs/avalanchego/vms/platformvm/locked" - status "github.com/ava-labs/avalanchego/vms/platformvm/status" - txs "github.com/ava-labs/avalanchego/vms/platformvm/txs" - gomock "go.uber.org/mock/gomock" -) - -// MockDiff is a mock of Diff interface. -type MockDiff struct { - ctrl *gomock.Controller - recorder *MockDiffMockRecorder -} - -// MockDiffMockRecorder is the mock recorder for MockDiff. -type MockDiffMockRecorder struct { - mock *MockDiff -} - -// NewMockDiff creates a new mock instance. -func NewMockDiff(ctrl *gomock.Controller) *MockDiff { - mock := &MockDiff{ctrl: ctrl} - mock.recorder = &MockDiffMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockDiff) EXPECT() *MockDiffMockRecorder { - return m.recorder -} - -// AddChain mocks base method. -func (m *MockDiff) AddChain(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0) -} - -// AddChain indicates an expected call of AddChain. -func (mr *MockDiffMockRecorder) AddChain(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockDiff)(nil).AddChain), arg0) -} - -// SetDepositOffer mocks base method. -func (m *MockDiff) SetDepositOffer(arg0 *deposit.Offer) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetDepositOffer", arg0) -} - -// SetDepositOffer indicates an expected call of SetDepositOffer. -func (mr *MockDiffMockRecorder) SetDepositOffer(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockDiff)(nil).SetDepositOffer), arg0) -} - -// AddRewardUTXO mocks base method. -func (m *MockDiff) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) -} - -// AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockDiffMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockDiff)(nil).AddRewardUTXO), arg0, arg1) -} - -// AddSubnet mocks base method. -func (m *MockDiff) AddSubnet(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnet", arg0) -} - -// AddSubnet indicates an expected call of AddSubnet. -func (mr *MockDiffMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockDiff)(nil).AddSubnet), arg0) -} - -// AddSubnetTransformation mocks base method. -func (m *MockDiff) AddSubnetTransformation(arg0 *txs.Tx) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnetTransformation", arg0) -} - -// AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockDiffMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).AddSubnetTransformation), arg0) -} - -// AddTx mocks base method. -func (m *MockDiff) AddTx(arg0 *txs.Tx, arg1 status.Status) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddTx", arg0, arg1) -} - -// AddTx indicates an expected call of AddTx. -func (mr *MockDiffMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), arg0, arg1) -} - -// AddUTXO mocks base method. -func (m *MockDiff) AddUTXO(arg0 *avax.UTXO) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddUTXO", arg0) -} - -// AddUTXO indicates an expected call of AddUTXO. -func (mr *MockDiffMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), arg0) -} - -// Apply mocks base method. -func (m *MockDiff) Apply(arg0 State) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Apply", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Apply indicates an expected call of Apply. -func (mr *MockDiffMockRecorder) Apply(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) -} - -// ApplyCaminoState mocks base method. -func (m *MockDiff) ApplyCaminoState(arg0 State) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ApplyCaminoState", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// ApplyCaminoState indicates an expected call of ApplyCaminoState. -func (mr *MockDiffMockRecorder) ApplyCaminoState(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyCaminoState", reflect.TypeOf((*MockDiff)(nil).ApplyCaminoState), arg0) -} - -// CaminoConfig mocks base method. -func (m *MockDiff) CaminoConfig() (*CaminoConfig, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CaminoConfig") - ret0, _ := ret[0].(*CaminoConfig) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CaminoConfig indicates an expected call of CaminoConfig. -func (mr *MockDiffMockRecorder) CaminoConfig() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockDiff)(nil).CaminoConfig)) -} - -// Config mocks base method. -func (m *MockDiff) Config() (*config.Config, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Config") - ret0, _ := ret[0].(*config.Config) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Config indicates an expected call of Config. -func (mr *MockDiffMockRecorder) Config() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Config", reflect.TypeOf((*MockDiff)(nil).Config)) -} - -// DeleteCurrentDelegator mocks base method. -func (m *MockDiff) DeleteCurrentDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) -} - -// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentDelegator), arg0) -} - -// DeleteCurrentValidator mocks base method. -func (m *MockDiff) DeleteCurrentValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentValidator", arg0) -} - -// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockDiffMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentValidator), arg0) -} - -// DeletePendingDelegator mocks base method. -func (m *MockDiff) DeletePendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingDelegator", arg0) -} - -// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockDiffMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockDiff)(nil).DeletePendingDelegator), arg0) -} - -// DeletePendingValidator mocks base method. -func (m *MockDiff) DeletePendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingValidator", arg0) -} - -// DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockDiffMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockDiff)(nil).DeletePendingValidator), arg0) -} - -// DeleteUTXO mocks base method. -func (m *MockDiff) DeleteUTXO(arg0 ids.ID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteUTXO", arg0) -} - -// DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) -} - -// GetAddressStates mocks base method. -func (m *MockDiff) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAddressStates", arg0) - ret0, _ := ret[0].(addrstate.AddressState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAddressStates indicates an expected call of GetAddressStates. -func (mr *MockDiffMockRecorder) GetAddressStates(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockDiff)(nil).GetAddressStates), arg0) -} - -// GetAllDepositOffers mocks base method. -func (m *MockDiff) GetAllDepositOffers() ([]*deposit.Offer, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAllDepositOffers") - ret0, _ := ret[0].([]*deposit.Offer) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAllDepositOffers indicates an expected call of GetAllDepositOffers. -func (mr *MockDiffMockRecorder) GetAllDepositOffers() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockDiff)(nil).GetAllDepositOffers)) -} - -// GetChains mocks base method. -func (m *MockDiff) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChains", arg0) - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChains indicates an expected call of GetChains. -func (mr *MockDiffMockRecorder) GetChains(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockDiff)(nil).GetChains), arg0) -} - -// GetClaimable mocks base method. -func (m *MockDiff) GetClaimable(arg0 ids.ID) (*Claimable, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetClaimable", arg0) - ret0, _ := ret[0].(*Claimable) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetClaimable indicates an expected call of GetClaimable. -func (mr *MockDiffMockRecorder) GetClaimable(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockDiff)(nil).GetClaimable), arg0) -} - -// GetProposal mocks base method. -func (m *MockDiff) GetProposal(arg0 ids.ID) (dac.ProposalState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposal", arg0) - ret0, _ := ret[0].(dac.ProposalState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetProposal indicates an expected call of GetProposal. -func (mr *MockDiffMockRecorder) GetProposal(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockDiff)(nil).GetProposal), arg0) -} - -// GetBaseFee mocks base method. -func (m *MockDiff) GetBaseFee() (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBaseFee") - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetBaseFee indicates an expected call of GetBaseFee. -func (mr *MockDiffMockRecorder) GetBaseFee() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockDiff)(nil).GetBaseFee)) -} - -// GetFeeDistribution mocks base method. -func (m *MockDiff) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetFeeDistribution") - ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetFeeDistribution indicates an expected call of GetFeeDistribution. -func (mr *MockDiffMockRecorder) GetFeeDistribution() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockDiff)(nil).GetFeeDistribution)) -} - -// GetCurrentDelegatorIterator mocks base method. -func (m *MockDiff) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentDelegatorIterator), arg0, arg1) -} - -// GetCurrentStakerIterator mocks base method. -func (m *MockDiff) GetCurrentStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. -func (mr *MockDiffMockRecorder) GetCurrentStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentStakerIterator)) -} - -// GetCurrentSupply mocks base method. -func (m *MockDiff) GetCurrentSupply(arg0 ids.ID) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockDiffMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).GetCurrentSupply), arg0) -} - -// GetCurrentValidator mocks base method. -func (m *MockDiff) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockDiffMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockDiff)(nil).GetCurrentValidator), arg0, arg1) -} - -// GetDelegateeReward mocks base method. -func (m *MockDiff) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockDiffMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).GetDelegateeReward), arg0, arg1) -} - -// GetDeposit mocks base method. -func (m *MockDiff) GetDeposit(arg0 ids.ID) (*deposit.Deposit, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeposit", arg0) - ret0, _ := ret[0].(*deposit.Deposit) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDeposit indicates an expected call of GetDeposit. -func (mr *MockDiffMockRecorder) GetDeposit(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockDiff)(nil).GetDeposit), arg0) -} - -// GetNextToUnlockDepositTime mocks base method. -func (m *MockDiff) GetNextToUnlockDepositTime(arg0 set.Set[ids.ID]) (time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", arg0) - ret0, _ := ret[0].(time.Time) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. -func (mr *MockDiffMockRecorder) GetNextToUnlockDepositTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockDiff)(nil).GetNextToUnlockDepositTime), arg0) -} - -// GetNextToUnlockDepositIDsAndTime mocks base method. -func (m *MockDiff) GetNextToUnlockDepositIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. -func (mr *MockDiffMockRecorder) GetNextToUnlockDepositIDsAndTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockDiff)(nil).GetNextToUnlockDepositIDsAndTime), arg0) -} - -// GetNextProposalExpirationTime mocks base method. -func (m *MockDiff) GetNextProposalExpirationTime(arg0 set.Set[ids.ID]) (time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", arg0) - ret0, _ := ret[0].(time.Time) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. -func (mr *MockDiffMockRecorder) GetNextProposalExpirationTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockDiff)(nil).GetNextProposalExpirationTime), arg0) -} - -// GetNextToExpireProposalIDsAndTime mocks base method. -func (m *MockDiff) GetNextToExpireProposalIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. -func (mr *MockDiffMockRecorder) GetNextToExpireProposalIDsAndTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockDiff)(nil).GetNextToExpireProposalIDsAndTime), arg0) -} - -// GetProposalIDsToFinish mocks base method. -func (m *MockDiff) GetProposalIDsToFinish() ([]ids.ID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposalIDsToFinish") - ret0, _ := ret[0].([]ids.ID) - ret2, _ := ret[1].(error) - return ret0, ret2 -} - -// GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. -func (mr *MockDiffMockRecorder) GetProposalIDsToFinish() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockDiff)(nil).GetProposalIDsToFinish)) -} - -// GetProposalIterator mocks base method. -func (m *MockDiff) GetProposalIterator() (ProposalsIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposalIterator") - ret0, _ := ret[0].(ProposalsIterator) - ret2, _ := ret[1].(error) - return ret0, ret2 -} - -// GetProposalIterator indicates an expected call of GetProposalIterator. -func (mr *MockDiffMockRecorder) GetProposalIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockDiff)(nil).GetProposalIterator)) -} - -// GetDepositOffer mocks base method. -func (m *MockDiff) GetDepositOffer(arg0 ids.ID) (*deposit.Offer, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDepositOffer", arg0) - ret0, _ := ret[0].(*deposit.Offer) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDepositOffer indicates an expected call of GetDepositOffer. -func (mr *MockDiffMockRecorder) GetDepositOffer(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockDiff)(nil).GetDepositOffer), arg0) -} - -// GetMultisigAlias mocks base method. -func (m *MockDiff) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) - ret0, _ := ret[0].(*multisig.AliasWithNonce) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetMultisigAlias indicates an expected call of GetMultisigAlias. -func (mr *MockDiffMockRecorder) GetMultisigAlias(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockDiff)(nil).GetMultisigAlias), arg0) -} - -// GetNotDistributedValidatorReward mocks base method. -func (m *MockDiff) GetNotDistributedValidatorReward() (uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. -func (mr *MockDiffMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockDiff)(nil).GetNotDistributedValidatorReward)) -} - -// GetPendingDelegatorIterator mocks base method. -func (m *MockDiff) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockDiffMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingDelegatorIterator), arg0, arg1) -} - -// GetPendingStakerIterator mocks base method. -func (m *MockDiff) GetPendingStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. -func (mr *MockDiffMockRecorder) GetPendingStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingStakerIterator)) -} - -// GetPendingValidator mocks base method. -func (m *MockDiff) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockDiffMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockDiff)(nil).GetPendingValidator), arg0, arg1) -} - -// GetDeferredStakerIterator mocks base method. -func (m *MockDiff) GetDeferredStakerIterator() (StakerIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. -func (mr *MockDiffMockRecorder) GetDeferredStakerIterator() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetDeferredStakerIterator)) -} - -// GetDeferredValidator mocks base method. -func (m *MockDiff) GetDeferredValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDeferredValidator indicates an expected call of GetDeferredValidator. -func (mr *MockDiffMockRecorder) GetDeferredValidator(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockDiff)(nil).GetDeferredValidator), arg0, arg1) -} - -// DeleteDeferredValidator mocks base method. -func (m *MockDiff) DeleteDeferredValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteDeferredValidator", arg0) -} - -// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. -func (mr *MockDiffMockRecorder) DeleteDeferredValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockDiff)(nil).DeleteDeferredValidator), arg0) -} - -// PutDeferredValidator mocks base method. -func (m *MockDiff) PutDeferredValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutDeferredValidator", arg0) -} - -// PutDeferredValidator indicates an expected call of PutDeferredValidator. -func (mr *MockDiffMockRecorder) PutDeferredValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockDiff)(nil).PutDeferredValidator), arg0) -} - -// GetRewardUTXOs mocks base method. -func (m *MockDiff) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. -func (mr *MockDiffMockRecorder) GetRewardUTXOs(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockDiff)(nil).GetRewardUTXOs), arg0) -} - -// GetSubnetOwner mocks base method. -func (m *MockDiff) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockDiffMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).GetSubnetOwner), arg0) -} - -// GetShortIDLink mocks base method. -func (m *MockDiff) GetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey) (ids.ShortID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetShortIDLink", arg0, arg1) - ret0, _ := ret[0].(ids.ShortID) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetShortIDLink indicates an expected call of GetShortIDLink. -func (mr *MockDiffMockRecorder) GetShortIDLink(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockDiff)(nil).GetShortIDLink), arg0, arg1) -} - -// GetSubnetTransformation mocks base method. -func (m *MockDiff) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockDiffMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).GetSubnetTransformation), arg0) -} - -// GetSubnets mocks base method. -func (m *MockDiff) GetSubnets() ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnets") - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnets indicates an expected call of GetSubnets. -func (mr *MockDiffMockRecorder) GetSubnets() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockDiff)(nil).GetSubnets)) -} - -// GetTimestamp mocks base method. -func (m *MockDiff) GetTimestamp() time.Time { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTimestamp") - ret0, _ := ret[0].(time.Time) - return ret0 -} - -// GetTimestamp indicates an expected call of GetTimestamp. -func (mr *MockDiffMockRecorder) GetTimestamp() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockDiff)(nil).GetTimestamp)) -} - -// GetTx mocks base method. -func (m *MockDiff) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(status.Status) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetTx indicates an expected call of GetTx. -func (mr *MockDiffMockRecorder) GetTx(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockDiff)(nil).GetTx), arg0) -} - -// GetUTXO mocks base method. -func (m *MockDiff) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0) - ret0, _ := ret[0].(*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetUTXO indicates an expected call of GetUTXO. -func (mr *MockDiffMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockDiff)(nil).GetUTXO), arg0) -} - -// LockedUTXOs mocks base method. -func (m *MockDiff) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) - ret0, _ := ret[0].([]*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// LockedUTXOs indicates an expected call of LockedUTXOs. -func (mr *MockDiffMockRecorder) LockedUTXOs(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockDiff)(nil).LockedUTXOs), arg0, arg1, arg2) -} - -// PutCurrentDelegator mocks base method. -func (m *MockDiff) PutCurrentDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentDelegator", arg0) -} - -// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockDiffMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).PutCurrentDelegator), arg0) -} - -// PutCurrentValidator mocks base method. -func (m *MockDiff) PutCurrentValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentValidator", arg0) -} - -// PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockDiffMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockDiff)(nil).PutCurrentValidator), arg0) -} - -// PutPendingDelegator mocks base method. -func (m *MockDiff) PutPendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingDelegator", arg0) -} - -// PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockDiffMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockDiff)(nil).PutPendingDelegator), arg0) -} - -// PutPendingValidator mocks base method. -func (m *MockDiff) PutPendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingValidator", arg0) -} - -// PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockDiffMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockDiff)(nil).PutPendingValidator), arg0) -} - -// SetAddressStates mocks base method. -func (m *MockDiff) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetAddressStates", arg0, arg1) -} - -// SetAddressStates indicates an expected call of SetAddressStates. -func (mr *MockDiffMockRecorder) SetAddressStates(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockDiff)(nil).SetAddressStates), arg0, arg1) -} - -// SetClaimable mocks base method. -func (m *MockDiff) SetClaimable(arg0 ids.ID, arg1 *Claimable) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetClaimable", arg0, arg1) -} - -// SetClaimable indicates an expected call of SetClaimable. -func (mr *MockDiffMockRecorder) SetClaimable(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockDiff)(nil).SetClaimable), arg0, arg1) -} - -// AddProposal mocks base method. -func (m *MockDiff) AddProposal(arg0 ids.ID, arg1 dac.ProposalState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposal", arg0, arg1) -} - -// AddProposal indicates an expected call of AddProposal. -func (mr *MockDiffMockRecorder) AddProposal(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockDiff)(nil).AddProposal), arg0, arg1) -} - -// ModifyProposal mocks base method. -func (m *MockDiff) ModifyProposal(arg0 ids.ID, arg1 dac.ProposalState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyProposal", arg0, arg1) -} - -// ModifyProposal indicates an expected call of ModifyProposal. -func (mr *MockDiffMockRecorder) ModifyProposal(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockDiff)(nil).ModifyProposal), arg0, arg1) -} - -// RemoveProposal mocks base method. -func (m *MockDiff) RemoveProposal(arg0 ids.ID, arg1 dac.ProposalState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposal", arg0, arg1) -} - -// RemoveProposal indicates an expected call of RemoveProposal. -func (mr *MockDiffMockRecorder) RemoveProposal(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockDiff)(nil).RemoveProposal), arg0, arg1) -} - -// AddProposalIDToFinish mocks base method. -func (m *MockDiff) AddProposalIDToFinish(arg0 ids.ID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposalIDToFinish", arg0) -} - -// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. -func (mr *MockDiffMockRecorder) AddProposalIDToFinish(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockDiff)(nil).AddProposalIDToFinish), arg0) -} - -// RemoveProposalIDToFinish mocks base method. -func (m *MockDiff) RemoveProposalIDToFinish(arg0 ids.ID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) -} - -// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. -func (mr *MockDiffMockRecorder) RemoveProposalIDToFinish(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockDiff)(nil).RemoveProposalIDToFinish), arg0) -} - -// SetBaseFee mocks base method. -func (m *MockDiff) SetBaseFee(arg0 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetBaseFee", arg0) -} - -// SetBaseFee indicates an expected call of SetBaseFee. -func (mr *MockDiffMockRecorder) SetBaseFee(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockDiff)(nil).SetBaseFee), arg0) -} - -// SetFeeDistribution mocks base method. -func (m *MockDiff) SetFeeDistribution(arg0 [dac.FeeDistributionFractionsCount]uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetFeeDistribution", arg0) -} - -// SetFeeDistribution indicates an expected call of SetFeeDistribution. -func (mr *MockDiffMockRecorder) SetFeeDistribution(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockDiff)(nil).SetFeeDistribution), arg0) -} - -// SetCurrentSupply mocks base method. -func (m *MockDiff) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) -} - -// SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockDiffMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).SetCurrentSupply), arg0, arg1) -} - -// SetDelegateeReward mocks base method. -func (m *MockDiff) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockDiffMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).SetDelegateeReward), arg0, arg1, arg2) -} - -// SetSubnetOwner mocks base method. -func (m *MockDiff) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) -} - -// SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockDiffMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).SetSubnetOwner), arg0, arg1) -} - -// SetMultisigAlias mocks base method. -func (m *MockDiff) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) -} - -// SetMultisigAlias indicates an expected call of SetMultisigAlias. -func (mr *MockDiffMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockDiff)(nil).SetMultisigAlias), arg0, arg1) -} - -// SetNotDistributedValidatorReward mocks base method. -func (m *MockDiff) SetNotDistributedValidatorReward(arg0 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetNotDistributedValidatorReward", arg0) -} - -// SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. -func (mr *MockDiffMockRecorder) SetNotDistributedValidatorReward(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockDiff)(nil).SetNotDistributedValidatorReward), arg0) -} - -// SetShortIDLink mocks base method. -func (m *MockDiff) SetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey, arg2 *ids.ShortID) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetShortIDLink", arg0, arg1, arg2) -} - -// SetShortIDLink indicates an expected call of SetShortIDLink. -func (mr *MockDiffMockRecorder) SetShortIDLink(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockDiff)(nil).SetShortIDLink), arg0, arg1, arg2) -} - -// SetTimestamp mocks base method. -func (m *MockDiff) SetTimestamp(arg0 time.Time) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetTimestamp", arg0) -} - -// SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockDiffMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockDiff)(nil).SetTimestamp), arg0) -} - -// AddDeposit mocks base method. -func (m *MockDiff) AddDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddDeposit", arg0, arg1) -} - -// AddDeposit indicates an expected call of AddDeposit. -func (mr *MockDiffMockRecorder) AddDeposit(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockDiff)(nil).AddDeposit), arg0, arg1) -} - -// ModifyDeposit mocks base method. -func (m *MockDiff) ModifyDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyDeposit", arg0, arg1) -} - -// ModifyDeposit indicates an expected call of ModifyDeposit. -func (mr *MockDiffMockRecorder) ModifyDeposit(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockDiff)(nil).ModifyDeposit), arg0, arg1) -} - -// RemoveDeposit mocks base method. -func (m *MockDiff) RemoveDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveDeposit", arg0, arg1) -} - -// RemoveDeposit indicates an expected call of RemoveDeposit. -func (mr *MockDiffMockRecorder) RemoveDeposit(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockDiff)(nil).RemoveDeposit), arg0, arg1) -} diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index 07711512c0c8..4d47021aa737 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -22,7 +22,6 @@ import ( multisig "github.com/ava-labs/avalanchego/vms/components/multisig" addrstate "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" block "github.com/ava-labs/avalanchego/vms/platformvm/block" - config "github.com/ava-labs/avalanchego/vms/platformvm/config" dac "github.com/ava-labs/avalanchego/vms/platformvm/dac" deposit "github.com/ava-labs/avalanchego/vms/platformvm/deposit" fx "github.com/ava-labs/avalanchego/vms/platformvm/fx" @@ -187,466 +186,1559 @@ func (mr *MockChainMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), arg0) } -// GetCurrentDelegatorIterator mocks base method. -func (m *MockChain) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { +// SetDepositOffer mocks base method. +func (m *MockChain) SetDepositOffer(arg0 *deposit.Offer) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetDepositOffer", arg0) } -// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { +// SetDepositOffer indicates an expected call of SetDepositOffer. +func (mr *MockChainMockRecorder) SetDepositOffer(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockChain)(nil).SetDepositOffer), arg0) } -// GetCurrentStakerIterator mocks base method. -func (m *MockChain) GetCurrentStakerIterator() (StakerIterator, error) { +// DeleteDeferredValidator mocks base method. +func (m *MockChain) DeleteDeferredValidator(arg0 *Staker) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "DeleteDeferredValidator", arg0) } -// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. -func (mr *MockChainMockRecorder) GetCurrentStakerIterator() *gomock.Call { +// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. +func (mr *MockChainMockRecorder) DeleteDeferredValidator(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockChain)(nil).DeleteDeferredValidator), arg0) } -// GetCurrentSupply mocks base method. -func (m *MockChain) GetCurrentSupply(arg0 ids.ID) (uint64, error) { +// PutDeferredValidator mocks base method. +func (m *MockChain) PutDeferredValidator(arg0 *Staker) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "PutDeferredValidator", arg0) } -// GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockChainMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { +// PutDeferredValidator indicates an expected call of PutDeferredValidator. +func (mr *MockChainMockRecorder) PutDeferredValidator(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockChain)(nil).GetCurrentSupply), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockChain)(nil).PutDeferredValidator), arg0) } -// GetCurrentValidator mocks base method. -func (m *MockChain) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// LockedUTXOs mocks base method. +func (m *MockChain) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) + ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) + ret0, _ := ret[0].([]*avax.UTXO) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockChainMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { +// LockedUTXOs indicates an expected call of LockedUTXOs. +func (mr *MockChainMockRecorder) LockedUTXOs(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockChain)(nil).GetCurrentValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockChain)(nil).LockedUTXOs), arg0, arg1, arg2) } -// GetDelegateeReward mocks base method. -func (m *MockChain) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { +// SetAddressStates mocks base method. +func (m *MockChain) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetAddressStates", arg0, arg1) } -// GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockChainMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { +// SetAddressStates indicates an expected call of SetAddressStates. +func (mr *MockChainMockRecorder) SetAddressStates(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockChain)(nil).GetDelegateeReward), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockChain)(nil).SetAddressStates), arg0, arg1) } -// GetPendingDelegatorIterator mocks base method. -func (m *MockChain) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { +// SetClaimable mocks base method. +func (m *MockChain) SetClaimable(arg0 ids.ID, arg1 *Claimable) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetClaimable", arg0, arg1) } -// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { +// SetClaimable indicates an expected call of SetClaimable. +func (mr *MockChainMockRecorder) SetClaimable(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetPendingDelegatorIterator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockChain)(nil).SetClaimable), arg0, arg1) } -// GetPendingStakerIterator mocks base method. -func (m *MockChain) GetPendingStakerIterator() (StakerIterator, error) { +// AddProposal mocks base method. +func (m *MockChain) AddProposal(arg0 ids.ID, arg1 dac.ProposalState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "AddProposal", arg0, arg1) } -// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. -func (mr *MockChainMockRecorder) GetPendingStakerIterator() *gomock.Call { +// AddProposal indicates an expected call of AddProposal. +func (mr *MockChainMockRecorder) AddProposal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockChain)(nil).GetPendingStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockChain)(nil).AddProposal), arg0, arg1) } -// GetPendingValidator mocks base method. -func (m *MockChain) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// ModifyProposal mocks base method. +func (m *MockChain) ModifyProposal(arg0 ids.ID, arg1 dac.ProposalState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "ModifyProposal", arg0, arg1) } -// GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { +// ModifyProposal indicates an expected call of ModifyProposal. +func (mr *MockChainMockRecorder) ModifyProposal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockChain)(nil).ModifyProposal), arg0, arg1) } -// GetSubnetOwner mocks base method. -func (m *MockChain) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { +// RemoveProposal mocks base method. +func (m *MockChain) RemoveProposal(arg0 ids.ID, arg1 dac.ProposalState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "RemoveProposal", arg0, arg1) } -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockChainMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { +// RemoveProposal indicates an expected call of RemoveProposal. +func (mr *MockChainMockRecorder) RemoveProposal(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockChain)(nil).GetSubnetOwner), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockChain)(nil).RemoveProposal), arg0, arg1) } -// GetSubnetTransformation mocks base method. -func (m *MockChain) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { +// AddProposalIDToFinish mocks base method. +func (m *MockChain) AddProposalIDToFinish(arg0 ids.ID) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "AddProposalIDToFinish", arg0) } -// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { +// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. +func (mr *MockChainMockRecorder) AddProposalIDToFinish(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockChain)(nil).AddProposalIDToFinish), arg0) } -// GetTimestamp mocks base method. -func (m *MockChain) GetTimestamp() time.Time { +// RemoveProposalIDToFinish mocks base method. +func (m *MockChain) RemoveProposalIDToFinish(arg0 ids.ID) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTimestamp") - ret0, _ := ret[0].(time.Time) - return ret0 + m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) } -// GetTimestamp indicates an expected call of GetTimestamp. -func (mr *MockChainMockRecorder) GetTimestamp() *gomock.Call { +// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. +func (mr *MockChainMockRecorder) RemoveProposalIDToFinish(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockChain)(nil).GetTimestamp)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockChain)(nil).RemoveProposalIDToFinish), arg0) } -// GetTx mocks base method. -func (m *MockChain) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { +// SetLastRewardImportTimestamp mocks base method. +func (m *MockChain) SetLastRewardImportTimestamp(arg0 uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(status.Status) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + m.ctrl.Call(m, "SetLastRewardImportTimestamp", arg0) } -// GetTx indicates an expected call of GetTx. -func (mr *MockChainMockRecorder) GetTx(arg0 interface{}) *gomock.Call { +// SetLastRewardImportTimestamp indicates an expected call of SetLastRewardImportTimestamp. +func (mr *MockChainMockRecorder) SetLastRewardImportTimestamp(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastRewardImportTimestamp", reflect.TypeOf((*MockChain)(nil).SetLastRewardImportTimestamp), + arg0) } -// GetUTXO mocks base method. -func (m *MockChain) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { +// AddDeposit mocks base method. +func (m *MockChain) AddDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0) - ret0, _ := ret[0].(*avax.UTXO) + m.ctrl.Call(m, "AddDeposit", arg0, arg1) +} + +// AddDeposit indicates an expected call of AddDeposit. +func (mr *MockChainMockRecorder) AddDeposit(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockChain)(nil).AddDeposit), arg0, arg1) +} + +// ModifyDeposit mocks base method. +func (m *MockChain) ModifyDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ModifyDeposit", arg0, arg1) +} + +// ModifyDeposit indicates an expected call of ModifyDeposit. +func (mr *MockChainMockRecorder) ModifyDeposit(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockChain)(nil).ModifyDeposit), arg0, arg1) +} + +// RemoveDeposit mocks base method. +func (m *MockChain) RemoveDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RemoveDeposit", arg0, arg1) +} + +// RemoveDeposit indicates an expected call of RemoveDeposit. +func (mr *MockChainMockRecorder) RemoveDeposit(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockChain)(nil).RemoveDeposit), arg0, arg1) +} + +// SetMultisigAlias mocks base method. +func (m *MockChain) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) +} + +// SetMultisigAlias indicates an expected call of SetMultisigAlias. +func (mr *MockChainMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockChain)(nil).SetMultisigAlias), arg0, arg1) +} + +// SetNotDistributedValidatorReward mocks base method. +func (m *MockChain) SetNotDistributedValidatorReward(arg0 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetNotDistributedValidatorReward", arg0) +} + +// SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. +func (mr *MockChainMockRecorder) SetNotDistributedValidatorReward(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockChain)(nil).SetNotDistributedValidatorReward), arg0) +} + +// SetShortIDLink mocks base method. +func (m *MockChain) SetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey, arg2 *ids.ShortID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetShortIDLink", arg0, arg1, arg2) +} + +// SetShortIDLink indicates an expected call of SetShortIDLink. +func (mr *MockChainMockRecorder) SetShortIDLink(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockChain)(nil).SetShortIDLink), arg0, arg1, arg2) +} + +// SetBaseFee mocks base method. +func (m *MockChain) SetBaseFee(arg0 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetBaseFee", arg0) +} + +// SetBaseFee indicates an expected call of SetBaseFee. +func (mr *MockChainMockRecorder) SetBaseFee(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockChain)(nil).SetBaseFee), arg0) +} + +// SetFeeDistribution mocks base method. +func (m *MockChain) SetFeeDistribution(arg0 [dac.FeeDistributionFractionsCount]uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetFeeDistribution", arg0) +} + +// SetFeeDistribution indicates an expected call of SetFeeDistribution. +func (mr *MockChainMockRecorder) SetFeeDistribution(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockChain)(nil).SetFeeDistribution), arg0) +} + +// GetShortIDLink mocks base method. +func (m *MockChain) GetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey) (ids.ShortID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetShortIDLink", arg0, arg1) + ret0, _ := ret[0].(ids.ShortID) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetUTXO indicates an expected call of GetUTXO. -func (mr *MockChainMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { +// GetShortIDLink indicates an expected call of GetShortIDLink. +func (mr *MockChainMockRecorder) GetShortIDLink(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockChain)(nil).GetShortIDLink), arg0, arg1) } -// PutCurrentDelegator mocks base method. -func (m *MockChain) PutCurrentDelegator(arg0 *Staker) { +// CaminoConfig mocks base method. +func (m *MockChain) CaminoConfig() (*CaminoConfig, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentDelegator", arg0) + ret := m.ctrl.Call(m, "CaminoConfig") + ret0, _ := ret[0].(*CaminoConfig) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockChainMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { +// CaminoConfig indicates an expected call of CaminoConfig. +func (mr *MockChainMockRecorder) CaminoConfig() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockChain)(nil).PutCurrentDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockChain)(nil).CaminoConfig)) } -// PutCurrentValidator mocks base method. -func (m *MockChain) PutCurrentValidator(arg0 *Staker) { +// GetAddressStates mocks base method. +func (m *MockChain) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentValidator", arg0) + ret := m.ctrl.Call(m, "GetAddressStates", arg0) + ret0, _ := ret[0].(addrstate.AddressState) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockChainMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { +// GetAddressStates indicates an expected call of GetAddressStates. +func (mr *MockChainMockRecorder) GetAddressStates(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockChain)(nil).PutCurrentValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockChain)(nil).GetAddressStates), arg0) } -// PutPendingDelegator mocks base method. -func (m *MockChain) PutPendingDelegator(arg0 *Staker) { +// GetAllDepositOffers mocks base method. +func (m *MockChain) GetAllDepositOffers() ([]*deposit.Offer, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingDelegator", arg0) + ret := m.ctrl.Call(m, "GetAllDepositOffers") + ret0, _ := ret[0].([]*deposit.Offer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAllDepositOffers indicates an expected call of GetAllDepositOffers. +func (mr *MockChainMockRecorder) GetAllDepositOffers() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockChain)(nil).GetAllDepositOffers)) +} + +// GetClaimable mocks base method. +func (m *MockChain) GetClaimable(arg0 ids.ID) (*Claimable, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetClaimable", arg0) + ret0, _ := ret[0].(*Claimable) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetClaimable indicates an expected call of GetClaimable. +func (mr *MockChainMockRecorder) GetClaimable(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockChain)(nil).GetClaimable), arg0) +} + +// GetProposal mocks base method. +func (m *MockChain) GetProposal(arg0 ids.ID) (dac.ProposalState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetProposal", arg0) + ret0, _ := ret[0].(dac.ProposalState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetProposal indicates an expected call of GetProposal. +func (mr *MockChainMockRecorder) GetProposal(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockChain)(nil).GetProposal), arg0) +} + +// GetBaseFee mocks base method. +func (m *MockChain) GetBaseFee() (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBaseFee") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBaseFee indicates an expected call of GetBaseFee. +func (mr *MockChainMockRecorder) GetBaseFee() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockChain)(nil).GetBaseFee)) +} + +// GetFeeDistribution mocks base method. +func (m *MockChain) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFeeDistribution") + ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFeeDistribution indicates an expected call of GetFeeDistribution. +func (mr *MockChainMockRecorder) GetFeeDistribution() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockChain)(nil).GetFeeDistribution)) +} + +// GetDeposit mocks base method. +func (m *MockChain) GetDeposit(arg0 ids.ID) (*deposit.Deposit, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDeposit", arg0) + ret0, _ := ret[0].(*deposit.Deposit) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDeposit indicates an expected call of GetDeposit. +func (mr *MockChainMockRecorder) GetDeposit(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockChain)(nil).GetDeposit), arg0) +} + +// GetNextToUnlockDepositTime mocks base method. +func (m *MockChain) GetNextToUnlockDepositTime(arg0 set.Set[ids.ID]) (time.Time, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", arg0) + ret0, _ := ret[0].(time.Time) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. +func (mr *MockChainMockRecorder) GetNextToUnlockDepositTime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockChain)(nil).GetNextToUnlockDepositTime), arg0) +} + +// GetNextToUnlockDepositIDsAndTime mocks base method. +func (m *MockChain) GetNextToUnlockDepositIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", arg0) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. +func (mr *MockChainMockRecorder) GetNextToUnlockDepositIDsAndTime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockChain)(nil).GetNextToUnlockDepositIDsAndTime), arg0) +} + +// GetNextProposalExpirationTime mocks base method. +func (m *MockChain) GetNextProposalExpirationTime(arg0 set.Set[ids.ID]) (time.Time, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", arg0) + ret0, _ := ret[0].(time.Time) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. +func (mr *MockChainMockRecorder) GetNextProposalExpirationTime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockChain)(nil).GetNextProposalExpirationTime), arg0) +} + +// GetNextToExpireProposalIDsAndTime mocks base method. +func (m *MockChain) GetNextToExpireProposalIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", arg0) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. +func (mr *MockChainMockRecorder) GetNextToExpireProposalIDsAndTime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockChain)(nil).GetNextToExpireProposalIDsAndTime), arg0) +} + +// GetProposalIDsToFinish mocks base method. +func (m *MockChain) GetProposalIDsToFinish() ([]ids.ID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetProposalIDsToFinish") + ret0, _ := ret[0].([]ids.ID) + ret2, _ := ret[1].(error) + return ret0, ret2 +} + +// GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. +func (mr *MockChainMockRecorder) GetProposalIDsToFinish() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockChain)(nil).GetProposalIDsToFinish)) +} + +// GetProposalIterator mocks base method. +func (m *MockChain) GetProposalIterator() (ProposalsIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetProposalIterator") + ret0, _ := ret[0].(ProposalsIterator) + ret2, _ := ret[1].(error) + return ret0, ret2 +} + +// GetProposalIterator indicates an expected call of GetProposalIterator. +func (mr *MockChainMockRecorder) GetProposalIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockChain)(nil).GetProposalIterator)) +} + +// GetDepositOffer mocks base method. +func (m *MockChain) GetDepositOffer(arg0 ids.ID) (*deposit.Offer, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDepositOffer", arg0) + ret0, _ := ret[0].(*deposit.Offer) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDepositOffer indicates an expected call of GetDepositOffer. +func (mr *MockChainMockRecorder) GetDepositOffer(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockChain)(nil).GetDepositOffer), arg0) +} + +// GetMultisigAlias mocks base method. +func (m *MockChain) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) + ret0, _ := ret[0].(*multisig.AliasWithNonce) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMultisigAlias indicates an expected call of GetMultisigAlias. +func (mr *MockChainMockRecorder) GetMultisigAlias(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockChain)(nil).GetMultisigAlias), arg0) +} + +// GetNotDistributedValidatorReward mocks base method. +func (m *MockChain) GetNotDistributedValidatorReward() (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. +func (mr *MockChainMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockChain)(nil).GetNotDistributedValidatorReward)) +} + +// GetDeferredStakerIterator mocks base method. +func (m *MockChain) GetDeferredStakerIterator() (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDeferredStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. +func (mr *MockChainMockRecorder) GetDeferredStakerIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockChain)(nil).GetDeferredStakerIterator)) +} + +// GetDeferredValidator mocks base method. +func (m *MockChain) GetDeferredValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDeferredValidator", arg0, arg1) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDeferredValidator indicates an expected call of GetDeferredValidator. +func (mr *MockChainMockRecorder) GetDeferredValidator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockChain)(nil).GetDeferredValidator), arg0, arg1) +} + +// GetCurrentDelegatorIterator mocks base method. +func (m *MockChain) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. +func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), arg0, arg1) +} + +// GetCurrentStakerIterator mocks base method. +func (m *MockChain) GetCurrentStakerIterator() (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. +func (mr *MockChainMockRecorder) GetCurrentStakerIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentStakerIterator)) +} + +// GetCurrentSupply mocks base method. +func (m *MockChain) GetCurrentSupply(arg0 ids.ID) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentSupply indicates an expected call of GetCurrentSupply. +func (mr *MockChainMockRecorder) GetCurrentSupply(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockChain)(nil).GetCurrentSupply), arg0) +} + +// GetCurrentValidator mocks base method. +func (m *MockChain) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCurrentValidator indicates an expected call of GetCurrentValidator. +func (mr *MockChainMockRecorder) GetCurrentValidator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockChain)(nil).GetCurrentValidator), arg0, arg1) +} + +// GetDelegateeReward mocks base method. +func (m *MockChain) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDelegateeReward indicates an expected call of GetDelegateeReward. +func (mr *MockChainMockRecorder) GetDelegateeReward(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockChain)(nil).GetDelegateeReward), arg0, arg1) +} + +// GetPendingDelegatorIterator mocks base method. +func (m *MockChain) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. +func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetPendingDelegatorIterator), arg0, arg1) +} + +// GetPendingStakerIterator mocks base method. +func (m *MockChain) GetPendingStakerIterator() (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. +func (mr *MockChainMockRecorder) GetPendingStakerIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockChain)(nil).GetPendingStakerIterator)) +} + +// GetPendingValidator mocks base method. +func (m *MockChain) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingValidator indicates an expected call of GetPendingValidator. +func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), arg0, arg1) +} + +// GetSubnetOwner mocks base method. +func (m *MockChain) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) + ret0, _ := ret[0].(fx.Owner) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnetOwner indicates an expected call of GetSubnetOwner. +func (mr *MockChainMockRecorder) GetSubnetOwner(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockChain)(nil).GetSubnetOwner), arg0) +} + +// GetSubnetTransformation mocks base method. +func (m *MockChain) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. +func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), arg0) +} + +// GetTimestamp mocks base method. +func (m *MockChain) GetTimestamp() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTimestamp") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// GetTimestamp indicates an expected call of GetTimestamp. +func (mr *MockChainMockRecorder) GetTimestamp() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockChain)(nil).GetTimestamp)) +} + +// GetTx mocks base method. +func (m *MockChain) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTx", arg0) + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(status.Status) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetTx indicates an expected call of GetTx. +func (mr *MockChainMockRecorder) GetTx(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), arg0) +} + +// GetUTXO mocks base method. +func (m *MockChain) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUTXO", arg0) + ret0, _ := ret[0].(*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUTXO indicates an expected call of GetUTXO. +func (mr *MockChainMockRecorder) GetUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), arg0) +} + +// PutCurrentDelegator mocks base method. +func (m *MockChain) PutCurrentDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutCurrentDelegator", arg0) +} + +// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. +func (mr *MockChainMockRecorder) PutCurrentDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockChain)(nil).PutCurrentDelegator), arg0) +} + +// PutCurrentValidator mocks base method. +func (m *MockChain) PutCurrentValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutCurrentValidator", arg0) +} + +// PutCurrentValidator indicates an expected call of PutCurrentValidator. +func (mr *MockChainMockRecorder) PutCurrentValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockChain)(nil).PutCurrentValidator), arg0) +} + +// PutPendingDelegator mocks base method. +func (m *MockChain) PutPendingDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutPendingDelegator", arg0) +} + +// PutPendingDelegator indicates an expected call of PutPendingDelegator. +func (mr *MockChainMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockChain)(nil).PutPendingDelegator), arg0) +} + +// PutPendingValidator mocks base method. +func (m *MockChain) PutPendingValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutPendingValidator", arg0) +} + +// PutPendingValidator indicates an expected call of PutPendingValidator. +func (mr *MockChainMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), arg0) +} + +// SetCurrentSupply mocks base method. +func (m *MockChain) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) +} + +// SetCurrentSupply indicates an expected call of SetCurrentSupply. +func (mr *MockChainMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockChain)(nil).SetCurrentSupply), arg0, arg1) +} + +// SetDelegateeReward mocks base method. +func (m *MockChain) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetDelegateeReward indicates an expected call of SetDelegateeReward. +func (mr *MockChainMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockChain)(nil).SetDelegateeReward), arg0, arg1, arg2) +} + +// SetSubnetOwner mocks base method. +func (m *MockChain) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) +} + +// SetSubnetOwner indicates an expected call of SetSubnetOwner. +func (mr *MockChainMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockChain)(nil).SetSubnetOwner), arg0, arg1) +} + +// SetTimestamp mocks base method. +func (m *MockChain) SetTimestamp(arg0 time.Time) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetTimestamp", arg0) +} + +// SetTimestamp indicates an expected call of SetTimestamp. +func (mr *MockChainMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), arg0) +} + +// MockDiff is a mock of Diff interface. +type MockDiff struct { + ctrl *gomock.Controller + recorder *MockDiffMockRecorder +} + +// MockDiffMockRecorder is the mock recorder for MockDiff. +type MockDiffMockRecorder struct { + mock *MockDiff +} + +// NewMockDiff creates a new mock instance. +func NewMockDiff(ctrl *gomock.Controller) *MockDiff { + mock := &MockDiff{ctrl: ctrl} + mock.recorder = &MockDiffMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDiff) EXPECT() *MockDiffMockRecorder { + return m.recorder +} + +// AddChain mocks base method. +func (m *MockDiff) AddChain(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddChain", arg0) +} + +// AddChain indicates an expected call of AddChain. +func (mr *MockDiffMockRecorder) AddChain(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockDiff)(nil).AddChain), arg0) +} + +// AddRewardUTXO mocks base method. +func (m *MockDiff) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) +} + +// AddRewardUTXO indicates an expected call of AddRewardUTXO. +func (mr *MockDiffMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockDiff)(nil).AddRewardUTXO), arg0, arg1) +} + +// AddSubnet mocks base method. +func (m *MockDiff) AddSubnet(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddSubnet", arg0) +} + +// AddSubnet indicates an expected call of AddSubnet. +func (mr *MockDiffMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockDiff)(nil).AddSubnet), arg0) +} + +// AddSubnetTransformation mocks base method. +func (m *MockDiff) AddSubnetTransformation(arg0 *txs.Tx) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddSubnetTransformation", arg0) +} + +// AddSubnetTransformation indicates an expected call of AddSubnetTransformation. +func (mr *MockDiffMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).AddSubnetTransformation), arg0) +} + +// AddTx mocks base method. +func (m *MockDiff) AddTx(arg0 *txs.Tx, arg1 status.Status) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddTx", arg0, arg1) +} + +// AddTx indicates an expected call of AddTx. +func (mr *MockDiffMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), arg0, arg1) +} + +// AddUTXO mocks base method. +func (m *MockDiff) AddUTXO(arg0 *avax.UTXO) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddUTXO", arg0) +} + +// AddUTXO indicates an expected call of AddUTXO. +func (mr *MockDiffMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), arg0) +} + +// Apply mocks base method. +func (m *MockDiff) Apply(arg0 Chain) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Apply", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Apply indicates an expected call of Apply. +func (mr *MockDiffMockRecorder) Apply(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) +} + +// DeleteCurrentDelegator mocks base method. +func (m *MockDiff) DeleteCurrentDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) +} + +// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. +func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentDelegator), arg0) +} + +// DeleteCurrentValidator mocks base method. +func (m *MockDiff) DeleteCurrentValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteCurrentValidator", arg0) +} + +// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. +func (mr *MockDiffMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentValidator), arg0) +} + +// DeletePendingDelegator mocks base method. +func (m *MockDiff) DeletePendingDelegator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeletePendingDelegator", arg0) +} + +// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. +func (mr *MockDiffMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockDiff)(nil).DeletePendingDelegator), arg0) +} + +// DeletePendingValidator mocks base method. +func (m *MockDiff) DeletePendingValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeletePendingValidator", arg0) +} + +// DeletePendingValidator indicates an expected call of DeletePendingValidator. +func (mr *MockDiffMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockDiff)(nil).DeletePendingValidator), arg0) +} + +// DeleteUTXO mocks base method. +func (m *MockDiff) DeleteUTXO(arg0 ids.ID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteUTXO", arg0) +} + +// DeleteUTXO indicates an expected call of DeleteUTXO. +func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) +} + +// SetDepositOffer mocks base method. +func (m *MockDiff) SetDepositOffer(arg0 *deposit.Offer) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetDepositOffer", arg0) +} + +// SetDepositOffer indicates an expected call of SetDepositOffer. +func (mr *MockDiffMockRecorder) SetDepositOffer(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockDiff)(nil).SetDepositOffer), arg0) +} + +// ApplyCaminoState mocks base method. +func (m *MockDiff) ApplyCaminoState(arg0 Chain) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ApplyCaminoState", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ApplyCaminoState indicates an expected call of ApplyCaminoState. +func (mr *MockDiffMockRecorder) ApplyCaminoState(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyCaminoState", reflect.TypeOf((*MockDiff)(nil).ApplyCaminoState), arg0) +} + +// DeleteDeferredValidator mocks base method. +func (m *MockDiff) DeleteDeferredValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteDeferredValidator", arg0) +} + +// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. +func (mr *MockDiffMockRecorder) DeleteDeferredValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockDiff)(nil).DeleteDeferredValidator), arg0) +} + +// PutDeferredValidator mocks base method. +func (m *MockDiff) PutDeferredValidator(arg0 *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutDeferredValidator", arg0) +} + +// PutDeferredValidator indicates an expected call of PutDeferredValidator. +func (mr *MockDiffMockRecorder) PutDeferredValidator(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockDiff)(nil).PutDeferredValidator), arg0) +} + +// SetAddressStates mocks base method. +func (m *MockDiff) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetAddressStates", arg0, arg1) +} + +// SetAddressStates indicates an expected call of SetAddressStates. +func (mr *MockDiffMockRecorder) SetAddressStates(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockDiff)(nil).SetAddressStates), arg0, arg1) +} + +// SetClaimable mocks base method. +func (m *MockDiff) SetClaimable(arg0 ids.ID, arg1 *Claimable) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetClaimable", arg0, arg1) +} + +// SetClaimable indicates an expected call of SetClaimable. +func (mr *MockDiffMockRecorder) SetClaimable(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockDiff)(nil).SetClaimable), arg0, arg1) +} + +// SetMultisigAlias mocks base method. +func (m *MockDiff) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) +} + +// SetMultisigAlias indicates an expected call of SetMultisigAlias. +func (mr *MockDiffMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockDiff)(nil).SetMultisigAlias), arg0, arg1) +} + +// SetNotDistributedValidatorReward mocks base method. +func (m *MockDiff) SetNotDistributedValidatorReward(arg0 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetNotDistributedValidatorReward", arg0) +} + +// SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. +func (mr *MockDiffMockRecorder) SetNotDistributedValidatorReward(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockDiff)(nil).SetNotDistributedValidatorReward), arg0) +} + +// SetShortIDLink mocks base method. +func (m *MockDiff) SetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey, arg2 *ids.ShortID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetShortIDLink", arg0, arg1, arg2) +} + +// SetShortIDLink indicates an expected call of SetShortIDLink. +func (mr *MockDiffMockRecorder) SetShortIDLink(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockDiff)(nil).SetShortIDLink), arg0, arg1, arg2) +} + +// AddProposal mocks base method. +func (m *MockDiff) AddProposal(arg0 ids.ID, arg1 dac.ProposalState) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddProposal", arg0, arg1) +} + +// AddProposal indicates an expected call of AddProposal. +func (mr *MockDiffMockRecorder) AddProposal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockDiff)(nil).AddProposal), arg0, arg1) +} + +// ModifyProposal mocks base method. +func (m *MockDiff) ModifyProposal(arg0 ids.ID, arg1 dac.ProposalState) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ModifyProposal", arg0, arg1) +} + +// ModifyProposal indicates an expected call of ModifyProposal. +func (mr *MockDiffMockRecorder) ModifyProposal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockDiff)(nil).ModifyProposal), arg0, arg1) +} + +// RemoveProposal mocks base method. +func (m *MockDiff) RemoveProposal(arg0 ids.ID, arg1 dac.ProposalState) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RemoveProposal", arg0, arg1) +} + +// RemoveProposal indicates an expected call of RemoveProposal. +func (mr *MockDiffMockRecorder) RemoveProposal(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockDiff)(nil).RemoveProposal), arg0, arg1) +} + +// AddProposalIDToFinish mocks base method. +func (m *MockDiff) AddProposalIDToFinish(arg0 ids.ID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddProposalIDToFinish", arg0) +} + +// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. +func (mr *MockDiffMockRecorder) AddProposalIDToFinish(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockDiff)(nil).AddProposalIDToFinish), arg0) +} + +// RemoveProposalIDToFinish mocks base method. +func (m *MockDiff) RemoveProposalIDToFinish(arg0 ids.ID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) +} + +// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. +func (mr *MockDiffMockRecorder) RemoveProposalIDToFinish(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockDiff)(nil).RemoveProposalIDToFinish), arg0) +} + +// SetBaseFee mocks base method. +func (m *MockDiff) SetBaseFee(arg0 uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetBaseFee", arg0) +} + +// SetBaseFee indicates an expected call of SetBaseFee. +func (mr *MockDiffMockRecorder) SetBaseFee(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockDiff)(nil).SetBaseFee), arg0) +} + +// AddDeposit mocks base method. +func (m *MockDiff) AddDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddDeposit", arg0, arg1) +} + +// AddDeposit indicates an expected call of AddDeposit. +func (mr *MockDiffMockRecorder) AddDeposit(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockDiff)(nil).AddDeposit), arg0, arg1) +} + +// ModifyDeposit mocks base method. +func (m *MockDiff) ModifyDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ModifyDeposit", arg0, arg1) +} + +// ModifyDeposit indicates an expected call of ModifyDeposit. +func (mr *MockDiffMockRecorder) ModifyDeposit(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockDiff)(nil).ModifyDeposit), arg0, arg1) +} + +// RemoveDeposit mocks base method. +func (m *MockDiff) RemoveDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RemoveDeposit", arg0, arg1) +} + +// RemoveDeposit indicates an expected call of RemoveDeposit. +func (mr *MockDiffMockRecorder) RemoveDeposit(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockDiff)(nil).RemoveDeposit), arg0, arg1) +} + +// SetFeeDistribution mocks base method. +func (m *MockDiff) SetFeeDistribution(arg0 [dac.FeeDistributionFractionsCount]uint64) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetFeeDistribution", arg0) +} + +// SetFeeDistribution indicates an expected call of SetFeeDistribution. +func (mr *MockDiffMockRecorder) SetFeeDistribution(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockDiff)(nil).SetFeeDistribution), arg0) +} + +// LockedUTXOs mocks base method. +func (m *MockDiff) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) + ret0, _ := ret[0].([]*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// LockedUTXOs indicates an expected call of LockedUTXOs. +func (mr *MockDiffMockRecorder) LockedUTXOs(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockDiff)(nil).LockedUTXOs), arg0, arg1, arg2) +} + +// GetShortIDLink mocks base method. +func (m *MockDiff) GetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey) (ids.ShortID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetShortIDLink", arg0, arg1) + ret0, _ := ret[0].(ids.ShortID) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockChainMockRecorder) PutPendingDelegator(arg0 interface{}) *gomock.Call { +// GetShortIDLink indicates an expected call of GetShortIDLink. +func (mr *MockDiffMockRecorder) GetShortIDLink(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockChain)(nil).PutPendingDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockDiff)(nil).GetShortIDLink), arg0, arg1) } -// PutPendingValidator mocks base method. -func (m *MockChain) PutPendingValidator(arg0 *Staker) { +// GetAddressStates mocks base method. +func (m *MockDiff) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingValidator", arg0) + ret := m.ctrl.Call(m, "GetAddressStates", arg0) + ret0, _ := ret[0].(addrstate.AddressState) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockChainMockRecorder) PutPendingValidator(arg0 interface{}) *gomock.Call { +// GetAddressStates indicates an expected call of GetAddressStates. +func (mr *MockDiffMockRecorder) GetAddressStates(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockDiff)(nil).GetAddressStates), arg0) } -// SetCurrentSupply mocks base method. -func (m *MockChain) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { +// GetClaimable mocks base method. +func (m *MockDiff) GetClaimable(arg0 ids.ID) (*Claimable, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) + ret := m.ctrl.Call(m, "GetClaimable", arg0) + ret0, _ := ret[0].(*Claimable) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockChainMockRecorder) SetCurrentSupply(arg0, arg1 interface{}) *gomock.Call { +// GetClaimable indicates an expected call of GetClaimable. +func (mr *MockDiffMockRecorder) GetClaimable(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockChain)(nil).SetCurrentSupply), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockDiff)(nil).GetClaimable), arg0) } -// SetDelegateeReward mocks base method. -func (m *MockChain) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { +// GetProposal mocks base method. +func (m *MockDiff) GetProposal(arg0 ids.ID) (dac.ProposalState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "GetProposal", arg0) + ret0, _ := ret[0].(dac.ProposalState) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockChainMockRecorder) SetDelegateeReward(arg0, arg1, arg2 interface{}) *gomock.Call { +// GetProposal indicates an expected call of GetProposal. +func (mr *MockDiffMockRecorder) GetProposal(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockChain)(nil).SetDelegateeReward), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockDiff)(nil).GetProposal), arg0) } -// SetSubnetOwner mocks base method. -func (m *MockChain) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { +// GetBaseFee mocks base method. +func (m *MockDiff) GetBaseFee() (uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) + ret := m.ctrl.Call(m, "GetBaseFee") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockChainMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock.Call { +// GetBaseFee indicates an expected call of GetBaseFee. +func (mr *MockDiffMockRecorder) GetBaseFee() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockChain)(nil).SetSubnetOwner), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockDiff)(nil).GetBaseFee)) } -// SetTimestamp mocks base method. -func (m *MockChain) SetTimestamp(arg0 time.Time) { +// GetDeposit mocks base method. +func (m *MockDiff) GetDeposit(arg0 ids.ID) (*deposit.Deposit, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetTimestamp", arg0) + ret := m.ctrl.Call(m, "GetDeposit", arg0) + ret0, _ := ret[0].(*deposit.Deposit) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockChainMockRecorder) SetTimestamp(arg0 interface{}) *gomock.Call { +// GetDeposit indicates an expected call of GetDeposit. +func (mr *MockDiffMockRecorder) GetDeposit(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockDiff)(nil).GetDeposit), arg0) } -// MockDiff is a mock of Diff interface. -type MockDiff struct { - ctrl *gomock.Controller - recorder *MockDiffMockRecorder +// GetNextToUnlockDepositTime mocks base method. +func (m *MockDiff) GetNextToUnlockDepositTime(arg0 set.Set[ids.ID]) (time.Time, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", arg0) + ret0, _ := ret[0].(time.Time) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// MockDiffMockRecorder is the mock recorder for MockDiff. -type MockDiffMockRecorder struct { - mock *MockDiff +// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. +func (mr *MockDiffMockRecorder) GetNextToUnlockDepositTime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockDiff)(nil).GetNextToUnlockDepositTime), arg0) } -// NewMockDiff creates a new mock instance. -func NewMockDiff(ctrl *gomock.Controller) *MockDiff { - mock := &MockDiff{ctrl: ctrl} - mock.recorder = &MockDiffMockRecorder{mock} - return mock +// GetNextToUnlockDepositIDsAndTime mocks base method. +func (m *MockDiff) GetNextToUnlockDepositIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", arg0) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockDiff) EXPECT() *MockDiffMockRecorder { - return m.recorder +// GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. +func (mr *MockDiffMockRecorder) GetNextToUnlockDepositIDsAndTime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockDiff)(nil).GetNextToUnlockDepositIDsAndTime), arg0) } -// AddChain mocks base method. -func (m *MockDiff) AddChain(arg0 *txs.Tx) { +// GetNextProposalExpirationTime mocks base method. +func (m *MockDiff) GetNextProposalExpirationTime(arg0 set.Set[ids.ID]) (time.Time, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0) + ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", arg0) + ret0, _ := ret[0].(time.Time) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddChain indicates an expected call of AddChain. -func (mr *MockDiffMockRecorder) AddChain(arg0 interface{}) *gomock.Call { +// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. +func (mr *MockDiffMockRecorder) GetNextProposalExpirationTime(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockDiff)(nil).AddChain), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockDiff)(nil).GetNextProposalExpirationTime), arg0) } -// AddRewardUTXO mocks base method. -func (m *MockDiff) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { +// GetNextToExpireProposalIDsAndTime mocks base method. +func (m *MockDiff) GetNextToExpireProposalIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) + ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", arg0) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockDiffMockRecorder) AddRewardUTXO(arg0, arg1 interface{}) *gomock.Call { +// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. +func (mr *MockDiffMockRecorder) GetNextToExpireProposalIDsAndTime(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockDiff)(nil).AddRewardUTXO), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockDiff)(nil).GetNextToExpireProposalIDsAndTime), arg0) } -// AddSubnet mocks base method. -func (m *MockDiff) AddSubnet(arg0 *txs.Tx) { +// GetProposalIDsToFinish mocks base method. +func (m *MockDiff) GetProposalIDsToFinish() ([]ids.ID, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnet", arg0) + ret := m.ctrl.Call(m, "GetProposalIDsToFinish") + ret0, _ := ret[0].([]ids.ID) + ret2, _ := ret[1].(error) + return ret0, ret2 } -// AddSubnet indicates an expected call of AddSubnet. -func (mr *MockDiffMockRecorder) AddSubnet(arg0 interface{}) *gomock.Call { +// GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. +func (mr *MockDiffMockRecorder) GetProposalIDsToFinish() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockDiff)(nil).AddSubnet), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockDiff)(nil).GetProposalIDsToFinish)) } -// AddSubnetTransformation mocks base method. -func (m *MockDiff) AddSubnetTransformation(arg0 *txs.Tx) { +// GetProposalIterator mocks base method. +func (m *MockDiff) GetProposalIterator() (ProposalsIterator, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnetTransformation", arg0) + ret := m.ctrl.Call(m, "GetProposalIterator") + ret0, _ := ret[0].(ProposalsIterator) + ret2, _ := ret[1].(error) + return ret0, ret2 } -// AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockDiffMockRecorder) AddSubnetTransformation(arg0 interface{}) *gomock.Call { +// GetProposalIterator indicates an expected call of GetProposalIterator. +func (mr *MockDiffMockRecorder) GetProposalIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).AddSubnetTransformation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockDiff)(nil).GetProposalIterator)) } -// AddTx mocks base method. -func (m *MockDiff) AddTx(arg0 *txs.Tx, arg1 status.Status) { +// GetDepositOffer mocks base method. +func (m *MockDiff) GetDepositOffer(arg0 ids.ID) (*deposit.Offer, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddTx", arg0, arg1) + ret := m.ctrl.Call(m, "GetDepositOffer", arg0) + ret0, _ := ret[0].(*deposit.Offer) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddTx indicates an expected call of AddTx. -func (mr *MockDiffMockRecorder) AddTx(arg0, arg1 interface{}) *gomock.Call { +// GetDepositOffer indicates an expected call of GetDepositOffer. +func (mr *MockDiffMockRecorder) GetDepositOffer(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockDiff)(nil).GetDepositOffer), arg0) } -// AddUTXO mocks base method. -func (m *MockDiff) AddUTXO(arg0 *avax.UTXO) { +// GetMultisigAlias mocks base method. +func (m *MockDiff) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddUTXO", arg0) + ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) + ret0, _ := ret[0].(*multisig.AliasWithNonce) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddUTXO indicates an expected call of AddUTXO. -func (mr *MockDiffMockRecorder) AddUTXO(arg0 interface{}) *gomock.Call { +// GetMultisigAlias indicates an expected call of GetMultisigAlias. +func (mr *MockDiffMockRecorder) GetMultisigAlias(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockDiff)(nil).GetMultisigAlias), arg0) } -// Apply mocks base method. -func (m *MockDiff) Apply(arg0 Chain) error { +// GetDeferredStakerIterator mocks base method. +func (m *MockDiff) GetDeferredStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Apply", arg0) - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "GetDeferredStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// Apply indicates an expected call of Apply. -func (mr *MockDiffMockRecorder) Apply(arg0 interface{}) *gomock.Call { +// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. +func (mr *MockDiffMockRecorder) GetDeferredStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetDeferredStakerIterator)) } -// DeleteCurrentDelegator mocks base method. -func (m *MockDiff) DeleteCurrentDelegator(arg0 *Staker) { +// GetDeferredValidator mocks base method. +func (m *MockDiff) GetDeferredValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) + ret := m.ctrl.Call(m, "GetDeferredValidator", arg0, arg1) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(arg0 interface{}) *gomock.Call { +// GetDeferredValidator indicates an expected call of GetDeferredValidator. +func (mr *MockDiffMockRecorder) GetDeferredValidator(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockDiff)(nil).GetDeferredValidator), arg0, arg1) } -// DeleteCurrentValidator mocks base method. -func (m *MockDiff) DeleteCurrentValidator(arg0 *Staker) { +// GetNotDistributedValidatorReward mocks base method. +func (m *MockDiff) GetNotDistributedValidatorReward() (uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentValidator", arg0) + ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockDiffMockRecorder) DeleteCurrentValidator(arg0 interface{}) *gomock.Call { +// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. +func (mr *MockDiffMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockDiff)(nil).GetNotDistributedValidatorReward)) } -// DeletePendingDelegator mocks base method. -func (m *MockDiff) DeletePendingDelegator(arg0 *Staker) { +// GetFeeDistribution mocks base method. +func (m *MockDiff) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingDelegator", arg0) + ret := m.ctrl.Call(m, "GetFeeDistribution") + ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockDiffMockRecorder) DeletePendingDelegator(arg0 interface{}) *gomock.Call { +// GetFeeDistribution indicates an expected call of GetFeeDistribution. +func (mr *MockDiffMockRecorder) GetFeeDistribution() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockDiff)(nil).DeletePendingDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockDiff)(nil).GetFeeDistribution)) } -// DeletePendingValidator mocks base method. -func (m *MockDiff) DeletePendingValidator(arg0 *Staker) { +// GetAllDepositOffers mocks base method. +func (m *MockDiff) GetAllDepositOffers() ([]*deposit.Offer, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingValidator", arg0) + ret := m.ctrl.Call(m, "GetAllDepositOffers") + ret0, _ := ret[0].([]*deposit.Offer) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockDiffMockRecorder) DeletePendingValidator(arg0 interface{}) *gomock.Call { +// GetAllDepositOffers indicates an expected call of GetAllDepositOffers. +func (mr *MockDiffMockRecorder) GetAllDepositOffers() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockDiff)(nil).DeletePendingValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockDiff)(nil).GetAllDepositOffers)) } -// DeleteUTXO mocks base method. -func (m *MockDiff) DeleteUTXO(arg0 ids.ID) { +// CaminoConfig mocks base method. +func (m *MockDiff) CaminoConfig() (*CaminoConfig, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteUTXO", arg0) + ret := m.ctrl.Call(m, "CaminoConfig") + ret0, _ := ret[0].(*CaminoConfig) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 interface{}) *gomock.Call { +// CaminoConfig indicates an expected call of CaminoConfig. +func (mr *MockDiffMockRecorder) CaminoConfig() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockDiff)(nil).CaminoConfig)) } // GetCurrentDelegatorIterator mocks base method. @@ -1173,21 +2265,6 @@ func (mr *MockStateMockRecorder) CommitBatch() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitBatch", reflect.TypeOf((*MockState)(nil).CommitBatch)) } -// Config mocks base method. -func (m *MockState) Config() (*config.Config, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Config") - ret0, _ := ret[0].(*config.Config) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Config indicates an expected call of Config. -func (mr *MockStateMockRecorder) Config() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Config", reflect.TypeOf((*MockState)(nil).Config)) -} - // DeleteCurrentDelegator mocks base method. func (m *MockState) DeleteCurrentDelegator(arg0 *Staker) { m.ctrl.T.Helper() @@ -2122,15 +3199,15 @@ func (mr *MockStateMockRecorder) SetSubnetOwner(arg0, arg1 interface{}) *gomock. } // SetMultisigAlias mocks base method. -func (m *MockState) SetMultisigAlias(arg0 *multisig.AliasWithNonce) { +func (m *MockState) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetMultisigAlias", arg0) + m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) } // SetMultisigAlias indicates an expected call of SetMultisigAlias. -func (mr *MockStateMockRecorder) SetMultisigAlias(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockState)(nil).SetMultisigAlias), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockState)(nil).SetMultisigAlias), arg0, arg1) } // SetNotDistributedValidatorReward mocks base method. diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 07c3aab8ad90..86b9044b20d6 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1808,7 +1808,7 @@ func (s *state) init(genesisBytes []byte) error { return err } - if err := s.caminoState.SyncGenesis(s, genesis); err != nil { + if err := s.caminoState.syncGenesis(s, genesis); err != nil { return err } From 6dc8ccb9761cfd3037d7295ca931467fb4643773 Mon Sep 17 00:00:00 2001 From: evlekht Date: Wed, 24 Jul 2024 21:18:29 +0400 Subject: [PATCH 266/267] [AVAX] Post Merge fixes for Cortina 18 (v1.10.18) --- .github/workflows/cnr-build-test-release.yml | 81 - .github/workflows/cnr-codeql-analysis.yml | 78 - .gitmodules | 3 - .golangci.yml | 2 - api/info/camino_service_test.go | 8 +- cache/mock_cacher.go | 156 +- chains/manager.go | 10 +- codec/linearcodec/camino_codec.go | 13 +- codec/linearcodec/camino_codec_test.go | 7 +- codec/reflectcodec/camino.go | 31 + codec/reflectcodec/struct_fielder.go | 36 +- codec/reflectcodec/type_codec.go | 41 +- database/mock_database.go | 30 +- genesis/camino_config.go | 9 +- go.mod | 2 +- go.sum | 20 +- network/camino_test.go | 69 + network/certs_test.go | 16 +- network/network_test.go | 16 +- network/peer/peer_test.go | 12 +- network/peer/upgrader.go | 21 +- network/test_cert_1.crt | 52 +- network/test_cert_2.crt | 52 +- network/test_cert_3.crt | 52 +- network/test_key_1.key | 100 +- network/test_key_2.key | 100 +- network/test_key_3.key | 100 +- node/node.go | 19 +- scripts/build_camino.sh | 2 +- scripts/build_tools.sh | 12 +- scripts/camino_mocks.mockgen.txt | 20 - scripts/lint.sh | 22 +- scripts/mock.gen.sh | 31 +- scripts/mocks.mockgen.source.txt | 2 + scripts/tests.e2e.sh | 2 +- staking/camino.go | 93 + staking/camino_test.go | 73 + staking/certificate.go | 12 +- staking/large_rsa_key.cert | Bin 4257 -> 2292 bytes staking/parse.go | 29 +- tests/fixture/tmpnet/defaults.go | 2 +- tests/fixture/tmpnet/node.go | 7 +- tests/fixture/tmpnet/node_process.go | 2 +- tools/camino-network-runner | 1 - tools/cert/main.go | 3 +- utils/constants/application.go | 2 +- utils/crypto/secp256k1/camino_secp256k1.go | 42 +- utils/ips/claimed_ip_port.go | 2 +- version/compatibility.json | 2 +- vms/avm/camino_service_test.go | 68 - vms/avm/service_test.go | 2 + vms/components/avax/camino_timed_utxo_test.go | 3 +- vms/components/avax/mock_atomic_utxos.go | 18 +- vms/components/message/camino_codec.go | 31 - vms/components/message/camino_readme.md | 4 + vms/components/message/codec.go | 11 + vms/platformvm/api/camino.go | 2 +- vms/platformvm/api/camino_test.go | 2 +- vms/platformvm/block/builder/builder.go | 13 +- .../block/builder/camino_builder.go | 15 + vms/platformvm/block/codec.go | 2 +- vms/platformvm/block/executor/verifier.go | 2 +- vms/platformvm/camino_helpers_test.go | 4 +- vms/platformvm/camino_service.go | 8 +- vms/platformvm/camino_vm_test.go | 23 +- .../dac/camino_add_member_proposal.go | 10 +- .../dac/camino_base_fee_proposal.go | 10 +- vms/platformvm/dac/camino_codec.go | 5 +- .../dac/camino_exclude_member_proposal.go | 10 +- .../dac/camino_fee_distribution_proposal.go | 10 +- vms/platformvm/dac/camino_general_proposal.go | 10 +- .../dac/camino_mock_bond_tx_ids_getter.go | 18 +- vms/platformvm/dac/camino_proposal.go | 4 +- vms/platformvm/genesis/camino.go | 7 +- vms/platformvm/network/camino_network.go | 86 +- vms/platformvm/network/gossip.go | 4 +- vms/platformvm/service.go | 2 +- vms/platformvm/state/camino.go | 6 +- vms/platformvm/state/camino_claimable.go | 2 +- vms/platformvm/state/camino_claimable_test.go | 4 +- vms/platformvm/state/camino_deposit.go | 2 +- vms/platformvm/state/camino_deposit_offer.go | 2 +- .../state/camino_deposit_offer_test.go | 16 +- vms/platformvm/state/camino_deposit_test.go | 6 +- vms/platformvm/state/camino_helpers_test.go | 4 +- vms/platformvm/state/camino_multisig_alias.go | 2 +- .../state/camino_multisig_alias_test.go | 4 +- vms/platformvm/state/camino_proposal.go | 2 +- vms/platformvm/state/camino_proposal_test.go | 6 +- vms/platformvm/state/camino_stakers.go | 8 +- vms/platformvm/state/camino_test.go | 2 +- .../state/mock_proposals_iterator.go | 8 +- vms/platformvm/state/mock_state.go | 3403 ++++++++--------- vms/platformvm/state/state.go | 2 +- .../state/test/camino_test_state.go | 5 +- vms/platformvm/test/camino_defaults.go | 40 +- vms/platformvm/test/camino_phase.go | 2 + .../txs/builder/camino_builder_test.go | 2 +- .../txs/camino_add_deposit_offer_tx_test.go | 3 +- .../txs/camino_add_proposal_tx_test.go | 9 +- vms/platformvm/txs/camino_add_vote_tx_test.go | 9 +- vms/platformvm/txs/camino_claim_tx_test.go | 3 +- vms/platformvm/txs/camino_deposit_tx_test.go | 3 +- .../txs/camino_finish_proposals_tx_test.go | 3 +- .../txs/camino_multisig_alias_tx_test.go | 3 +- vms/platformvm/txs/camino_owner_id.go | 2 +- .../txs/camino_register_node_tx_test.go | 3 +- .../txs/camino_rewards_import_tx_test.go | 3 +- .../txs/camino_unlock_deposit_tx_test.go | 3 +- vms/platformvm/txs/codec.go | 2 +- .../txs/executor/camino_helpers_test.go | 4 +- .../txs/executor/camino_tx_executor.go | 21 +- .../txs/executor/camino_tx_executor_test.go | 34 +- .../txs/executor/dac/camino_dac_test.go | 17 +- vms/platformvm/utxo/camino_helpers_test.go | 6 +- vms/platformvm/utxo/camino_locked_test.go | 5 +- vms/platformvm/utxo/camino_multisig_test.go | 3 +- vms/platformvm/utxo/mock_verifier.go | 8 +- vms/platformvm/vm.go | 3 +- vms/proposervm/batched_vm_test.go | 2 +- vms/proposervm/block.go | 1 - vms/proposervm/block/block.go | 12 +- vms/proposervm/block/build.go | 3 +- vms/proposervm/block/build_test.go | 4 +- vms/proposervm/block/camino_test.go | 113 + vms/proposervm/block/parse_test.go | 14 +- vms/proposervm/post_fork_block_test.go | 9 - vms/proposervm/pre_fork_block_test.go | 2 - vms/proposervm/state/block_state_test.go | 20 +- vms/proposervm/state_syncable_vm_test.go | 8 +- vms/proposervm/vm.go | 10 + vms/proposervm/vm_test.go | 37 +- vms/secp256k1fx/camino_credential_test.go | 3 +- vms/secp256k1fx/camino_fx_test.go | 2 +- .../camino_transfer_output_test.go | 3 +- vms/secp256k1fx/mock_alias_getter.go | 10 +- 136 files changed, 3069 insertions(+), 2740 deletions(-) delete mode 100644 .github/workflows/cnr-build-test-release.yml delete mode 100644 .github/workflows/cnr-codeql-analysis.yml delete mode 100644 .gitmodules create mode 100644 codec/reflectcodec/camino.go create mode 100644 network/camino_test.go delete mode 100644 scripts/camino_mocks.mockgen.txt create mode 100644 staking/camino.go create mode 100644 staking/camino_test.go delete mode 160000 tools/camino-network-runner delete mode 100644 vms/avm/camino_service_test.go delete mode 100644 vms/components/message/camino_codec.go create mode 100644 vms/components/message/camino_readme.md create mode 100644 vms/proposervm/block/camino_test.go diff --git a/.github/workflows/cnr-build-test-release.yml b/.github/workflows/cnr-build-test-release.yml deleted file mode 100644 index 92efd7aad941..000000000000 --- a/.github/workflows/cnr-build-test-release.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: CNR - Build + test + release - -on: - push: - branches: - - chain4travel - - dev - pull_request: - branches: - - chain4travel - - dev - -permissions: - contents: write - -jobs: - lint_test: - name: Lint tests - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: update dependencies - run: git submodule update --init --recursive - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '1.19' - - name: Run static analysis tests - working-directory: ./tools/camino-network-runner - shell: bash - run: scripts/lint.sh - - unit_test: - name: Unit tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: update dependencies - run: git submodule update --init --recursive - - uses: actions/setup-go@v3 - with: - go-version: '1.19' - - - name: run unit tests - run: go test -v -timeout 10m -race ./... - working-directory: ./tools/camino-network-runner - e2e_test: - name: e2e tests - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: update dependencies - run: git submodule update --init --recursive - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '1.20.10' - - - name: build camino node - shell: bash - run: scripts/build.sh - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '1.19' - - - name: build cnr - working-directory: ./tools/camino-network-runner - shell: bash - run: scripts/build.sh - - - name: Run cnr e2e tests - working-directory: ./tools/camino-network-runner - shell: bash - run: scripts/tests.e2e.sh ${{ github.workspace }}/build/caminogo \ No newline at end of file diff --git a/.github/workflows/cnr-codeql-analysis.yml b/.github/workflows/cnr-codeql-analysis.yml deleted file mode 100644 index cc73c30ac181..000000000000 --- a/.github/workflows/cnr-codeql-analysis.yml +++ /dev/null @@ -1,78 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CNR-CodeQL" - -on: - push: - branches: [ chain4travel, dev ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ chain4travel, dev ] - schedule: - - cron: '44 11 * * 4' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'go' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://git.io/codeql-language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: update dependencies - run: git submodule update --init --recursive - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - working-directory: ./tools/camino-network-runner - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - queries: security-extended - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - with: - working-directory: ./tools/camino-network-runner - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - working-directory: ./tools/camino-network-runner diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d4badeaebdb0..000000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "tools/camino-network-runner"] - path = tools/camino-network-runner - url = ../camino-network-runner.git diff --git a/.golangci.yml b/.golangci.yml index c94179beffd7..fad97cb63712 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -19,8 +19,6 @@ run: # Allowed values: readonly|vendor|mod # By default, it isn't set. modules-download-mode: readonly - skip-dirs: - - "tools/camino-network-runner" output: # Make issues output unique by line. diff --git a/api/info/camino_service_test.go b/api/info/camino_service_test.go index e0715ddd856f..5706f2f759bf 100644 --- a/api/info/camino_service_test.go +++ b/api/info/camino_service_test.go @@ -7,19 +7,13 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" "github.com/ava-labs/avalanchego/utils/logging" ) func TestGetGenesisBytes(t *testing.T) { - mockLog := logging.NewMockLogger(gomock.NewController(t)) - service := Info{log: mockLog} - - mockLog.EXPECT().Debug(gomock.Any()).Times(1) - + service := Info{log: logging.NoLog{}} service.GenesisBytes = []byte("some random bytes") - reply := GetGenesisBytesReply{} require.NoError(t, service.GetGenesisBytes(nil, nil, &reply)) require.Equal(t, GetGenesisBytesReply{GenesisBytes: service.GenesisBytes}, reply) diff --git a/cache/mock_cacher.go b/cache/mock_cacher.go index bdbcdab15fb0..7b8f0bd24f9a 100644 --- a/cache/mock_cacher.go +++ b/cache/mock_cacher.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/cache (interfaces: Cacher) +// Source: cache/cache.go +// +// Generated by this command: +// +// mockgen -source=cache/cache.go -destination=cache/mock_cacher.go -package=cache -exclude_interfaces= +// // Package cache is a generated GoMock package. package cache @@ -37,15 +39,15 @@ func (m *MockCacher[K, V]) EXPECT() *MockCacherMockRecorder[K, V] { } // Evict mocks base method. -func (m *MockCacher[K, V]) Evict(arg0 K) { +func (m *MockCacher[K, V]) Evict(key K) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Evict", arg0) + m.ctrl.Call(m, "Evict", key) } // Evict indicates an expected call of Evict. -func (mr *MockCacherMockRecorder[K, V]) Evict(arg0 interface{}) *gomock.Call { +func (mr *MockCacherMockRecorder[K, V]) Evict(key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Evict", reflect.TypeOf((*MockCacher[K, V])(nil).Evict), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Evict", reflect.TypeOf((*MockCacher[K, V])(nil).Evict), key) } // Flush mocks base method. @@ -60,6 +62,21 @@ func (mr *MockCacherMockRecorder[K, V]) Flush() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Flush", reflect.TypeOf((*MockCacher[K, V])(nil).Flush)) } +// Get mocks base method. +func (m *MockCacher[K, V]) Get(key K) (V, bool) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", key) + ret0, _ := ret[0].(V) + ret1, _ := ret[1].(bool) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockCacherMockRecorder[K, V]) Get(key any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockCacher[K, V])(nil).Get), key) +} + // Len mocks base method. func (m *MockCacher[K, V]) Len() int { m.ctrl.T.Helper() @@ -74,43 +91,126 @@ func (mr *MockCacherMockRecorder[K, V]) Len() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Len", reflect.TypeOf((*MockCacher[K, V])(nil).Len)) } -// Get mocks base method. -func (m *MockCacher[K, V]) Get(arg0 K) (V, bool) { +// PortionFilled mocks base method. +func (m *MockCacher[K, V]) PortionFilled() float64 { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", arg0) - ret0, _ := ret[0].(V) - ret1, _ := ret[1].(bool) - return ret0, ret1 + ret := m.ctrl.Call(m, "PortionFilled") + ret0, _ := ret[0].(float64) + return ret0 } -// Get indicates an expected call of Get. -func (mr *MockCacherMockRecorder[K, V]) Get(arg0 interface{}) *gomock.Call { +// PortionFilled indicates an expected call of PortionFilled. +func (mr *MockCacherMockRecorder[K, V]) PortionFilled() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockCacher[K, V])(nil).Get), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortionFilled", reflect.TypeOf((*MockCacher[K, V])(nil).PortionFilled)) } // Put mocks base method. -func (m *MockCacher[K, V]) Put(arg0 K, arg1 V) { +func (m *MockCacher[K, V]) Put(key K, value V) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Put", arg0, arg1) + m.ctrl.Call(m, "Put", key, value) } // Put indicates an expected call of Put. -func (mr *MockCacherMockRecorder[K, V]) Put(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockCacherMockRecorder[K, V]) Put(key, value any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockCacher[K, V])(nil).Put), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockCacher[K, V])(nil).Put), key, value) } -// PortionFilled mocks base method. -func (m *MockCacher[K, V]) PortionFilled() float64 { +// MockEvictable is a mock of Evictable interface. +type MockEvictable[K comparable] struct { + ctrl *gomock.Controller + recorder *MockEvictableMockRecorder[K] +} + +// MockEvictableMockRecorder is the mock recorder for MockEvictable. +type MockEvictableMockRecorder[K comparable] struct { + mock *MockEvictable[K] +} + +// NewMockEvictable creates a new mock instance. +func NewMockEvictable[K comparable](ctrl *gomock.Controller) *MockEvictable[K] { + mock := &MockEvictable[K]{ctrl: ctrl} + mock.recorder = &MockEvictableMockRecorder[K]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEvictable[K]) EXPECT() *MockEvictableMockRecorder[K] { + return m.recorder +} + +// Evict mocks base method. +func (m *MockEvictable[K]) Evict() { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PortionFilled") - ret0, _ := ret[0].(float64) + m.ctrl.Call(m, "Evict") +} + +// Evict indicates an expected call of Evict. +func (mr *MockEvictableMockRecorder[K]) Evict() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Evict", reflect.TypeOf((*MockEvictable[K])(nil).Evict)) +} + +// Key mocks base method. +func (m *MockEvictable[K]) Key() K { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Key") + ret0, _ := ret[0].(K) return ret0 } -// PortionFilled indicates an expected call of PortionFilled. -func (mr *MockCacherMockRecorder[K, V]) PortionFilled() *gomock.Call { +// Key indicates an expected call of Key. +func (mr *MockEvictableMockRecorder[K]) Key() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortionFilled", reflect.TypeOf((*MockCacher[K, V])(nil).PortionFilled)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Key", reflect.TypeOf((*MockEvictable[K])(nil).Key)) +} + +// MockDeduplicator is a mock of Deduplicator interface. +type MockDeduplicator[K comparable, V Evictable[K]] struct { + ctrl *gomock.Controller + recorder *MockDeduplicatorMockRecorder[K, V] +} + +// MockDeduplicatorMockRecorder is the mock recorder for MockDeduplicator. +type MockDeduplicatorMockRecorder[K comparable, V Evictable[K]] struct { + mock *MockDeduplicator[K, V] +} + +// NewMockDeduplicator creates a new mock instance. +func NewMockDeduplicator[K comparable, V Evictable[K]](ctrl *gomock.Controller) *MockDeduplicator[K, V] { + mock := &MockDeduplicator[K, V]{ctrl: ctrl} + mock.recorder = &MockDeduplicatorMockRecorder[K, V]{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockDeduplicator[K, V]) EXPECT() *MockDeduplicatorMockRecorder[K, V] { + return m.recorder +} + +// Deduplicate mocks base method. +func (m *MockDeduplicator[K, V]) Deduplicate(arg0 V) V { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Deduplicate", arg0) + ret0, _ := ret[0].(V) + return ret0 +} + +// Deduplicate indicates an expected call of Deduplicate. +func (mr *MockDeduplicatorMockRecorder[K, V]) Deduplicate(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Deduplicate", reflect.TypeOf((*MockDeduplicator[K, V])(nil).Deduplicate), arg0) +} + +// Flush mocks base method. +func (m *MockDeduplicator[K, V]) Flush() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Flush") +} + +// Flush indicates an expected call of Flush. +func (mr *MockDeduplicatorMockRecorder[K, V]) Flush() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Flush", reflect.TypeOf((*MockDeduplicator[K, V])(nil).Flush)) } diff --git a/chains/manager.go b/chains/manager.go index 97f80e1a79c5..6603520b58dd 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -264,18 +264,22 @@ type manager struct { } // New returns a new Manager -func New(config *ManagerConfig) Manager { +func New(config *ManagerConfig) (Manager, error) { + cert, err := staking.CertificateFromX509(config.StakingTLSCert.Leaf) + if err != nil { + return nil, err + } return &manager{ Aliaser: ids.NewAliaser(), ManagerConfig: *config, stakingSigner: config.StakingTLSCert.PrivateKey.(crypto.Signer), - stakingCert: staking.CertificateFromX509(config.StakingTLSCert.Leaf), + stakingCert: cert, subnets: make(map[ids.ID]subnets.Subnet), chains: make(map[ids.ID]handler.Handler), chainsQueue: buffer.NewUnboundedBlockingDeque[ChainParameters](initialQueueSize), unblockChainCreatorCh: make(chan struct{}), chainCreatorShutdownCh: make(chan struct{}), - } + }, nil } // Router that this chain manager is using to route consensus messages to chains diff --git a/codec/linearcodec/camino_codec.go b/codec/linearcodec/camino_codec.go index 4b38ee49ea7b..69d1c07ca681 100644 --- a/codec/linearcodec/camino_codec.go +++ b/codec/linearcodec/camino_codec.go @@ -6,6 +6,7 @@ package linearcodec import ( "fmt" "reflect" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/reflectcodec" @@ -36,7 +37,7 @@ type caminoLinearCodec struct { nextCustomTypeID uint32 } -func NewCamino(tagNames []string, maxSliceLen uint32) CaminoCodec { +func NewCamino(durangoTime time.Time, tagNames []string, maxSliceLen uint32) CaminoCodec { hCodec := &caminoLinearCodec{ linearCodec: linearCodec{ nextTypeID: 0, @@ -44,18 +45,18 @@ func NewCamino(tagNames []string, maxSliceLen uint32) CaminoCodec { }, nextCustomTypeID: firstCustomTypeID, } - hCodec.Codec = reflectcodec.New(hCodec, tagNames, maxSliceLen) + hCodec.Codec = reflectcodec.New(hCodec, tagNames, durangoTime, maxSliceLen) return hCodec } // NewDefault is a convenience constructor; it returns a new codec with reasonable default values -func NewCaminoDefault() CaminoCodec { - return NewCamino([]string{reflectcodec.DefaultTagName}, DefaultMaxSliceLength) +func NewCaminoDefault(durangoTime time.Time) CaminoCodec { + return NewCamino(durangoTime, []string{reflectcodec.DefaultTagName}, DefaultMaxSliceLength) } // NewCustomMaxLength is a convenience constructor; it returns a new codec with custom max length and default tags -func NewCaminoCustomMaxLength(maxSliceLen uint32) CaminoCodec { - return NewCamino([]string{reflectcodec.DefaultTagName}, maxSliceLen) +func NewCaminoCustomMaxLength(durangoTime time.Time, maxSliceLen uint32) CaminoCodec { + return NewCamino(durangoTime, []string{reflectcodec.DefaultTagName}, maxSliceLen) } // RegisterCustomType is used to register custom types that may be diff --git a/codec/linearcodec/camino_codec_test.go b/codec/linearcodec/camino_codec_test.go index 5830884c81bb..925e8505b6a9 100644 --- a/codec/linearcodec/camino_codec_test.go +++ b/codec/linearcodec/camino_codec_test.go @@ -7,25 +7,26 @@ import ( "testing" "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/utils/timer/mockable" ) func TestVectorsCamino(t *testing.T) { for _, test := range codec.Tests { - c := NewCaminoDefault() + c := NewCaminoDefault(mockable.MaxTime) test(c, t) } } func TestMultipleTagsCamino(t *testing.T) { for _, test := range codec.MultipleTagsTests { - c := NewCamino([]string{"tag1", "tag2"}, DefaultMaxSliceLength) + c := NewCamino(mockable.MaxTime, []string{"tag1", "tag2"}, DefaultMaxSliceLength) test(c, t) } } func TestVersionCamino(t *testing.T) { for _, test := range codec.VersionTests { - c := NewCaminoDefault() + c := NewCaminoDefault(mockable.MaxTime) test(c, t) } } diff --git a/codec/reflectcodec/camino.go b/codec/reflectcodec/camino.go new file mode 100644 index 000000000000..58da5154e169 --- /dev/null +++ b/codec/reflectcodec/camino.go @@ -0,0 +1,31 @@ +// Copyright (C) 2022, Chain4Travel AG. All rights reserved. +// See the file LICENSE for licensing terms. + +package reflectcodec + +import "reflect" + +const ( + upgradeVersionTagName = "upgradeVersion" + UpgradeVersionIDFieldName = "UpgradeVersionID" +) + +func checkUpgrade(t reflect.Type, numFields int) (bool, int) { + if numFields > 0 && + t.Field(0).Type.Kind() == reflect.Uint64 && + t.Field(0).Name == UpgradeVersionIDFieldName { + return true, 1 + } + return false, 0 +} + +type SerializedFields struct { + Fields []FieldDesc + CheckUpgrade bool + MaxUpgradeVersion uint16 +} + +type FieldDesc struct { + Index int + UpgradeVersion uint16 +} diff --git a/codec/reflectcodec/struct_fielder.go b/codec/reflectcodec/struct_fielder.go index e714cdab5e9a..a40d86b4df30 100644 --- a/codec/reflectcodec/struct_fielder.go +++ b/codec/reflectcodec/struct_fielder.go @@ -16,6 +16,7 @@ package reflectcodec import ( "fmt" "reflect" + "strconv" "sync" "github.com/ava-labs/avalanchego/codec" @@ -34,13 +35,13 @@ type StructFielder interface { // is un-exported. // GetSerializedField(Foo) --> [1,5,8] means Foo.Field(1), Foo.Field(5), // Foo.Field(8) are to be serialized/deserialized. - GetSerializedFields(t reflect.Type) ([]int, error) + GetSerializedFields(t reflect.Type) (SerializedFields, error) } func NewStructFielder(tagNames []string) StructFielder { return &structFielder{ tags: tagNames, - serializedFieldIndices: make(map[reflect.Type][]int), + serializedFieldIndices: make(map[reflect.Type]SerializedFields), } } @@ -56,10 +57,10 @@ type structFielder struct { // that is serialized/deserialized e.g. Foo --> [1,5,8] means Foo.Field(1), // etc. are to be serialized/deserialized. We assume this cache is pretty // small (a few hundred keys at most) and doesn't take up much memory. - serializedFieldIndices map[reflect.Type][]int + serializedFieldIndices map[reflect.Type]SerializedFields } -func (s *structFielder) GetSerializedFields(t reflect.Type) ([]int, error) { +func (s *structFielder) GetSerializedFields(t reflect.Type) (SerializedFields, error) { if serializedFields, ok := s.getCachedSerializedFields(t); ok { // use pre-computed result return serializedFields, nil } @@ -68,8 +69,9 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]int, error) { defer s.lock.Unlock() numFields := t.NumField() - serializedFields := make([]int, 0, numFields) - for i := 0; i < numFields; i++ { // Go through all fields of this struct + checkUpgrade, startIndex := checkUpgrade(t, numFields) + serializedFields := SerializedFields{Fields: make([]FieldDesc, 0, numFields), CheckUpgrade: checkUpgrade} + for i := startIndex; i < numFields; i++ { // Go through all fields of this struct field := t.Field(i) // Multiple tags per fields can be specified. @@ -86,19 +88,33 @@ func (s *structFielder) GetSerializedFields(t reflect.Type) ([]int, error) { continue } if !field.IsExported() { // Can only marshal exported fields - return nil, fmt.Errorf("can not marshal %w: %s", + return SerializedFields{}, fmt.Errorf("can not marshal %w: %s", codec.ErrUnexportedField, field.Name, ) } - serializedFields = append(serializedFields, i) + + upgradeVersionTag := field.Tag.Get(upgradeVersionTagName) + upgradeVersion := uint16(0) + if upgradeVersionTag != "" { + v, err := strconv.ParseUint(upgradeVersionTag, 10, 8) + if err != nil { + return SerializedFields{}, fmt.Errorf("can't parse %s (%s)", upgradeVersionTagName, upgradeVersionTag) + } + upgradeVersion = uint16(v) + serializedFields.MaxUpgradeVersion = upgradeVersion + } + + serializedFields.Fields = append(serializedFields.Fields, FieldDesc{ + Index: i, + UpgradeVersion: upgradeVersion, + }) } - serializedFields.MaxUpgradeVersion = maxUpgradeVersion s.serializedFieldIndices[t] = serializedFields // cache result return serializedFields, nil } -func (s *structFielder) getCachedSerializedFields(t reflect.Type) ([]int, bool) { +func (s *structFielder) getCachedSerializedFields(t reflect.Type) (SerializedFields, bool) { s.lock.RLock() defer s.lock.RUnlock() diff --git a/codec/reflectcodec/type_codec.go b/codec/reflectcodec/type_codec.go index 1d6bbee7cff0..f21545913156 100644 --- a/codec/reflectcodec/type_codec.go +++ b/codec/reflectcodec/type_codec.go @@ -221,8 +221,20 @@ func (c *genericCodec) size( size int constSize = true ) - for _, fieldIndex := range serializedFields { - innerSize, innerConstSize, err := c.size(value.Field(fieldIndex), typeStack) + upgradeVersion := uint16(0) + if serializedFields.CheckUpgrade { + upgradeVersionID := value.Field(0).Uint() + if upgradeVersionID&codec.UpgradePrefix == codec.UpgradePrefix { + upgradeVersion = codec.UpgradeVersionID(upgradeVersionID).Version() + size += wrappers.LongLen + } + } + + for _, fieldDesc := range serializedFields.Fields { + if fieldDesc.UpgradeVersion > upgradeVersion { + break + } + innerSize, innerConstSize, err := c.size(value.Field(fieldDesc.Index), typeStack) if err != nil { return 0, false, err } @@ -428,8 +440,22 @@ func (c *genericCodec) marshal( if err != nil { return err } - for _, fieldIndex := range serializedFields { // Go through all fields of this struct that are serialized - if err := c.marshal(value.Field(fieldIndex), p, typeStack); err != nil { // Serialize the field and write to byte array + upgradeVersion := uint16(0) + if serializedFields.CheckUpgrade { + upgradeVersionID := value.Field(0).Uint() + if upgradeVersionID&codec.UpgradePrefix == codec.UpgradePrefix { + upgradeVersion = codec.UpgradeVersionID(upgradeVersionID).Version() + p.PackLong(upgradeVersionID) + if p.Err != nil { + return p.Err + } + } + } + for _, fieldDesc := range serializedFields.Fields { // Go through all fields of this struct that are serialized + if fieldDesc.UpgradeVersion > upgradeVersion { + break + } + if err := c.marshal(value.Field(fieldDesc.Index), p, typeStack); err != nil { // Serialize the field and write to byte array return err } } @@ -707,8 +733,11 @@ func (c *genericCodec) unmarshal( } } // Go through the fields and umarshal into them - for _, fieldIndex := range serializedFieldIndices { - if err := c.unmarshal(p, value.Field(fieldIndex), typeStack); err != nil { + for _, fieldDesc := range serializedFieldIndices.Fields { + if fieldDesc.UpgradeVersion > upgradeVersion { + break + } + if err := c.unmarshal(p, value.Field(fieldDesc.Index), typeStack); err != nil { return err } } diff --git a/database/mock_database.go b/database/mock_database.go index f790f2f08e37..e393b47091d7 100644 --- a/database/mock_database.go +++ b/database/mock_database.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/database (interfaces: Database) +// +// Generated by this command: +// +// mockgen -package=database -destination=database/mock_database.go github.com/ava-labs/avalanchego/database Database +// // Package database is a generated GoMock package. package database @@ -60,7 +62,7 @@ func (m *MockDatabase) Compact(arg0, arg1 []byte) error { } // Compact indicates an expected call of Compact. -func (mr *MockDatabaseMockRecorder) Compact(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) Compact(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Compact", reflect.TypeOf((*MockDatabase)(nil).Compact), arg0, arg1) } @@ -74,7 +76,7 @@ func (m *MockDatabase) Delete(arg0 []byte) error { } // Delete indicates an expected call of Delete. -func (mr *MockDatabaseMockRecorder) Delete(arg0 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) Delete(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockDatabase)(nil).Delete), arg0) } @@ -89,7 +91,7 @@ func (m *MockDatabase) Get(arg0 []byte) ([]byte, error) { } // Get indicates an expected call of Get. -func (mr *MockDatabaseMockRecorder) Get(arg0 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) Get(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockDatabase)(nil).Get), arg0) } @@ -104,22 +106,22 @@ func (m *MockDatabase) Has(arg0 []byte) (bool, error) { } // Has indicates an expected call of Has. -func (mr *MockDatabaseMockRecorder) Has(arg0 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) Has(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockDatabase)(nil).Has), arg0) } // HealthCheck mocks base method. -func (m *MockDatabase) HealthCheck(arg0 context.Context) (interface{}, error) { +func (m *MockDatabase) HealthCheck(arg0 context.Context) (any, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "HealthCheck", arg0) - ret0, _ := ret[0].(interface{}) + ret0, _ := ret[0].(any) ret1, _ := ret[1].(error) return ret0, ret1 } // HealthCheck indicates an expected call of HealthCheck. -func (mr *MockDatabaseMockRecorder) HealthCheck(arg0 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) HealthCheck(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HealthCheck", reflect.TypeOf((*MockDatabase)(nil).HealthCheck), arg0) } @@ -161,7 +163,7 @@ func (m *MockDatabase) NewIteratorWithPrefix(arg0 []byte) Iterator { } // NewIteratorWithPrefix indicates an expected call of NewIteratorWithPrefix. -func (mr *MockDatabaseMockRecorder) NewIteratorWithPrefix(arg0 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) NewIteratorWithPrefix(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithPrefix", reflect.TypeOf((*MockDatabase)(nil).NewIteratorWithPrefix), arg0) } @@ -175,7 +177,7 @@ func (m *MockDatabase) NewIteratorWithStart(arg0 []byte) Iterator { } // NewIteratorWithStart indicates an expected call of NewIteratorWithStart. -func (mr *MockDatabaseMockRecorder) NewIteratorWithStart(arg0 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) NewIteratorWithStart(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStart", reflect.TypeOf((*MockDatabase)(nil).NewIteratorWithStart), arg0) } @@ -189,7 +191,7 @@ func (m *MockDatabase) NewIteratorWithStartAndPrefix(arg0, arg1 []byte) Iterator } // NewIteratorWithStartAndPrefix indicates an expected call of NewIteratorWithStartAndPrefix. -func (mr *MockDatabaseMockRecorder) NewIteratorWithStartAndPrefix(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) NewIteratorWithStartAndPrefix(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIteratorWithStartAndPrefix", reflect.TypeOf((*MockDatabase)(nil).NewIteratorWithStartAndPrefix), arg0, arg1) } @@ -203,7 +205,7 @@ func (m *MockDatabase) Put(arg0, arg1 []byte) error { } // Put indicates an expected call of Put. -func (mr *MockDatabaseMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDatabaseMockRecorder) Put(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockDatabase)(nil).Put), arg0, arg1) } diff --git a/genesis/camino_config.go b/genesis/camino_config.go index 0a07fe68ba17..3786ce7b79e5 100644 --- a/genesis/camino_config.go +++ b/genesis/camino_config.go @@ -9,6 +9,7 @@ import ( "fmt" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/hashing" @@ -121,9 +122,11 @@ func (a CaminoAllocation) Unparse(networkID uint32) (UnparsedCaminoAllocation, e return ua, err } -func (a CaminoAllocation) Less(other CaminoAllocation) bool { - return a.XAmount < other.XAmount || - (a.XAmount == other.XAmount && a.AVAXAddr.Less(other.AVAXAddr)) +func (a CaminoAllocation) Compare(other CaminoAllocation) int { + if amountCmp := utils.Compare(a.XAmount, other.XAmount); amountCmp != 0 { + return amountCmp + } + return a.AVAXAddr.Compare(other.AVAXAddr) } type PlatformAllocation struct { diff --git a/go.mod b/go.mod index 0e063a815541..c4b4a6d248d8 100644 --- a/go.mod +++ b/go.mod @@ -162,4 +162,4 @@ require ( replace github.com/ava-labs/avalanche-ledger-go => github.com/chain4travel/camino-ledger-go v0.0.13-c4t -replace github.com/ava-labs/coreth => github.com/chain4travel/caminoethvm v1.1.17-rc0 +replace github.com/ava-labs/coreth => github.com/chain4travel/caminoethvm v1.1.18-rc0 diff --git a/go.sum b/go.sum index 43472c6b767e..60f05f305b94 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chain4travel/caminoethvm v1.1.17-rc0 h1:wA4Qds83AXP71w1XP1wlts7p6B8P70g14YRX3pnV9P8= -github.com/chain4travel/caminoethvm v1.1.17-rc0/go.mod h1:xSjZ76NJK1UUMaYl1mLrkdNbb1RDUhtBA71WXkJI50Y= +github.com/chain4travel/caminoethvm v1.1.18-rc0 h1:pzYPYEv40IwbR8yNbGCn+Vms4Rh8iR5Y1I8VaeiZiAQ= +github.com/chain4travel/caminoethvm v1.1.18-rc0/go.mod h1:4lQHHwvaN5o1QzbcpqTI3qbVBulByo112welHnu2aEs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -705,6 +705,7 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -747,6 +748,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -794,6 +796,9 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -818,6 +823,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -889,10 +895,16 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -905,6 +917,9 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -969,6 +984,7 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/network/camino_test.go b/network/camino_test.go new file mode 100644 index 000000000000..314862c436e6 --- /dev/null +++ b/network/camino_test.go @@ -0,0 +1,69 @@ +// Copyright (C) 2023, Chain4Travel AG. All rights reserved. +// See the file LICENSE for licensing terms. + +package network + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/utils/perms" +) + +// Convinient way to run generateTestKeyAndCertFile. Comment out SkipNow before run. +func TestGenerateTestCert(t *testing.T) { + t.SkipNow() + for i := 1; i <= 3; i++ { + require.NoError(t, generateTestKeyAndCertFile( + fmt.Sprintf("test_key_%d.key", i), + fmt.Sprintf("test_cert_%d.crt", i), + )) + } +} + +// Creates key and cert files. Those are used by tests in this package. +func generateTestKeyAndCertFile(keyPath, certPath string) error { + certBytes, keyBytes, err := staking.NewCertAndKeyBytesWithSecpKey(nil) + if err != nil { + return err + } + + // Ensure directory where key/cert will live exist + if err := os.MkdirAll(filepath.Dir(certPath), perms.ReadWriteExecute); err != nil { + return fmt.Errorf("couldn't create path for cert: %w", err) + } + if err := os.MkdirAll(filepath.Dir(keyPath), perms.ReadWriteExecute); err != nil { + return fmt.Errorf("couldn't create path for key: %w", err) + } + + // Write cert to disk + certFile, err := os.Create(certPath) + if err != nil { + return fmt.Errorf("couldn't create cert file: %w", err) + } + if _, err := certFile.Write(certBytes); err != nil { + return fmt.Errorf("couldn't write cert file: %w", err) + } + if err := certFile.Close(); err != nil { + return fmt.Errorf("couldn't close cert file: %w", err) + } + + // Write key to disk + keyOut, err := os.Create(keyPath) + if err != nil { + return fmt.Errorf("couldn't create key file: %w", err) + } + if _, err := keyOut.Write(keyBytes); err != nil { + return fmt.Errorf("couldn't write private key: %w", err) + } + if err := keyOut.Close(); err != nil { + return fmt.Errorf("couldn't close key file: %w", err) + } + + return nil +} diff --git a/network/certs_test.go b/network/certs_test.go index 93c9a99628e2..543fd5eccb8f 100644 --- a/network/certs_test.go +++ b/network/certs_test.go @@ -68,8 +68,13 @@ func init() { cert1, cert2, cert3, } + stakingCert1, err := staking.CertificateFromX509(cert1.Leaf) + if err != nil { + panic(err) + } + ip = ips.NewClaimedIPPort( - staking.CertificateFromX509(cert1.Leaf), + stakingCert1, ips.IPPort{ IP: net.IPv4(127, 0, 0, 1), Port: 9651, @@ -77,8 +82,13 @@ func init() { 1, // timestamp nil, // signature ) + + stakingCert2, err := staking.CertificateFromX509(cert2.Leaf) + if err != nil { + panic(err) + } otherIP = ips.NewClaimedIPPort( - staking.CertificateFromX509(cert2.Leaf), + stakingCert2, ips.IPPort{ IP: net.IPv4(127, 0, 0, 1), Port: 9651, @@ -104,7 +114,7 @@ func getTLS(t *testing.T, index int) (ids.NodeID, *tls.Certificate, *tls.Config) } tlsCert := tlsCerts[index] - nodeID, err := peer.CertToID(tlsCert.Leaf) + nodeID, err := staking.TLSCertToID(tlsCert.Leaf) require.NoError(t, err) return nodeID, tlsCert, tlsConfigs[index] diff --git a/network/network_test.go b/network/network_test.go index 90c063a99bb7..79864075c32b 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -396,9 +396,12 @@ func TestTrackVerifiesSignatures(t *testing.T) { nodeID, tlsCert, _ := getTLS(t, 1) require.NoError(network.config.Validators.AddStaker(constants.PrimaryNetworkID, nodeID, nil, ids.Empty, 1)) - err := network.Track([]*ips.ClaimedIPPort{ + stakingCert, err := staking.CertificateFromX509(tlsCert.Leaf) + require.NoError(err) + + err = network.Track([]*ips.ClaimedIPPort{ ips.NewClaimedIPPort( - staking.CertificateFromX509(tlsCert.Leaf), + stakingCert, ips.IPPort{ IP: net.IPv4(123, 132, 123, 123), Port: 10000, @@ -551,15 +554,16 @@ func TestDialDeletesNonValidators(t *testing.T) { wg.Add(len(networks)) for i, net := range networks { if i != 0 { - err := net.Track([]*ips.ClaimedIPPort{ + stakingCert, err := staking.CertificateFromX509(config.TLSConfig.Certificates[0].Leaf) + require.NoError(err) + require.NoError(net.Track([]*ips.ClaimedIPPort{ ips.NewClaimedIPPort( - staking.CertificateFromX509(config.TLSConfig.Certificates[0].Leaf), + stakingCert, ip.IPPort, ip.Timestamp, ip.Signature, ), - }) - require.NoError(err) + })) } go func(net Network) { diff --git a/network/peer/peer_test.go b/network/peer/peer_test.go index 574f3e51a6c8..82a2560b22d9 100644 --- a/network/peer/peer_test.go +++ b/network/peer/peer_test.go @@ -78,17 +78,17 @@ func makeRawTestPeers(t *testing.T, trackedSubnets set.Set[ids.ID]) (*rawTestPee tlsCert0, err := staking.NewTLSCert() require.NoError(err) - cert0 := staking.CertificateFromX509(tlsCert0.Leaf) - - tlsCert1, err := staking.NewTLSCert() + cert0, err := staking.CertificateFromX509(tlsCert0.Leaf) require.NoError(err) - cert1 := staking.CertificateFromX509(tlsCert1.Leaf) - nodeID0, err := CertToID(tlsCert0.Leaf) + tlsCert1, err := staking.NewTLSCert() require.NoError(err) - nodeID1, err := CertToID(tlsCert1.Leaf) + cert1, err := staking.CertificateFromX509(tlsCert1.Leaf) require.NoError(err) + nodeID0 := cert0.NodeID + nodeID1 := cert1.NodeID + mc := newMessageCreator(t) metrics, err := NewMetrics( diff --git a/network/peer/upgrader.go b/network/peer/upgrader.go index 260a7e3a6ca3..185b38ee20c6 100644 --- a/network/peer/upgrader.go +++ b/network/peer/upgrader.go @@ -15,7 +15,6 @@ package peer import ( "crypto/tls" - "crypto/x509" "errors" "net" "time" @@ -24,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/staking" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" ) var ( @@ -105,22 +103,5 @@ func connToIDAndCert(conn *tls.Conn, invalidCerts prometheus.Counter, durangoTim return ids.EmptyNodeID, nil, nil, err } - nodeID, err := CertToID(tlsCert) - return nodeID, conn, peerCert, err -} - -func CertToID(cert *x509.Certificate) (ids.NodeID, error) { - pubKeyBytes, err := secp256k1.RecoverSecp256PublicKey(cert) - if err != nil { - return ids.EmptyNodeID, err - } - return ids.ToNodeID(pubKeyBytes) -} - -func StakingCertToID(cert *staking.Certificate) (ids.NodeID, error) { - tlsCert, err := x509.ParseCertificate(cert.Raw) - if err != nil { - return ids.EmptyNodeID, err - } - return CertToID(tlsCert) + return peerCert.NodeID, conn, peerCert, err } diff --git a/network/test_cert_1.crt b/network/test_cert_1.crt index 2f2b95e658ad..fdea827de0d8 100644 --- a/network/test_cert_1.crt +++ b/network/test_cert_1.crt @@ -1,27 +1,29 @@ -----BEGIN CERTIFICATE----- -MIIEnTCCAoWgAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw -MFoYDzIxMjQwMTA5MTQ0NTU4WjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEAqCOUESK8b5N894dVCSIs4mTfNTdhaL5cnw3ZXSbZlfquBRJOxhqHXutG -An9++OTWvevrssaXBxGT4oOT3N11dm4iKh7ewi3to+1Sfqq71blCVZtBDOeWpZx0 -WwhPO37Us26fCR7T2gStiTHY9qE0QV/9p15OCAFsRb94JuhF0OR0d6tRm0yQ6b7Y -NRzpaBw4MBxZD9h84+QDdhsTyxI0xk/NnbG74pykjsau0/YA9mNqHHSnL4DyD5qu -IKqRfD5HQHemx66I3jEXUB/GxTHhxz5uskIpS9AV3oclvVi14BjSEWgNkJX+nMi+ -tjuSKouAFpzJZzZme2DvmyAecxbNVBdajOTe2QRiG7HKh1OdMZabd2dUNv5S9/gd -bI53s4R++z/H4llsBfk6B2+/DmqDRauh4Mz9HTf0Pud7Nz2b7r77PnPTjHExgN3R -i+Yo6LskRCQTzzTVwW/RY+rNVux9UE6ZPLarDbXnSyetKMUS7qlz8NUerWjtkC6i -om570LfTGs3GxIqVgoGg0mXuji+EoG+XpYR3PRaeo8cAmfEu7T+SxgSfJAv7DyZv -+a2VTZcOPDI1KTLrM8Xovy17t5rd9cy1/75vxnKLiGDEhzWJmNl4IvIYbtihWWl5 -ksdFYbe9Dpvuh/wBCGoK+kmCirUM1DiizWn5TxJeS1qYI8I2sYMCAwEAAaMgMB4w -DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB -AABzczRjzfhlmV+bFDzAs7nszQlZREcoRuWe5qHy7VKLvZvIAaYlcApB34hH7nDq -T/8fS8g8rC+Tzw0iCPF21Z4AzSe76V6EU4VGWWe8l00nDszfvavE5BF24z8dCuVC -1gScC1tvG6FPT23koZ0BVmyueCIa7sdqFlDz8rrRpLWfUcLj38gxwWM2JVBHQUvV -j87lzpTNH+2nPiwrKISqUPFi4YvbWKe8T4bY2Elw7THiNLZGfgqOXVkeIVi4fs97 -Tc5uscZ4OpSTlrfJqMJEV8cMRvrDmhD/VWbJvnk7lyELPoHx6MUinBswBT51yvmY -bZh4AZ43GSvSyo/V7p9scytQP3zM1MeHpsFa0RHwGVFp2BmO1abvydAxX0NMWasv -WUzXCKliXsVD/qUeCU/CFnaBqpzBvm4AFBgwHzprwzP9Be/mz/TjTcsfrmoiyxlr -QjXNk9TnP9d+aeOJsRz+JSYyHETACO5PkCg+XCDyEOf+kQAzVb9Dp0oWaCovXciU -A5z0DSDzyKVBOQo0syb5NFsLZ2DeJemNbP+3kCNzBBASQ4VWAvRbLjPh3Oe8A5PZ -xezCvzRE05O6tYkz5C5hcKbpAjfP8G8RV6ERjLBICBfb7XI7T0hixhiNHlIKknkJ -F82B/zDt+qBFARw8A/qr44RF+vy3Ql4IS2ZcflAv2pTO +MIIE8DCCAtigAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw +MFoYDzIxMjQwMzE4MTYwMTI5WjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAvsEZXaDjj95upEeri5jtyXOL6eg63IfTX+EEsTL8ntDZVBEAI8082PPH +0tYmn/TzyYpabiGeRhmnVmClxKDmRjZKo7yzQXjMWBASjGl3aY9ywR0sDDf/Zp66 +wtNGP7JyJEgJFfQyPCU7Updy4ZCfa6PUEJ9zYVCbeLIZq5UQJriwn5kd+MlPup5m +McEEj8nGgROceSGEU7n6lj9jR054ZVhtmhg5TyZ4FazS+JVlspPrLvCLnzZx8wRK +DFz0d0PyI7ys6Op2CfEhF7OY9SGbW5bRFszUiWeZLxXKTyDcKJclr8hDX6U/3Eiv +D57K9Iy7j1dr4GSbQqanYjmrKHHcHdY3RA9ZNo4kPtdDNlMEHv4CK7W4ErawI9Uz +2x67AFpF9yhSU9V8a4MZRNodjCdiIpoL05KfEeLv/qPnovh45a0+OSZQ+sfAuNZU +JHvYTWNFrWlWOmKc7VxeRP27hkj3quFLTzfDAYKYJAia0S/D37MlN9oEonWfE2KM +wn1eXWckebAdp8+zE7qIu/CN27zramypmfJGY0PJKtiTdOQHZL2faD1bjzN9JVTM +GET+4ltYQcwldVy0fiJZD+snVRe4tK+5a159Ifetg9tyHp8xnirXZf5LbTMd5GCY +GXpRmej9yeX6ffPKsugMiGOiEYQEsbadnLXhLgw7Sc9KzH6bfKsCAwEAAaNzMHEw +DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwUQYJKoZIhvcNAQkVAQH/BEEb +C+HFwdeYOcU1MCyPv0eYmIVFic/Qe/VC0MkpE+Y2xcQeC2JMEW9qXRkDxkqsogC4 +BIb+wTzAe/k0qZJyW39LTzANBgkqhkiG9w0BAQsFAAOCAgEAb6/SwnSwJtdK9p9u +AjHrhrho2UNdm1ng8C5vZZKmsYEvdOMsm3HACZm9p87gzNwG8lAOGIOsAMVUwDWd +2fMCP2XGqK5XLR1YSZJ4tQ6FMWM9vmovcmBOdIC8U++QDg+YPBueP6VFd4pnrRBO +bNwfzsIz3Y3tPJUWsrAIm0l9Pb/S+aN/SE+Fkh0H+lGeyEOwYjjodrNz/8zUMNu/ +XwE160kBmhsAzxqOwX8LDsk+iD5pUOqRVh7mAfLsB9azJbT52kxZY/e+8F80dEjQ +ZVHW5BpTrKZRQET9QcDYzvwRtqC8Lo/D9j7Rw9EyITxTK5US/7TZzv0n1JVYGZkN +B+ssz8hg2JULWr37s1LLGMSw+UcTNixrQcJ+TSmtKIVnJC+T8qYBHeEMV9AY2c/V +H06BkOFF3epOwV1f8TvtNmmfzC/I6zi6nU3ucrrz5VJpFYXBX3MgvkIV4k+W25EA +ZwGOSOidQJeoSOw/StYgRyL8pK5GGNm14HYcwfRfTv9rAvwaoJ75YmHxb2GKmIyY +4sHCIOE7G8hgRVbHXlt6zOJ/PTHCHpjGIkb3ensDIRgKhMAmwZcugtNvYCzGMHTA +tzXYMbb2AedwlPPBEDGOLZNTiYnHGngiQw47G+2O95xmPhJp8enm+nu+kCL8yf0n +oQp/Rh3sD1jtRwRwHkfcMeXSc5c= -----END CERTIFICATE----- diff --git a/network/test_cert_2.crt b/network/test_cert_2.crt index 283e286be446..9da575477df7 100644 --- a/network/test_cert_2.crt +++ b/network/test_cert_2.crt @@ -1,27 +1,29 @@ -----BEGIN CERTIFICATE----- -MIIEnTCCAoWgAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw -MFoYDzIxMjQwMTA5MTQ0NTQ3WjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEArT7afarml6cvCmAySAO8GQka1mcQIMACyEWy6KsqiccX+DoGh5ECyQSa -WFKWKGdQ32dAWGVlSkmmgJ1jtW749hSguysav3EPMaxe/ad5CV1MwyyccGS9U99M -z0UVuFEXVjN5W6UlcULp1oJDj07NzZP6ByRiDvnjzgeYb3jHwjqOBNwex1jLW6vp -oWD03zTanVQXZaaGcEISCI2CgDP3uXfd0NQpoGVpf9gMi0cdGu8gpqbLqBjzjzr8 -GDBQYGaWKFnlqe6X9nBUad/qNE3Zeb3ehSg+M2ecQzTZFWirfa6cGTtovu04RMML -9OLflQy3rTRST2HQ6z0gpVCP3V2Mg/LmAuWyhOLVYNkhEwkRHvddzFksRzQ+ghpP -cGfvI0dwxQV0CbEMVjd9zVEA6dOrMLI3st2922hqF23Al1+Hwcu1G/T3ybfSTwjd -YZ23IgkQF4r+RIXevzgOBBXfEwE8XERW2zNwUG5Sv5dxx+FgDjX0EGbrzgY6OeKT -D1SP/7WQLjwmGgwyNJYkAklvEKwU+dlGD5NpgvJ9fg8R1wUhp2HhSZ1l1OUVmRYw -YqUm7dTLK1CJU2BH2sRyZcUkwstjvgi688zfHNttGYmAnx6wGS12jWf+W4df+QNI -Ng6AdcJ5Ee0z0JAbTpZW/zX3CTSroow7igHnd4AwvKEVQFcyO/MCAwEAAaMgMB4w -DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB -ACePaZvjw2KiheheWNjzOv2B+7uLVe7oEbThEUQypEmTFK8wKaHwI4BGdBGEOr/N -LZ1M2wAYgwzMTEDJE+GEB2ZHIdH9cH5lu7ITsOMVcBSJttEJVhhEtbMwVJ9JC62j -AsW4VmHFpEik+xvinxedKczXOa21YJo4sv2TiFWFaSHqPeRo7HA1dxQYOwiLsS6e -JKIupMrn8IZz2YN5gFhbvQTBp2J3u6kxMIzN0a+BPARR4fwMn5lVMVvye/+8Kwtw -dZHSN1FYUcFqHagmhNlNkAOaGQklSFWtsVVQxQCFS2bxEImLj5kG16fCAsQoRC0J -ZS2OaRncrtB0r0Qu1JB5XJP9FLflSb57KIxBNVrl+iWdWikgBFE6cMthMwgLfQ99 -k8AMp6KrCjcxqegN+P30ct/JwahKPq2+SwtdHG3yrZ2TJEjhOtersrTnRK9zqm9v -lqS7JsiztjgqnhMs2eTdXygfEe0AoZihGTaaLYj37A9+2RECkuijkjBghG2NBnv6 -264lTghZyZcZgZNCgYglYC1bhifEorJpYf6TOOcDAi5UH8R7vi4x70vI6sIDrhga -d9E63EVe11QdIjceceMlNm42UTrhl0epMbL6FIzU+d91qBgd9qT6YqoYPFZSiYFy -2hArgLxH2fxTXatCAit5g1MEk0w1MiHVrPZ8lTU3U/ET +MIIE8DCCAtigAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw +MFoYDzIxMjQwMzE4MTYwMTMwWjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAtPZD0vWJsOtAvfFRmZLg+DtKfWuLTxQpvQ+Nk8Qhb+HMrSdvQGEfP0Ng +ooicuB6qDeqIZDpTQE+wL25d+G3Kl7IMinnIQKUfhfP6nAaQfBJ/sNK2O5CbvorB +hx5Sux5tYeoTlueRmMzwNwaBwHaOI01qrCdU2lZq7Dw6SwR9zg6FTxpTgDuoQ6l5 +lqLV3aFj7hFxW4HrVVjJlv4E6ud40TBBpK1eMVTHuTWro9fR0ywC2JSNn0ziGaxq +i60yqtyjxAuW29O+cqFj8aZMUd5Ctp1fhpKSIQ29X91WwXY3An7ktDQFRdG82BLP +kuMzuO36w2VjotUvVY3yFKjp4cRX8gUqyR8VrmP47Q3ggz2ikGc9WrPjKusqOHBa +SVUdesGzxz/02O+B1S2jCeg2RyNDSvGv2+95a8LIU81hknWO91ehUIpjToBXKr2d +uHO/yWIeFvjeY5GzDPSQynAeYwuGlk4yOQtfrMqAssSsyzzeNh2p7NwL6x+UOfgv +7emRIaGvXS3IDOrZhYqFzrepuKdAbZjlaB9UR2SzEHfSUFfZ7Vr1uuEdAR8E/AVP +IML1ZcGJBZCgk5XtBONXpz/OC6mBhEHwyYsT3WKEbYV1YUvLSLJblazCuu/8lt2H +XdKiJOnO7bqaljULrRurUjvm8tPw4emh8Wn5lpdsS5WwNh7dtbsCAwEAAaNzMHEw +DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwUQYJKoZIhvcNAQkVAQH/BEEb +Ptzr6dH/qgkH6FajLU+2aSz2Ilbptfq2MyWpjou2G39Q4keXs03sA2N5q8zxwpIl +U5QntRoh+XYMqk7P2XiiezANBgkqhkiG9w0BAQsFAAOCAgEAZXsfQvMp3IvDeFVZ +wT53Nre6UGESh0XH1YfRcYfKH62GQc52RiO2W1/0L8hg+QEeOZEkXV4c6Z+3bKhY +rogtLlUZJtHcY7GoV11BdzLeHKpSgIvtZ00kAXB9pivGufJe0PSHXKGtpmcf7Uim +SfVYyP7c7/J+pWgixrqqROatQLh/vXTsFDSrjhzQukRChECGG3rkp6X7czeh95A+ +S+u37MaOS1LGlTzvZOJRvTl/SxSObLKRj6vPmRnqnc6sMCLH6904yEK6NFMY1D1a +Ixp+3o0pnqTAbLpXzXQOEPOHaq/Bqd7cKLX5pbscptJ2Fy6hY8f3WcIzEb2spB1v +KHpmb8yYG/QXS1JmIm/ywPyniLzAXljZJoLmgG3brXXPqhvoEocPXUtMUFiA3kLt +AVMZCoCZqJlPUmR9CKYV9ELAeYZJ838la6/9aTHzK812FCun2uOkTrTqkd6bMiV7 +Qv0dyiYpOUy6F/O9ZhqCWU+JIjOQ+8jXD537G+pJOm+HJiFPWjL0a9J57DrKObXT +SGUX0o4PKLwLSbpQNNbXUHq46DU7mPn2AmgjrYnXaFmGLdOsOrN9Vy4vMqFhgPVO +4v/a3oyFwpve5t0/PZDYsLJCb8MDE4RDxlGa5xI47UeYV7j1DqlAVDO3stKxvz0K +Mg2BgFkrVQaV5n9r8J8GMzGIDM0= -----END CERTIFICATE----- diff --git a/network/test_cert_3.crt b/network/test_cert_3.crt index c0977191ec7b..8667b3581bcc 100644 --- a/network/test_cert_3.crt +++ b/network/test_cert_3.crt @@ -1,27 +1,29 @@ -----BEGIN CERTIFICATE----- -MIIEnTCCAoWgAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw -MFoYDzIxMjQwMTA5MTQ0NTM0WjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC -CgKCAgEA5aV76ivIZ1iWmW0OzGMCrmFQBnej9JntQ1jP9yiacKu7j5Z/bD/eqoyc -jRwoSiesErfnThAGy7H80glVw/XmC0fYNPVDPyzAEdNk46M3yEI8hAKI6aSkl1s1 -KVAHpQuNcG+3xIB39OOMx0XuycZ6gqzyMmjqeT0cThNDXTwGbodMVDAf0q220QAq -zB/lz0sjHPXlYh25LJ1yPtl+vlcfGrP+q+2ODR9rnI79PE7AZB4Xc6wUIca5XXkH -PS7zQ1Ida1xrf446MYCVuazLFhpzq8/nhkxNMzxdZsJaWavL+xkpjGxAySvj0jlu -QFGsmsxOIU/XgJD/VRqqyISXpl2wg0l8mpsU9fV7bEW1y6MIc7AARRgbbEPiDz8m -/O8mjEW3C16untLHB7LzPCCitTssGR65Shkj+Lw+aM4X5ZI+Xm8eHTRCek8T5Cl3 -Sm2UFkLk2mun6cwoyWWhwi6+EfW6ks0c7qSHtJTP8DgLrWxYmBuD9PKSHclpa4/5 -toj52YnT6fIBJWz5ggIdntRCaH8+0eWvwuvDsdPUL7JQFjJmfQOdMenlNqW2aEvx -+JZiYLJBWj9cjpI33P5CAfFEVM3IFlDHmMHRTQ/kKLcfvSDfuofEBoMt4tjf01Um -dfi8kFKWl9ba9I7CoQ13U4J1wkk6KxatZP7eGCmKRoq8w+Y38NsCAwEAAaMgMB4w -DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB -AKsvbN5/r4YPguetl+jIhqpr4TZM8GNZRGTqkKC8clRspBeihJqkNQWsnZiFkJTH -NhNAx+7tlJHqeGdojc2XjBAkc+//qYqXKHgihsO54bVG9oN9IPO+mpPumRRhGneH -jTUE/hLFqwA4ZPw5L1HtJ0m1yqg/HXf4aBXcVQ/YO8YN17ZgLpueYt+Chi1pP/Ku -TzHuoKuHst2T6uuZQZxcD+XJoXwdOt7mfPTh5y9/Psjn+qx833DNWSwF3O/lEghA -2yOb+5CFta2LLUHH894oj5SvgJ/5cvn4+NbyDCUv5ebvE98BMh72PLNRuIRV0gfO -XalMIZ+9Jm2TGXD0dWt9GeZ5z3h+nCEB6s3x0sqluaWG3lTUx+4T/aIxdGuvPFi6 -7DWm7TG7yxFGfbECyyXXL+B/gyHhE1Q93nE3wK9flSG+ljqFJS+8wytht52XhgwE -lV1AwHgxkbkFzNIwB0s7etR9+wBcQvFKqeCZrDeG1twKNcY1dv1D/OCUlBYJvL/X -YADeT2ZjFzHhWhv6TLVEAtqytT1o4qXh6VWeIrwfMG0VcQSiJyNxwO/aW5BOTM44 -EelDzvSjo/pRxqN/m44Iuf0Ran86DO7LmjNYh/04FN3oaL9cFIaT9BWXt/Xx2Fdw -+dg5bPSJ62ExVnnNRlY9lQECkSoRZK2epcICs+3YmmGX +MIIE8DCCAtigAwIBAgIBADANBgkqhkiG9w0BAQsFADAAMCAXDTk5MTIzMTAwMDAw +MFoYDzIxMjQwMzE4MTYwMTMxWjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAsnMwCGlZFe4NiWHzXNHQzv5O9AOZGRf4sBQaLullMyC+QJAiISxZGPSd +zcc2Yo3C873ORRjY4ipY5jpicdL4/5GthxGGMiz9ypbubBXfNZ+NGfC/okESEKZ2 +lCQeIfeG4x+VfFwfLbN4zPLGRj+dDziunImr7ceNFx9iR8IMkvzyHjsXhQYeGRu8 +sB8pY9aIYbkxn2M02rqXRNj3FNc5v6lPlmbh8WRPdD9lYGBSf7lbtqfGVNSEW4ld +LWonA3dtP9VyEA/8sJ1zUS3HzWaL6ndms2PQ329wb7F3OU5cc8OxGLSQ2e+hrcQw +ZC8qhbqI53Da3yiKGeEjsZxuIyLoDWHAFM3RwKjAjkTlqf+YeZ6yQDHd8a4QKJxO +mpBpDke+YhpBWXXOeAiQV9lI+ZO4eNzuMhZxGrL788C4zdm9ORpXP4gM9LKVEcX0 +85Yz4T560jiD4g95V8DvOb1+NBWY762IQmzXGvXD0ZO/HD10x7dDsJ325PfzfBp1 +imPaJJwRK4PW0OXEZA4tJJl6GwgCGjlP+VGcW8Hypzy4rWivQQGok8YcDBzrzm8S +iVdVSSptgq+5mrbBEnxeNCP86v45iQKVEBYZjNxwnWyhBww2PJ1u0LCpdeSq2KOs +bkQBJu0sBLvOG1JvQF49FbTlI5nIjmrze5fKskX4xgMXBRR22y8CAwEAAaNzMHEw +DgYDVR0PAQH/BAQDAgSwMAwGA1UdEwEB/wQCMAAwUQYJKoZIhvcNAQkVAQH/BEEb +a6VUI7aCC05oxh/67D8Q0ORevEIa3GC8wI2soXvmEZIf3t4FBhFsVtpfRo/obWkE +dc0M6cSydxFKK3D1q8hwvzANBgkqhkiG9w0BAQsFAAOCAgEAa2xMhEVRnQK7rHWC +GVRlIcX9F6uWnb8NhgJ+kKRBdoKZ4u2pWf4NlIkwOleUQqLr112QHJ0kyv3T2DOX +lKkNyqeMf5jAOW8hRWKcm26hivsD6XdaA2W2hWjnFO3qvVncSv4DECrGFj5O4J8a +xNmA0T9l1+xtXWqKmYCISeycalBAWd7Qhl6veZd44MB9OEaWMYspJ2vNenV91C5f +oe6YLFe84TqAFSYHdp+Onkweg7OD3kX6873ey0VNrU7W119O+ciy1zbepcRP4rmD ++grTF5LFPnvQTvY872CRLXyeToF4U5yQIK+ObmrHh3S1TUoHuXpHE33OWRB1Wbd/ +6N2hiaukfk4WQx6nmMLtNd8G36Mj08kpeXSQIGfMw4JgddT6O5+y6ladUQ2/HrGq +DXz6Ip3S6XbIdj9ifUXz7ZZmQw419YK74DekbMxteV7Wu/3EKM3ofTeR52dKC3op +XN2J9NjAydFMb/dCbWUk2wYNgeWToQhnEZKM4//H9Sp4oCVVCvAU4TmhSlf4rNwd +Ma/L8vqkO1U4n8b4jb+E1271d9ozWOspSdbSKGz2QnAA+wHDoVZ7CzRoZWZpuR9T +mqakDAXUyJ76qQdrdmvp0oqaOp4lX5PwHxQuqG7eff/YGB6Cqk0I0ckMeNAsWsha +QWkCWSgEkL0mgz3A05Rns6TeUzU= -----END CERTIFICATE----- diff --git a/network/test_key_1.key b/network/test_key_1.key index c49775114d66..98adab941bc9 100644 --- a/network/test_key_1.key +++ b/network/test_key_1.key @@ -1,52 +1,52 @@ -----BEGIN PRIVATE KEY----- -MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCoI5QRIrxvk3z3 -h1UJIiziZN81N2FovlyfDdldJtmV+q4FEk7GGode60YCf3745Na96+uyxpcHEZPi -g5Pc3XV2biIqHt7CLe2j7VJ+qrvVuUJVm0EM55alnHRbCE87ftSzbp8JHtPaBK2J -Mdj2oTRBX/2nXk4IAWxFv3gm6EXQ5HR3q1GbTJDpvtg1HOloHDgwHFkP2Hzj5AN2 -GxPLEjTGT82dsbvinKSOxq7T9gD2Y2ocdKcvgPIPmq4gqpF8PkdAd6bHrojeMRdQ -H8bFMeHHPm6yQilL0BXehyW9WLXgGNIRaA2Qlf6cyL62O5Iqi4AWnMlnNmZ7YO+b -IB5zFs1UF1qM5N7ZBGIbscqHU50xlpt3Z1Q2/lL3+B1sjnezhH77P8fiWWwF+ToH -b78OaoNFq6HgzP0dN/Q+53s3PZvuvvs+c9OMcTGA3dGL5ijouyREJBPPNNXBb9Fj -6s1W7H1QTpk8tqsNtedLJ60oxRLuqXPw1R6taO2QLqKibnvQt9MazcbEipWCgaDS -Ze6OL4Sgb5elhHc9Fp6jxwCZ8S7tP5LGBJ8kC/sPJm/5rZVNlw48MjUpMuszxei/ -LXu3mt31zLX/vm/GcouIYMSHNYmY2Xgi8hhu2KFZaXmSx0Vht70Om+6H/AEIagr6 -SYKKtQzUOKLNaflPEl5LWpgjwjaxgwIDAQABAoICAHGe8U0PGyWPFlCzLDyq0of+ -wHNWxEWi9jYphqyTN1BJgVU+BOuMO9RhywKfI6+P/KmFBtbdqmuFblkQr1f+c4Uf -cYjjKYcwwDkZg7jDKYGI2pG9A51z1nJ9oodtuxUqZRQH+gKQyXq31Ik0nTg0wXo4 -ItH6QWLZi1AqzkgEiEFcUHQZ2mDGwdqjM7nYmsXW5AVm8qxpkCP0Dn6+V4bP+8fT -X9BjreK6Fd3B15y2zfmyPp+SGPRZ/7mZvnemq/+4mi+va43enPEBXY6wmoLhbYBV -6ToeyYdIy65/x3oHu4f/Xd2TYi9FnTRX18CPyvtjH6CoPNW5hlFztRcwAkOlsgQ7 -sZ+9FGAnRvz1lrBg80DeCHeSKVkDHmMQSINhPcPnlMJpxn6iiZjdvz/Bd+9RRqZl -xUI/lV3/Wueh8SeCQlFOj3fHBZEaq6QoC/VmmaeIiLEm1hj+ymuFxwOtA6AKWLb3 -59XnEkONeTfv9d2eQ7NOPU86n/zhWHUKodmBUEaxLDaUwRkS1Adb4rLuRwrMfn3a -2KkknYWzvyrlk8lDqKAMeQneFmpresGAXeIn0vt434eaGcK4a/IZ8PebuhZxGq1Z -bVbxVm0AsLmd9X3htR6MOiZswnVmA3JCw1AMKZpLMDRSbjV0uYuhBJQsN4Y/kyOK -l52JtymFNvbuRF+836+RAoIBAQDZ9wyihmgsEPLl7PHzfYo4pnTs1puoT5PS7GjO -iVm7UtOKaawsJxKX3cxzSFVXONs9hbPPzmsQEL3Xz+lUsgrSeXReF00KLRbfE2LM -dv9hlJVMQXEKnEkFYNNgETyZIJE3ZDDqdd2PDzNM8aKHlvLYREiETCwVn7r4x5QE -jIHC0gUjRJHqUgSdAMa+qvranPLxVV9mpJmL2RXjjb/OtJosFef9h5augSNI9tPS -EDLm4wMjyXr25Vu20/cusmTlOhCzi2d23hNHx8nPE0nCEVtZ2rnnWyH/ozqRnpXX -EPh0IeZQmebBhHWzkjIPaOa05Ua5rkVAQau8/FUUubjXytyZAoIBAQDFerIQwodP -V46WVC0LtSq4ju88x1vgDfT0NFE3H6hIX7Mc91zt0NGOhzv4crfjnoj+romNfQwD -0ymtudnnoaGPFBRrRF8T+26jfFpes7Ve5q/PpY78zJH1ZLwyKKX4dzgeY0Aj9FbO -q4dzh21oD7wyknRm0NTqOvgLAuxoBFZ4FTgudKNDzGymgIaQVT1+h0226og289WT -iptkpOZ/HcxQts2U3j3a87pJB0IFjIrBTtVqIyphdwRVDa929WGDITUPHa3aqykx -Ma/zvXvocAlIDITVwxXlS16DkSS+5jdN/CUj5h0O6FefGaJmk6/bFQIeXM4fRhRF -M0cs1mxXkNR7AoIBAQCFxYftn4wDr4tD7f44sE3Kou6UBMqXq+9PvmQ8jjOSMi0+ -f8h5eKmCp0+5WSV3WJ/FzG8lFMzEmWHKOAI+Rt85ee0fajGQE0g8NMuoLUhjfSt8 -F5XnKy/tqxVPmoSUflZhpo4W96u5B1021f4oNU5pyM6w04ci5lt8IBEKEan6Bae9 -k3HyW9AVA8r2bj1zOmwoDXt1pYPPPraeZ/rWRCVy9SbihPrHst4TA9nQzLxQ0/az -Wg6rxOxa8xB7imU+AjsJ1n7zhyxSG54SBwZ3outr5D/AbEAbgvSJNslDq1iw/bU6 -tpnXHxKV2R38MyeU0jpr7zb1Tti2Li+RfsKhPhHRAoIBAHfbpXH4r6mfaeKiCokd -l2VXE6tfEMtnjTIfAuAjLb9nnk3JcTTCVj5cpDCCaEwV7+4sPz6KFB3KL3TK5Y/q -ESXHOTF12QNGyvsdQbhS+JU2DKVKRgP3oetADd2fwESTD5OaB9cKuRlNELQ1EVlk -m4RSUaYJwAC+c8gzKQtk/pp5vpSrpGBFFfjk70dxBRbjxm5r4OsBibK4IOKwF1o1 -2sluek6NqRtYbMtgRVka2SjE0VFPMKzhUNbSrJnWCy5MnGilSdz7n8/E6ZdVfXwx -a+C4AHPBqWt3GFFgad4X2p9Rl7U3OJHQwUXGiEQcBVNCZ/vHti9TGIB7xApZxn5L -YDsCggEBAJ8RhrfEzm2YkyODFKFwgOszHQ3TNSvbC4+yLOUMSdzdKIyroOq0t53A -PSs046TINd+EDs9Pi6E69C+RYLim1NYMHeHFMzmKnQPXPwJVnYYUKInbIMURcuE9 -8FNBSKg3SUGz31SwG4bRIkJluMUp5oSAEUxWaxbUzLYkZex2uxnUGSd6TjddWKk1 -+SuoiZ3+W6yPWWh7TDKAR/oukBCmLIJI7dXSwv2DhagRpppdoMfqcnsCAgs/omB8 -Ku4y/jEkGbxLgo3Qd6U1o/QZlZG+9Q0iaxQS4dIpMxA3LwrL5txy00bm3JeWMB4H -MUZqfFgfj8ESxFBEeToOwr3Jq46vOwQ= +MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC+wRldoOOP3m6k +R6uLmO3Jc4vp6Drch9Nf4QSxMvye0NlUEQAjzTzY88fS1iaf9PPJilpuIZ5GGadW +YKXEoOZGNkqjvLNBeMxYEBKMaXdpj3LBHSwMN/9mnrrC00Y/snIkSAkV9DI8JTtS +l3LhkJ9ro9QQn3NhUJt4shmrlRAmuLCfmR34yU+6nmYxwQSPycaBE5x5IYRTufqW +P2NHTnhlWG2aGDlPJngVrNL4lWWyk+su8IufNnHzBEoMXPR3Q/IjvKzo6nYJ8SEX +s5j1IZtbltEWzNSJZ5kvFcpPINwolyWvyENfpT/cSK8Pnsr0jLuPV2vgZJtCpqdi +Oasocdwd1jdED1k2jiQ+10M2UwQe/gIrtbgStrAj1TPbHrsAWkX3KFJT1XxrgxlE +2h2MJ2IimgvTkp8R4u/+o+ei+HjlrT45JlD6x8C41lQke9hNY0WtaVY6YpztXF5E +/buGSPeq4UtPN8MBgpgkCJrRL8PfsyU32gSidZ8TYozCfV5dZyR5sB2nz7MTuoi7 +8I3bvOtqbKmZ8kZjQ8kq2JN05AdkvZ9oPVuPM30lVMwYRP7iW1hBzCV1XLR+IlkP +6ydVF7i0r7lrXn0h962D23IenzGeKtdl/kttMx3kYJgZelGZ6P3J5fp988qy6AyI +Y6IRhASxtp2cteEuDDtJz0rMfpt8qwIDAQABAoICAHFi/tz0wc/G/CWSpJm6Mb5J +fKVxcWudITwg2VUrZZZRtp2N7XNakAy1+9WLjjIOvMrT/qTwPtCUdy+VC3Qx4C9k +HkHt7O/CClVeWGg2WNDaf+/ik0hAEQTC3WjphRxfyhFe8GeoXCP8TaLue08xVFH7 +dBbdcQwrif7YfwHK/WrG5dY4geRcZZQci8qPXVLLMb+QFLa8AZhzOE0PKMg+ELrN +MXkjZQ1zZHYd4Nn6lBTucCHawmPFTT6TEiD/MCGktc4gXPemRrvqJS2diBJOA7cR +kv/miX+ToS6n2TXn5nYKQlCWzdWQuMEMQ2MZlLKA5QxzfqBHrTKVNXHhrafA5oGe +c5HF7Y3jF6Sl0o564t7xefgfCg93Q4wvxKpSIROZYQwcM331Rp7DpiAhz3P4oSqj +pk+jnL6DtXs/ACxwNEh+ta1ofvOAzBwlH9ZtXiuQPKhdIqsZjYDF43ms3/P/g8Yv +1iGrvXr56g+ehkTSMJWHrmSxr4QQKRPxzYNUO0oRMmseZsO87aTi8SWS4sUTXM/5 +Mdy02id6qI1RD84oU7P4ii9MsNz5hLHBzQ9l50t8FWSSEtraS7G5KWJ+5Yh7Q21h +n61Tuzs5XQw86akmek/w9NKIRutnUSuiAu46R4hwwvNnLqMZi/ys0XazXMjxBI3R +jPc91/saVS8VZUQ1wjuBAoIBAQDtDyLIMFul+Mmmq9xgu03lLzgF/Zv+3xPMWEyk +vOF2CPRZJIZaZCdCII/6QYfJ+Tg0fNBXVg4M0zvMguFBoRdQdW3R70EDibBxQg5W +VbtZYwJySoQa+WZ/hncN400eDdOt++VhZ4fSIh36NZRE7oazs6lhx2A8LA7CpGGT +/fpmP/ovRICxECZsqTyvSZSjZHwiMBn46SMF4rEI77eXw2eqK5diS/nEWwtOYuXy +BDOaHYdBNhOFtjEB1jXAZvawOhlGE1y3P3O3OGuGoBvW2G8Eq6Tt3AxlN9oc/jOT +Yj7wUnBgxV78g5qDVzgoE+EDGxxwxwwkt53BwVmQ8zilrYqRAoIBAQDN/tVGbZFu +4DPVQJr3+smn3ecWuqhWYXSiyIL/WIiLn63YMplMRoei6FTuRFWxhIwM9+YRVIOp +nC0xDyWL1ZEzjbPQypStsLsogfaENv3tVllPCBU//E5MjqB8aWv7an/u6WngqsM3 +JN5VihhnKEF4VW2PG1aSa41YiA8ZEYoqobP9v0yvOhzMnHAdLHZ6vy/3c36CsK5F +Gju2efncMiNs/q+p7l+cYwhzFdXovVJjwBmSAoMpuaRWqpKdTlFO/x2MUCKOQ/hL +tL/W7IUbpwcRUjAQIuoAu2k2943Bx/y736hqxs9D7xMu9ynFTDxYw4dNEyYdxYn3 +kXSGO3Dd9dl7AoIBABl6uv5RVEhuiR4E8tbiyuiLPrZGH/Iw/+vCwdojAwiwxbKf +HmGwyhdtcIwxZurqgoQBtlLsyO3P9mlw1806B0t6k6cw1AgRUImb0/armEtvPOAT +6kcL71xdk4ZGnA9S5SGaJXlmq06GpDo0cA9Io+nEsbv0tf9BrQR2rpY9giBjV/yk +nEBrv/WF6yPcAMHfFwiFqwT56e3EA8s2GMGTGx1LOiYyjFHyhzCRqK1uji1OZy83 +JLoGbxYHdBeN+Y3PcM/7XMfFZiaXRddedh+Ne8FAwaVfNWXbrvHW0KxSrvkdoz6D +eEYjzwO26C5GlLTEwTXN7xwzMB2XLo1J1xjXokECggEALuPhHGT4g+qZIePQ4r29 +hW6nma7nfrI0YJGP8BvxCQdSBTKPXqN3YIfOPWZks0Het1z+i9dXGRap2s791vTI +Vpnc4pwad+cQ00myGaqC5rGPJsRKQgRmtlqJAYjlwZceg/2x0ihMw5Kq4YHLyD+L +l56qj7bDYBUHWa2u8h/h+Y5RcGNJS2HJCHJbuuhSF+LJQmSR2aHqKWStTv449/yZ +v8fBqMbQEMMiO0AvLwlZZcdmiqvzu128oNW3BgO70mWUDkp3czbZoDIGsR+ptP+y +RikVM7ce2QfQDWkQZZnmV8Wzioqyx132Wex9H6IY4oOvmsXPGVvL6gS8J4oESSIb +XQKCAQAFjafw2VtyhsVxpQx9Nlw1WU8YMGmvwJs0g80RsQutHChnQcgXfASfSJcq +8r1aJc4apTCsol7KTfrU5ui2nTGYD9XHrazNETki4mhufqPiOJSBjoSDenobIU65 +dBbwOqoChLXg72aSo3XMViDm+w0kwpC39nCzuSdssxIsL8GjRSQJSivLQghChfRZ +GnG0IF4809Qa/kBvrnTwXM7K6HVGhJeKYzNJqvWF7mhuEEqMzYhZMOxFwFa+ZoSr +evCGsC/zzuagFVjxsTFvDtUHwx+vUdIOIWOkFeYyrzaV6W/Dme2Fsr1sXcojOFzU +/9hCIUsYMEfZ5FMGf6gJPRYm1MhL -----END PRIVATE KEY----- diff --git a/network/test_key_2.key b/network/test_key_2.key index bcc0a192b2b4..80bae94193ca 100644 --- a/network/test_key_2.key +++ b/network/test_key_2.key @@ -1,52 +1,52 @@ -----BEGIN PRIVATE KEY----- -MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCtPtp9quaXpy8K -YDJIA7wZCRrWZxAgwALIRbLoqyqJxxf4OgaHkQLJBJpYUpYoZ1DfZ0BYZWVKSaaA -nWO1bvj2FKC7Kxq/cQ8xrF79p3kJXUzDLJxwZL1T30zPRRW4URdWM3lbpSVxQunW -gkOPTs3Nk/oHJGIO+ePOB5hveMfCOo4E3B7HWMtbq+mhYPTfNNqdVBdlpoZwQhII -jYKAM/e5d93Q1CmgZWl/2AyLRx0a7yCmpsuoGPOPOvwYMFBgZpYoWeWp7pf2cFRp -3+o0Tdl5vd6FKD4zZ5xDNNkVaKt9rpwZO2i+7ThEwwv04t+VDLetNFJPYdDrPSCl -UI/dXYyD8uYC5bKE4tVg2SETCREe913MWSxHND6CGk9wZ+8jR3DFBXQJsQxWN33N -UQDp06swsjey3b3baGoXbcCXX4fBy7Ub9PfJt9JPCN1hnbciCRAXiv5Ehd6/OA4E -Fd8TATxcRFbbM3BQblK/l3HH4WAONfQQZuvOBjo54pMPVI//tZAuPCYaDDI0liQC -SW8QrBT52UYPk2mC8n1+DxHXBSGnYeFJnWXU5RWZFjBipSbt1MsrUIlTYEfaxHJl -xSTCy2O+CLrzzN8c220ZiYCfHrAZLXaNZ/5bh1/5A0g2DoB1wnkR7TPQkBtOllb/ -NfcJNKuijDuKAed3gDC8oRVAVzI78wIDAQABAoICAQCIgPu7BMuINoyUClPT9k1h -FJF22eIVS/VlQ7XCKgvsX1j9lwrKCnI9XUkXyorR7wYD4OEMRWhX7kwpDtoffP7h -NkOm9kGvEjA8nWqDRk/SFxeCuUXSMS4URd/JeM+yWQKgQxKeKTOlWGnTQPRmmFsE -XlIlCn/Q+QiLr+RmAK601VpNbfs6azZgVsZRB4opzQVr7XQ5/cnz7bszzfxDc67/ -DflSr7jUztMfjmXj3/aI4F3DsazKGE7gTkOP85GBQ5OQ27Rf/sTxwnRgr7Nj3us6 -R2ZrWNgZvMudEKjze3OUJd6M6wiPV258j4p+O7ybPlgDOzSXo6TvlUyBtUaFz04E -5S7bgimNUxEjFzTxkn9W/FTUeauvJcgDk+JmMZ+I9dFdMIuyksndywN9KdXBVxZH -1ZtO1P6JeFpxF7zQUmkH+/6RZd9PbQGlpNI06nAj98LVwqSDCO1aejLqoXYs9zqG -DOU4JdRm3qK0eshIghkvVOWIYhqKPkskQfbTFY+hasg82cGGFyzxqOsSiuW+CVIy -3iF3WyfKgvLMABoK/38zutsMT+/mOtA7rjErh1NJuwwWkkglmuwQMDqaWdOASs+v -MK8JjSi6zDpnbp70Prw5pUlHvvsD1iYWo7SOcpFos+U5zw1jHJJvnAatzcXWixuu -Xzbn2BtCqSFigW7waMy14QKCAQEAx/Nwy2xH9lVGfz8aO2CB0FGL9Ra3Jcv4HFJT -nw6/yvVLvRAwr87+/c+qbIzwLKbQXV/4vmNsqPrIJiazY+Tk739DjcW8YaMbejfr -ASPHtYbeF0FmVbxBHNZ/JSDSYUXdFZ7JlBiDSs3zhPlFBZYG2tU3JJZCR8+9J/Ss -JEIwL9UlapMznMwljFkLbvZ2oFstKkfdY61WxROOIwuGaKr0yRnNvMMp135JiB/O -dwh/NfROt4JzQ5O4ipMg6Wc73+OvBsOSQHYZQHl9NOaK1uomu5bUY7H8pLwGU7sw -LmPRzrGiu8dB+UUEyFkNI2xzwkjet+0UGupDyOfsCMf9hlzWmwKCAQEA3c8FeHkl -Il4GEB0VEw1NtC5x6i+s3NiPOlUmH+nOHgdaI7/BfljfTokQBGo+GkXkJ36yTEMh -L9Vtya3HtW4VEHNfPMjntPztn4XQvMZdSpu/k8rM44m+CB0DDLhFfwRr2cyUAwHz -xebXw8KhceqaWRp6ygJGx5Sk0gr7s7nhmIByjdx4tddEH/MahLklGdV7Vnp+yb3o -zNLVx/aDueknArgUb/zvZRcYWuNoGs9ac4pl0m6jan/x0ZcdBF0SU2bI6ltvF3WT -qwcvVnbJbBwq5PRuL4ZUqrqmXBbBAkpLJTx+kfPKD4bgcZTBnV2TxDbzze9CeieT -YCtg4u+khW7ZiQKCAQBrMIEuPD0TvEFPo8dvP1w4Dg9Gc0f5li/LFwNHCIQezIMu -togzJ3ehHvuQt7llZoPbGsDhZ7FvoQk9EpAmpCVqksHnNbK4cNUhHur3sHO2R7e1 -pdSzb3lEeWStxbuic+6CUZ5kqwNvTZsXlP3Acd344EZwcbDUiHQyAENsKKNmcRBe -4szPaM1UQMQVV0De1CIRQXdYoSsb+VDATsReRg9140Rcxg8fO881jz+CpmZzySWN -0PvzpTRP7XG+Th5V9tv0d1FnByigXMCXZGPXtKzQ8ZmoXFlBAp8tsfKxW8e005uW -qMogVDStJrgZXmFsLN5goVKe3yk5gcMSLgwmRIyzAoIBAQCoE6CkmsAd27uiaDc4 -+aLA/1TIzZmiu+NEo5NBKY1LyexvHHZGBJgqTcg6YDtw8zchCmuXSGMUeRk5cxrb -C3Cgx5wKVn7l8acqc18qPPIigATavBkn7o92XG2cLOJUjogfQVuDL+6GLxeeupRV -2x1cmakj/DegMq32j+YNWbRuOB8WClPaDyYLQ877dcR8X/2XGTmMLAEFfFoMrWtB -7D/oWo76EWNiae7FqH6RmkCDPwNLQxVHtW4LkQOm89PYKRHkLKbw0uKz/bzMOzUE -XA/Q8Lux/YuY19kJ/SACWUO6Eq4icObTfzQCPWO9mFRJog57JWttXyHZBOXk8Qzt -I4NpAoIBACurK0zJxaGUdTjmzaVipauyOZYFBsbzvCWsdSNodtZ/mw6n/qkj2N33 -vNCRLrsQAkDKATzWrscRg+xvl5/wIa4B3s8TZNIp3hL7bvI/NoR5bi5M0vcjdXEd -DeKeZsSBzEs5zivM3aWEF5MSR2zpJPNYyD0PnT6EvZOkMoq6LM3FJcouS1ChePLQ -wHEY5ZMqPODOcQ+EixNXl6FGdywaJYxKnG4liG9zdJ0lGNIivTA7gyM+JCbG4fs8 -73uGsbCpts5Y2xKFp3uK8HjWKbOCR3dE4mOZM8M/NlsUGNjSydXZMIJYWR8nvVmo -i3mHicYaTQxj0ruIz7JHOtFNVGi1sME= +MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC09kPS9Ymw60C9 +8VGZkuD4O0p9a4tPFCm9D42TxCFv4cytJ29AYR8/Q2CiiJy4HqoN6ohkOlNAT7Av +bl34bcqXsgyKechApR+F8/qcBpB8En+w0rY7kJu+isGHHlK7Hm1h6hOW55GYzPA3 +BoHAdo4jTWqsJ1TaVmrsPDpLBH3ODoVPGlOAO6hDqXmWotXdoWPuEXFbgetVWMmW +/gTq53jRMEGkrV4xVMe5Nauj19HTLALYlI2fTOIZrGqLrTKq3KPEC5bb075yoWPx +pkxR3kK2nV+GkpIhDb1f3VbBdjcCfuS0NAVF0bzYEs+S4zO47frDZWOi1S9VjfIU +qOnhxFfyBSrJHxWuY/jtDeCDPaKQZz1as+Mq6yo4cFpJVR16wbPHP/TY74HVLaMJ +6DZHI0NK8a/b73lrwshTzWGSdY73V6FQimNOgFcqvZ24c7/JYh4W+N5jkbMM9JDK +cB5jC4aWTjI5C1+syoCyxKzLPN42Hans3AvrH5Q5+C/t6ZEhoa9dLcgM6tmFioXO +t6m4p0BtmOVoH1RHZLMQd9JQV9ntWvW64R0BHwT8BU8gwvVlwYkFkKCTle0E41en +P84LqYGEQfDJixPdYoRthXVhS8tIsluVrMK67/yW3Ydd0qIk6c7tupqWNQutG6tS +O+by0/Dh6aHxafmWl2xLlbA2Ht21uwIDAQABAoICAD4gnkB7E/6thdiwVPeIubv/ +fx94IKfRoFLMWCr3FxO2TfLUqxlLPtMVasPiawu7W17TumfOrm5R7YcbOR/lcbyK +4EtabCnlhuESVmPizRALudMXRIFGsHHGaZLeEkEzvRH0ry0L66yuD3qUvU86ZKoy +FgFsr3EWYjcgplLDA/4Odi4mN6y6zpYMRTY2SX6BvjEpw+VKwWTXyr4QD9gmCBCp +pJ/I9aGyHa+0gW0K13rMjV2WAtlCKA3wZ9P0boTCo2bXI7/s/mGUjx+TnHgu+nB/ +ryAgihLXCME02GgrEc/FiPdlNLo3u8HjE2i2oDdJXOJgmMh6sHmK9iWpqEJeimJ0 +kQxL+lXD29IDurxk+cBh5iOt09fTvbcOoiatCFuFs782kELgwAqLTBHvd7x2jTfg +P676EBe9vF+Do8WT9b3fBVnEGE1X1bl1TwSnLZ/BfzZhe8YITWubqoDs3izNTS/0 +guiw3KdI64yVLAB+ONL7J4JBiZXs9RsDJqMI9XNSNVV869j+NxAhxrcZ7ujPdWcu +gr9IV+hs9qMfllXIqut92EnsJif2/6QF6lHCLqLTziJ0D4MypDr3msEt78LJYs9K +vTXL2zhmnNibpaitJYxdpru/kqvL6CUubMUcieZHo0dwwW5h/Y8m+ebPHxoapElm +b9HUtHHo9rXvoMFzSuJBAoIBAQDFPYIeDplhddAUBP+NIAclqdZ64PfgGlhyTBDb +FGYLKpZva2KwTsHyr/wsc5mlipaCqF3K0YgLy2Xh5N7rE2eD7dd15mfnf6y2ByDU +rLRciwmPwJP3SbRckIWJagSt4k5vg6w7GUfZXxOhrBrLTAWWI/AdsLgOV42G/Uku +zUHEC0vUHCPKCAOWSqapC0WaMlROBTwHwC+6XHmxcgw7JBg/9K52SCQyGrgedEQO +PpswTo17lxbA3wk+Gyk4CKVVAppHxcJBzCIafTVkoh7/nbtYhKXS73ZrtSKNZoXN +ynpQc9byHD6ItfOIuhQQI1///hIHty7tkIPyTv6Zd4UuoPYJAoIBAQDq30uuE5Pq +U+WYF1CJzRFiRSDfT8bp3erdl6Y2mVhGCm6MANI2nDa8iQtTnK08zbQNjKrFDCzr +3uC4tHBHUOWm+PWgo3pTFXa2nlozsBuKNJ5DujFQjZ6T1eQ+JELttQ9fCT1x3qCW +zhd1vDi5X2Ku0RCHbRdpxGNZMdhMWYMG6XnFym1E3NAtlpQMLxkYFs6QcLHzXGDK +tRGs0+TqDGSMPP1B0zkp0D5330fJsK5p5VZsq0m+iHsIblFr7ithT81g7Sw6qNlv +MvbcE+GN9jGExE6UKm24b33i+G9rY+ZKyTDcU5Jjm9gyZrtzjwovCNbE6Z5vafQL +pNhnmNgILB6jAoIBAQCyNebw3WP8SQRecj2r9zo973xYvhd4ppUvgEbii0W/5RTT +SwV6I07dxeBlEXXLurJPD2zfKf5wGbDOL4qyf2/SJf29CxbqddNJDJu/TOQRkZZs +CiYnErMhx3rAM8hSi90uqJvfMfJXFq6YLvZupRuPEp2LVfaXDshTJVsQLGi1hzdW +SK6VhjQngP+gUQzsS3kcnWIl5qG5EoDpsRAYB37ZmmxfdsMtejLNYWN0M2DofrEa +7+KhFWQ2dzgA5t7rNlTLcIUaCiTuJh8t88VqU8vIKOHi+nXWz2yOsglHbSCivGeD +jb16rFuEOAyUoEHG/Hqx+fMutpphPrqPUwxEmy5xAoIBAQC1/VGpz7e0QU/MunwI +WqKWr5PaFPm/Ktoa26/J7KYOl3Sy/MvlzsNG8TWakvNVAtr6CL4lstp35Zng5Md/ +KvrXl17UGvfkuuPieu7P0Cx2uXDMb9BYZ3Oxf3G8iOJnR/1iGUnIGsX6NDTPYInf +cT6I0KvrE6epp6eHbGz6M/2n9G8LyF9ElYilWmDa0/+wv7NNDlWEiVbimszYStO8 +Wt/qHjPqtl07vgU5YwRADqwGl9KQn2SjwyL6FGj4pXJtk6VC7mNwDHd2h1nqi2kh +U9to0adFfV7JI3K61N+Yqa6+0ggPIJ50mkQ6QYoL75DngwTPTWobUFDuWMvp8e+q +3WzbAoIBAGnDcsQ8u1tk7K6dexykbK8zsJ9VazBJEpt6ExIrw6E8rsHMyZzygoI4 +00gW2eJQiDzqaOeIDXA0J9J1RAiOzCnfBPzIPlOvNuzAH0iOuzPx9kyhtVnuJSiv +neK9eoxd/MruDbl6jsSlBLP2BHhn4/Z03UltVeRql+wpLiY7dT/YmeDWQllRHIIn +JVs0tnBE+c52rGpEZnGosaOedWK2LQ4lLlGi6c2Oqzx8GInierKEHNr7ADEOosdV +KVAdCctLCwl7rzc+umkl8v2eIXTdfXbun69iEaO6S0Zq4us3hpjmyuBSKbonvTPc +sNyt0CfeWOACrfkDeQgeTEAYwHQK32M= -----END PRIVATE KEY----- diff --git a/network/test_key_3.key b/network/test_key_3.key index 2cef238b67a9..de4f94c07524 100644 --- a/network/test_key_3.key +++ b/network/test_key_3.key @@ -1,52 +1,52 @@ -----BEGIN PRIVATE KEY----- -MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDlpXvqK8hnWJaZ -bQ7MYwKuYVAGd6P0me1DWM/3KJpwq7uPln9sP96qjJyNHChKJ6wSt+dOEAbLsfzS -CVXD9eYLR9g09UM/LMAR02TjozfIQjyEAojppKSXWzUpUAelC41wb7fEgHf044zH -Re7JxnqCrPIyaOp5PRxOE0NdPAZuh0xUMB/SrbbRACrMH+XPSyMc9eViHbksnXI+ -2X6+Vx8as/6r7Y4NH2ucjv08TsBkHhdzrBQhxrldeQc9LvNDUh1rXGt/jjoxgJW5 -rMsWGnOrz+eGTE0zPF1mwlpZq8v7GSmMbEDJK+PSOW5AUayazE4hT9eAkP9VGqrI -hJemXbCDSXyamxT19XtsRbXLowhzsABFGBtsQ+IPPyb87yaMRbcLXq6e0scHsvM8 -IKK1OywZHrlKGSP4vD5ozhflkj5ebx4dNEJ6TxPkKXdKbZQWQuTaa6fpzCjJZaHC -Lr4R9bqSzRzupIe0lM/wOAutbFiYG4P08pIdyWlrj/m2iPnZidPp8gElbPmCAh2e -1EJofz7R5a/C68Ox09QvslAWMmZ9A50x6eU2pbZoS/H4lmJgskFaP1yOkjfc/kIB -8URUzcgWUMeYwdFND+Qotx+9IN+6h8QGgy3i2N/TVSZ1+LyQUpaX1tr0jsKhDXdT -gnXCSTorFq1k/t4YKYpGirzD5jfw2wIDAQABAoICAQC/Rt32h29NvTj7JB5OWS2z -h3R7Xo2ev9Mi5EecSyKQNEpuZ+FMjcpubd47nrdkRLULhkhP+gNfCKpXW9Um+psY -zEemnJ7dcO2uK1B+VsWwtJLpNZ9KVIuPUjXuai1j6EJv423Ca2r++8WXeYVSZVJH -o7u8By09vIvl8B+M+eE1kNYfzVHETlLWtHfxO6RTy/a8OYhM+ArzwVSWStxJuBE9 -Ua0PETffcEtWxLbi04lmGrZX7315QKfG1ncUHBYc/blpYjpbrWCFON/9HpKtn2y3 -L91dPBKVWXNGkx1kUTb+t8+mmchAh6Ejyhgt1Jma+g8dqf4KpTs3bJXRnLcfqCvL -Kq+wCUGv7iVWlTmhlzLpneajLDdBxGfbkAgwPFOyZoJNrnh6hU60TPc1IV6YSLlB -GsxesK9QWUrg3BAN4iKD3FvDt0qeUPbPztxEZi1OzSYQDZUQBrBL+WHuD9NxeAYe -2yx1OlPMo73gK5GW/MHBCz77+NX2kVURlTvYW4TsmInCRvOTsVNkRPUJtiHYT7Ss -Y8SzS5F/u9sfjFAVowGgwtNfq8Rm6Q1QdPZltiUNBgiTekFNQEy7WhzVg6MlT5Ca -BRqUhN3+CFwxLZ9rSQL6gxfAHk9umb0ee4JU9JgcYjtb5AtyE6DmmcSZPSejjxit -HwZ/g5MDK7kk5fKMcnL7kQKCAQEA895z7T0c6y3rhWfEUMDdTlsPgAoxYNf+jXyJ -aQmtfnDP9tf8BdPpobfHp29e7JRaGGa9QWPaaemBPHXMmD+IegG9/E+PQdHQwFSG -OpI13uCBULt8a+MMUbTCg1V4uXqf2j1BUo9SFQ6aXh/Rg1gVBgsq1M6eyvel93io -0X+/cinsDEpB5HENZwBuRb0SP0RfCgQR9Yh+jIy2TwJDDNw3sG1TvIo9aK7blSwB -z/gwSDx1UUa2KReD4ChYcqgLFUj3F/uF2f20P/JuaUn7tU3HoCsbG0C+Cci/XSJ9 -gu8xYl64Vg16bO3CflqjucPTFXgyBOt0lIug77YYa9CgCUJvEwKCAQEA8RHqGghV -meDnRXvPmAEwtoT7IKBe+eYjGN6wc2o+QZzjeUFkyfOtaB8rqriUXqvihD2GD6XQ -O/cSNCqp5g6yUhBLo3b9BmCsQsvxkhMpwB/hdi5aYjn+CFQVD4rAso9yGwRBWoA0 -gQdGMKenOUhU/PtVKyTTUuY7rFD8RhYq0ZLqEgO7chn8QXCNPo7MfE/qF9vQBosP -ktiS0FG442PJp2B/lYKK6N2w77ZeCoLhQowaNN0/N36kX/n4bjBE2XFLNpSuHtlg -C7bV/RMR5i/3yB0eRVUDVlqC077qlC1w0tCNZvvi6kbWwIu/4pQTdcA8mAz5B7Lc -OwOMbA2GT4OIGQKCAQABoyS0Gwzup0hFhQTUZfcWZ5YbDfZ25/xVhtiFVANOLgO3 -bIvMnjebVliIzz6b6AMS1t2+aqU0wNSVS1UsUIDiENDtuLsFfhsgr3CXRBQIgwlb -OWcEcmnKwqPrrc85r5ETLgYaP8wVSBvRNfV6JEU/3SNUem6mfjMnDjBT97+ZTJ7B -Fl6K4hds8ZvL7BELS7I3pv9X3qq61tcCgMlidLgK/zDouyTeZw4iWkFI3Cm20nEX -MppWfEnuX1b4rhgk9HB0QMQNSp7DLyV+n3iJJxSIBsIP1Mdx2V8viOO+1UxHlMs4 -CK8hvBbqMkGXJbFtG3l6fvoxZR6XfWl8j9IDPebxAoIBAF07cnBy/LgwdQE4awb8 -ntxX/c+WdmTrjnNV3KQmWMGDba49jj9UkKIOPBMgo7EhhM9kA+8VT72BRncKcP7a -fDikuLwVjrHivXxv55N4+dKmAcp1DtuiVg7ehe6m2PO16olsUeIwZx3ntEuo61GK -GeRlR4ESEvCivj1cbNSmShUXXpNtAheU2Sxt3RJuo8MIHR7xEjkVmwZN4CnVEU5Q -D3M+LNmjzRlWc9GhlCk4iOn1yUTctFBAGE5OHLhwzo/R8ya+xcCEjVK6eXQQ5gFC -V+/64vQpdsr04lgGJC7+i/3cTnOfwxicIP4CjkmQvx3xJP4hNka189qW+r3nVSR3 -WDECggEAAQCCqF4J8C2keY+o/kYQBq0tHhrC28HgiVQuCGc4XruYQtDh4di/I72F -RsvgVHS29ApAlh29i29ws7K2bU6WIc+JR3nmwAHUtiJmxRZhn/c722AvRXF5YMH/ -u46bEURHF5sGz8vr5chX/R4LiF579xyNsB9KC3mPqdjW/L6ACQdrBJVAS9cwplO0 -D+YWxmCE1Ps2tQtz6ZN+LUC7WO6M24k8KW2y4Scue0/23uCllWFgS3/vxDdQDZWn -+7AvMYPh4Wrfdd0t0cU+c9rirFYVz+uo/QBUIZOIw64AvIUjZpHTbhcjz1mAqcgJ -eAOQk+OFUTNKeI9uJwoNYOguHsxt2w== +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCyczAIaVkV7g2J +YfNc0dDO/k70A5kZF/iwFBou6WUzIL5AkCIhLFkY9J3NxzZijcLzvc5FGNjiKljm +OmJx0vj/ka2HEYYyLP3Klu5sFd81n40Z8L+iQRIQpnaUJB4h94bjH5V8XB8ts3jM +8sZGP50POK6ciavtx40XH2JHwgyS/PIeOxeFBh4ZG7ywHylj1ohhuTGfYzTaupdE +2PcU1zm/qU+WZuHxZE90P2VgYFJ/uVu2p8ZU1IRbiV0taicDd20/1XIQD/ywnXNR +LcfNZovqd2azY9Dfb3BvsXc5Tlxzw7EYtJDZ76GtxDBkLyqFuojncNrfKIoZ4SOx +nG4jIugNYcAUzdHAqMCOROWp/5h5nrJAMd3xrhAonE6akGkOR75iGkFZdc54CJBX +2Uj5k7h43O4yFnEasvvzwLjN2b05Glc/iAz0spURxfTzljPhPnrSOIPiD3lXwO85 +vX40FZjvrYhCbNca9cPRk78cPXTHt0Ownfbk9/N8GnWKY9oknBErg9bQ5cRkDi0k +mXobCAIaOU/5UZxbwfKnPLitaK9BAaiTxhwMHOvObxKJV1VJKm2Cr7matsESfF40 +I/zq/jmJApUQFhmM3HCdbKEHDDY8nW7QsKl15KrYo6xuRAEm7SwEu84bUm9AXj0V +tOUjmciOavN7l8qyRfjGAxcFFHbbLwIDAQABAoICAF9mLRuSFkofBaWYc93/XT4L +vnG9Kq+7nPulA4pow+1dZ9hkNZq+drNcsrA7+9scJkjgA9H0wp3GPdh3BgIL44nd +e4Nl3vQcEWGo5rVpy/aC4ZAooIpBd0LneyUfWeyWw8nQLL5bEWABPmdysoUDpRdq +Gg8dmoh30fm2kXgDSW2bRGTc+mnnJ1gM+Aa/4gS5wBdeRiULiEoWzp/DzfOaTAkm +nqGtRsUh90gSTEQFupUFpv4zG1hmdIvrF6EbyteTlRg3J89mfJR+2BNiAhrQ46Pp +SUJF7nhEvzs3CKHePpa024x1m6qm7SxUYfptLLJpUp9IOfprVckYD1j4Y/jsxFje +W/D7j/iNijzngDWcWHWG9tgyUOANpmTpTR3gyyZlAxPpoh6vIUSmH1pY6VSxvG41 +LYjDLLVWT16fpz3/VAcBH2YnwXgXPFXAeKsFsxMlsVDJWCt6+Eau355HKGyTqTzC +/ajfiPXIB9ld3iCBVDcpJQYEi/aPSj1ppsob6ZbYwwfiHvzzyGErMT6gv/VEM6XU +slYdY+RzLL5WUDNrooTbxwG0DGSUToLsTdgS5d/E6AAz1Zjb7W3wuusNfblNWFEo +gegajf7ZrvzV5kiCyFTqx336i7yUNzWz6DHen+tn7MnZMDVhz1gRDiuk3jS1T3f9 +6MA3XGy4nvfOTXrd5mDBAoIBAQDNHO12xK7OnTjF+/7mmCjGJT7qbw1K1UpmYCCX +TN7s01fvmpmZ8bYwbSej2NTaEg0V54oTcroWuZpU9LBW4XNdgvnCfCETRzMjYsrv +A+IWBeG7qhwfYKPbAIFo5ZYZzeXyahWkeLwDAG9LLnT3Dfku89swAsMxa5yPrZRO +Iy/BE4OBuIx0KNM1NeJ0KX3gH5waXyhz3LNWSzaVkK/ETtAY+Lsr8SZyNKxTOuI4 +y3c6MteFFv9VTvR0vcTWwSVGH5XkfCYG7KjDLzljCD2vRYbff1jft8Phz8Ez4GYZ +WShBTD3lCyBEwhdksMS5Jt7un2LNEw9wPLuFHql1TSwHwvm5AoIBAQDeuNhQSunU +Ra/pYP6Q7x3ZTthaRtzqkAvWHECHJW06Sjm+O7eyAm66F41w8l4a0mh+BMWGnybd +ZrNyj/ZMgrNQ7zmmD8pLL37aHSqfizzK1s2DPpJFS5MzBEf9kUD7fNLAzKledyzR +DW9k1NKm53X25+EM578FzTHYq3d0D9hXg4L4GgHJKYtEreKWfhOVL/Vz2Bk0idZf +T79tRJ7jnCX7r3wMBV1vL7rUM4LBYJ6f4rda/iua6zEC+St2cCB53XXnGUovC/iW +1K1GKWntyJVV6crdWmSlvWl7y6OTXSEhmXGCuAByGGjkOag0OcU2fCpwA5EvNRVv +IqZooabuAVAnAoIBAEC106UYwB2nNHYh3nVZo+N/dK35gzQMvoA165JQSjRlKOUK +3VLYEyaMCWmDywNRlpdGiSVBmLv6qloLKGcAkaj63VkiWD0AxX1weZ2WmAliqajP +LjgoAQniyvERHZ3ee6FTHqjY/lfkFzic24HmAqtxe8FV3ccFsEsT9CoCp9o+Ecsn +MgijqJ6s9Vi4jmHbFyCqzNRg2KNs7zeYghto0fZO4p4mYn69Z3CKrzxD1MWjrKLs +cnmzgyQhiqxGG0BYTq3bDRQ6LbQGfhBkVTGqubZhMuTB0Sa4qLd5IDz3B+Ax8YUF +UZTftwmpSycuwD6AQmd4j/JU9sQ0vDmpsy5vsOECggEAf1zK7ld4kdfr+ZRq3qyu +sAcDd9SQHl6TNjRfvijr5mptzNhPeq8jbK1tR8qBf+sUsAPAhPRcAD3rnjavDR+s +tTqoB8t9zjLx4n7NUgEImaHuUgAlGxVVrtXi6SD4PRgrWO9wZ0HVUhLRwaJmd+Vi +svf03TFlLkciGxoqrCcnexwMeB4/KS7lojehnJeqUSTkwwMvnri36zcqa6zTA6vW +mK/ISwOCY8Oyngh63GSJMTsvyQwSGXwnQeEFNqx2FdpLwwTWREMfO/mQwM+L8NtE +cqXISX6YkaLYQF+6Qdn+yTz7CVp5fsVwrho+kub6XObySa3wh0Ne53e0G59dWztK +/wKCAQEArQbzk/KDSJqRFgyK+HkZkygDllDy1ZYMY22SSCkONqFH17TVmRxNApnK +6K2EMjQaGTnTNrJqCDcojPJQcj2JJicvHp+PdOhzZWdqtvI9X0O7ZX4+IhlPsxiL +T9VtqhA5m1qG799RENc9RN+I+JRqrlictc7O2bnQLIv+tTVaTm6Ei0/5VhF2UUVs +gDPnYV6w0ehTWD1AwtjkRXKDdfKFh79dohqCyaNMoWtvy2JHvSEx49pz8Kbj/06K +DT+xUeix1DTcLWjUMOQHGuDZLd7cDG+J+WKAKCmRrmN7LC5Zzt+U+WCYARVz8mp0 +nYXu723STiOS//FeD/l8QRi2BJt3nQ== -----END PRIVATE KEY----- diff --git a/node/node.go b/node/node.go index e6c1d6a35f74..990624c34075 100644 --- a/node/node.go +++ b/node/node.go @@ -128,21 +128,19 @@ func New( logger logging.Logger, ) (*Node, error) { tlsCert := config.StakingTLSCert.Leaf - stakingCert := staking.CertificateFromX509(tlsCert) - if err := staking.ValidateCertificate(stakingCert); err != nil { - return nil, fmt.Errorf("invalid staking certificate: %w", err) + stakingCert, err := staking.CertificateFromX509(tlsCert) + if err != nil { + return nil, fmt.Errorf("failed to create staking certificate out of x509 cert: %w", err) } - // Get the nodeID from certificate (secp256k1 public key) - nodeID, err := peer.CertToID(tlsCert) - if err != nil { - return nil, fmt.Errorf("cannot extract nodeID from certificate: %w", err) + if err := staking.ValidateCertificate(stakingCert); err != nil { + return nil, fmt.Errorf("invalid staking certificate: %w", err) } n := &Node{ Log: logger, LogFactory: logFactory, - ID: nodeID, + ID: stakingCert.NodeID, Config: config, } @@ -1123,7 +1121,7 @@ func (n *Node) initChainManager(avaxAssetID ids.ID) error { return fmt.Errorf("couldn't initialize chain router: %w", err) } - n.chainManager = chains.New(&chains.ManagerConfig{ + n.chainManager, err = chains.New(&chains.ManagerConfig{ SybilProtectionEnabled: n.Config.SybilProtectionEnabled, StakingTLSCert: n.Config.StakingTLSCert, StakingBLSKey: n.Config.StakingSigningKey, @@ -1168,6 +1166,9 @@ func (n *Node) initChainManager(avaxAssetID ids.ID) error { Tracer: n.tracer, ChainDataDir: n.Config.ChainDataDir, }) + if err != nil { + return fmt.Errorf("couldn't initialize chain router: %w", err) + } // Notify the API server when new chains are created n.chainManager.AddRegistrant(n.APIServer) diff --git a/scripts/build_camino.sh b/scripts/build_camino.sh index 46aab6ea679c..99bc63327f33 100755 --- a/scripts/build_camino.sh +++ b/scripts/build_camino.sh @@ -27,7 +27,7 @@ done # Dockerfile # README.md # go.mod -go_version_minimum="1.20.10" +go_version_minimum="1.20.12" go_version() { go version | sed -nE -e 's/[^0-9.]+([0-9.]+).+/\1/p' diff --git a/scripts/build_tools.sh b/scripts/build_tools.sh index 669850f79f3d..ab469c480c6e 100755 --- a/scripts/build_tools.sh +++ b/scripts/build_tools.sh @@ -20,14 +20,4 @@ tools_dir=$build_dir/tools/ mkdir -p "$tools_dir" echo "Building cert tool..." -go build -ldflags="-s -w" -o "$tools_dir/cert" "$CAMINOGO_PATH/tools/cert/"*.go - -echo "Building camino-network-runner tool..." -CAMINO_NETWORK_RUNNER_PATH="$CAMINOGO_PATH"/tools/camino-network-runner - -if [ ! -f "$CAMINO_NETWORK_RUNNER_PATH/.git" ]; then - echo "Initializing git submodules..." - git --git-dir "$CAMINOGO_PATH/.git" submodule update --init --recursive -fi - -"$CAMINO_NETWORK_RUNNER_PATH/scripts/build.sh" "$tools_dir" \ No newline at end of file +go build -ldflags="-s -w" -o "$tools_dir/cert" "$CAMINOGO_PATH/tools/cert/"*.go \ No newline at end of file diff --git a/scripts/camino_mocks.mockgen.txt b/scripts/camino_mocks.mockgen.txt deleted file mode 100644 index 0eea8923cc3b..000000000000 --- a/scripts/camino_mocks.mockgen.txt +++ /dev/null @@ -1,20 +0,0 @@ -// TODO @evlekht - -// add this to 'scripts/mocks.mockgen.txt' when mockgen will -// be able to process this files correctly (some generics issues) - -github.com/ava-labs/avalanchego/cache=Cacher=cache/mock_cacher.go -github.com/ava-labs/avalanchego/vms/components/avax=AtomicUTXOManager=vms/components/avax/mock_atomic_utxos.go -github.com/ava-labs/avalanchego/vms/platformvm/state=Chain,Diff,State,Versions=vms/platformvm/state/mock_state.go - - -// avax also have their own mocks excluded from list, -// though there is no comment about not forgetting -// to add them back or why they were excluded: - -github.com/ava-labs/avalanchego/snow/networking/router=Router=snow/networking/router/mock_router.go -github.com/ava-labs/avalanchego/snow/networking/sender=ExternalSender=snow/networking/sender/mock_external_sender.go -github.com/ava-labs/avalanchego/snow/validators=Set=snow/validators/mock_set.go -github.com/ava-labs/avalanchego/snow/validators=Manager=snow/validators/mock_manager.go -github.com/ava-labs/avalanchego/vms/platformvm/txs=Staker=vms/platformvm/txs/mock_staker.go -github.com/ava-labs/avalanchego/vms/platformvm/txs=UnsignedTx=vms/platformvm/txs/mock_unsigned_tx.go \ No newline at end of file diff --git a/scripts/lint.sh b/scripts/lint.sh index fb487274c791..2785e5bc6da6 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -52,14 +52,14 @@ function test_license_header { } function test_single_import { - if grep -R -zo -P --exclude-dir='camino-network-runner' 'import \(\n\t".*"\n\)' .; then + if grep -R -zo -P 'import \(\n\t".*"\n\)' .; then echo "" return 1 fi } function test_require_error_is_no_funcs_as_params { - if grep -R -zo -P --exclude-dir='camino-network-runner' 'require.ErrorIs\(.+?\)[^\n]*\)\n' .; then + if grep -R -zo -P 'require.ErrorIs\(.+?\)[^\n]*\)\n' .; then echo "" return 1 fi @@ -67,7 +67,7 @@ function test_require_error_is_no_funcs_as_params { function test_require_equal_zero { # check if the first arg, other than t, is 0 - if grep -R -o -P --exclude-dir='camino-network-runner' 'require\.Equal\((t, )?(u?int\d*\(0\)|0)' .; then + if grep -R -o -P 'require\.Equal\((t, )?(u?int\d*\(0\)|0)' .; then echo "" echo "Use require.Zero instead of require.Equal when testing for 0." echo "" @@ -75,7 +75,7 @@ function test_require_equal_zero { fi # check if the last arg is 0 - if grep -R -zo -P --exclude-dir='camino-network-runner' 'require\.Equal\(.+?, (u?int\d*\(0\)|0)\)\n' .; then + if grep -R -zo -P 'require\.Equal\(.+?, (u?int\d*\(0\)|0)\)\n' .; then echo "" echo "Use require.Zero instead of require.Equal when testing for 0." echo "" @@ -84,7 +84,7 @@ function test_require_equal_zero { } function test_require_len_zero { - if grep -R -o -P --exclude-dir='camino-network-runner' 'require\.Len\((t, )?.+, 0(,|\))' .; then + if grep -R -o -P 'require\.Len\((t, )?.+, 0(,|\))' .; then echo "" echo "Use require.Empty instead of require.Len when testing for 0 length." echo "" @@ -102,7 +102,7 @@ function test_require_equal_len { # These should match: # - require.Equal(2, len(foo)) # - require.Equal(t, 2, len(foo)) - if grep -R -o -P --exclude-dir='scripts' --exclude-dir='camino-network-runner' 'require\.Equal\((t, )?.*, len\([^,]*$' .; then + if grep -R -o -P --exclude-dir='scripts' 'require\.Equal\((t, )?.*, len\([^,]*$' .; then echo "" echo "Use require.Len instead of require.Equal when testing for length." echo "" @@ -111,21 +111,21 @@ function test_require_equal_len { } function test_require_nil { - if grep -R -o -P --exclude-dir='camino-network-runner' 'require\..+?!= nil' .; then + if grep -R -o -P 'require\..+?!= nil' .; then echo "" echo "Use require.NotNil when testing for nil inequality." echo "" return 1 fi - if grep -R -o -P --exclude-dir='camino-network-runner' 'require\..+?== nil' .; then + if grep -R -o -P 'require\..+?== nil' .; then echo "" echo "Use require.Nil when testing for nil equality." echo "" return 1 fi - if grep -R -o -P --exclude-dir='camino-network-runner' 'require\.ErrorIs.+?nil\)' .; then + if grep -R -o -P 'require\.ErrorIs.+?nil\)' .; then echo "" echo "Use require.NoError instead of require.ErrorIs when testing for nil error." echo "" @@ -134,7 +134,7 @@ function test_require_nil { } function test_require_no_error_inline_func { - if grep -R -zo -P --exclude-dir='camino-network-runner' '\t+err :?= ((?!require|if).|\n)*require\.NoError\((t, )?err\)' .; then + if grep -R -zo -P '\t+err :?= ((?!require|if).|\n)*require\.NoError\((t, )?err\)' .; then echo "" echo "Checking that a function with a single error return doesn't error should be done in-line." echo "" @@ -144,7 +144,7 @@ function test_require_no_error_inline_func { # Ref: https://go.dev/doc/effective_go#blank_implements function test_interface_compliance_nil { - if grep -R -o -P --exclude-dir='camino-network-runner' '_ .+? = &.+?\{\}' .; then + if grep -R -o -P '_ .+? = &.+?\{\}' .; then echo "" echo "Interface compliance checks need to be of the form:" echo " var _ json.Marshaler = (*RawMessage)(nil)" diff --git a/scripts/mock.gen.sh b/scripts/mock.gen.sh index 786eedc728f7..39eac0d9196d 100755 --- a/scripts/mock.gen.sh +++ b/scripts/mock.gen.sh @@ -19,38 +19,39 @@ input="scripts/mocks.mockgen.txt" while IFS= read -r line do IFS='=' read -r src_import_path interface_name output_path <<< "${line}" - package_name=$(basename "$(dirname "$output_path")") + package_name="$(basename "$(dirname "$output_path")")" echo "Generating ${output_path}..." - outputted_files+=(${output_path}) - mockgen -package=${package_name} -destination=${output_path} ${src_import_path} ${interface_name} - + outputted_files+=("${output_path}") + mockgen -package="${package_name}" -destination="${output_path}" "${src_import_path}" "${interface_name}" + done < "$input" # tuples of (source import path, comma-separated interface names to exclude, output file path) input="scripts/mocks.mockgen.source.txt" while IFS= read -r line do - IFS='=' read source_path exclude_interfaces output_path <<< "${line}" - package_name=$(basename $(dirname $output_path)) - outputted_files+=(${output_path}) + IFS='=' read -r source_path exclude_interfaces output_path <<< "${line}" + package_name=$(basename "$(dirname "$output_path")") + outputted_files+=("${output_path}") echo "Generating ${output_path}..." mockgen \ - -source=${source_path} \ - -destination=${output_path} \ - -package=${package_name} \ - -exclude_interfaces=${exclude_interfaces} - + -source="${source_path}" \ + -destination="${output_path}" \ + -package="${package_name}" \ + -exclude_interfaces="${exclude_interfaces}" + done < "$input" -all_generated_files=( $(grep -Rl 'Code generated by MockGen. DO NOT EDIT.') ) +mapfile -t all_generated_files < <(grep -Rl 'Code generated by MockGen. DO NOT EDIT.') # Exclude certain files outputted_files+=('scripts/mock.gen.sh') # This file -outputted_files+=('vms/components/avax/mock_transferable_out.go') # Embedded verify.IsState +outputted_files+=('vms/components/avax/mock_transferable_out.go') # Embedded verify.IsState outputted_files+=('vms/platformvm/fx/mock_fx.go') # Embedded verify.IsNotState +outputted_files+=('vms/platformvm/state/mock_state.go') # Can't use 2 (or 3) different files to generate one mock file in source mode -diff_files=(`echo ${all_generated_files[@]} ${outputted_files[@]} | tr ' ' '\n' | sort | uniq -u`) +mapfile -t diff_files < <(echo "${all_generated_files[@]}" "${outputted_files[@]}" | tr ' ' '\n' | sort | uniq -u) if (( ${#diff_files[@]} )); then printf "\nFAILURE\n" diff --git a/scripts/mocks.mockgen.source.txt b/scripts/mocks.mockgen.source.txt index 02782a7b7d9c..0f9499dbd2e9 100644 --- a/scripts/mocks.mockgen.source.txt +++ b/scripts/mocks.mockgen.source.txt @@ -8,3 +8,5 @@ vms/platformvm/block/executor/manager.go==vms/platformvm/block/executor/mock_man vms/platformvm/txs/staker_tx.go=ValidatorTx,DelegatorTx,StakerTx,PermissionlessStaker=vms/platformvm/txs/mock_staker_tx.go vms/platformvm/txs/unsigned_tx.go==vms/platformvm/txs/mock_unsigned_tx.go x/merkledb/db.go=ChangeProofer,RangeProofer,Clearer,Prefetcher=x/merkledb/mock_db.go +cache/cache.go==cache/mock_cacher.go +vms/components/avax/atomic_utxos.go==vms/components/avax/mock_atomic_utxos.go diff --git a/scripts/tests.e2e.sh b/scripts/tests.e2e.sh index adaca365802e..67fbfeb4c660 100755 --- a/scripts/tests.e2e.sh +++ b/scripts/tests.e2e.sh @@ -5,7 +5,7 @@ set -euo pipefail # e.g., # ./scripts/tests.e2e.sh # ./scripts/tests.e2e.sh --ginkgo.label-filter=x # All arguments are supplied to ginkgo -# E2E_SERIAL=1 ./scripts/tests.e2e.sh ./build/caminogo # Run tests serially +# E2E_SERIAL=1 ./scripts/tests.e2e.sh # Run tests serially # CAMINOGO_BIN_PATH=./build/caminogo ./scripts/tests.e2e.sh # Customization of caminogo path # E2E_USE_EXISTING_NETWORK=1 TMPNET_NETWORK_DIR=/path/to ./scripts/tests.e2e.sh # Execute against an existing network if ! [[ "$0" =~ scripts/tests.e2e.sh ]]; then diff --git a/staking/camino.go b/staking/camino.go new file mode 100644 index 000000000000..4e9514fe14b7 --- /dev/null +++ b/staking/camino.go @@ -0,0 +1,93 @@ +// Copyright (C) 2024, Chain4Travel AG. All rights reserved. +// See the file LICENSE for licensing terms. + +package staking + +import ( + "crypto" + "crypto/x509" + "crypto/x509/pkix" + "errors" + + "golang.org/x/crypto/cryptobyte" + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +) + +var ( + errWrongCertificateVersion = errors.New("certificate version must be 3 (2 if versioning starts with 0)") + errNoCertificateExtensions = errors.New("certificate must have extensions") + errMissingNodePubKey = errors.New("certificate must have extension with node public key") +) + +func TLSCertToID(cert *x509.Certificate) (ids.NodeID, error) { + pubKeyBytes, err := secp256k1.RecoverSecp256PublicKey(cert) + if err != nil { + return ids.EmptyNodeID, err + } + return ids.ToNodeID(pubKeyBytes) +} + +func getNodeID(input cryptobyte.String, certVersion int, pubKey crypto.PublicKey) (ids.NodeID, error) { + if certVersion != 2 { + return ids.EmptyNodeID, errWrongCertificateVersion + } + var extensions cryptobyte.String + var hasExtensions bool + if !input.ReadOptionalASN1(&extensions, &hasExtensions, cryptobyte_asn1.Tag(3).Constructed().ContextSpecific()) { + return ids.EmptyNodeID, errors.New("x509: malformed extensions") + } + if !hasExtensions { + return ids.EmptyNodeID, errNoCertificateExtensions + } + if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) { + return ids.EmptyNodeID, errors.New("x509: malformed extensions") + } + var secp256k1PubKeyBytes []byte +L: + for !extensions.Empty() { + var extension cryptobyte.String + if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) { + return ids.EmptyNodeID, errors.New("x509: malformed extension") + } + ext, err := parseExtension(extension) + if err != nil { + return ids.EmptyNodeID, err + } + secp256k1PubKeyBytes, err = secp256k1.RecoverSecp256PublicKeyFromExtension(&ext, pubKey) + switch { + case err == secp256k1.ErrWrongExtensionType: + continue + case err == nil: + break L + default: + return ids.EmptyNodeID, err + } + } + + if secp256k1PubKeyBytes == nil { + return ids.EmptyNodeID, errMissingNodePubKey + } + + return ids.ToNodeID(secp256k1PubKeyBytes) +} + +func parseExtension(der cryptobyte.String) (pkix.Extension, error) { + var ext pkix.Extension + if !der.ReadASN1ObjectIdentifier(&ext.Id) { + return ext, errors.New("x509: malformed extension OID field") + } + if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) { + if !der.ReadASN1Boolean(&ext.Critical) { + return ext, errors.New("x509: malformed extension critical field") + } + } + var val cryptobyte.String + if !der.ReadASN1(&val, cryptobyte_asn1.OCTET_STRING) { + return ext, errors.New("x509: malformed extension value field") + } + ext.Value = val + return ext, nil +} diff --git a/staking/camino_test.go b/staking/camino_test.go new file mode 100644 index 000000000000..2354e4da89a1 --- /dev/null +++ b/staking/camino_test.go @@ -0,0 +1,73 @@ +// Copyright (C) 2024, Chain4Travel AG. All rights reserved. +// See the file LICENSE for licensing terms. + +package staking + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "fmt" + "math/big" + "os" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/require" + + utilsSecp256k1 "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/perms" +) + +// Convinient way to run generateTestCertFile. Comment out SkipNow before run. +func TestGenerateTestCertFile(t *testing.T) { + t.SkipNow() + const certPath = "large_rsa_key.cert" + require.NoError(t, generateTestCertFile(certPath)) +} + +// Creates cert file with double-sized rsaKey. This cert file is used by tests in this package. +func generateTestCertFile(certPath string) error { + // Create RSA key to sign cert with + rsaKey, err := rsa.GenerateKey(rand.Reader, 8192) // twice as much bytes! + if err != nil { + return fmt.Errorf("couldn't generate rsa key: %w", err) + } + // Create SECP256K1 key to sign cert with + secpKey := utilsSecp256k1.RsaPrivateKeyToSecp256PrivateKey(rsaKey) + extension := utilsSecp256k1.SignRsaPublicKey(secpKey, &rsaKey.PublicKey) + + // Create self-signed staking cert + certTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(0), + NotBefore: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC), + NotAfter: time.Now().AddDate(100, 0, 0), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment, + ExtraExtensions: []pkix.Extension{*extension}, + BasicConstraintsValid: true, + } + certBytes, err := x509.CreateCertificate(rand.Reader, certTemplate, certTemplate, &rsaKey.PublicKey, rsaKey) + if err != nil { + return fmt.Errorf("couldn't create certificate: %w", err) + } + + // Ensure directory where key/cert will live exist + if err := os.MkdirAll(filepath.Dir(certPath), perms.ReadWriteExecute); err != nil { + return fmt.Errorf("couldn't create path for cert: %w", err) + } + + // Write cert to disk + certFile, err := os.Create(certPath) + if err != nil { + return fmt.Errorf("couldn't create cert file: %w", err) + } + if _, err := certFile.Write(certBytes); err != nil { + return fmt.Errorf("couldn't write cert file: %w", err) + } + if err := certFile.Close(); err != nil { + return fmt.Errorf("couldn't close cert file: %w", err) + } + return nil +} diff --git a/staking/certificate.go b/staking/certificate.go index b3e1a511f63f..fba0205819c6 100644 --- a/staking/certificate.go +++ b/staking/certificate.go @@ -6,10 +6,13 @@ package staking import ( "crypto" "crypto/x509" + + "github.com/ava-labs/avalanchego/ids" ) type Certificate struct { Raw []byte + NodeID ids.NodeID PublicKey crypto.PublicKey // TODO: Remove after v1.11.x activates. SignatureAlgorithm x509.SignatureAlgorithm @@ -19,10 +22,15 @@ type Certificate struct { // // Invariant: The provided certificate must be a parseable into a staking // certificate. -func CertificateFromX509(cert *x509.Certificate) *Certificate { +func CertificateFromX509(cert *x509.Certificate) (*Certificate, error) { + nodeID, err := TLSCertToID(cert) + if err != nil { + return nil, err + } return &Certificate{ Raw: cert.Raw, + NodeID: nodeID, PublicKey: cert.PublicKey, SignatureAlgorithm: cert.SignatureAlgorithm, - } + }, nil } diff --git a/staking/large_rsa_key.cert b/staking/large_rsa_key.cert index 45e60a6b79919488a024e8fa9689ad81ef9419a9..d4b2d69f6cf18487f86554e27d364951d46efc50 100644 GIT binary patch delta 2244 zcmV;#2s`(oA@mUlFoFp1FoFcwkq9q;G%zzUG%++WF*Gz&LNQUW) z`OT(jqRYNSzz}$r_-aE~4MHH&O(eoMKCu}V{+fpu3ptFRh1IOSThVcQ_jF!=?$*^p z)3Qufk+~lD^34pf??C9Pexq|@($?re>rK|t0iKhK^w|>=y`^n{c}CF##QES{Ldi&v zEVWXs$xA>3mS5Z@$wQw!dFnHJYIUC~&x;`pZF z{XfwB%Z)XBtdm~Unbnh|u*|FV z$YaIaFTHpiCd-vGv5bDbhCTut%WJktdnnwd)_d)EA|8V|1*>(nm#Dc+y(LaJENr&? z7@>@Hr>Kf@$rrX`o;)-4`n+4#@;Sv}WFp|oVjG4!Q8W?ebIfmHZmS+X2_GfxB8t+4 zUv6~LKH?|3ESCoiRB*X}PP-JMb>&FyX> zPZ(4eaG5>CAJv5ua3fGOp~YGWVRQ^&l2W2nCFF^h!7_3NH_Mtx*r zEb-#rZy~J3+QIP{V@fwq-sj>U&41>9li@h2ul}z>t4-+Z*7f<^1=zxeU91!x7PZ@? zZ>{e%G#bAhFGg2MR%t~$f)mSvEq05JRbA||{@PG*9hqftH4_!abfB%PmQNEm$)eR? zY9;aClueXCc#7Rc7+Py?AO?UBR}Z`GFBZ>`XShyC-G$TSk-H*X3A-=>N5~?Sh45^h zK95R@Gxg0iM2Rfbki^C_&&~Qwv zK8kXp-#?HWvc-%Ma9mEI?@9$d9cba6$XjJg6HRCDD*~^ilCUmudL|Ud%1#-7*HN>~s{~kBhFj(x{S4C@s#4Hp(_?&!S7+ z-mx@VCU8}QY)It#5LJ#PjB|dBpn@VjecM*K+hD1>7l_iV_gXQ4V_6h-*aI_>FkX}I zmCOF~L$@Nqn8DFc1>WxAf5lMi7%FhQ5spqivid>AekH1XMOx_k5K<*%v3M8H3^3Me zy5+qjX%=xyXsoTj!AeGR)#JDXVI4n(Lc{6YofF!4mDP7>`_ zUZkJwxDb}0j}Nm=aOqn54%9sPExVsm8?{W&iPMfnmVD#H@tBF9e<}CidS`A}A7^af zYpzC~1yI>$Yd6%)SGr1qM}}KHZoiG8)ONH(6f@y>xbgJK<2&Xl4wR0=pKdlF zZzQ<~X*vowE$A^We?=)eF1k+@G#65@BCx20Hi19&#v7$!g~F-|cd`inMh6Jd=#|ay z8r|{YEJyVJbTYaFM%ALozj~tLJ-Q`@pLETb8`34fn@Z-fYICd z9iba5mp+t<%lW#VU7QpczxP5Nxt;eGleV`G_n0G|e+QDNyn9tNC+dD60mH$W z%lwz-aipyHfL?1#qLKwu(`sPx*RUBGNMH%)hBH)^Dfar@?1SOI}f>JjwIniyedoT^pz^4*d2!t+2Byhjf?^_0N|7rT~9 zSe;IR3UjzIZkzDY&aB#jvE`o?M-KQly6(gpyHfk;qQt=caOYW0_=#dQxp`RwBQ{y= z|0ZqY;vAnjiQod8g(OO`$`R6_YJokSt1zfPs)00}P(Q{4gIg5}BJp8!EMvn`)52-V S!b9;46eE*`{N3ezkdDz6+C{bi delta 4225 zcmV-{5Pt9U5uqUnFoF=BFoFn$kq9q;GcY(XGB7hWH!wI_FaR)u2qG{I1_>&LNQU;$9X3-HaWhHvM7`}{!sU2N) zOs;vyv6iAGLp$rFko{|(6#|^knTXI0Y}#Kx!{`%Vh_kr({hs3!rY6!AP{fH7ZY06E`}G6Uq`dp zdU$+JaI}7B1*y{P3gkB%c3HzG$9K9If*-|ddkC(=to0NPQ+oOLcp#+=54<48+zYEY z>X!5#LyeiknrlyqUV1VovQA=uLhka>4HVb+og+xU=-~OCFJ}XXQ5ybtnN{rk+7+tX zA%DUEvHO)9N6bjbmiSejddWPae3c&(^#cLbm{H7`%xdgg9`#Mx}s2j=7l$d5kKWX zXU517mR%qWGJtZr!v6kRj9K#Zj6q^BSfw?P}dXUp^>yav6s zSQ0aH(gp!+^DduNP^4i(EnNws&6|q;Pp*ZohP<#MP|XrEWL-JwMbjW#%1v(1N)53H z!sjg~{9AS32R9UA-Ovqx@X3v>?62RXejM$k_RKnO_A&0U|Ayn*t6D;$(+m@!vo8s zMIhyZ%HpTvHbludi2VM2dcwm}nfM&mty*{~1OO(Rv<@B31~$fjkH8)kaV$lv{;6+4 zzid9kdb7GQaiokHVWv*0e^cTD%3sr}z_cfX5S zkgx|?-+j4etrL`}mgzhU)w)gw@n*X_y-q_k%G(Bv5^*t64m^M-N_`0^?U6JKEaMrZ z0J&hfr&#AFE-Uzv$IdrICGkO6L4ja^qs765>Orv}*_FzFV|ay?CuY}1g?uv!r5cSf zAF!;Fj6dxj%ZuLZuLT5{^^DpB{2e7WJHn3X_==N{EKbB9Kiau(4yS0E$p!r|A~l3G zkIx;JZ=m36NXEy>au7Wf9l`LHieowXxnm)~JcZjvKA5-^NF-O+%jPMI&5NPIU#y9wPIP2xWluf7@WXGE z{$_UnWz#c(3`ox*+DE;Zl2vblN`*Z|#Lh4)WUSL}Ltb(3-r6#nj7CFf>~n> z*slDO7k-kmxyPrz=OO`F) z+F>Fb+B_rLWC858D23ttk*AMHp!;qw-}M*^q(^SAid`|{!(H7H8gMJgx~R{I2&{*_ zdF}gio9de1a|;c(UIj0bi>RlYb;c-@5{?9a0f=YDYTC%?LrfvZ)p;lrts<#N$Db5(Jl4bykAWEdNS4_w! zeZ4r{Vzl|#ya~RqZl88r=29}VorXH&T5G}07NZyoN#)RXQ5cO9GsIJp_b^q3CPFuP zf;;1-{;xr5(cu7_@BTW$`d{_(Js2Tz5K(?93o3>xpf+mgXPLLIb){3y3z&|7knQU2 zA6!(9@r*mlGr(OG*n_n39*83Lj+ZFuxyU?URje!IcmLS98dW7lNNd{k&81S!Pis&M z-d#?69NPiQrN@4iRpSV)|0n2c3&kNEt9)_`#wz&AT$1b||!d>R*p+fUn*S(~ly9pH8*ZyZDV^AZEh zvOfL$n6kITS+Zq~s)2tWH&Nt9i)eGgOF6b)B1y{U+Wts5k;?Ck0|{2JkL#yS&sq&Bxmm`)Cf`;?O( zLK%xOk`o?s-bnGM&_V>{v)&Q+5}8^aerKEVrR^3_u}lOtZ#o|$zc*io2wNsf3iSf# z`6ulH0|5X5qaZLIlWznce+>o+Duzgg_YDC73k3iJf(QWsQF5W&{SkN)Y5Nyue<&u`42SX z@py#!bmA%7K3PJ@tG%-$$q4ivDc=B*QR`P-I`1>RJYajN1aJuSMZ-1l3E3etx3COfeb`tz(S zuQPLHjEZ+|2-bVee`Q?JNY1b?%zx6zx#a?nSii^M928UlvpLG4Pi*EO7e<=p5?Sn# z;2qHTiut!ST5ercknynI(O{1DkDZfMjF!TruR&WlWWJhv48-uLb$Ka%TissYY=qiJ zv~6EeQ*+&b1lcr*4>meNdVjsyEGd;S5;8(qQo69l1gxVyf6}fFXo(0}zb-itH7y<7 z_v~k2QLEFP@sCsvcy7Qqm^7fs1TeNe9&TvV@xjB0BkCUZ9v~#(LVZUF>jr&CKy0We zkR43KMBLGR(}t0lH}nN(c1!^_5@%0v+ta~{kbpdA* z;>ht^SqJ25_^)&Pk6h!MO^h-G$*RQEHIE$T!5_9xG;&XQs2TAE+_V5f5&Gk0+beDI(Vm)dW%?Z}Lp?%DWNH*&@Ug-{1|Wqmu{Nj1J5 zCC5>cV^Jp=#3Mh-J zO^StFzcG4t6;3Hil!=urlYvn2y6f>peb!rNKWGVZuScb;!uiku%bH6Vb7mPW~T+v2oX}fG8 zAA9MDJ#~#=@7b#dQp!53g5^?;?*46o*RrxG1esZ2G>r@<1}ZTJ#DS&tOZ!!%wDU1) zNwQrdwjB3Z7(wn&1@_BL=1J6(f4WX}3QPPKL2LjDKsoktWNk}ddY|VAKWy0*F58Vj z9OnTOJNVu;^lH+4)<=K%2?o{pu$h|=tAi=W!^+snynreyP>3 zx|mcrGNN-6kb8A%*ArAGMd#ZgU_c7-sKpk`H)Fb*QLm7o2-l=4<pq|PgDR}C7Z@QHl*DK2W&|U6o$1zy!EM~PepJrFKfD&9e<45cmIlWb5cHDv@jKNN}_rA*B)l1W@*qA9b@orL1r#0&I*Y{BB>Nz`QM1B_nDb zG--$2FeHZ$KVKcffQZ@Dw`WiS|4_=GZpVf1XI>%Er=r>) XswNwCI3W%OL|TDOEVWE!>fCI6Oiup1 diff --git a/staking/parse.go b/staking/parse.go index fd21c3cbe38e..ef94a1550941 100644 --- a/staking/parse.go +++ b/staking/parse.go @@ -61,7 +61,10 @@ func ParseCertificate(der []byte) (*Certificate, error) { if err != nil { return nil, err } - stakingCert := CertificateFromX509(x509Cert) + stakingCert, err := CertificateFromX509(x509Cert) + if err != nil { + return nil, err + } return stakingCert, ValidateCertificate(stakingCert) } @@ -86,7 +89,8 @@ func ParseCertificatePermissive(bytes []byte) (*Certificate, error) { if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) { return nil, ErrMalformedTBSCertificate } - if !input.SkipOptionalASN1(cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) { + var certVersion int + if !input.ReadOptionalASN1Integer(&certVersion, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific(), 0) { return nil, ErrMalformedVersion } if !input.SkipASN1(cryptobyte_asn1.INTEGER) { @@ -105,14 +109,15 @@ func ParseCertificatePermissive(bytes []byte) (*Certificate, error) { return nil, ErrMalformedIssuer } - // Read the "subject public key info" into input. - if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) { + // Read the "subject public key info" into spki. + var spki cryptobyte.String + if !input.ReadASN1(&spki, cryptobyte_asn1.SEQUENCE) { return nil, ErrMalformedSPKI } // Read the public key algorithm identifier. var pkAISeq cryptobyte.String - if !input.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) { + if !spki.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) { return nil, ErrMalformedPublicKeyAlgorithmIdentifier } var pkAI asn1.ObjectIdentifier @@ -123,15 +128,23 @@ func ParseCertificatePermissive(bytes []byte) (*Certificate, error) { // Note: Unlike the x509 package, we require parsing the public key. var spk asn1.BitString - if !input.ReadASN1BitString(&spk) { + if !spki.ReadASN1BitString(&spk) { return nil, ErrMalformedSubjectPublicKey } + publicKey, signatureAlgorithm, err := parsePublicKey(pkAI, spk) - return &Certificate{ + cert := &Certificate{ Raw: bytes, SignatureAlgorithm: signatureAlgorithm, PublicKey: publicKey, - }, err + } + if err != nil { + return cert, err + } + + nodeID, err := getNodeID(input, certVersion, publicKey) + cert.NodeID = nodeID + return cert, err } // Ref: https://github.com/golang/go/blob/go1.19.12/src/crypto/x509/parser.go#L215-L306 diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index 2b88ef49afc1..c10b84f98ea4 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -44,7 +44,7 @@ func DefaultFlags() FlagsMap { config.HTTPHostKey: "127.0.0.1", config.StakingHostKey: "127.0.0.1", config.HealthCheckFreqKey: "2s", - config.AdminAPIEnabledKey: true, + config.AdminAPIEnabledKey: "e2e", config.IpcAPIEnabledKey: true, config.IndexEnabledKey: true, config.LogDisplayLevelKey: "INFO", diff --git a/tests/fixture/tmpnet/node.go b/tests/fixture/tmpnet/node.go index 59025b649112..ea21e0f27ff0 100644 --- a/tests/fixture/tmpnet/node.go +++ b/tests/fixture/tmpnet/node.go @@ -330,8 +330,11 @@ func (n *Node) EnsureNodeID() error { if err != nil { return fmt.Errorf("failed to ensure node ID: failed to load tls cert: %w", err) } - stakingCert := staking.CertificateFromX509(tlsCert.Leaf) - n.NodeID = ids.NodeIDFromCert(stakingCert) + stakingCert, err := staking.CertificateFromX509(tlsCert.Leaf) + if err != nil { + return fmt.Errorf("failed to ensure node ID: failed to load tls cert: %w", err) + } + n.NodeID = stakingCert.NodeID return nil } diff --git a/tests/fixture/tmpnet/node_process.go b/tests/fixture/tmpnet/node_process.go index c2e2e33139bf..b9fae2f9508c 100644 --- a/tests/fixture/tmpnet/node_process.go +++ b/tests/fixture/tmpnet/node_process.go @@ -23,7 +23,7 @@ import ( ) const ( - AvalancheGoPathEnvName = "AVALANCHEGO_PATH" + AvalancheGoPathEnvName = "CAMINOGO_BIN_PATH" defaultNodeInitTimeout = 10 * time.Second ) diff --git a/tools/camino-network-runner b/tools/camino-network-runner deleted file mode 160000 index 07d845d68b74..000000000000 --- a/tools/camino-network-runner +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 07d845d68b74d7abe99f7fd49ce0681071142fd7 diff --git a/tools/cert/main.go b/tools/cert/main.go index c0bb1896786a..76a4e7465ac8 100644 --- a/tools/cert/main.go +++ b/tools/cert/main.go @@ -13,7 +13,6 @@ import ( "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/cb58" utilsSecp256k1 "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" @@ -72,7 +71,7 @@ func main() { os.Exit(1) } - id, err := peer.CertToID(cert.Leaf) + id, err := staking.TLSCertToID(cert.Leaf) if err != nil { fmt.Printf("cannot extract nodeID from certificate: %s\n", err) os.Exit(1) diff --git a/utils/constants/application.go b/utils/constants/application.go index 68c42f64d294..56da9b0a2d14 100644 --- a/utils/constants/application.go +++ b/utils/constants/application.go @@ -15,7 +15,7 @@ package constants // Variables to be exported // Can be overwritten with -X during build step -var ( +const ( // PlatformName exports the name of the platform PlatformName = "camino" diff --git a/utils/crypto/secp256k1/camino_secp256k1.go b/utils/crypto/secp256k1/camino_secp256k1.go index 0f50c421a179..68ed08a32320 100644 --- a/utils/crypto/secp256k1/camino_secp256k1.go +++ b/utils/crypto/secp256k1/camino_secp256k1.go @@ -4,6 +4,7 @@ package secp256k1 import ( + "crypto" rsa "crypto/rsa" x509 "crypto/x509" "crypto/x509/pkix" @@ -20,9 +21,10 @@ import ( var oidLocalKeyID = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 21} var ( - errWrongCertType = errors.New("wrong certificate type") - errNoSignature = errors.New("failed to extract signature from certificate") - errRecoverFailed = errors.New("failed to recover public key") + errNoSignature = errors.New("failed to extract signature from certificate") + errRecoverFailed = errors.New("failed to recover public key") + errNotRSAPublicKey = errors.New("certificate public key is not rsa public key") + ErrWrongExtensionType = errors.New("wrong extension type") ) // Takes a RSA privateKey and builds using it's hash an secp256k1 private key. @@ -49,26 +51,34 @@ func SignRsaPublicKey(privKey *secp256k1.PrivateKey, pubKey *rsa.PublicKey) *pki // This is the reverse what has been done in RsaPrivateKeyToSecp256PrivateKey // It returns the marshalled public key func RecoverSecp256PublicKey(cert *x509.Certificate) ([]byte, error) { - // Recover RSA public key from certificate - rPubKey := cert.PublicKey.(*rsa.PublicKey) - if rPubKey == nil { - return nil, errWrongCertType - } - - // Locate the signature in certificate - var signature []byte for _, ext := range cert.Extensions { if ext.Id.Equal(oidLocalKeyID) { - signature = ext.Value - break + return recoverSecp256PublicKeyFromExtension(&ext, cert.PublicKey) //nolint:gosec } } - if signature == nil { + return nil, errNoSignature +} + +func RecoverSecp256PublicKeyFromExtension(ext *pkix.Extension, publicKey crypto.PublicKey) ([]byte, error) { + if !ext.Id.Equal(oidLocalKeyID) { + return nil, ErrWrongExtensionType + } + + return recoverSecp256PublicKeyFromExtension(ext, publicKey) +} + +func recoverSecp256PublicKeyFromExtension(ext *pkix.Extension, publicKey crypto.PublicKey) ([]byte, error) { + if ext.Value == nil { return nil, errNoSignature } - data := hashing.ComputeHash256(x509.MarshalPKCS1PublicKey(rPubKey)) - sPubKey, _, err := ecdsa.RecoverCompact(signature, data) + rsaPubKey, ok := publicKey.(*rsa.PublicKey) + if !ok { + return nil, errNotRSAPublicKey + } + + data := hashing.ComputeHash256(x509.MarshalPKCS1PublicKey(rsaPubKey)) + sPubKey, _, err := ecdsa.RecoverCompact(ext.Value, data) if err != nil { return nil, errRecoverFailed } diff --git a/utils/ips/claimed_ip_port.go b/utils/ips/claimed_ip_port.go index 2ef6c0a71087..fdd31e44229e 100644 --- a/utils/ips/claimed_ip_port.go +++ b/utils/ips/claimed_ip_port.go @@ -47,7 +47,7 @@ func NewClaimedIPPort( IPPort: ipPort, Timestamp: timestamp, Signature: signature, - NodeID: ids.NodeIDFromCert(cert), + NodeID: cert.NodeID, } packer := wrappers.Packer{ diff --git a/version/compatibility.json b/version/compatibility.json index fcf0a459e59d..620bcb57215d 100644 --- a/version/compatibility.json +++ b/version/compatibility.json @@ -1,6 +1,6 @@ { "31": [ - "v1.10.18" + "v1.1.18" ], "30": [ "v1.1.17", diff --git a/vms/avm/camino_service_test.go b/vms/avm/camino_service_test.go deleted file mode 100644 index 9eeb88f79c42..000000000000 --- a/vms/avm/camino_service_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2022-2024, Chain4Travel AG. All rights reserved. -// See the file LICENSE for licensing terms. - -package avm - -import ( - "context" - "net/http" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestGetAssetDescriptionC4T(t *testing.T) { - env := setup(t, &envConfig{}) - env.vm.ctx.Lock.Unlock() - defer stopEnv(t, env) - - type args struct { - in0 *http.Request - args *GetAssetDescriptionArgs - reply *GetAssetDescriptionReply - } - tests := []struct { - name string - args args - expectedErr error - want []string - }{ - { - name: "With given assetId", - args: args{ - in0: nil, - reply: &GetAssetDescriptionReply{}, - args: &GetAssetDescriptionArgs{ - AssetID: env.vm.ctx.AVAXAssetID.String(), - }, - }, - want: []string{"AVAX", "SYMB", env.vm.ctx.AVAXAssetID.String()}, - }, - { - name: "Without assetId", - args: args{ - in0: nil, - reply: &GetAssetDescriptionReply{}, - args: &GetAssetDescriptionArgs{ - AssetID: env.vm.ctx.AVAXAssetID.String(), - }, - }, - want: []string{"AVAX", "SYMB", env.vm.feeAssetID.String()}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := env.service.GetAssetDescription(tt.args.in0, tt.args.args, tt.args.reply) - require.ErrorIs(t, err, tt.expectedErr) - require.Equal(t, tt.want[0], tt.args.reply.Name, "Wrong name returned from GetAssetDescription %s", tt.args.reply.Name) - require.Equal(t, tt.want[1], tt.args.reply.Symbol, "Wrong symbol returned from GetAssetDescription %s", tt.args.reply.Symbol) - require.Equal(t, tt.want[2], tt.args.reply.AssetID.String()) - }) - } -} - -func stopEnv(t *testing.T, env *environment) { - env.vm.ctx.Lock.Lock() - require.NoError(t, env.vm.Shutdown(context.Background())) - env.vm.ctx.Lock.Unlock() -} diff --git a/vms/avm/service_test.go b/vms/avm/service_test.go index c659b8e9de9e..9f4894943568 100644 --- a/vms/avm/service_test.go +++ b/vms/avm/service_test.go @@ -2087,6 +2087,8 @@ func TestGetAssetDescription(t *testing.T) { AssetID: avaxAssetID.String(), }, &reply)) + require.Equal(reply.AssetID, env.vm.feeAssetID) + require.Equal("AVAX", reply.Name) require.Equal("SYMB", reply.Symbol) } diff --git a/vms/components/avax/camino_timed_utxo_test.go b/vms/components/avax/camino_timed_utxo_test.go index 48f003e253ad..c30a6c0e6595 100644 --- a/vms/components/avax/camino_timed_utxo_test.go +++ b/vms/components/avax/camino_timed_utxo_test.go @@ -5,6 +5,7 @@ package avax import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -16,7 +17,7 @@ import ( ) func TestRewardUTXOSerializeC(t *testing.T) { - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) manager := codec.NewDefaultManager() errs := wrappers.Errs{} diff --git a/vms/components/avax/mock_atomic_utxos.go b/vms/components/avax/mock_atomic_utxos.go index 9623379c04aa..68f8b7d80f47 100644 --- a/vms/components/avax/mock_atomic_utxos.go +++ b/vms/components/avax/mock_atomic_utxos.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2022, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/avax (interfaces: AtomicUTXOManager) +// Source: vms/components/avax/atomic_utxos.go +// +// Generated by this command: +// +// mockgen -source=vms/components/avax/atomic_utxos.go -destination=vms/components/avax/mock_atomic_utxos.go -package=avax -exclude_interfaces= +// // Package avax is a generated GoMock package. package avax @@ -39,9 +41,9 @@ func (m *MockAtomicUTXOManager) EXPECT() *MockAtomicUTXOManagerMockRecorder { } // GetAtomicUTXOs mocks base method. -func (m *MockAtomicUTXOManager) GetAtomicUTXOs(arg0 ids.ID, arg1 set.Set[ids.ShortID], arg2 ids.ShortID, arg3 ids.ID, arg4 int) ([]*UTXO, ids.ShortID, ids.ID, error) { +func (m *MockAtomicUTXOManager) GetAtomicUTXOs(chainID ids.ID, addrs set.Set[ids.ShortID], startAddr ids.ShortID, startUTXOID ids.ID, limit int) ([]*UTXO, ids.ShortID, ids.ID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAtomicUTXOs", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "GetAtomicUTXOs", chainID, addrs, startAddr, startUTXOID, limit) ret0, _ := ret[0].([]*UTXO) ret1, _ := ret[1].(ids.ShortID) ret2, _ := ret[2].(ids.ID) @@ -50,7 +52,7 @@ func (m *MockAtomicUTXOManager) GetAtomicUTXOs(arg0 ids.ID, arg1 set.Set[ids.Sho } // GetAtomicUTXOs indicates an expected call of GetAtomicUTXOs. -func (mr *MockAtomicUTXOManagerMockRecorder) GetAtomicUTXOs(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockAtomicUTXOManagerMockRecorder) GetAtomicUTXOs(chainID, addrs, startAddr, startUTXOID, limit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAtomicUTXOs", reflect.TypeOf((*MockAtomicUTXOManager)(nil).GetAtomicUTXOs), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAtomicUTXOs", reflect.TypeOf((*MockAtomicUTXOManager)(nil).GetAtomicUTXOs), chainID, addrs, startAddr, startUTXOID, limit) } diff --git a/vms/components/message/camino_codec.go b/vms/components/message/camino_codec.go deleted file mode 100644 index a6dbc60fd21c..000000000000 --- a/vms/components/message/camino_codec.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2022-2024, Chain4Travel AG. All rights reserved. -// See the file LICENSE for licensing terms. - -package message - -import ( - "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/codec/linearcodec" - "github.com/ava-labs/avalanchego/utils/wrappers" -) - -const ( - CodecVersion uint16 = 0 -) - -// Codec does serialization and deserialization -var Codec codec.Manager - -func init() { - Codec = codec.NewManager(maxMessageSize) - lc := linearcodec.NewCaminoDefault() - - errs := wrappers.Errs{} - errs.Add( - lc.RegisterType(&CaminoRewardMessage{}), - Codec.RegisterCodec(CodecVersion, lc), - ) - if errs.Errored() { - panic(errs.Err) - } -} diff --git a/vms/components/message/camino_readme.md b/vms/components/message/camino_readme.md new file mode 100644 index 000000000000..9d2f86211c1e --- /dev/null +++ b/vms/components/message/camino_readme.md @@ -0,0 +1,4 @@ +This codec types are only used in communication between nodes or node chains. + +`CaminoRewardMessage` is sent from C chain to P chain +`Tx` message is sent from one node to another (tx gossip) diff --git a/vms/components/message/codec.go b/vms/components/message/codec.go index 5614125b1cee..5d28233be3db 100644 --- a/vms/components/message/codec.go +++ b/vms/components/message/codec.go @@ -1,3 +1,13 @@ +// Copyright (C) 2024, Chain4Travel AG. All rights reserved. +// +// This file is a derived work, based on ava-labs code whose +// original notices appear below. +// +// It is distributed under the same license conditions as the +// original code from which it is derived. +// +// Much love to the original authors for their work. +// ********************************************************** // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. @@ -25,6 +35,7 @@ func init() { lc := linearcodec.NewDefault(time.Time{}) err := utils.Err( + lc.RegisterType(&CaminoRewardMessage{}), lc.RegisterType(&Tx{}), Codec.RegisterCodec(CodecVersion, lc), ) diff --git a/vms/platformvm/api/camino.go b/vms/platformvm/api/camino.go index debab84df10f..41bcfcf0a598 100644 --- a/vms/platformvm/api/camino.go +++ b/vms/platformvm/api/camino.go @@ -274,7 +274,7 @@ func buildCaminoGenesis(args *BuildGenesisArgs, reply *BuildGenesisReply) error } // Marshal genesis to bytes - bytes, err := genesis.Codec.Marshal(genesis.Version, g) + bytes, err := genesis.Codec.Marshal(genesis.CodecVersion, g) if err != nil { return fmt.Errorf("couldn't marshal genesis: %w", err) } diff --git a/vms/platformvm/api/camino_test.go b/vms/platformvm/api/camino_test.go index 21f33cda811e..b86c08a1de8c 100644 --- a/vms/platformvm/api/camino_test.go +++ b/vms/platformvm/api/camino_test.go @@ -599,7 +599,7 @@ func TestBuildCaminoGenesis(t *testing.T) { expectedGenesis, err := tt.expectedGenesis(t) require.NoError(t, err) - bytes, err := genesis.Codec.Marshal(genesis.Version, expectedGenesis) + bytes, err := genesis.Codec.Marshal(genesis.CodecVersion, expectedGenesis) require.NoError(t, err) expectedReply.Bytes = string(bytes) diff --git a/vms/platformvm/block/builder/builder.go b/vms/platformvm/block/builder/builder.go index 0d7c13680f79..387ea0b665f9 100644 --- a/vms/platformvm/block/builder/builder.go +++ b/vms/platformvm/block/builder/builder.go @@ -314,8 +314,7 @@ func buildBlock( blockTxs, ) } - - // TODO@ packBlockTxs + if block, err := caminoBuildBlock(builder, parentID, height, timestamp, parentState); err != nil { return nil, err } else if block != nil { @@ -394,10 +393,12 @@ func packBlockTxs( return nil, err } - executor := &txexecutor.StandardTxExecutor{ - Backend: backend, - State: txDiff, - Tx: tx, + executor := &txexecutor.CaminoStandardTxExecutor{ + StandardTxExecutor: txexecutor.StandardTxExecutor{ + Backend: backend, + State: txDiff, + Tx: tx, + }, } err = tx.Unsigned.Visit(executor) diff --git a/vms/platformvm/block/builder/camino_builder.go b/vms/platformvm/block/builder/camino_builder.go index 0cddf98dbb55..974d4d20ef68 100644 --- a/vms/platformvm/block/builder/camino_builder.go +++ b/vms/platformvm/block/builder/camino_builder.go @@ -41,6 +41,13 @@ func caminoBuildBlock( return nil, fmt.Errorf("could not build tx to unlock deposits: %w", err) } + // User-signed unlockDepositTx with partial unlock and + // system-issued unlockDepositTx with full unlock for the same deposit + // will conflict with each other resulting in block rejection. + // After that, txs (depending on node config) could be re-added to mempool + // and this case could happen again. + // Because of this, we can't allow block with system unlockDepositTx contain other txs. + return block.NewBanffStandardBlock( timestamp, parentID, @@ -64,6 +71,14 @@ func caminoBuildBlock( return nil, fmt.Errorf("could not build tx to finish proposals: %w", err) } + // User-signed addVoteTx and system-issued finishProposalsTx for the same proposal + // will conflict with each other resulting either in block rejection or + // in possible unexpected proposal outcome (finishProposalsTx issuing desicion + // is happenning based on before this addVoteTx state). + // After that, if block is rejected, txs (depending on node config) could be re-added to mempool + // and this case could happen again. + // Because of this, we can't allow block with system finishProposalsTx contain other txs. + // FinishProposalsTx should never be in block with addVoteTx, // because it can affect state of proposals. return block.NewBanffStandardBlock( diff --git a/vms/platformvm/block/codec.go b/vms/platformvm/block/codec.go index 7ec1e003c25b..6e8bd9605e5b 100644 --- a/vms/platformvm/block/codec.go +++ b/vms/platformvm/block/codec.go @@ -42,7 +42,7 @@ var ( // concurrently func InitCodec(durangoTime time.Time) error { c := linearcodec.NewCaminoDefault(durangoTime) - gc := linearcodec.NewCaminoCustomMaxLength(math.MaxInt32, time.Time{}) + gc := linearcodec.NewCaminoCustomMaxLength(time.Time{}, math.MaxInt32) errs := wrappers.Errs{} for _, c := range []linearcodec.CaminoCodec{c, gc} { diff --git a/vms/platformvm/block/executor/verifier.go b/vms/platformvm/block/executor/verifier.go index b46102b5c48d..c6324135e639 100644 --- a/vms/platformvm/block/executor/verifier.go +++ b/vms/platformvm/block/executor/verifier.go @@ -472,7 +472,7 @@ func (v *verifier) processStandardTxs(txs []*txs.Tx, state state.Diff, parentID txExecutor := executor.CaminoStandardTxExecutor{ StandardTxExecutor: executor.StandardTxExecutor{ Backend: v.txExecutorBackend, - State: onAcceptState, + State: state, Tx: tx, }, } diff --git a/vms/platformvm/camino_helpers_test.go b/vms/platformvm/camino_helpers_test.go index 4256626e9653..17f48759b2d9 100644 --- a/vms/platformvm/camino_helpers_test.go +++ b/vms/platformvm/camino_helpers_test.go @@ -99,7 +99,9 @@ func newCaminoVM(t *testing.T, genesisConfig api.Camino, phase test.Phase, genes ) require.NoError(err) - require.NoError(vm.Network.IssueTx(context.Background(), testSubnet1)) + vm.ctx.Lock.Unlock() + require.NoError(vm.issueTx(context.Background(), testSubnet1)) + vm.ctx.Lock.Lock() blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(err) require.NoError(blk.Verify(context.Background())) diff --git a/vms/platformvm/camino_service.go b/vms/platformvm/camino_service.go index c6c786bbd39c..d3cc1d82304d 100644 --- a/vms/platformvm/camino_service.go +++ b/vms/platformvm/camino_service.go @@ -244,7 +244,7 @@ func (s *CaminoService) GetConfiguration(_ *http.Request, _ *struct{}, reply *Ge reply.SupplyCap = json.Uint64(s.vm.RewardConfig.SupplyCap) // Codec information - reply.CodecVersion = json.Uint16(txs.Version) + reply.CodecVersion = json.Uint16(txs.CodecVersion) caminoConfig, err := s.vm.state.CaminoConfig() if err != nil { @@ -427,7 +427,7 @@ func (s *CaminoService) Spend(_ *http.Request, args *SpendArgs, response *SpendR return fmt.Errorf("%w: %w", errCreateTransferables, err) } - bytes, err := txs.Codec.Marshal(txs.Version, ins) + bytes, err := txs.Codec.Marshal(txs.CodecVersion, ins) if err != nil { return fmt.Errorf("%w: %w", errSerializeTransferables, err) } @@ -436,7 +436,7 @@ func (s *CaminoService) Spend(_ *http.Request, args *SpendArgs, response *SpendR return fmt.Errorf("%w: %w", errEncodeTransferables, err) } - bytes, err = txs.Codec.Marshal(txs.Version, outs) + bytes, err = txs.Codec.Marshal(txs.CodecVersion, outs) if err != nil { return fmt.Errorf("%w: %w", errSerializeTransferables, err) } @@ -453,7 +453,7 @@ func (s *CaminoService) Spend(_ *http.Request, args *SpendArgs, response *SpendR } } - bytes, err = txs.Codec.Marshal(txs.Version, owners) + bytes, err = txs.Codec.Marshal(txs.CodecVersion, owners) if err != nil { return fmt.Errorf("%w: %w", errSerializeOwners, err) } diff --git a/vms/platformvm/camino_vm_test.go b/vms/platformvm/camino_vm_test.go index 6109b34306dd..4f9a10d7bbe8 100644 --- a/vms/platformvm/camino_vm_test.go +++ b/vms/platformvm/camino_vm_test.go @@ -624,8 +624,8 @@ func TestProposals(t *testing.T) { // Try to vote on proposal, expect to fail vm.clock.Set(baseFeeProposalState.StartTime().Add(-time.Second)) addVoteTx := buildSimpleVoteTx(t, vm, proposerKey, fee, proposalTx.ID(), test.FundedKeys[0], 0) - err = vm.Network.IssueTx(context.Background(), addVoteTx) - require.ErrorIs(err, txexecutor.ErrProposalInactive) + err = issueTx(t, vm, addVoteTx) + require.ErrorIs(err, dac.ErrNotYetActive) vm.clock.Set(baseFeeProposalState.StartTime()) optionWeights := make([]uint32, len(baseFeeProposalState.Options)) @@ -1168,7 +1168,7 @@ func TestExcludeMemberProposals(t *testing.T) { if tt.moreExclude { excludeMemberProposalTx := buildExcludeMemberProposalTx(t, vm, fundsKey, proposalBondAmount, fee, consortiumSecretaryKey, memberToExcludeAddr, proposalStartTime, proposalStartTime.Add(time.Duration(dac.ExcludeMemberProposalMinDuration)*time.Second), true) - err = vm.Network.IssueTx(context.Background(), excludeMemberProposalTx) + err = issueTx(t, vm, excludeMemberProposalTx) require.ErrorIs(err, txexecutor.ErrInvalidProposal) height, err = vm.GetCurrentHeight(context.Background()) require.NoError(err) @@ -1279,7 +1279,7 @@ func TestExcludeMemberProposals(t *testing.T) { func buildAndAcceptBlock(t *testing.T, vm *VM, tx *txs.Tx) block.Block { t.Helper() if tx != nil { - require.NoError(t, vm.Network.IssueTx(context.Background(), tx)) + require.NoError(t, issueTx(t, vm, tx)) } blk, err := vm.Builder.BuildBlock(context.Background()) require.NoError(t, err) @@ -1381,7 +1381,7 @@ func buildBaseFeeProposalTx( End: uint64(endTime.Unix()), Options: options, }} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposal) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposal) require.NoError(t, err) proposalTx, err := txs.NewSigned(&txs.AddProposalTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ @@ -1428,7 +1428,7 @@ func buildAddMemberProposalTx( proposal = &dac.AdminProposal{Proposal: proposal} } wrapper := &txs.ProposalWrapper{Proposal: proposal} - proposalBytes, err := txs.Codec.Marshal(txs.Version, wrapper) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, wrapper) require.NoError(t, err) proposalTx, err := txs.NewSigned(&txs.AddProposalTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ @@ -1476,7 +1476,7 @@ func buildExcludeMemberProposalTx( proposal = &dac.AdminProposal{Proposal: proposal} } wrapper := &txs.ProposalWrapper{Proposal: proposal} - proposalBytes, err := txs.Codec.Marshal(txs.Version, wrapper) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, wrapper) require.NoError(t, err) proposalTx, err := txs.NewSigned(&txs.AddProposalTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ @@ -1535,7 +1535,7 @@ func buildSimpleVoteTx( nil, nil, 0, ) require.NoError(t, err) - voteBytes, err := txs.Codec.Marshal(txs.Version, &txs.VoteWrapper{Vote: &dac.SimpleVote{OptionIndex: votedOption}}) + voteBytes, err := txs.Codec.Marshal(txs.CodecVersion, &txs.VoteWrapper{Vote: &dac.SimpleVote{OptionIndex: votedOption}}) require.NoError(t, err) addVoteTx, err := txs.NewSigned(&txs.AddVoteTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ @@ -1610,3 +1610,10 @@ func buildAndAcceptBaseTx( require.Len(t, blk.Txs(), 1) checkTx(t, vm, blk.ID(), feeTestingTx.ID()) } + +func issueTx(t *testing.T, vm *VM, tx *txs.Tx) error { + t.Helper() + vm.ctx.Lock.Unlock() + defer vm.ctx.Lock.Lock() + return vm.issueTx(context.Background(), tx) +} diff --git a/vms/platformvm/dac/camino_add_member_proposal.go b/vms/platformvm/dac/camino_add_member_proposal.go index 3ce3949941a1..3f89ba1f1230 100644 --- a/vms/platformvm/dac/camino_add_member_proposal.go +++ b/vms/platformvm/dac/camino_add_member_proposal.go @@ -101,9 +101,15 @@ func (p *AddMemberProposalState) EndTime() time.Time { return time.Unix(int64(p.End), 0) } -func (p *AddMemberProposalState) IsActiveAt(time time.Time) bool { +func (p *AddMemberProposalState) VerifyActive(time time.Time) error { timestamp := uint64(time.Unix()) - return p.Start <= timestamp && timestamp <= p.End + switch { + case timestamp < p.Start: + return ErrNotYetActive + case timestamp > p.End: + return ErrNotActive // should never happen, cause finished proposals removed from state + } + return nil } func (p *AddMemberProposalState) CanBeFinished() bool { diff --git a/vms/platformvm/dac/camino_base_fee_proposal.go b/vms/platformvm/dac/camino_base_fee_proposal.go index 7d51093b3fb0..bf8c8e10673a 100644 --- a/vms/platformvm/dac/camino_base_fee_proposal.go +++ b/vms/platformvm/dac/camino_base_fee_proposal.go @@ -121,9 +121,15 @@ func (p *BaseFeeProposalState) EndTime() time.Time { return time.Unix(int64(p.End), 0) } -func (p *BaseFeeProposalState) IsActiveAt(time time.Time) bool { +func (p *BaseFeeProposalState) VerifyActive(time time.Time) error { timestamp := uint64(time.Unix()) - return p.Start <= timestamp && timestamp <= p.End + switch { + case timestamp < p.Start: + return ErrNotYetActive + case timestamp > p.End: + return ErrNotActive // should never happen, cause finished proposals removed from state + } + return nil } func (p *BaseFeeProposalState) CanBeFinished() bool { diff --git a/vms/platformvm/dac/camino_codec.go b/vms/platformvm/dac/camino_codec.go index be4325d52af8..42b2a0de8dd2 100644 --- a/vms/platformvm/dac/camino_codec.go +++ b/vms/platformvm/dac/camino_codec.go @@ -5,6 +5,7 @@ package dac import ( "math" + "time" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/codec/linearcodec" @@ -17,9 +18,9 @@ const Version = 0 var Codec codec.Manager func init() { - c := linearcodec.NewCaminoDefault() + c := linearcodec.NewCaminoDefault(time.Time{}) Codec = codec.NewDefaultManager() - gc := linearcodec.NewCaminoCustomMaxLength(math.MaxInt32) + gc := linearcodec.NewCaminoCustomMaxLength(time.Time{}, math.MaxInt32) errs := wrappers.Errs{} for _, c := range []linearcodec.CaminoCodec{c, gc} { diff --git a/vms/platformvm/dac/camino_exclude_member_proposal.go b/vms/platformvm/dac/camino_exclude_member_proposal.go index e471e4a0142d..dcd6a0ef6199 100644 --- a/vms/platformvm/dac/camino_exclude_member_proposal.go +++ b/vms/platformvm/dac/camino_exclude_member_proposal.go @@ -110,9 +110,15 @@ func (p *ExcludeMemberProposalState) EndTime() time.Time { return time.Unix(int64(p.End), 0) } -func (p *ExcludeMemberProposalState) IsActiveAt(time time.Time) bool { +func (p *ExcludeMemberProposalState) VerifyActive(time time.Time) error { timestamp := uint64(time.Unix()) - return p.Start <= timestamp && timestamp <= p.End + switch { + case timestamp < p.Start: + return ErrNotYetActive + case timestamp > p.End: + return ErrNotActive // should never happen, cause finished proposals removed from state + } + return nil } func (p *ExcludeMemberProposalState) CanBeFinished() bool { diff --git a/vms/platformvm/dac/camino_fee_distribution_proposal.go b/vms/platformvm/dac/camino_fee_distribution_proposal.go index d50d4c19c12f..2a3cd5f92824 100644 --- a/vms/platformvm/dac/camino_fee_distribution_proposal.go +++ b/vms/platformvm/dac/camino_fee_distribution_proposal.go @@ -134,9 +134,15 @@ func (p *FeeDistributionProposalState) EndTime() time.Time { return time.Unix(int64(p.End), 0) } -func (p *FeeDistributionProposalState) IsActiveAt(time time.Time) bool { +func (p *FeeDistributionProposalState) VerifyActive(time time.Time) error { timestamp := uint64(time.Unix()) - return p.Start <= timestamp && timestamp <= p.End + switch { + case timestamp < p.Start: + return ErrNotYetActive + case timestamp > p.End: + return ErrNotActive // should never happen, cause finished proposals removed from state + } + return nil } func (p *FeeDistributionProposalState) CanBeFinished() bool { diff --git a/vms/platformvm/dac/camino_general_proposal.go b/vms/platformvm/dac/camino_general_proposal.go index 8a6c4c2bdb67..7454d94e2a62 100644 --- a/vms/platformvm/dac/camino_general_proposal.go +++ b/vms/platformvm/dac/camino_general_proposal.go @@ -165,9 +165,15 @@ func (p *GeneralProposalState) EndTime() time.Time { return time.Unix(int64(p.End), 0) } -func (p *GeneralProposalState) IsActiveAt(time time.Time) bool { +func (p *GeneralProposalState) VerifyActive(time time.Time) error { timestamp := uint64(time.Unix()) - return p.Start <= timestamp && timestamp <= p.End + switch { + case timestamp < p.Start: + return ErrNotYetActive + case timestamp > p.End: + return ErrNotActive // should never happen, cause finished proposals removed from state + } + return nil } func (p *GeneralProposalState) CanBeFinished() bool { diff --git a/vms/platformvm/dac/camino_mock_bond_tx_ids_getter.go b/vms/platformvm/dac/camino_mock_bond_tx_ids_getter.go index afd37bcc9412..462b5d792010 100644 --- a/vms/platformvm/dac/camino_mock_bond_tx_ids_getter.go +++ b/vms/platformvm/dac/camino_mock_bond_tx_ids_getter.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/dac (interfaces: BondTxIDsGetter) +// +// Generated by this command: +// +// mockgen -package=dac -destination=vms/platformvm/dac/camino_mock_bond_tx_ids_getter.go github.com/ava-labs/avalanchego/vms/platformvm/dac BondTxIDsGetter +// // Package dac is a generated GoMock package. package dac @@ -47,7 +49,7 @@ func (m *MockBondTxIDsGetter) AddMemberProposal(arg0 *AddMemberProposalState) ([ } // AddMemberProposal indicates an expected call of AddMemberProposal. -func (mr *MockBondTxIDsGetterMockRecorder) AddMemberProposal(arg0 interface{}) *gomock.Call { +func (mr *MockBondTxIDsGetterMockRecorder) AddMemberProposal(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddMemberProposal", reflect.TypeOf((*MockBondTxIDsGetter)(nil).AddMemberProposal), arg0) } @@ -62,7 +64,7 @@ func (m *MockBondTxIDsGetter) BaseFeeProposal(arg0 *BaseFeeProposalState) ([]ids } // BaseFeeProposal indicates an expected call of BaseFeeProposal. -func (mr *MockBondTxIDsGetterMockRecorder) BaseFeeProposal(arg0 interface{}) *gomock.Call { +func (mr *MockBondTxIDsGetterMockRecorder) BaseFeeProposal(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BaseFeeProposal", reflect.TypeOf((*MockBondTxIDsGetter)(nil).BaseFeeProposal), arg0) } @@ -77,7 +79,7 @@ func (m *MockBondTxIDsGetter) ExcludeMemberProposal(arg0 *ExcludeMemberProposalS } // ExcludeMemberProposal indicates an expected call of ExcludeMemberProposal. -func (mr *MockBondTxIDsGetterMockRecorder) ExcludeMemberProposal(arg0 interface{}) *gomock.Call { +func (mr *MockBondTxIDsGetterMockRecorder) ExcludeMemberProposal(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExcludeMemberProposal", reflect.TypeOf((*MockBondTxIDsGetter)(nil).ExcludeMemberProposal), arg0) } @@ -92,7 +94,7 @@ func (m *MockBondTxIDsGetter) FeeDistributionProposal(arg0 *FeeDistributionPropo } // FeeDistributionProposal indicates an expected call of FeeDistributionProposal. -func (mr *MockBondTxIDsGetterMockRecorder) FeeDistributionProposal(arg0 interface{}) *gomock.Call { +func (mr *MockBondTxIDsGetterMockRecorder) FeeDistributionProposal(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FeeDistributionProposal", reflect.TypeOf((*MockBondTxIDsGetter)(nil).FeeDistributionProposal), arg0) } @@ -107,7 +109,7 @@ func (m *MockBondTxIDsGetter) GeneralProposal(arg0 *GeneralProposalState) ([]ids } // GeneralProposal indicates an expected call of GeneralProposal. -func (mr *MockBondTxIDsGetterMockRecorder) GeneralProposal(arg0 interface{}) *gomock.Call { +func (mr *MockBondTxIDsGetterMockRecorder) GeneralProposal(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GeneralProposal", reflect.TypeOf((*MockBondTxIDsGetter)(nil).GeneralProposal), arg0) } diff --git a/vms/platformvm/dac/camino_proposal.go b/vms/platformvm/dac/camino_proposal.go index d21639573008..c19c5aeff78e 100644 --- a/vms/platformvm/dac/camino_proposal.go +++ b/vms/platformvm/dac/camino_proposal.go @@ -25,6 +25,8 @@ var ( errWrongOptionsCount = errors.New("wrong options count") errEndNotAfterStart = errors.New("proposal end-time is not after start-time") errWrongDuration = errors.New("wrong proposal duration") + ErrNotActive = errors.New("proposal is not active anymore") + ErrNotYetActive = errors.New("proposal is not yet active") ErrWrongVote = errors.New("this proposal can't be voted with this vote") ErrNotAllowedToVoteOnProposal = errors.New("this address has already voted or not allowed to vote on this proposal") @@ -78,7 +80,7 @@ type Proposal interface { type ProposalState interface { EndTime() time.Time - IsActiveAt(time time.Time) bool + VerifyActive(time time.Time) error // Once a proposal has become Finishable, it cannot be undone by adding more votes. Should only return true, when future votes cannot change the outcome of proposal. CanBeFinished() bool IsSuccessful() bool // should be called only for finished proposals diff --git a/vms/platformvm/genesis/camino.go b/vms/platformvm/genesis/camino.go index 16d8172f1942..6e9b444c8f1b 100644 --- a/vms/platformvm/genesis/camino.go +++ b/vms/platformvm/genesis/camino.go @@ -7,6 +7,7 @@ import ( "time" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/vms/components/multisig" as "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" @@ -76,8 +77,8 @@ func (b *Block) Init() error { return nil } -func (b *Block) Less(b1 *Block) bool { - return b.Timestamp < b1.Timestamp +func (b *Block) Compare(b1 *Block) int { + return utils.Compare(b.Timestamp, b1.Timestamp) } func (b *Block) Time() time.Time { @@ -93,7 +94,7 @@ func (b *Block) Txs() []*txs.Tx { // Generate deposit offer id from its bytes hash and set it to offer's ID field func SetDepositOfferID(offer *deposit.Offer) error { - bytes, err := txs.GenesisCodec.Marshal(txs.Version, offer) + bytes, err := txs.GenesisCodec.Marshal(txs.CodecVersion, offer) if err != nil { return err } diff --git a/vms/platformvm/network/camino_network.go b/vms/platformvm/network/camino_network.go index c8536e361c82..be24529d276d 100644 --- a/vms/platformvm/network/camino_network.go +++ b/vms/platformvm/network/camino_network.go @@ -7,53 +7,73 @@ import ( "context" "errors" "fmt" + "sync" "time" "go.uber.org/zap" - "github.com/ava-labs/avalanchego/cache" + "github.com/prometheus/client_golang/prometheus" + "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/message" - "github.com/ava-labs/avalanchego/vms/platformvm/block/executor" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - txBuilder "github.com/ava-labs/avalanchego/vms/platformvm/txs/builder" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) var errUnknownCrossChainMessage = errors.New("unknown cross-chain message") +type SystemTxBuilder interface { + NewRewardsImportTx() (*txs.Tx, error) +} + type caminoNetwork struct { - network - txBuilder txBuilder.CaminoBuilder + *network + txBuilder SystemTxBuilder + lock sync.Locker } func NewCamino( - ctx *snow.Context, - manager executor.Manager, + log logging.Logger, + nodeID ids.NodeID, + subnetID ids.ID, + vdrs validators.State, + txVerifier TxVerifier, mempool mempool.Mempool, partialSyncPrimaryNetwork bool, appSender common.AppSender, - txBuilder txBuilder.CaminoBuilder, -) Network { + registerer prometheus.Registerer, + config Config, + txBuilder SystemTxBuilder, + lock sync.Locker, +) (Network, error) { + avaxNetwork, err := New( + log, + nodeID, + subnetID, + vdrs, + txVerifier, + mempool, + partialSyncPrimaryNetwork, + appSender, + registerer, + config, + ) + if err != nil { + return nil, err + } + return &caminoNetwork{ - network: network{ - AppHandler: common.NewNoOpAppHandler(ctx.Log), - - ctx: ctx, - manager: manager, - mempool: mempool, - partialSyncPrimaryNetwork: partialSyncPrimaryNetwork, - appSender: appSender, - recentTxs: &cache.LRU[ids.ID, struct{}]{Size: recentCacheSize}, - }, + network: avaxNetwork.(*network), txBuilder: txBuilder, - } + lock: lock, + }, nil } func (n *caminoNetwork) CrossChainAppRequest(ctx context.Context, chainID ids.ID, requestID uint32, _ time.Time, request []byte) error { - n.ctx.Log.Debug("called CrossChainAppRequest message handler", + n.log.Debug("called CrossChainAppRequest message handler", zap.Stringer("chainID", chainID), zap.Uint32("requestID", requestID), zap.Int("messageLen", len(request)), @@ -70,7 +90,7 @@ func (n *caminoNetwork) CrossChainAppRequest(ctx context.Context, chainID ids.ID requestID, []byte(n.caminoRewardMessage()), ); err != nil { - n.ctx.Log.Error("caminoCrossChainAppRequest failed to send response", zap.Error(err)) + n.log.Error("caminoCrossChainAppRequest failed to send response", zap.Error(err)) // we don't want fatal here: response is for logging only, so // its better to not respond properly, than crash the whole node return nil @@ -89,33 +109,33 @@ func (n *caminoNetwork) caminoRewardMessage() string { if !ok { // should never happen err = fmt.Errorf("unexpected tx type: expected *txs.RewardsImportTx, got %T", utx) - n.ctx.Log.Error("caminoCrossChainAppRequest failed to create rewardsImportTx", zap.Error(err)) + n.log.Error("caminoCrossChainAppRequest failed to create rewardsImportTx", zap.Error(err)) return fmt.Sprintf("caminoCrossChainAppRequest failed to issue rewardsImportTx: %s", err) } - n.ctx.Lock.Lock() - defer n.ctx.Lock.Unlock() + n.lock.Lock() + defer n.lock.Unlock() if err := n.issueTx(tx); err != nil { - n.ctx.Log.Error("caminoCrossChainAppRequest failed to issue rewardsImportTx", zap.Error(err)) + n.log.Error("caminoCrossChainAppRequest failed to issue rewardsImportTx", zap.Error(err)) return fmt.Sprintf("caminoCrossChainAppRequest failed to issue rewardsImportTx: %s", err) } - amounts := make([]uint64, len(utx.Ins)) + amts := make([]uint64, len(utx.Ins)) for i := range utx.Ins { - amounts[i] = utx.Ins[i].In.Amount() + amts[i] = utx.Ins[i].In.Amount() } - return fmt.Sprintf("caminoCrossChainAppRequest issued rewardsImportTx with utxos with %v nCAM", amounts) + return fmt.Sprintf("caminoCrossChainAppRequest issued rewardsImportTx with utxos with %v nCAM", amts) } func (n *caminoNetwork) newRewardsImportTx() (*txs.Tx, error) { - n.ctx.Lock.Lock() - defer n.ctx.Lock.Unlock() + n.lock.Lock() + defer n.lock.Unlock() tx, err := n.txBuilder.NewRewardsImportTx() if err != nil { - n.ctx.Log.Error("caminoCrossChainAppRequest failed to create rewardsImportTx", zap.Error(err)) + n.log.Error("caminoCrossChainAppRequest failed to create rewardsImportTx", zap.Error(err)) return nil, fmt.Errorf("caminoCrossChainAppRequest failed to create rewardsImportTx: %w", err) } return tx, nil diff --git a/vms/platformvm/network/gossip.go b/vms/platformvm/network/gossip.go index fa40567430f7..877d6336e5be 100644 --- a/vms/platformvm/network/gossip.go +++ b/vms/platformvm/network/gossip.go @@ -5,6 +5,7 @@ package network import ( "context" + "errors" "fmt" "sync" "time" @@ -13,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/platformvm/dac" "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) @@ -93,7 +95,7 @@ func (g *gossipMempool) Add(tx *txs.Tx) error { return fmt.Errorf("tx %s dropped: %w", txID, mempool.ErrDuplicateTx) } - if reason := g.Mempool.GetDropReason(txID); reason != nil { + if reason := g.Mempool.GetDropReason(txID); reason != nil && !errors.Is(reason, dac.ErrNotYetActive) { // If the tx is being dropped - just ignore it // // TODO: Should we allow re-verification of the transaction even if it diff --git a/vms/platformvm/service.go b/vms/platformvm/service.go index cc4e8ddaffac..b7b3526a0de0 100644 --- a/vms/platformvm/service.go +++ b/vms/platformvm/service.go @@ -1624,7 +1624,7 @@ func (s *Service) buildExportAVAX(args *ExportAVAXArgs) (*txs.Tx, ids.ShortID, e } to, err = ids.ShortFromString(args.To) if err != nil { - return err + return nil, ids.ShortEmpty, err } } diff --git a/vms/platformvm/state/camino.go b/vms/platformvm/state/camino.go index d9a4379122a9..15fc4c839281 100644 --- a/vms/platformvm/state/camino.go +++ b/vms/platformvm/state/camino.go @@ -446,12 +446,12 @@ func (cs *caminoState) syncGenesis(s *state, g *genesis.Genesis) error { } txIDs.Add(tx.ID()) - validatorTx, ok := tx.Unsigned.(txs.ValidatorTx) + validatorTx, ok := tx.Unsigned.(txs.ScheduledStaker) if !ok { - return fmt.Errorf("expected tx type txs.ValidatorTx but got %T", tx.Unsigned) + return fmt.Errorf("expected a scheduled staker but got %T", tx.Unsigned) } - staker, err := NewCurrentStaker(tx.ID(), validatorTx, 0) + staker, err := NewCurrentStaker(tx.ID(), validatorTx, validatorTx.StartTime(), 0) if err != nil { return err } diff --git a/vms/platformvm/state/camino_claimable.go b/vms/platformvm/state/camino_claimable.go index cac2a875aa47..4190b4bab64a 100644 --- a/vms/platformvm/state/camino_claimable.go +++ b/vms/platformvm/state/camino_claimable.go @@ -88,7 +88,7 @@ func (cs *caminoState) writeClaimableAndValidatorRewards() error { return err } } else { - claimableBytes, err := block.GenesisCodec.Marshal(block.Version, claimable) + claimableBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, claimable) if err != nil { return fmt.Errorf("failed to serialize claimable: %w", err) } diff --git a/vms/platformvm/state/camino_claimable_test.go b/vms/platformvm/state/camino_claimable_test.go index 1a5338027379..ecddab09a6e8 100644 --- a/vms/platformvm/state/camino_claimable_test.go +++ b/vms/platformvm/state/camino_claimable_test.go @@ -20,7 +20,7 @@ import ( func TestGetClaimable(t *testing.T) { claimableOwnerID := ids.ID{1} claimable := &Claimable{Owner: &secp256k1fx.OutputOwners{Addrs: []ids.ShortID{}}} - claimableBytes, err := block.GenesisCodec.Marshal(block.Version, claimable) + claimableBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, claimable) require.NoError(t, err) testError := errors.New("test error") @@ -314,7 +314,7 @@ func TestWriteClaimableAndValidatorRewards(t *testing.T) { claimableOwnerID1 := ids.ID{1} claimableOwnerID2 := ids.ID{2} claimable1 := &Claimable{Owner: &secp256k1fx.OutputOwners{}, ValidatorReward: 1, ExpiredDepositReward: 2} - claimableBytes1, err := block.GenesisCodec.Marshal(block.Version, claimable1) + claimableBytes1, err := block.GenesisCodec.Marshal(block.CodecVersion, claimable1) require.NoError(t, err) tests := map[string]struct { diff --git a/vms/platformvm/state/camino_deposit.go b/vms/platformvm/state/camino_deposit.go index 0a0eed194a90..9d06c59741fe 100644 --- a/vms/platformvm/state/camino_deposit.go +++ b/vms/platformvm/state/camino_deposit.go @@ -157,7 +157,7 @@ func (cs *caminoState) writeDeposits() error { return err } } else { - depositBytes, err := block.GenesisCodec.Marshal(block.Version, depositDiff.Deposit) + depositBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositDiff.Deposit) if err != nil { return fmt.Errorf("failed to serialize deposit: %w", err) } diff --git a/vms/platformvm/state/camino_deposit_offer.go b/vms/platformvm/state/camino_deposit_offer.go index a46282527e96..94e1fd26380e 100644 --- a/vms/platformvm/state/camino_deposit_offer.go +++ b/vms/platformvm/state/camino_deposit_offer.go @@ -85,7 +85,7 @@ func (cs *caminoState) writeDepositOffers() error { } delete(cs.depositOffers, offerID) } else { - offerBytes, err := block.GenesisCodec.Marshal(block.Version, offer) + offerBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, offer) if err != nil { return fmt.Errorf("failed to serialize deposit offer: %w", err) } diff --git a/vms/platformvm/state/camino_deposit_offer_test.go b/vms/platformvm/state/camino_deposit_offer_test.go index d21a71a07169..dee0c41c3965 100644 --- a/vms/platformvm/state/camino_deposit_offer_test.go +++ b/vms/platformvm/state/camino_deposit_offer_test.go @@ -283,13 +283,13 @@ func TestWriteDepositOffers(t *testing.T) { depositOffer0_3 := &deposit.Offer{ID: ids.ID{3}} depositOffer0_4 := &deposit.Offer{ID: ids.ID{4}} depositOffer1_5 := &deposit.Offer{ID: ids.ID{5}, UpgradeVersionID: codec.UpgradeVersion1} - depositOffer2modifiedBytes, err := block.GenesisCodec.Marshal(block.Version, depositOffer0_2modified) + depositOffer2modifiedBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositOffer0_2modified) require.NoError(t, err) - depositOffer2Bytes, err := block.GenesisCodec.Marshal(block.Version, depositOffer0_2) + depositOffer2Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositOffer0_2) require.NoError(t, err) - depositOffer3Bytes, err := block.GenesisCodec.Marshal(block.Version, depositOffer0_3) + depositOffer3Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositOffer0_3) require.NoError(t, err) - depositOffer5Bytes, err := block.GenesisCodec.Marshal(block.Version, depositOffer1_5) + depositOffer5Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositOffer1_5) require.NoError(t, err) testError := errors.New("test error") @@ -404,13 +404,13 @@ func TestLoadDepositOffers(t *testing.T) { depositOffer1_4 := &deposit.Offer{ UpgradeVersionID: codec.UpgradeVersion1, ID: ids.ID{4}, Memo: []byte("4"), } - depositOffer1Bytes, err := block.GenesisCodec.Marshal(block.Version, depositOffer0_1) + depositOffer1Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositOffer0_1) require.NoError(t, err) - depositOffer2Bytes, err := block.GenesisCodec.Marshal(block.Version, depositOffer0_2) + depositOffer2Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositOffer0_2) require.NoError(t, err) - depositOffer3Bytes, err := block.GenesisCodec.Marshal(block.Version, depositOffer0_3) + depositOffer3Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositOffer0_3) require.NoError(t, err) - depositOffer4Bytes, err := block.GenesisCodec.Marshal(block.Version, depositOffer1_4) + depositOffer4Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, depositOffer1_4) require.NoError(t, err) tests := map[string]struct { diff --git a/vms/platformvm/state/camino_deposit_test.go b/vms/platformvm/state/camino_deposit_test.go index 941a193e8986..5aec81b3754f 100644 --- a/vms/platformvm/state/camino_deposit_test.go +++ b/vms/platformvm/state/camino_deposit_test.go @@ -28,7 +28,7 @@ func TestGetDeposit(t *testing.T) { Addrs: []ids.ShortID{{1}}, }, } - depositBytes, err := block.GenesisCodec.Marshal(block.Version, deposit1) + depositBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, deposit1) require.NoError(t, err) testError := errors.New("test error") @@ -608,9 +608,9 @@ func TestWriteDeposits(t *testing.T) { }, } depositEndtime := deposit2.EndTime() - deposit1Bytes, err := block.GenesisCodec.Marshal(block.Version, deposit1) + deposit1Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, deposit1) require.NoError(t, err) - deposit2Bytes, err := block.GenesisCodec.Marshal(block.Version, deposit2) + deposit2Bytes, err := block.GenesisCodec.Marshal(block.CodecVersion, deposit2) require.NoError(t, err) tests := map[string]struct { diff --git a/vms/platformvm/state/camino_helpers_test.go b/vms/platformvm/state/camino_helpers_test.go index 44f53090de01..70f73085bf3c 100644 --- a/vms/platformvm/state/camino_helpers_test.go +++ b/vms/platformvm/state/camino_helpers_test.go @@ -57,7 +57,9 @@ func newEmptyState(t *testing.T) *state { newState, err := newState( memdb.New(), metrics.Noop, - validators.NewManager(), + &config.Config{ + Validators: validators.NewManager(), + }, execCfg, &snow.Context{}, prometheus.NewRegistry(), diff --git a/vms/platformvm/state/camino_multisig_alias.go b/vms/platformvm/state/camino_multisig_alias.go index 306290a7b485..9db5601d22b3 100644 --- a/vms/platformvm/state/camino_multisig_alias.go +++ b/vms/platformvm/state/camino_multisig_alias.go @@ -78,7 +78,7 @@ func (cs *caminoState) writeMultisigAliases() error { Owners: alias.Owners, Nonce: alias.Nonce, } - aliasBytes, err := block.GenesisCodec.Marshal(block.Version, multisigAlias) + aliasBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, multisigAlias) if err != nil { return fmt.Errorf("failed to serialize multisig alias: %w", err) } diff --git a/vms/platformvm/state/camino_multisig_alias_test.go b/vms/platformvm/state/camino_multisig_alias_test.go index f5a50ed92772..59bdac116a88 100644 --- a/vms/platformvm/state/camino_multisig_alias_test.go +++ b/vms/platformvm/state/camino_multisig_alias_test.go @@ -26,7 +26,7 @@ func TestGetMultisigAlias(t *testing.T) { Memo: []byte("multisigAlias memo"), }, } - multisigAliasBytes, err := block.GenesisCodec.Marshal(block.Version, &msigAlias{ + multisigAliasBytes, err := block.GenesisCodec.Marshal(block.CodecVersion, &msigAlias{ Owners: multisigAlias.Owners, Memo: multisigAlias.Memo, }) @@ -232,7 +232,7 @@ func TestSetMultisigAlias(t *testing.T) { func TestWriteMultisigAliases(t *testing.T) { multisigAlias1 := &multisig.AliasWithNonce{Alias: multisig.Alias{ID: ids.ShortID{1}, Owners: &secp256k1fx.OutputOwners{}}} multisigAlias2 := &multisig.AliasWithNonce{Alias: multisig.Alias{ID: ids.ShortID{2}, Owners: &secp256k1fx.OutputOwners{}}} - multisigAliasBytes1, err := block.GenesisCodec.Marshal(block.Version, &msigAlias{Owners: multisigAlias1.Owners}) + multisigAliasBytes1, err := block.GenesisCodec.Marshal(block.CodecVersion, &msigAlias{Owners: multisigAlias1.Owners}) require.NoError(t, err) testError := errors.New("test error") diff --git a/vms/platformvm/state/camino_proposal.go b/vms/platformvm/state/camino_proposal.go index 42525fbdb6d7..63dd6c6ba8b7 100644 --- a/vms/platformvm/state/camino_proposal.go +++ b/vms/platformvm/state/camino_proposal.go @@ -198,7 +198,7 @@ func (cs *caminoState) writeProposals() error { return err } } else { - proposalBytes, err := dac.Codec.Marshal(block.Version, &proposalStateWrapper{ProposalState: proposalDiff.Proposal}) + proposalBytes, err := dac.Codec.Marshal(block.CodecVersion, &proposalStateWrapper{ProposalState: proposalDiff.Proposal}) if err != nil { return fmt.Errorf("failed to serialize deposit: %w", err) } diff --git a/vms/platformvm/state/camino_proposal_test.go b/vms/platformvm/state/camino_proposal_test.go index c06742275673..18f04977bd7f 100644 --- a/vms/platformvm/state/camino_proposal_test.go +++ b/vms/platformvm/state/camino_proposal_test.go @@ -33,7 +33,7 @@ func TestGetProposal(t *testing.T) { TotalAllowedVoters: 5, }, } - proposalBytes, err := dac.Codec.Marshal(block.Version, wrapper) + proposalBytes, err := dac.Codec.Marshal(block.CodecVersion, wrapper) require.NoError(t, err) testError := errors.New("test error") @@ -845,9 +845,9 @@ func TestWriteProposals(t *testing.T) { }} proposalEndtime := proposalWrapper2.EndTime() - proposal1Bytes, err := dac.Codec.Marshal(block.Version, proposalWrapper1) + proposal1Bytes, err := dac.Codec.Marshal(block.CodecVersion, proposalWrapper1) require.NoError(t, err) - proposal2Bytes, err := dac.Codec.Marshal(block.Version, proposalWrapper2) + proposal2Bytes, err := dac.Codec.Marshal(block.CodecVersion, proposalWrapper2) require.NoError(t, err) tests := map[string]struct { diff --git a/vms/platformvm/state/camino_stakers.go b/vms/platformvm/state/camino_stakers.go index 948a0b12cf88..986939609ac3 100644 --- a/vms/platformvm/state/camino_stakers.go +++ b/vms/platformvm/state/camino_stakers.go @@ -5,6 +5,7 @@ package state import ( "fmt" + "time" "github.com/ava-labs/avalanchego/database" @@ -52,7 +53,12 @@ func (cs *caminoState) loadDeferredValidators(s *state) error { return fmt.Errorf("expected tx type txs.Staker but got %T", tx.Unsigned) } - staker, err := NewCurrentStaker(txID, stakerTx, 0) + var startTime time.Time + if scheduledStakerTx, ok := tx.Unsigned.(txs.ScheduledStaker); ok { + startTime = scheduledStakerTx.StartTime() + } + + staker, err := NewCurrentStaker(txID, stakerTx, startTime, 0) if err != nil { return err } diff --git a/vms/platformvm/state/camino_test.go b/vms/platformvm/state/camino_test.go index d3ffc5089a57..dcf93969143e 100644 --- a/vms/platformvm/state/camino_test.go +++ b/vms/platformvm/state/camino_test.go @@ -163,7 +163,7 @@ func getExpectedSupply( func TestSyncGenesis(t *testing.T) { require := require.New(t) - s, _ := newInitializedState(require) + s := newInitializedState(require) db := memdb.New() validatorsDB := prefixdb.New(validatorsPrefix, db) diff --git a/vms/platformvm/state/mock_proposals_iterator.go b/vms/platformvm/state/mock_proposals_iterator.go index 99120f95922c..ad4e61131311 100644 --- a/vms/platformvm/state/mock_proposals_iterator.go +++ b/vms/platformvm/state/mock_proposals_iterator.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: ProposalsIterator) +// +// Generated by this command: +// +// mockgen -package=state -destination=vms/platformvm/state/mock_proposals_iterator.go github.com/ava-labs/avalanchego/vms/platformvm/state ProposalsIterator +// // Package state is a generated GoMock package. package state diff --git a/vms/platformvm/state/mock_state.go b/vms/platformvm/state/mock_state.go index 70a6952d8048..ae2482892b33 100644 --- a/vms/platformvm/state/mock_state.go +++ b/vms/platformvm/state/mock_state.go @@ -1,9 +1,9 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/avalanchego/vms/platformvm/state (interfaces: Chain,Diff,State,Versions) +// Source: vms/platformvm/state/state.go // // Generated by this command: // -// mockgen -package=state -destination=vms/platformvm/state/mock_state.go github.com/ava-labs/avalanchego/vms/platformvm/state Chain,Diff,State,Versions +// mockgen -source=vms/platformvm/state/state.go -destination=vms/platformvm/state/mock_state.go -package=state -exclude_interfaces= // // Package state is a generated GoMock package. @@ -57,1499 +57,1594 @@ func (m *MockChain) EXPECT() *MockChainMockRecorder { } // AddChain mocks base method. -func (m *MockChain) AddChain(arg0 *txs.Tx) { +func (m *MockChain) AddChain(createChainTx *txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0) + m.ctrl.Call(m, "AddChain", createChainTx) } // AddChain indicates an expected call of AddChain. -func (mr *MockChainMockRecorder) AddChain(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) AddChain(createChainTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockChain)(nil).AddChain), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockChain)(nil).AddChain), createChainTx) +} + +// AddDeposit mocks base method. +func (m *MockChain) AddDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddDeposit", depositTxID, deposit) +} + +// AddDeposit indicates an expected call of AddDeposit. +func (mr *MockChainMockRecorder) AddDeposit(depositTxID, deposit any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockChain)(nil).AddDeposit), depositTxID, deposit) +} + +// AddProposal mocks base method. +func (m *MockChain) AddProposal(proposalID ids.ID, proposal dac.ProposalState) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddProposal", proposalID, proposal) +} + +// AddProposal indicates an expected call of AddProposal. +func (mr *MockChainMockRecorder) AddProposal(proposalID, proposal any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockChain)(nil).AddProposal), proposalID, proposal) +} + +// AddProposalIDToFinish mocks base method. +func (m *MockChain) AddProposalIDToFinish(proposalID ids.ID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddProposalIDToFinish", proposalID) +} + +// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. +func (mr *MockChainMockRecorder) AddProposalIDToFinish(proposalID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockChain)(nil).AddProposalIDToFinish), proposalID) } // AddRewardUTXO mocks base method. -func (m *MockChain) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { +func (m *MockChain) AddRewardUTXO(txID ids.ID, utxo *avax.UTXO) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) + m.ctrl.Call(m, "AddRewardUTXO", txID, utxo) } // AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockChainMockRecorder) AddRewardUTXO(arg0, arg1 any) *gomock.Call { +func (mr *MockChainMockRecorder) AddRewardUTXO(txID, utxo any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockChain)(nil).AddRewardUTXO), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockChain)(nil).AddRewardUTXO), txID, utxo) } // AddSubnet mocks base method. -func (m *MockChain) AddSubnet(arg0 *txs.Tx) { +func (m *MockChain) AddSubnet(createSubnetTx *txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnet", arg0) + m.ctrl.Call(m, "AddSubnet", createSubnetTx) } // AddSubnet indicates an expected call of AddSubnet. -func (mr *MockChainMockRecorder) AddSubnet(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) AddSubnet(createSubnetTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockChain)(nil).AddSubnet), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockChain)(nil).AddSubnet), createSubnetTx) } // AddSubnetTransformation mocks base method. -func (m *MockChain) AddSubnetTransformation(arg0 *txs.Tx) { +func (m *MockChain) AddSubnetTransformation(transformSubnetTx *txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnetTransformation", arg0) + m.ctrl.Call(m, "AddSubnetTransformation", transformSubnetTx) } // AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockChainMockRecorder) AddSubnetTransformation(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) AddSubnetTransformation(transformSubnetTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockChain)(nil).AddSubnetTransformation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockChain)(nil).AddSubnetTransformation), transformSubnetTx) } // AddTx mocks base method. -func (m *MockChain) AddTx(arg0 *txs.Tx, arg1 status.Status) { +func (m *MockChain) AddTx(tx *txs.Tx, status status.Status) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddTx", arg0, arg1) + m.ctrl.Call(m, "AddTx", tx, status) } // AddTx indicates an expected call of AddTx. -func (mr *MockChainMockRecorder) AddTx(arg0, arg1 any) *gomock.Call { +func (mr *MockChainMockRecorder) AddTx(tx, status any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockChain)(nil).AddTx), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockChain)(nil).AddTx), tx, status) } // AddUTXO mocks base method. -func (m *MockChain) AddUTXO(arg0 *avax.UTXO) { +func (m *MockChain) AddUTXO(utxo *avax.UTXO) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddUTXO", arg0) + m.ctrl.Call(m, "AddUTXO", utxo) } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockChainMockRecorder) AddUTXO(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) AddUTXO(utxo any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockChain)(nil).AddUTXO), utxo) +} + +// CaminoConfig mocks base method. +func (m *MockChain) CaminoConfig() (*CaminoConfig, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CaminoConfig") + ret0, _ := ret[0].(*CaminoConfig) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CaminoConfig indicates an expected call of CaminoConfig. +func (mr *MockChainMockRecorder) CaminoConfig() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockChain)(nil).AddUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockChain)(nil).CaminoConfig)) } // DeleteCurrentDelegator mocks base method. -func (m *MockChain) DeleteCurrentDelegator(arg0 *Staker) { +func (m *MockChain) DeleteCurrentDelegator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) + m.ctrl.Call(m, "DeleteCurrentDelegator", staker) } // DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockChainMockRecorder) DeleteCurrentDelegator(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) DeleteCurrentDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentDelegator), staker) } // DeleteCurrentValidator mocks base method. -func (m *MockChain) DeleteCurrentValidator(arg0 *Staker) { +func (m *MockChain) DeleteCurrentValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentValidator", arg0) + m.ctrl.Call(m, "DeleteCurrentValidator", staker) } // DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockChainMockRecorder) DeleteCurrentValidator(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) DeleteCurrentValidator(staker any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentValidator), staker) +} + +// DeleteDeferredValidator mocks base method. +func (m *MockChain) DeleteDeferredValidator(staker *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "DeleteDeferredValidator", staker) +} + +// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. +func (mr *MockChainMockRecorder) DeleteDeferredValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockChain)(nil).DeleteCurrentValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockChain)(nil).DeleteDeferredValidator), staker) } // DeletePendingDelegator mocks base method. -func (m *MockChain) DeletePendingDelegator(arg0 *Staker) { +func (m *MockChain) DeletePendingDelegator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingDelegator", arg0) + m.ctrl.Call(m, "DeletePendingDelegator", staker) } // DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockChainMockRecorder) DeletePendingDelegator(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) DeletePendingDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockChain)(nil).DeletePendingDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockChain)(nil).DeletePendingDelegator), staker) } // DeletePendingValidator mocks base method. -func (m *MockChain) DeletePendingValidator(arg0 *Staker) { +func (m *MockChain) DeletePendingValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingValidator", arg0) + m.ctrl.Call(m, "DeletePendingValidator", staker) } // DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockChainMockRecorder) DeletePendingValidator(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) DeletePendingValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockChain)(nil).DeletePendingValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockChain)(nil).DeletePendingValidator), staker) } // DeleteUTXO mocks base method. -func (m *MockChain) DeleteUTXO(arg0 ids.ID) { +func (m *MockChain) DeleteUTXO(utxoID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteUTXO", arg0) + m.ctrl.Call(m, "DeleteUTXO", utxoID) } // DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockChainMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { +func (mr *MockChainMockRecorder) DeleteUTXO(utxoID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockChain)(nil).DeleteUTXO), utxoID) } -// SetDepositOffer mocks base method. -func (m *MockChain) SetDepositOffer(arg0 *deposit.Offer) { +// GetAddressStates mocks base method. +func (m *MockChain) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetDepositOffer", arg0) + ret := m.ctrl.Call(m, "GetAddressStates", arg0) + ret0, _ := ret[0].(addrstate.AddressState) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetDepositOffer indicates an expected call of SetDepositOffer. -func (mr *MockChainMockRecorder) SetDepositOffer(arg0 interface{}) *gomock.Call { +// GetAddressStates indicates an expected call of GetAddressStates. +func (mr *MockChainMockRecorder) GetAddressStates(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockChain)(nil).SetDepositOffer), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockChain)(nil).GetAddressStates), arg0) } -// DeleteDeferredValidator mocks base method. -func (m *MockChain) DeleteDeferredValidator(arg0 *Staker) { +// GetAllDepositOffers mocks base method. +func (m *MockChain) GetAllDepositOffers() ([]*deposit.Offer, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteDeferredValidator", arg0) + ret := m.ctrl.Call(m, "GetAllDepositOffers") + ret0, _ := ret[0].([]*deposit.Offer) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. -func (mr *MockChainMockRecorder) DeleteDeferredValidator(arg0 interface{}) *gomock.Call { +// GetAllDepositOffers indicates an expected call of GetAllDepositOffers. +func (mr *MockChainMockRecorder) GetAllDepositOffers() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockChain)(nil).DeleteDeferredValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockChain)(nil).GetAllDepositOffers)) } -// PutDeferredValidator mocks base method. -func (m *MockChain) PutDeferredValidator(arg0 *Staker) { +// GetBaseFee mocks base method. +func (m *MockChain) GetBaseFee() (uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutDeferredValidator", arg0) + ret := m.ctrl.Call(m, "GetBaseFee") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// PutDeferredValidator indicates an expected call of PutDeferredValidator. -func (mr *MockChainMockRecorder) PutDeferredValidator(arg0 interface{}) *gomock.Call { +// GetBaseFee indicates an expected call of GetBaseFee. +func (mr *MockChainMockRecorder) GetBaseFee() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockChain)(nil).PutDeferredValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockChain)(nil).GetBaseFee)) } -// LockedUTXOs mocks base method. -func (m *MockChain) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { +// GetClaimable mocks base method. +func (m *MockChain) GetClaimable(ownerID ids.ID) (*Claimable, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) - ret0, _ := ret[0].([]*avax.UTXO) + ret := m.ctrl.Call(m, "GetClaimable", ownerID) + ret0, _ := ret[0].(*Claimable) ret1, _ := ret[1].(error) return ret0, ret1 } -// LockedUTXOs indicates an expected call of LockedUTXOs. -func (mr *MockChainMockRecorder) LockedUTXOs(arg0, arg1, arg2 interface{}) *gomock.Call { +// GetClaimable indicates an expected call of GetClaimable. +func (mr *MockChainMockRecorder) GetClaimable(ownerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockChain)(nil).LockedUTXOs), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockChain)(nil).GetClaimable), ownerID) } -// SetAddressStates mocks base method. -func (m *MockChain) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { +// GetCurrentDelegatorIterator mocks base method. +func (m *MockChain) GetCurrentDelegatorIterator(subnetID ids.ID, nodeID ids.NodeID) (StakerIterator, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetAddressStates", arg0, arg1) + ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", subnetID, nodeID) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetAddressStates indicates an expected call of SetAddressStates. -func (mr *MockChainMockRecorder) SetAddressStates(arg0, arg1 interface{}) *gomock.Call { +// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. +func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockChain)(nil).SetAddressStates), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), subnetID, nodeID) } -// SetClaimable mocks base method. -func (m *MockChain) SetClaimable(arg0 ids.ID, arg1 *Claimable) { +// GetCurrentStakerIterator mocks base method. +func (m *MockChain) GetCurrentStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetClaimable", arg0, arg1) + ret := m.ctrl.Call(m, "GetCurrentStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetClaimable indicates an expected call of SetClaimable. -func (mr *MockChainMockRecorder) SetClaimable(arg0, arg1 interface{}) *gomock.Call { +// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. +func (mr *MockChainMockRecorder) GetCurrentStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockChain)(nil).SetClaimable), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentStakerIterator)) } -// AddProposal mocks base method. -func (m *MockChain) AddProposal(arg0 ids.ID, arg1 dac.ProposalState) { +// GetCurrentSupply mocks base method. +func (m *MockChain) GetCurrentSupply(subnetID ids.ID) (uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposal", arg0, arg1) + ret := m.ctrl.Call(m, "GetCurrentSupply", subnetID) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddProposal indicates an expected call of AddProposal. -func (mr *MockChainMockRecorder) AddProposal(arg0, arg1 interface{}) *gomock.Call { +// GetCurrentSupply indicates an expected call of GetCurrentSupply. +func (mr *MockChainMockRecorder) GetCurrentSupply(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockChain)(nil).AddProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockChain)(nil).GetCurrentSupply), subnetID) } -// ModifyProposal mocks base method. -func (m *MockChain) ModifyProposal(arg0 ids.ID, arg1 dac.ProposalState) { +// GetCurrentValidator mocks base method. +func (m *MockChain) GetCurrentValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyProposal", arg0, arg1) + ret := m.ctrl.Call(m, "GetCurrentValidator", subnetID, nodeID) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// ModifyProposal indicates an expected call of ModifyProposal. -func (mr *MockChainMockRecorder) ModifyProposal(arg0, arg1 interface{}) *gomock.Call { +// GetCurrentValidator indicates an expected call of GetCurrentValidator. +func (mr *MockChainMockRecorder) GetCurrentValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockChain)(nil).ModifyProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockChain)(nil).GetCurrentValidator), subnetID, nodeID) } -// RemoveProposal mocks base method. -func (m *MockChain) RemoveProposal(arg0 ids.ID, arg1 dac.ProposalState) { +// GetDeferredStakerIterator mocks base method. +func (m *MockChain) GetDeferredStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposal", arg0, arg1) + ret := m.ctrl.Call(m, "GetDeferredStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// RemoveProposal indicates an expected call of RemoveProposal. -func (mr *MockChainMockRecorder) RemoveProposal(arg0, arg1 interface{}) *gomock.Call { +// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. +func (mr *MockChainMockRecorder) GetDeferredStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockChain)(nil).RemoveProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockChain)(nil).GetDeferredStakerIterator)) } -// AddProposalIDToFinish mocks base method. -func (m *MockChain) AddProposalIDToFinish(arg0 ids.ID) { +// GetDeferredValidator mocks base method. +func (m *MockChain) GetDeferredValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposalIDToFinish", arg0) + ret := m.ctrl.Call(m, "GetDeferredValidator", subnetID, nodeID) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. -func (mr *MockChainMockRecorder) AddProposalIDToFinish(arg0 interface{}) *gomock.Call { +// GetDeferredValidator indicates an expected call of GetDeferredValidator. +func (mr *MockChainMockRecorder) GetDeferredValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockChain)(nil).AddProposalIDToFinish), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockChain)(nil).GetDeferredValidator), subnetID, nodeID) } -// RemoveProposalIDToFinish mocks base method. -func (m *MockChain) RemoveProposalIDToFinish(arg0 ids.ID) { +// GetDelegateeReward mocks base method. +func (m *MockChain) GetDelegateeReward(subnetID ids.ID, nodeID ids.NodeID) (uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) + ret := m.ctrl.Call(m, "GetDelegateeReward", subnetID, nodeID) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. -func (mr *MockChainMockRecorder) RemoveProposalIDToFinish(arg0 interface{}) *gomock.Call { +// GetDelegateeReward indicates an expected call of GetDelegateeReward. +func (mr *MockChainMockRecorder) GetDelegateeReward(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockChain)(nil).RemoveProposalIDToFinish), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockChain)(nil).GetDelegateeReward), subnetID, nodeID) } -// SetLastRewardImportTimestamp mocks base method. -func (m *MockChain) SetLastRewardImportTimestamp(arg0 uint64) { +// GetDeposit mocks base method. +func (m *MockChain) GetDeposit(depositTxID ids.ID) (*deposit.Deposit, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetLastRewardImportTimestamp", arg0) + ret := m.ctrl.Call(m, "GetDeposit", depositTxID) + ret0, _ := ret[0].(*deposit.Deposit) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetLastRewardImportTimestamp indicates an expected call of SetLastRewardImportTimestamp. -func (mr *MockChainMockRecorder) SetLastRewardImportTimestamp(arg0 interface{}) *gomock.Call { +// GetDeposit indicates an expected call of GetDeposit. +func (mr *MockChainMockRecorder) GetDeposit(depositTxID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastRewardImportTimestamp", reflect.TypeOf((*MockChain)(nil).SetLastRewardImportTimestamp), - arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockChain)(nil).GetDeposit), depositTxID) } -// AddDeposit mocks base method. -func (m *MockChain) AddDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { +// GetDepositOffer mocks base method. +func (m *MockChain) GetDepositOffer(offerID ids.ID) (*deposit.Offer, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddDeposit", arg0, arg1) + ret := m.ctrl.Call(m, "GetDepositOffer", offerID) + ret0, _ := ret[0].(*deposit.Offer) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddDeposit indicates an expected call of AddDeposit. -func (mr *MockChainMockRecorder) AddDeposit(arg0, arg1 interface{}) *gomock.Call { +// GetDepositOffer indicates an expected call of GetDepositOffer. +func (mr *MockChainMockRecorder) GetDepositOffer(offerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockChain)(nil).AddDeposit), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockChain)(nil).GetDepositOffer), offerID) } -// ModifyDeposit mocks base method. -func (m *MockChain) ModifyDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { +// GetFeeDistribution mocks base method. +func (m *MockChain) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyDeposit", arg0, arg1) + ret := m.ctrl.Call(m, "GetFeeDistribution") + ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// ModifyDeposit indicates an expected call of ModifyDeposit. -func (mr *MockChainMockRecorder) ModifyDeposit(arg0, arg1 interface{}) *gomock.Call { +// GetFeeDistribution indicates an expected call of GetFeeDistribution. +func (mr *MockChainMockRecorder) GetFeeDistribution() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockChain)(nil).ModifyDeposit), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockChain)(nil).GetFeeDistribution)) } -// RemoveDeposit mocks base method. -func (m *MockChain) RemoveDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { +// GetMultisigAlias mocks base method. +func (m *MockChain) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveDeposit", arg0, arg1) + ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) + ret0, _ := ret[0].(*multisig.AliasWithNonce) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// RemoveDeposit indicates an expected call of RemoveDeposit. -func (mr *MockChainMockRecorder) RemoveDeposit(arg0, arg1 interface{}) *gomock.Call { +// GetMultisigAlias indicates an expected call of GetMultisigAlias. +func (mr *MockChainMockRecorder) GetMultisigAlias(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockChain)(nil).RemoveDeposit), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockChain)(nil).GetMultisigAlias), arg0) } -// SetMultisigAlias mocks base method. -func (m *MockChain) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { +// GetNextProposalExpirationTime mocks base method. +func (m *MockChain) GetNextProposalExpirationTime(removedProposalIDs set.Set[ids.ID]) (time.Time, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) + ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", removedProposalIDs) + ret0, _ := ret[0].(time.Time) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetMultisigAlias indicates an expected call of SetMultisigAlias. -func (mr *MockChainMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { +// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. +func (mr *MockChainMockRecorder) GetNextProposalExpirationTime(removedProposalIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockChain)(nil).SetMultisigAlias), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockChain)(nil).GetNextProposalExpirationTime), removedProposalIDs) } -// SetNotDistributedValidatorReward mocks base method. -func (m *MockChain) SetNotDistributedValidatorReward(arg0 uint64) { +// GetNextToExpireProposalIDsAndTime mocks base method. +func (m *MockChain) GetNextToExpireProposalIDsAndTime(removedProposalIDs set.Set[ids.ID]) ([]ids.ID, time.Time, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetNotDistributedValidatorReward", arg0) + ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", removedProposalIDs) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. -func (mr *MockChainMockRecorder) SetNotDistributedValidatorReward(arg0 interface{}) *gomock.Call { +// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. +func (mr *MockChainMockRecorder) GetNextToExpireProposalIDsAndTime(removedProposalIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockChain)(nil).SetNotDistributedValidatorReward), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockChain)(nil).GetNextToExpireProposalIDsAndTime), removedProposalIDs) } -// SetShortIDLink mocks base method. -func (m *MockChain) SetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey, arg2 *ids.ShortID) { +// GetNextToUnlockDepositIDsAndTime mocks base method. +func (m *MockChain) GetNextToUnlockDepositIDsAndTime(removedDepositIDs set.Set[ids.ID]) ([]ids.ID, time.Time, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetShortIDLink", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", removedDepositIDs) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// SetShortIDLink indicates an expected call of SetShortIDLink. -func (mr *MockChainMockRecorder) SetShortIDLink(arg0, arg1, arg2 interface{}) *gomock.Call { +// GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. +func (mr *MockChainMockRecorder) GetNextToUnlockDepositIDsAndTime(removedDepositIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockChain)(nil).SetShortIDLink), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockChain)(nil).GetNextToUnlockDepositIDsAndTime), removedDepositIDs) } -// SetBaseFee mocks base method. -func (m *MockChain) SetBaseFee(arg0 uint64) { +// GetNextToUnlockDepositTime mocks base method. +func (m *MockChain) GetNextToUnlockDepositTime(removedDepositIDs set.Set[ids.ID]) (time.Time, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetBaseFee", arg0) + ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", removedDepositIDs) + ret0, _ := ret[0].(time.Time) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetBaseFee indicates an expected call of SetBaseFee. -func (mr *MockChainMockRecorder) SetBaseFee(arg0 interface{}) *gomock.Call { +// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. +func (mr *MockChainMockRecorder) GetNextToUnlockDepositTime(removedDepositIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockChain)(nil).SetBaseFee), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockChain)(nil).GetNextToUnlockDepositTime), removedDepositIDs) } -// SetFeeDistribution mocks base method. -func (m *MockChain) SetFeeDistribution(arg0 [dac.FeeDistributionFractionsCount]uint64) { +// GetNotDistributedValidatorReward mocks base method. +func (m *MockChain) GetNotDistributedValidatorReward() (uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetFeeDistribution", arg0) + ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetFeeDistribution indicates an expected call of SetFeeDistribution. -func (mr *MockChainMockRecorder) SetFeeDistribution(arg0 interface{}) *gomock.Call { +// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. +func (mr *MockChainMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockChain)(nil).SetFeeDistribution), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockChain)(nil).GetNotDistributedValidatorReward)) } -// GetShortIDLink mocks base method. -func (m *MockChain) GetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey) (ids.ShortID, error) { +// GetPendingDelegatorIterator mocks base method. +func (m *MockChain) GetPendingDelegatorIterator(subnetID ids.ID, nodeID ids.NodeID) (StakerIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetShortIDLink", arg0, arg1) - ret0, _ := ret[0].(ids.ShortID) + ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", subnetID, nodeID) + ret0, _ := ret[0].(StakerIterator) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetShortIDLink indicates an expected call of GetShortIDLink. -func (mr *MockChainMockRecorder) GetShortIDLink(arg0, arg1 interface{}) *gomock.Call { +// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. +func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockChain)(nil).GetShortIDLink), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetPendingDelegatorIterator), subnetID, nodeID) } -// CaminoConfig mocks base method. -func (m *MockChain) CaminoConfig() (*CaminoConfig, error) { +// GetPendingStakerIterator mocks base method. +func (m *MockChain) GetPendingStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CaminoConfig") - ret0, _ := ret[0].(*CaminoConfig) + ret := m.ctrl.Call(m, "GetPendingStakerIterator") + ret0, _ := ret[0].(StakerIterator) ret1, _ := ret[1].(error) return ret0, ret1 } -// CaminoConfig indicates an expected call of CaminoConfig. -func (mr *MockChainMockRecorder) CaminoConfig() *gomock.Call { +// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. +func (mr *MockChainMockRecorder) GetPendingStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockChain)(nil).CaminoConfig)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockChain)(nil).GetPendingStakerIterator)) } -// GetAddressStates mocks base method. -func (m *MockChain) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { +// GetPendingValidator mocks base method. +func (m *MockChain) GetPendingValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAddressStates", arg0) - ret0, _ := ret[0].(addrstate.AddressState) + ret := m.ctrl.Call(m, "GetPendingValidator", subnetID, nodeID) + ret0, _ := ret[0].(*Staker) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetAddressStates indicates an expected call of GetAddressStates. -func (mr *MockChainMockRecorder) GetAddressStates(arg0 interface{}) *gomock.Call { +// GetPendingValidator indicates an expected call of GetPendingValidator. +func (mr *MockChainMockRecorder) GetPendingValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockChain)(nil).GetAddressStates), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), subnetID, nodeID) } -// GetAllDepositOffers mocks base method. -func (m *MockChain) GetAllDepositOffers() ([]*deposit.Offer, error) { +// GetProposal mocks base method. +func (m *MockChain) GetProposal(proposalID ids.ID) (dac.ProposalState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAllDepositOffers") - ret0, _ := ret[0].([]*deposit.Offer) + ret := m.ctrl.Call(m, "GetProposal", proposalID) + ret0, _ := ret[0].(dac.ProposalState) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetAllDepositOffers indicates an expected call of GetAllDepositOffers. -func (mr *MockChainMockRecorder) GetAllDepositOffers() *gomock.Call { +// GetProposal indicates an expected call of GetProposal. +func (mr *MockChainMockRecorder) GetProposal(proposalID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockChain)(nil).GetAllDepositOffers)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockChain)(nil).GetProposal), proposalID) } -// GetClaimable mocks base method. -func (m *MockChain) GetClaimable(arg0 ids.ID) (*Claimable, error) { +// GetProposalIDsToFinish mocks base method. +func (m *MockChain) GetProposalIDsToFinish() ([]ids.ID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetClaimable", arg0) - ret0, _ := ret[0].(*Claimable) + ret := m.ctrl.Call(m, "GetProposalIDsToFinish") + ret0, _ := ret[0].([]ids.ID) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetClaimable indicates an expected call of GetClaimable. -func (mr *MockChainMockRecorder) GetClaimable(arg0 interface{}) *gomock.Call { +// GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. +func (mr *MockChainMockRecorder) GetProposalIDsToFinish() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockChain)(nil).GetClaimable), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockChain)(nil).GetProposalIDsToFinish)) } -// GetProposal mocks base method. -func (m *MockChain) GetProposal(arg0 ids.ID) (dac.ProposalState, error) { +// GetProposalIterator mocks base method. +func (m *MockChain) GetProposalIterator() (ProposalsIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposal", arg0) - ret0, _ := ret[0].(dac.ProposalState) + ret := m.ctrl.Call(m, "GetProposalIterator") + ret0, _ := ret[0].(ProposalsIterator) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetProposal indicates an expected call of GetProposal. -func (mr *MockChainMockRecorder) GetProposal(arg0 interface{}) *gomock.Call { +// GetProposalIterator indicates an expected call of GetProposalIterator. +func (mr *MockChainMockRecorder) GetProposalIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockChain)(nil).GetProposal), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockChain)(nil).GetProposalIterator)) } -// GetBaseFee mocks base method. -func (m *MockChain) GetBaseFee() (uint64, error) { +// GetShortIDLink mocks base method. +func (m *MockChain) GetShortIDLink(id ids.ShortID, key ShortLinkKey) (ids.ShortID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBaseFee") - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "GetShortIDLink", id, key) + ret0, _ := ret[0].(ids.ShortID) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetBaseFee indicates an expected call of GetBaseFee. -func (mr *MockChainMockRecorder) GetBaseFee() *gomock.Call { +// GetShortIDLink indicates an expected call of GetShortIDLink. +func (mr *MockChainMockRecorder) GetShortIDLink(id, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockChain)(nil).GetBaseFee)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockChain)(nil).GetShortIDLink), id, key) } -// GetFeeDistribution mocks base method. -func (m *MockChain) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { +// GetSubnetOwner mocks base method. +func (m *MockChain) GetSubnetOwner(subnetID ids.ID) (fx.Owner, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetFeeDistribution") - ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) + ret := m.ctrl.Call(m, "GetSubnetOwner", subnetID) + ret0, _ := ret[0].(fx.Owner) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetFeeDistribution indicates an expected call of GetFeeDistribution. -func (mr *MockChainMockRecorder) GetFeeDistribution() *gomock.Call { +// GetSubnetOwner indicates an expected call of GetSubnetOwner. +func (mr *MockChainMockRecorder) GetSubnetOwner(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockChain)(nil).GetFeeDistribution)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockChain)(nil).GetSubnetOwner), subnetID) } -// GetDeposit mocks base method. -func (m *MockChain) GetDeposit(arg0 ids.ID) (*deposit.Deposit, error) { +// GetSubnetTransformation mocks base method. +func (m *MockChain) GetSubnetTransformation(subnetID ids.ID) (*txs.Tx, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeposit", arg0) - ret0, _ := ret[0].(*deposit.Deposit) + ret := m.ctrl.Call(m, "GetSubnetTransformation", subnetID) + ret0, _ := ret[0].(*txs.Tx) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDeposit indicates an expected call of GetDeposit. -func (mr *MockChainMockRecorder) GetDeposit(arg0 interface{}) *gomock.Call { +// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. +func (mr *MockChainMockRecorder) GetSubnetTransformation(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockChain)(nil).GetDeposit), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), subnetID) } -// GetNextToUnlockDepositTime mocks base method. -func (m *MockChain) GetNextToUnlockDepositTime(arg0 set.Set[ids.ID]) (time.Time, error) { +// GetTimestamp mocks base method. +func (m *MockChain) GetTimestamp() time.Time { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", arg0) + ret := m.ctrl.Call(m, "GetTimestamp") ret0, _ := ret[0].(time.Time) - ret1, _ := ret[1].(error) - return ret0, ret1 + return ret0 } -// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. -func (mr *MockChainMockRecorder) GetNextToUnlockDepositTime(arg0 interface{}) *gomock.Call { +// GetTimestamp indicates an expected call of GetTimestamp. +func (mr *MockChainMockRecorder) GetTimestamp() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockChain)(nil).GetNextToUnlockDepositTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockChain)(nil).GetTimestamp)) } -// GetNextToUnlockDepositIDsAndTime mocks base method. -func (m *MockChain) GetNextToUnlockDepositIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { +// GetTx mocks base method. +func (m *MockChain) GetTx(txID ids.ID) (*txs.Tx, status.Status, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) + ret := m.ctrl.Call(m, "GetTx", txID) + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(status.Status) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } -// GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. -func (mr *MockChainMockRecorder) GetNextToUnlockDepositIDsAndTime(arg0 interface{}) *gomock.Call { +// GetTx indicates an expected call of GetTx. +func (mr *MockChainMockRecorder) GetTx(txID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockChain)(nil).GetNextToUnlockDepositIDsAndTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), txID) } -// GetNextProposalExpirationTime mocks base method. -func (m *MockChain) GetNextProposalExpirationTime(arg0 set.Set[ids.ID]) (time.Time, error) { +// GetUTXO mocks base method. +func (m *MockChain) GetUTXO(utxoID ids.ID) (*avax.UTXO, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", arg0) - ret0, _ := ret[0].(time.Time) + ret := m.ctrl.Call(m, "GetUTXO", utxoID) + ret0, _ := ret[0].(*avax.UTXO) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. -func (mr *MockChainMockRecorder) GetNextProposalExpirationTime(arg0 interface{}) *gomock.Call { +// GetUTXO indicates an expected call of GetUTXO. +func (mr *MockChainMockRecorder) GetUTXO(utxoID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockChain)(nil).GetNextProposalExpirationTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), utxoID) } -// GetNextToExpireProposalIDsAndTime mocks base method. -func (m *MockChain) GetNextToExpireProposalIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { +// LockedUTXOs mocks base method. +func (m *MockChain) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) + ret0, _ := ret[0].([]*avax.UTXO) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. -func (mr *MockChainMockRecorder) GetNextToExpireProposalIDsAndTime(arg0 interface{}) *gomock.Call { +// LockedUTXOs indicates an expected call of LockedUTXOs. +func (mr *MockChainMockRecorder) LockedUTXOs(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockChain)(nil).GetNextToExpireProposalIDsAndTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockChain)(nil).LockedUTXOs), arg0, arg1, arg2) } -// GetProposalIDsToFinish mocks base method. -func (m *MockChain) GetProposalIDsToFinish() ([]ids.ID, error) { +// ModifyDeposit mocks base method. +func (m *MockChain) ModifyDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposalIDsToFinish") - ret0, _ := ret[0].([]ids.ID) - ret2, _ := ret[1].(error) - return ret0, ret2 + m.ctrl.Call(m, "ModifyDeposit", depositTxID, deposit) } -// GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. -func (mr *MockChainMockRecorder) GetProposalIDsToFinish() *gomock.Call { +// ModifyDeposit indicates an expected call of ModifyDeposit. +func (mr *MockChainMockRecorder) ModifyDeposit(depositTxID, deposit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockChain)(nil).GetProposalIDsToFinish)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockChain)(nil).ModifyDeposit), depositTxID, deposit) } -// GetProposalIterator mocks base method. -func (m *MockChain) GetProposalIterator() (ProposalsIterator, error) { +// ModifyProposal mocks base method. +func (m *MockChain) ModifyProposal(proposalID ids.ID, proposal dac.ProposalState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposalIterator") - ret0, _ := ret[0].(ProposalsIterator) - ret2, _ := ret[1].(error) - return ret0, ret2 + m.ctrl.Call(m, "ModifyProposal", proposalID, proposal) } -// GetProposalIterator indicates an expected call of GetProposalIterator. -func (mr *MockChainMockRecorder) GetProposalIterator() *gomock.Call { +// ModifyProposal indicates an expected call of ModifyProposal. +func (mr *MockChainMockRecorder) ModifyProposal(proposalID, proposal any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockChain)(nil).GetProposalIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockChain)(nil).ModifyProposal), proposalID, proposal) } -// GetDepositOffer mocks base method. -func (m *MockChain) GetDepositOffer(arg0 ids.ID) (*deposit.Offer, error) { +// PutCurrentDelegator mocks base method. +func (m *MockChain) PutCurrentDelegator(staker *Staker) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDepositOffer", arg0) - ret0, _ := ret[0].(*deposit.Offer) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "PutCurrentDelegator", staker) } -// GetDepositOffer indicates an expected call of GetDepositOffer. -func (mr *MockChainMockRecorder) GetDepositOffer(arg0 interface{}) *gomock.Call { +// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. +func (mr *MockChainMockRecorder) PutCurrentDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockChain)(nil).GetDepositOffer), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockChain)(nil).PutCurrentDelegator), staker) } -// GetMultisigAlias mocks base method. -func (m *MockChain) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { +// PutCurrentValidator mocks base method. +func (m *MockChain) PutCurrentValidator(staker *Staker) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) - ret0, _ := ret[0].(*multisig.AliasWithNonce) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "PutCurrentValidator", staker) } -// GetMultisigAlias indicates an expected call of GetMultisigAlias. -func (mr *MockChainMockRecorder) GetMultisigAlias(arg0 interface{}) *gomock.Call { +// PutCurrentValidator indicates an expected call of PutCurrentValidator. +func (mr *MockChainMockRecorder) PutCurrentValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockChain)(nil).GetMultisigAlias), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockChain)(nil).PutCurrentValidator), staker) } -// GetNotDistributedValidatorReward mocks base method. -func (m *MockChain) GetNotDistributedValidatorReward() (uint64, error) { +// PutDeferredValidator mocks base method. +func (m *MockChain) PutDeferredValidator(staker *Staker) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "PutDeferredValidator", staker) } -// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. -func (mr *MockChainMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { +// PutDeferredValidator indicates an expected call of PutDeferredValidator. +func (mr *MockChainMockRecorder) PutDeferredValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockChain)(nil).GetNotDistributedValidatorReward)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockChain)(nil).PutDeferredValidator), staker) } -// GetDeferredStakerIterator mocks base method. -func (m *MockChain) GetDeferredStakerIterator() (StakerIterator, error) { +// PutPendingDelegator mocks base method. +func (m *MockChain) PutPendingDelegator(staker *Staker) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "PutPendingDelegator", staker) } -// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. -func (mr *MockChainMockRecorder) GetDeferredStakerIterator() *gomock.Call { +// PutPendingDelegator indicates an expected call of PutPendingDelegator. +func (mr *MockChainMockRecorder) PutPendingDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockChain)(nil).GetDeferredStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockChain)(nil).PutPendingDelegator), staker) } -// GetDeferredValidator mocks base method. -func (m *MockChain) GetDeferredValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// PutPendingValidator mocks base method. +func (m *MockChain) PutPendingValidator(staker *Staker) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "PutPendingValidator", staker) } -// GetDeferredValidator indicates an expected call of GetDeferredValidator. -func (mr *MockChainMockRecorder) GetDeferredValidator(arg0, arg1 interface{}) *gomock.Call { +// PutPendingValidator indicates an expected call of PutPendingValidator. +func (mr *MockChainMockRecorder) PutPendingValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockChain)(nil).GetDeferredValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), staker) } -// GetCurrentDelegatorIterator mocks base method. -func (m *MockChain) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { +// RemoveDeposit mocks base method. +func (m *MockChain) RemoveDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "RemoveDeposit", depositTxID, deposit) } -// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockChainMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *gomock.Call { +// RemoveDeposit indicates an expected call of RemoveDeposit. +func (mr *MockChainMockRecorder) RemoveDeposit(depositTxID, deposit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentDelegatorIterator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockChain)(nil).RemoveDeposit), depositTxID, deposit) } -// GetCurrentStakerIterator mocks base method. -func (m *MockChain) GetCurrentStakerIterator() (StakerIterator, error) { +// RemoveProposal mocks base method. +func (m *MockChain) RemoveProposal(proposalID ids.ID, proposal dac.ProposalState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "RemoveProposal", proposalID, proposal) } -// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. -func (mr *MockChainMockRecorder) GetCurrentStakerIterator() *gomock.Call { +// RemoveProposal indicates an expected call of RemoveProposal. +func (mr *MockChainMockRecorder) RemoveProposal(proposalID, proposal any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockChain)(nil).GetCurrentStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockChain)(nil).RemoveProposal), proposalID, proposal) } -// GetCurrentSupply mocks base method. -func (m *MockChain) GetCurrentSupply(arg0 ids.ID) (uint64, error) { +// RemoveProposalIDToFinish mocks base method. +func (m *MockChain) RemoveProposalIDToFinish(arg0 ids.ID) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) } -// GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockChainMockRecorder) GetCurrentSupply(arg0 any) *gomock.Call { +// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. +func (mr *MockChainMockRecorder) RemoveProposalIDToFinish(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockChain)(nil).GetCurrentSupply), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockChain)(nil).RemoveProposalIDToFinish), arg0) } -// GetCurrentValidator mocks base method. -func (m *MockChain) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// SetAddressStates mocks base method. +func (m *MockChain) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetAddressStates", arg0, arg1) } -// GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockChainMockRecorder) GetCurrentValidator(arg0, arg1 any) *gomock.Call { +// SetAddressStates indicates an expected call of SetAddressStates. +func (mr *MockChainMockRecorder) SetAddressStates(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockChain)(nil).GetCurrentValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockChain)(nil).SetAddressStates), arg0, arg1) } -// GetDelegateeReward mocks base method. -func (m *MockChain) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { +// SetBaseFee mocks base method. +func (m *MockChain) SetBaseFee(arg0 uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetBaseFee", arg0) } -// GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockChainMockRecorder) GetDelegateeReward(arg0, arg1 any) *gomock.Call { +// SetBaseFee indicates an expected call of SetBaseFee. +func (mr *MockChainMockRecorder) SetBaseFee(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockChain)(nil).GetDelegateeReward), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockChain)(nil).SetBaseFee), arg0) } -// GetPendingDelegatorIterator mocks base method. -func (m *MockChain) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { +// SetClaimable mocks base method. +func (m *MockChain) SetClaimable(ownerID ids.ID, claimable *Claimable) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetClaimable", ownerID, claimable) } -// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockChainMockRecorder) GetPendingDelegatorIterator(arg0, arg1 any) *gomock.Call { +// SetClaimable indicates an expected call of SetClaimable. +func (mr *MockChainMockRecorder) SetClaimable(ownerID, claimable any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockChain)(nil).GetPendingDelegatorIterator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockChain)(nil).SetClaimable), ownerID, claimable) } -// GetPendingStakerIterator mocks base method. -func (m *MockChain) GetPendingStakerIterator() (StakerIterator, error) { +// SetCurrentSupply mocks base method. +func (m *MockChain) SetCurrentSupply(subnetID ids.ID, cs uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetCurrentSupply", subnetID, cs) } -// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. -func (mr *MockChainMockRecorder) GetPendingStakerIterator() *gomock.Call { +// SetCurrentSupply indicates an expected call of SetCurrentSupply. +func (mr *MockChainMockRecorder) SetCurrentSupply(subnetID, cs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockChain)(nil).GetPendingStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockChain)(nil).SetCurrentSupply), subnetID, cs) } -// GetPendingValidator mocks base method. -func (m *MockChain) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// SetDelegateeReward mocks base method. +func (m *MockChain) SetDelegateeReward(subnetID ids.ID, nodeID ids.NodeID, amount uint64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "SetDelegateeReward", subnetID, nodeID, amount) + ret0, _ := ret[0].(error) + return ret0 } -// GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockChainMockRecorder) GetPendingValidator(arg0, arg1 any) *gomock.Call { +// SetDelegateeReward indicates an expected call of SetDelegateeReward. +func (mr *MockChainMockRecorder) SetDelegateeReward(subnetID, nodeID, amount any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockChain)(nil).GetPendingValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockChain)(nil).SetDelegateeReward), subnetID, nodeID, amount) } -// GetSubnetOwner mocks base method. -func (m *MockChain) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { +// SetDepositOffer mocks base method. +func (m *MockChain) SetDepositOffer(offer *deposit.Offer) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetDepositOffer", offer) } -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockChainMockRecorder) GetSubnetOwner(arg0 any) *gomock.Call { +// SetDepositOffer indicates an expected call of SetDepositOffer. +func (mr *MockChainMockRecorder) SetDepositOffer(offer any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockChain)(nil).GetSubnetOwner), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockChain)(nil).SetDepositOffer), offer) } -// GetSubnetTransformation mocks base method. -func (m *MockChain) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { +// SetFeeDistribution mocks base method. +func (m *MockChain) SetFeeDistribution(arg0 [3]uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetFeeDistribution", arg0) } -// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockChainMockRecorder) GetSubnetTransformation(arg0 any) *gomock.Call { +// SetFeeDistribution indicates an expected call of SetFeeDistribution. +func (mr *MockChainMockRecorder) SetFeeDistribution(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockChain)(nil).GetSubnetTransformation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockChain)(nil).SetFeeDistribution), arg0) } -// GetTimestamp mocks base method. -func (m *MockChain) GetTimestamp() time.Time { +// SetMultisigAlias mocks base method. +func (m *MockChain) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTimestamp") - ret0, _ := ret[0].(time.Time) - return ret0 + m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) } -// GetTimestamp indicates an expected call of GetTimestamp. -func (mr *MockChainMockRecorder) GetTimestamp() *gomock.Call { +// SetMultisigAlias indicates an expected call of SetMultisigAlias. +func (mr *MockChainMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockChain)(nil).GetTimestamp)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockChain)(nil).SetMultisigAlias), arg0, arg1) } -// GetTx mocks base method. -func (m *MockChain) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { +// SetNotDistributedValidatorReward mocks base method. +func (m *MockChain) SetNotDistributedValidatorReward(reward uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(status.Status) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + m.ctrl.Call(m, "SetNotDistributedValidatorReward", reward) } -// GetTx indicates an expected call of GetTx. -func (mr *MockChainMockRecorder) GetTx(arg0 any) *gomock.Call { +// SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. +func (mr *MockChainMockRecorder) SetNotDistributedValidatorReward(reward any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockChain)(nil).GetTx), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockChain)(nil).SetNotDistributedValidatorReward), reward) } -// GetUTXO mocks base method. -func (m *MockChain) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { +// SetShortIDLink mocks base method. +func (m *MockChain) SetShortIDLink(id ids.ShortID, key ShortLinkKey, link *ids.ShortID) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0) - ret0, _ := ret[0].(*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetShortIDLink", id, key, link) } -// GetUTXO indicates an expected call of GetUTXO. -func (mr *MockChainMockRecorder) GetUTXO(arg0 any) *gomock.Call { +// SetShortIDLink indicates an expected call of SetShortIDLink. +func (mr *MockChainMockRecorder) SetShortIDLink(id, key, link any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockChain)(nil).GetUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockChain)(nil).SetShortIDLink), id, key, link) } -// PutCurrentDelegator mocks base method. -func (m *MockChain) PutCurrentDelegator(arg0 *Staker) { +// SetSubnetOwner mocks base method. +func (m *MockChain) SetSubnetOwner(subnetID ids.ID, owner fx.Owner) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentDelegator", arg0) + m.ctrl.Call(m, "SetSubnetOwner", subnetID, owner) } -// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockChainMockRecorder) PutCurrentDelegator(arg0 any) *gomock.Call { +// SetSubnetOwner indicates an expected call of SetSubnetOwner. +func (mr *MockChainMockRecorder) SetSubnetOwner(subnetID, owner any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockChain)(nil).PutCurrentDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockChain)(nil).SetSubnetOwner), subnetID, owner) } -// PutCurrentValidator mocks base method. -func (m *MockChain) PutCurrentValidator(arg0 *Staker) { +// SetTimestamp mocks base method. +func (m *MockChain) SetTimestamp(tm time.Time) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentValidator", arg0) + m.ctrl.Call(m, "SetTimestamp", tm) } -// PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockChainMockRecorder) PutCurrentValidator(arg0 any) *gomock.Call { +// SetTimestamp indicates an expected call of SetTimestamp. +func (mr *MockChainMockRecorder) SetTimestamp(tm any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockChain)(nil).PutCurrentValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), tm) } -// PutPendingDelegator mocks base method. -func (m *MockChain) PutPendingDelegator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingDelegator", arg0) +// MockState is a mock of State interface. +type MockState struct { + ctrl *gomock.Controller + recorder *MockStateMockRecorder } -// PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockChainMockRecorder) PutPendingDelegator(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockChain)(nil).PutPendingDelegator), arg0) +// MockStateMockRecorder is the mock recorder for MockState. +type MockStateMockRecorder struct { + mock *MockState } -// PutPendingValidator mocks base method. -func (m *MockChain) PutPendingValidator(arg0 *Staker) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingValidator", arg0) +// NewMockState creates a new mock instance. +func NewMockState(ctrl *gomock.Controller) *MockState { + mock := &MockState{ctrl: ctrl} + mock.recorder = &MockStateMockRecorder{mock} + return mock } -// PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockChainMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockChain)(nil).PutPendingValidator), arg0) +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockState) EXPECT() *MockStateMockRecorder { + return m.recorder } -// SetCurrentSupply mocks base method. -func (m *MockChain) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { +// Abort mocks base method. +func (m *MockState) Abort() { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) + m.ctrl.Call(m, "Abort") } -// SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockChainMockRecorder) SetCurrentSupply(arg0, arg1 any) *gomock.Call { +// Abort indicates an expected call of Abort. +func (mr *MockStateMockRecorder) Abort() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockChain)(nil).SetCurrentSupply), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Abort", reflect.TypeOf((*MockState)(nil).Abort)) } -// SetDelegateeReward mocks base method. -func (m *MockChain) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { +// AddChain mocks base method. +func (m *MockState) AddChain(createChainTx *txs.Tx) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.Call(m, "AddChain", createChainTx) } -// SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockChainMockRecorder) SetDelegateeReward(arg0, arg1, arg2 any) *gomock.Call { +// AddChain indicates an expected call of AddChain. +func (mr *MockStateMockRecorder) AddChain(createChainTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockChain)(nil).SetDelegateeReward), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockState)(nil).AddChain), createChainTx) } -// SetSubnetOwner mocks base method. -func (m *MockChain) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { +// AddDeposit mocks base method. +func (m *MockState) AddDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) + m.ctrl.Call(m, "AddDeposit", depositTxID, deposit) } -// SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockChainMockRecorder) SetSubnetOwner(arg0, arg1 any) *gomock.Call { +// AddDeposit indicates an expected call of AddDeposit. +func (mr *MockStateMockRecorder) AddDeposit(depositTxID, deposit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockChain)(nil).SetSubnetOwner), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockState)(nil).AddDeposit), depositTxID, deposit) } -// SetTimestamp mocks base method. -func (m *MockChain) SetTimestamp(arg0 time.Time) { +// AddProposal mocks base method. +func (m *MockState) AddProposal(proposalID ids.ID, proposal dac.ProposalState) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetTimestamp", arg0) + m.ctrl.Call(m, "AddProposal", proposalID, proposal) } -// SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockChainMockRecorder) SetTimestamp(arg0 any) *gomock.Call { +// AddProposal indicates an expected call of AddProposal. +func (mr *MockStateMockRecorder) AddProposal(proposalID, proposal any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockChain)(nil).SetTimestamp), arg0) -} - -// MockDiff is a mock of Diff interface. -type MockDiff struct { - ctrl *gomock.Controller - recorder *MockDiffMockRecorder -} - -// MockDiffMockRecorder is the mock recorder for MockDiff. -type MockDiffMockRecorder struct { - mock *MockDiff + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockState)(nil).AddProposal), proposalID, proposal) } -// NewMockDiff creates a new mock instance. -func NewMockDiff(ctrl *gomock.Controller) *MockDiff { - mock := &MockDiff{ctrl: ctrl} - mock.recorder = &MockDiffMockRecorder{mock} - return mock +// AddProposalIDToFinish mocks base method. +func (m *MockState) AddProposalIDToFinish(proposalID ids.ID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddProposalIDToFinish", proposalID) } -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockDiff) EXPECT() *MockDiffMockRecorder { - return m.recorder +// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. +func (mr *MockStateMockRecorder) AddProposalIDToFinish(proposalID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockState)(nil).AddProposalIDToFinish), proposalID) } -// AddChain mocks base method. -func (m *MockDiff) AddChain(arg0 *txs.Tx) { +// AddRewardUTXO mocks base method. +func (m *MockState) AddRewardUTXO(txID ids.ID, utxo *avax.UTXO) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0) + m.ctrl.Call(m, "AddRewardUTXO", txID, utxo) } -// AddChain indicates an expected call of AddChain. -func (mr *MockDiffMockRecorder) AddChain(arg0 any) *gomock.Call { +// AddRewardUTXO indicates an expected call of AddRewardUTXO. +func (mr *MockStateMockRecorder) AddRewardUTXO(txID, utxo any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockDiff)(nil).AddChain), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockState)(nil).AddRewardUTXO), txID, utxo) } -// AddRewardUTXO mocks base method. -func (m *MockDiff) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { +// AddStatelessBlock mocks base method. +func (m *MockState) AddStatelessBlock(block block.Block) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) + m.ctrl.Call(m, "AddStatelessBlock", block) } -// AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockDiffMockRecorder) AddRewardUTXO(arg0, arg1 any) *gomock.Call { +// AddStatelessBlock indicates an expected call of AddStatelessBlock. +func (mr *MockStateMockRecorder) AddStatelessBlock(block any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockDiff)(nil).AddRewardUTXO), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddStatelessBlock", reflect.TypeOf((*MockState)(nil).AddStatelessBlock), block) } // AddSubnet mocks base method. -func (m *MockDiff) AddSubnet(arg0 *txs.Tx) { +func (m *MockState) AddSubnet(createSubnetTx *txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnet", arg0) + m.ctrl.Call(m, "AddSubnet", createSubnetTx) } // AddSubnet indicates an expected call of AddSubnet. -func (mr *MockDiffMockRecorder) AddSubnet(arg0 any) *gomock.Call { +func (mr *MockStateMockRecorder) AddSubnet(createSubnetTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockDiff)(nil).AddSubnet), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockState)(nil).AddSubnet), createSubnetTx) } // AddSubnetTransformation mocks base method. -func (m *MockDiff) AddSubnetTransformation(arg0 *txs.Tx) { +func (m *MockState) AddSubnetTransformation(transformSubnetTx *txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnetTransformation", arg0) + m.ctrl.Call(m, "AddSubnetTransformation", transformSubnetTx) } // AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockDiffMockRecorder) AddSubnetTransformation(arg0 any) *gomock.Call { +func (mr *MockStateMockRecorder) AddSubnetTransformation(transformSubnetTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).AddSubnetTransformation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockState)(nil).AddSubnetTransformation), transformSubnetTx) } // AddTx mocks base method. -func (m *MockDiff) AddTx(arg0 *txs.Tx, arg1 status.Status) { +func (m *MockState) AddTx(tx *txs.Tx, status status.Status) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddTx", arg0, arg1) + m.ctrl.Call(m, "AddTx", tx, status) } // AddTx indicates an expected call of AddTx. -func (mr *MockDiffMockRecorder) AddTx(arg0, arg1 any) *gomock.Call { +func (mr *MockStateMockRecorder) AddTx(tx, status any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockState)(nil).AddTx), tx, status) } // AddUTXO mocks base method. -func (m *MockDiff) AddUTXO(arg0 *avax.UTXO) { +func (m *MockState) AddUTXO(utxo *avax.UTXO) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddUTXO", arg0) + m.ctrl.Call(m, "AddUTXO", utxo) } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockDiffMockRecorder) AddUTXO(arg0 any) *gomock.Call { +func (mr *MockStateMockRecorder) AddUTXO(utxo any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockState)(nil).AddUTXO), utxo) } -// Apply mocks base method. -func (m *MockDiff) Apply(arg0 Chain) error { +// ApplyValidatorPublicKeyDiffs mocks base method. +func (m *MockState) ApplyValidatorPublicKeyDiffs(ctx context.Context, validators map[ids.NodeID]*validators.GetValidatorOutput, startHeight, endHeight uint64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Apply", arg0) + ret := m.ctrl.Call(m, "ApplyValidatorPublicKeyDiffs", ctx, validators, startHeight, endHeight) ret0, _ := ret[0].(error) return ret0 } -// Apply indicates an expected call of Apply. -func (mr *MockDiffMockRecorder) Apply(arg0 any) *gomock.Call { +// ApplyValidatorPublicKeyDiffs indicates an expected call of ApplyValidatorPublicKeyDiffs. +func (mr *MockStateMockRecorder) ApplyValidatorPublicKeyDiffs(ctx, validators, startHeight, endHeight any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyValidatorPublicKeyDiffs", reflect.TypeOf((*MockState)(nil).ApplyValidatorPublicKeyDiffs), ctx, validators, startHeight, endHeight) } -// DeleteCurrentDelegator mocks base method. -func (m *MockDiff) DeleteCurrentDelegator(arg0 *Staker) { +// ApplyValidatorWeightDiffs mocks base method. +func (m *MockState) ApplyValidatorWeightDiffs(ctx context.Context, validators map[ids.NodeID]*validators.GetValidatorOutput, startHeight, endHeight uint64, subnetID ids.ID) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) + ret := m.ctrl.Call(m, "ApplyValidatorWeightDiffs", ctx, validators, startHeight, endHeight, subnetID) + ret0, _ := ret[0].(error) + return ret0 } -// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(arg0 any) *gomock.Call { +// ApplyValidatorWeightDiffs indicates an expected call of ApplyValidatorWeightDiffs. +func (mr *MockStateMockRecorder) ApplyValidatorWeightDiffs(ctx, validators, startHeight, endHeight, subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyValidatorWeightDiffs", reflect.TypeOf((*MockState)(nil).ApplyValidatorWeightDiffs), ctx, validators, startHeight, endHeight, subnetID) } -// DeleteCurrentValidator mocks base method. -func (m *MockDiff) DeleteCurrentValidator(arg0 *Staker) { +// CaminoConfig mocks base method. +func (m *MockState) CaminoConfig() (*CaminoConfig, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentValidator", arg0) + ret := m.ctrl.Call(m, "CaminoConfig") + ret0, _ := ret[0].(*CaminoConfig) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockDiffMockRecorder) DeleteCurrentValidator(arg0 any) *gomock.Call { +// CaminoConfig indicates an expected call of CaminoConfig. +func (mr *MockStateMockRecorder) CaminoConfig() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockState)(nil).CaminoConfig)) } -// DeletePendingDelegator mocks base method. -func (m *MockDiff) DeletePendingDelegator(arg0 *Staker) { +// Checksum mocks base method. +func (m *MockState) Checksum() ids.ID { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingDelegator", arg0) + ret := m.ctrl.Call(m, "Checksum") + ret0, _ := ret[0].(ids.ID) + return ret0 } -// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockDiffMockRecorder) DeletePendingDelegator(arg0 any) *gomock.Call { +// Checksum indicates an expected call of Checksum. +func (mr *MockStateMockRecorder) Checksum() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockDiff)(nil).DeletePendingDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Checksum", reflect.TypeOf((*MockState)(nil).Checksum)) } -// DeletePendingValidator mocks base method. -func (m *MockDiff) DeletePendingValidator(arg0 *Staker) { +// Close mocks base method. +func (m *MockState) Close() error { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingValidator", arg0) + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 } -// DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockDiffMockRecorder) DeletePendingValidator(arg0 any) *gomock.Call { +// Close indicates an expected call of Close. +func (mr *MockStateMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockDiff)(nil).DeletePendingValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockState)(nil).Close)) } -// DeleteUTXO mocks base method. -func (m *MockDiff) DeleteUTXO(arg0 ids.ID) { +// Commit mocks base method. +func (m *MockState) Commit() error { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteUTXO", arg0) + ret := m.ctrl.Call(m, "Commit") + ret0, _ := ret[0].(error) + return ret0 } -// DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockDiffMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { +// Commit indicates an expected call of Commit. +func (mr *MockStateMockRecorder) Commit() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockState)(nil).Commit)) } -// SetDepositOffer mocks base method. -func (m *MockDiff) SetDepositOffer(arg0 *deposit.Offer) { +// CommitBatch mocks base method. +func (m *MockState) CommitBatch() (database.Batch, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetDepositOffer", arg0) + ret := m.ctrl.Call(m, "CommitBatch") + ret0, _ := ret[0].(database.Batch) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetDepositOffer indicates an expected call of SetDepositOffer. -func (mr *MockDiffMockRecorder) SetDepositOffer(arg0 interface{}) *gomock.Call { +// CommitBatch indicates an expected call of CommitBatch. +func (mr *MockStateMockRecorder) CommitBatch() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockDiff)(nil).SetDepositOffer), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitBatch", reflect.TypeOf((*MockState)(nil).CommitBatch)) } -// ApplyCaminoState mocks base method. -func (m *MockDiff) ApplyCaminoState(arg0 Chain) error { +// DeleteCurrentDelegator mocks base method. +func (m *MockState) DeleteCurrentDelegator(staker *Staker) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ApplyCaminoState", arg0) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.Call(m, "DeleteCurrentDelegator", staker) } -// ApplyCaminoState indicates an expected call of ApplyCaminoState. -func (mr *MockDiffMockRecorder) ApplyCaminoState(arg0 interface{}) *gomock.Call { +// DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. +func (mr *MockStateMockRecorder) DeleteCurrentDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyCaminoState", reflect.TypeOf((*MockDiff)(nil).ApplyCaminoState), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockState)(nil).DeleteCurrentDelegator), staker) } -// DeleteDeferredValidator mocks base method. -func (m *MockDiff) DeleteDeferredValidator(arg0 *Staker) { +// DeleteCurrentValidator mocks base method. +func (m *MockState) DeleteCurrentValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteDeferredValidator", arg0) + m.ctrl.Call(m, "DeleteCurrentValidator", staker) } -// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. -func (mr *MockDiffMockRecorder) DeleteDeferredValidator(arg0 interface{}) *gomock.Call { +// DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. +func (mr *MockStateMockRecorder) DeleteCurrentValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockDiff)(nil).DeleteDeferredValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockState)(nil).DeleteCurrentValidator), staker) } -// PutDeferredValidator mocks base method. -func (m *MockDiff) PutDeferredValidator(arg0 *Staker) { +// DeleteDeferredValidator mocks base method. +func (m *MockState) DeleteDeferredValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutDeferredValidator", arg0) + m.ctrl.Call(m, "DeleteDeferredValidator", staker) } -// PutDeferredValidator indicates an expected call of PutDeferredValidator. -func (mr *MockDiffMockRecorder) PutDeferredValidator(arg0 interface{}) *gomock.Call { +// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. +func (mr *MockStateMockRecorder) DeleteDeferredValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockDiff)(nil).PutDeferredValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockState)(nil).DeleteDeferredValidator), staker) } -// SetAddressStates mocks base method. -func (m *MockDiff) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { +// DeletePendingDelegator mocks base method. +func (m *MockState) DeletePendingDelegator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetAddressStates", arg0, arg1) + m.ctrl.Call(m, "DeletePendingDelegator", staker) } -// SetAddressStates indicates an expected call of SetAddressStates. -func (mr *MockDiffMockRecorder) SetAddressStates(arg0, arg1 interface{}) *gomock.Call { +// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. +func (mr *MockStateMockRecorder) DeletePendingDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockDiff)(nil).SetAddressStates), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockState)(nil).DeletePendingDelegator), staker) } -// SetClaimable mocks base method. -func (m *MockDiff) SetClaimable(arg0 ids.ID, arg1 *Claimable) { +// DeletePendingValidator mocks base method. +func (m *MockState) DeletePendingValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetClaimable", arg0, arg1) + m.ctrl.Call(m, "DeletePendingValidator", staker) } -// SetClaimable indicates an expected call of SetClaimable. -func (mr *MockDiffMockRecorder) SetClaimable(arg0, arg1 interface{}) *gomock.Call { +// DeletePendingValidator indicates an expected call of DeletePendingValidator. +func (mr *MockStateMockRecorder) DeletePendingValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockDiff)(nil).SetClaimable), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockState)(nil).DeletePendingValidator), staker) } -// SetMultisigAlias mocks base method. -func (m *MockDiff) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { +// DeleteUTXO mocks base method. +func (m *MockState) DeleteUTXO(utxoID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) + m.ctrl.Call(m, "DeleteUTXO", utxoID) } -// SetMultisigAlias indicates an expected call of SetMultisigAlias. -func (mr *MockDiffMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { +// DeleteUTXO indicates an expected call of DeleteUTXO. +func (mr *MockStateMockRecorder) DeleteUTXO(utxoID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockDiff)(nil).SetMultisigAlias), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockState)(nil).DeleteUTXO), utxoID) } -// SetNotDistributedValidatorReward mocks base method. -func (m *MockDiff) SetNotDistributedValidatorReward(arg0 uint64) { +// GetAddressStates mocks base method. +func (m *MockState) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetNotDistributedValidatorReward", arg0) + ret := m.ctrl.Call(m, "GetAddressStates", arg0) + ret0, _ := ret[0].(addrstate.AddressState) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. -func (mr *MockDiffMockRecorder) SetNotDistributedValidatorReward(arg0 interface{}) *gomock.Call { +// GetAddressStates indicates an expected call of GetAddressStates. +func (mr *MockStateMockRecorder) GetAddressStates(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockDiff)(nil).SetNotDistributedValidatorReward), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockState)(nil).GetAddressStates), arg0) } -// SetShortIDLink mocks base method. -func (m *MockDiff) SetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey, arg2 *ids.ShortID) { +// GetAllDepositOffers mocks base method. +func (m *MockState) GetAllDepositOffers() ([]*deposit.Offer, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetShortIDLink", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "GetAllDepositOffers") + ret0, _ := ret[0].([]*deposit.Offer) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetShortIDLink indicates an expected call of SetShortIDLink. -func (mr *MockDiffMockRecorder) SetShortIDLink(arg0, arg1, arg2 interface{}) *gomock.Call { +// GetAllDepositOffers indicates an expected call of GetAllDepositOffers. +func (mr *MockStateMockRecorder) GetAllDepositOffers() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockDiff)(nil).SetShortIDLink), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockState)(nil).GetAllDepositOffers)) } -// AddProposal mocks base method. -func (m *MockDiff) AddProposal(arg0 ids.ID, arg1 dac.ProposalState) { +// GetBaseFee mocks base method. +func (m *MockState) GetBaseFee() (uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposal", arg0, arg1) + ret := m.ctrl.Call(m, "GetBaseFee") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddProposal indicates an expected call of AddProposal. -func (mr *MockDiffMockRecorder) AddProposal(arg0, arg1 interface{}) *gomock.Call { +// GetBaseFee indicates an expected call of GetBaseFee. +func (mr *MockStateMockRecorder) GetBaseFee() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockDiff)(nil).AddProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockState)(nil).GetBaseFee)) } -// ModifyProposal mocks base method. -func (m *MockDiff) ModifyProposal(arg0 ids.ID, arg1 dac.ProposalState) { +// GetBlockIDAtHeight mocks base method. +func (m *MockState) GetBlockIDAtHeight(height uint64) (ids.ID, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyProposal", arg0, arg1) + ret := m.ctrl.Call(m, "GetBlockIDAtHeight", height) + ret0, _ := ret[0].(ids.ID) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// ModifyProposal indicates an expected call of ModifyProposal. -func (mr *MockDiffMockRecorder) ModifyProposal(arg0, arg1 interface{}) *gomock.Call { +// GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. +func (mr *MockStateMockRecorder) GetBlockIDAtHeight(height any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockDiff)(nil).ModifyProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockState)(nil).GetBlockIDAtHeight), height) } -// RemoveProposal mocks base method. -func (m *MockDiff) RemoveProposal(arg0 ids.ID, arg1 dac.ProposalState) { +// GetChains mocks base method. +func (m *MockState) GetChains(subnetID ids.ID) ([]*txs.Tx, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposal", arg0, arg1) + ret := m.ctrl.Call(m, "GetChains", subnetID) + ret0, _ := ret[0].([]*txs.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// RemoveProposal indicates an expected call of RemoveProposal. -func (mr *MockDiffMockRecorder) RemoveProposal(arg0, arg1 interface{}) *gomock.Call { +// GetChains indicates an expected call of GetChains. +func (mr *MockStateMockRecorder) GetChains(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockDiff)(nil).RemoveProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockState)(nil).GetChains), subnetID) } -// AddProposalIDToFinish mocks base method. -func (m *MockDiff) AddProposalIDToFinish(arg0 ids.ID) { +// GetClaimable mocks base method. +func (m *MockState) GetClaimable(ownerID ids.ID) (*Claimable, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposalIDToFinish", arg0) + ret := m.ctrl.Call(m, "GetClaimable", ownerID) + ret0, _ := ret[0].(*Claimable) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. -func (mr *MockDiffMockRecorder) AddProposalIDToFinish(arg0 interface{}) *gomock.Call { +// GetClaimable indicates an expected call of GetClaimable. +func (mr *MockStateMockRecorder) GetClaimable(ownerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockDiff)(nil).AddProposalIDToFinish), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockState)(nil).GetClaimable), ownerID) } -// RemoveProposalIDToFinish mocks base method. -func (m *MockDiff) RemoveProposalIDToFinish(arg0 ids.ID) { +// GetCurrentDelegatorIterator mocks base method. +func (m *MockState) GetCurrentDelegatorIterator(subnetID ids.ID, nodeID ids.NodeID) (StakerIterator, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) + ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", subnetID, nodeID) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. -func (mr *MockDiffMockRecorder) RemoveProposalIDToFinish(arg0 interface{}) *gomock.Call { +// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. +func (mr *MockStateMockRecorder) GetCurrentDelegatorIterator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockDiff)(nil).RemoveProposalIDToFinish), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockState)(nil).GetCurrentDelegatorIterator), subnetID, nodeID) } -// SetBaseFee mocks base method. -func (m *MockDiff) SetBaseFee(arg0 uint64) { +// GetCurrentStakerIterator mocks base method. +func (m *MockState) GetCurrentStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetBaseFee", arg0) + ret := m.ctrl.Call(m, "GetCurrentStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetBaseFee indicates an expected call of SetBaseFee. -func (mr *MockDiffMockRecorder) SetBaseFee(arg0 interface{}) *gomock.Call { +// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. +func (mr *MockStateMockRecorder) GetCurrentStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockDiff)(nil).SetBaseFee), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockState)(nil).GetCurrentStakerIterator)) } -// AddDeposit mocks base method. -func (m *MockDiff) AddDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { +// GetCurrentSupply mocks base method. +func (m *MockState) GetCurrentSupply(subnetID ids.ID) (uint64, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddDeposit", arg0, arg1) + ret := m.ctrl.Call(m, "GetCurrentSupply", subnetID) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddDeposit indicates an expected call of AddDeposit. -func (mr *MockDiffMockRecorder) AddDeposit(arg0, arg1 interface{}) *gomock.Call { +// GetCurrentSupply indicates an expected call of GetCurrentSupply. +func (mr *MockStateMockRecorder) GetCurrentSupply(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockDiff)(nil).AddDeposit), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockState)(nil).GetCurrentSupply), subnetID) } -// ModifyDeposit mocks base method. -func (m *MockDiff) ModifyDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { +// GetCurrentValidator mocks base method. +func (m *MockState) GetCurrentValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyDeposit", arg0, arg1) + ret := m.ctrl.Call(m, "GetCurrentValidator", subnetID, nodeID) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// ModifyDeposit indicates an expected call of ModifyDeposit. -func (mr *MockDiffMockRecorder) ModifyDeposit(arg0, arg1 interface{}) *gomock.Call { +// GetCurrentValidator indicates an expected call of GetCurrentValidator. +func (mr *MockStateMockRecorder) GetCurrentValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockDiff)(nil).ModifyDeposit), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockState)(nil).GetCurrentValidator), subnetID, nodeID) } -// RemoveDeposit mocks base method. -func (m *MockDiff) RemoveDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { +// GetDeferredStakerIterator mocks base method. +func (m *MockState) GetDeferredStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveDeposit", arg0, arg1) + ret := m.ctrl.Call(m, "GetDeferredStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// RemoveDeposit indicates an expected call of RemoveDeposit. -func (mr *MockDiffMockRecorder) RemoveDeposit(arg0, arg1 interface{}) *gomock.Call { +// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. +func (mr *MockStateMockRecorder) GetDeferredStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockDiff)(nil).RemoveDeposit), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockState)(nil).GetDeferredStakerIterator)) } -// SetFeeDistribution mocks base method. -func (m *MockDiff) SetFeeDistribution(arg0 [dac.FeeDistributionFractionsCount]uint64) { +// GetDeferredValidator mocks base method. +func (m *MockState) GetDeferredValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetFeeDistribution", arg0) + ret := m.ctrl.Call(m, "GetDeferredValidator", subnetID, nodeID) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetFeeDistribution indicates an expected call of SetFeeDistribution. -func (mr *MockDiffMockRecorder) SetFeeDistribution(arg0 interface{}) *gomock.Call { +// GetDeferredValidator indicates an expected call of GetDeferredValidator. +func (mr *MockStateMockRecorder) GetDeferredValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockDiff)(nil).SetFeeDistribution), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockState)(nil).GetDeferredValidator), subnetID, nodeID) } -// LockedUTXOs mocks base method. -func (m *MockDiff) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { +// GetDelegateeReward mocks base method. +func (m *MockState) GetDelegateeReward(subnetID ids.ID, nodeID ids.NodeID) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) - ret0, _ := ret[0].([]*avax.UTXO) + ret := m.ctrl.Call(m, "GetDelegateeReward", subnetID, nodeID) + ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// LockedUTXOs indicates an expected call of LockedUTXOs. -func (mr *MockDiffMockRecorder) LockedUTXOs(arg0, arg1, arg2 interface{}) *gomock.Call { +// GetDelegateeReward indicates an expected call of GetDelegateeReward. +func (mr *MockStateMockRecorder) GetDelegateeReward(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockDiff)(nil).LockedUTXOs), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockState)(nil).GetDelegateeReward), subnetID, nodeID) } -// GetShortIDLink mocks base method. -func (m *MockDiff) GetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey) (ids.ShortID, error) { +// GetDeposit mocks base method. +func (m *MockState) GetDeposit(depositTxID ids.ID) (*deposit.Deposit, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetShortIDLink", arg0, arg1) - ret0, _ := ret[0].(ids.ShortID) + ret := m.ctrl.Call(m, "GetDeposit", depositTxID) + ret0, _ := ret[0].(*deposit.Deposit) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetShortIDLink indicates an expected call of GetShortIDLink. -func (mr *MockDiffMockRecorder) GetShortIDLink(arg0, arg1 interface{}) *gomock.Call { +// GetDeposit indicates an expected call of GetDeposit. +func (mr *MockStateMockRecorder) GetDeposit(depositTxID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockDiff)(nil).GetShortIDLink), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockState)(nil).GetDeposit), depositTxID) } -// GetAddressStates mocks base method. -func (m *MockDiff) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { +// GetDepositOffer mocks base method. +func (m *MockState) GetDepositOffer(offerID ids.ID) (*deposit.Offer, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAddressStates", arg0) - ret0, _ := ret[0].(addrstate.AddressState) + ret := m.ctrl.Call(m, "GetDepositOffer", offerID) + ret0, _ := ret[0].(*deposit.Offer) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetAddressStates indicates an expected call of GetAddressStates. -func (mr *MockDiffMockRecorder) GetAddressStates(arg0 interface{}) *gomock.Call { +// GetDepositOffer indicates an expected call of GetDepositOffer. +func (mr *MockStateMockRecorder) GetDepositOffer(offerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockDiff)(nil).GetAddressStates), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockState)(nil).GetDepositOffer), offerID) } -// GetClaimable mocks base method. -func (m *MockDiff) GetClaimable(arg0 ids.ID) (*Claimable, error) { +// GetFeeDistribution mocks base method. +func (m *MockState) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetClaimable", arg0) - ret0, _ := ret[0].(*Claimable) + ret := m.ctrl.Call(m, "GetFeeDistribution") + ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetClaimable indicates an expected call of GetClaimable. -func (mr *MockDiffMockRecorder) GetClaimable(arg0 interface{}) *gomock.Call { +// GetFeeDistribution indicates an expected call of GetFeeDistribution. +func (mr *MockStateMockRecorder) GetFeeDistribution() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockDiff)(nil).GetClaimable), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockState)(nil).GetFeeDistribution)) } -// GetProposal mocks base method. -func (m *MockDiff) GetProposal(arg0 ids.ID) (dac.ProposalState, error) { +// GetLastAccepted mocks base method. +func (m *MockState) GetLastAccepted() ids.ID { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposal", arg0) - ret0, _ := ret[0].(dac.ProposalState) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "GetLastAccepted") + ret0, _ := ret[0].(ids.ID) + return ret0 } -// GetProposal indicates an expected call of GetProposal. -func (mr *MockDiffMockRecorder) GetProposal(arg0 interface{}) *gomock.Call { +// GetLastAccepted indicates an expected call of GetLastAccepted. +func (mr *MockStateMockRecorder) GetLastAccepted() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockDiff)(nil).GetProposal), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastAccepted", reflect.TypeOf((*MockState)(nil).GetLastAccepted)) } -// GetBaseFee mocks base method. -func (m *MockDiff) GetBaseFee() (uint64, error) { +// GetMultisigAlias mocks base method. +func (m *MockState) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBaseFee") - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) + ret0, _ := ret[0].(*multisig.AliasWithNonce) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetBaseFee indicates an expected call of GetBaseFee. -func (mr *MockDiffMockRecorder) GetBaseFee() *gomock.Call { +// GetMultisigAlias indicates an expected call of GetMultisigAlias. +func (mr *MockStateMockRecorder) GetMultisigAlias(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockDiff)(nil).GetBaseFee)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockState)(nil).GetMultisigAlias), arg0) } -// GetDeposit mocks base method. -func (m *MockDiff) GetDeposit(arg0 ids.ID) (*deposit.Deposit, error) { +// GetNextProposalExpirationTime mocks base method. +func (m *MockState) GetNextProposalExpirationTime(removedProposalIDs set.Set[ids.ID]) (time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeposit", arg0) - ret0, _ := ret[0].(*deposit.Deposit) + ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", removedProposalIDs) + ret0, _ := ret[0].(time.Time) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDeposit indicates an expected call of GetDeposit. -func (mr *MockDiffMockRecorder) GetDeposit(arg0 interface{}) *gomock.Call { +// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. +func (mr *MockStateMockRecorder) GetNextProposalExpirationTime(removedProposalIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockDiff)(nil).GetDeposit), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockState)(nil).GetNextProposalExpirationTime), removedProposalIDs) } -// GetNextToUnlockDepositTime mocks base method. -func (m *MockDiff) GetNextToUnlockDepositTime(arg0 set.Set[ids.ID]) (time.Time, error) { +// GetNextToExpireProposalIDsAndTime mocks base method. +func (m *MockState) GetNextToExpireProposalIDsAndTime(removedProposalIDs set.Set[ids.ID]) ([]ids.ID, time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", arg0) - ret0, _ := ret[0].(time.Time) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", removedProposalIDs) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. -func (mr *MockDiffMockRecorder) GetNextToUnlockDepositTime(arg0 interface{}) *gomock.Call { +// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. +func (mr *MockStateMockRecorder) GetNextToExpireProposalIDsAndTime(removedProposalIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockDiff)(nil).GetNextToUnlockDepositTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockState)(nil).GetNextToExpireProposalIDsAndTime), removedProposalIDs) } // GetNextToUnlockDepositIDsAndTime mocks base method. -func (m *MockDiff) GetNextToUnlockDepositIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { +func (m *MockState) GetNextToUnlockDepositIDsAndTime(removedDepositIDs set.Set[ids.ID]) ([]ids.ID, time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", arg0) + ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", removedDepositIDs) ret0, _ := ret[0].([]ids.ID) ret1, _ := ret[1].(time.Time) ret2, _ := ret[2].(error) @@ -1557,793 +1652,908 @@ func (m *MockDiff) GetNextToUnlockDepositIDsAndTime(arg0 set.Set[ids.ID]) ([]ids } // GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. -func (mr *MockDiffMockRecorder) GetNextToUnlockDepositIDsAndTime(arg0 interface{}) *gomock.Call { +func (mr *MockStateMockRecorder) GetNextToUnlockDepositIDsAndTime(removedDepositIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockDiff)(nil).GetNextToUnlockDepositIDsAndTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockState)(nil).GetNextToUnlockDepositIDsAndTime), removedDepositIDs) } -// GetNextProposalExpirationTime mocks base method. -func (m *MockDiff) GetNextProposalExpirationTime(arg0 set.Set[ids.ID]) (time.Time, error) { +// GetNextToUnlockDepositTime mocks base method. +func (m *MockState) GetNextToUnlockDepositTime(removedDepositIDs set.Set[ids.ID]) (time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", arg0) + ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", removedDepositIDs) ret0, _ := ret[0].(time.Time) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. -func (mr *MockDiffMockRecorder) GetNextProposalExpirationTime(arg0 interface{}) *gomock.Call { +// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. +func (mr *MockStateMockRecorder) GetNextToUnlockDepositTime(removedDepositIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockDiff)(nil).GetNextProposalExpirationTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockState)(nil).GetNextToUnlockDepositTime), removedDepositIDs) } -// GetNextToExpireProposalIDsAndTime mocks base method. -func (m *MockDiff) GetNextToExpireProposalIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { +// GetNotDistributedValidatorReward mocks base method. +func (m *MockState) GetNotDistributedValidatorReward() (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. -func (mr *MockDiffMockRecorder) GetNextToExpireProposalIDsAndTime(arg0 interface{}) *gomock.Call { +// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. +func (mr *MockStateMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockState)(nil).GetNotDistributedValidatorReward)) +} + +// GetPendingDelegatorIterator mocks base method. +func (m *MockState) GetPendingDelegatorIterator(subnetID ids.ID, nodeID ids.NodeID) (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", subnetID, nodeID) + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. +func (mr *MockStateMockRecorder) GetPendingDelegatorIterator(subnetID, nodeID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockState)(nil).GetPendingDelegatorIterator), subnetID, nodeID) +} + +// GetPendingStakerIterator mocks base method. +func (m *MockState) GetPendingStakerIterator() (StakerIterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. +func (mr *MockStateMockRecorder) GetPendingStakerIterator() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockState)(nil).GetPendingStakerIterator)) +} + +// GetPendingValidator mocks base method. +func (m *MockState) GetPendingValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPendingValidator", subnetID, nodeID) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPendingValidator indicates an expected call of GetPendingValidator. +func (mr *MockStateMockRecorder) GetPendingValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockDiff)(nil).GetNextToExpireProposalIDsAndTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockState)(nil).GetPendingValidator), subnetID, nodeID) +} + +// GetProposal mocks base method. +func (m *MockState) GetProposal(proposalID ids.ID) (dac.ProposalState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetProposal", proposalID) + ret0, _ := ret[0].(dac.ProposalState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetProposal indicates an expected call of GetProposal. +func (mr *MockStateMockRecorder) GetProposal(proposalID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockState)(nil).GetProposal), proposalID) } // GetProposalIDsToFinish mocks base method. -func (m *MockDiff) GetProposalIDsToFinish() ([]ids.ID, error) { +func (m *MockState) GetProposalIDsToFinish() ([]ids.ID, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetProposalIDsToFinish") ret0, _ := ret[0].([]ids.ID) - ret2, _ := ret[1].(error) - return ret0, ret2 + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. -func (mr *MockDiffMockRecorder) GetProposalIDsToFinish() *gomock.Call { +func (mr *MockStateMockRecorder) GetProposalIDsToFinish() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockDiff)(nil).GetProposalIDsToFinish)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockState)(nil).GetProposalIDsToFinish)) } // GetProposalIterator mocks base method. -func (m *MockDiff) GetProposalIterator() (ProposalsIterator, error) { +func (m *MockState) GetProposalIterator() (ProposalsIterator, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetProposalIterator") ret0, _ := ret[0].(ProposalsIterator) - ret2, _ := ret[1].(error) - return ret0, ret2 + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetProposalIterator indicates an expected call of GetProposalIterator. -func (mr *MockDiffMockRecorder) GetProposalIterator() *gomock.Call { +func (mr *MockStateMockRecorder) GetProposalIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockDiff)(nil).GetProposalIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockState)(nil).GetProposalIterator)) } -// GetDepositOffer mocks base method. -func (m *MockDiff) GetDepositOffer(arg0 ids.ID) (*deposit.Offer, error) { +// GetRewardUTXOs mocks base method. +func (m *MockState) GetRewardUTXOs(txID ids.ID) ([]*avax.UTXO, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDepositOffer", arg0) - ret0, _ := ret[0].(*deposit.Offer) + ret := m.ctrl.Call(m, "GetRewardUTXOs", txID) + ret0, _ := ret[0].([]*avax.UTXO) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDepositOffer indicates an expected call of GetDepositOffer. -func (mr *MockDiffMockRecorder) GetDepositOffer(arg0 interface{}) *gomock.Call { +// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. +func (mr *MockStateMockRecorder) GetRewardUTXOs(txID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockDiff)(nil).GetDepositOffer), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockState)(nil).GetRewardUTXOs), txID) } -// GetMultisigAlias mocks base method. -func (m *MockDiff) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { +// GetShortIDLink mocks base method. +func (m *MockState) GetShortIDLink(id ids.ShortID, key ShortLinkKey) (ids.ShortID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) - ret0, _ := ret[0].(*multisig.AliasWithNonce) + ret := m.ctrl.Call(m, "GetShortIDLink", id, key) + ret0, _ := ret[0].(ids.ShortID) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetMultisigAlias indicates an expected call of GetMultisigAlias. -func (mr *MockDiffMockRecorder) GetMultisigAlias(arg0 interface{}) *gomock.Call { +// GetShortIDLink indicates an expected call of GetShortIDLink. +func (mr *MockStateMockRecorder) GetShortIDLink(id, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockDiff)(nil).GetMultisigAlias), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockState)(nil).GetShortIDLink), id, key) } -// GetDeferredStakerIterator mocks base method. -func (m *MockDiff) GetDeferredStakerIterator() (StakerIterator, error) { +// GetStartTime mocks base method. +func (m *MockState) GetStartTime(nodeID ids.NodeID, subnetID ids.ID) (time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredStakerIterator") - ret0, _ := ret[0].(StakerIterator) + ret := m.ctrl.Call(m, "GetStartTime", nodeID, subnetID) + ret0, _ := ret[0].(time.Time) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. -func (mr *MockDiffMockRecorder) GetDeferredStakerIterator() *gomock.Call { +// GetStartTime indicates an expected call of GetStartTime. +func (mr *MockStateMockRecorder) GetStartTime(nodeID, subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetDeferredStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStartTime", reflect.TypeOf((*MockState)(nil).GetStartTime), nodeID, subnetID) } -// GetDeferredValidator mocks base method. -func (m *MockDiff) GetDeferredValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// GetStatelessBlock mocks base method. +func (m *MockState) GetStatelessBlock(blockID ids.ID) (block.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) + ret := m.ctrl.Call(m, "GetStatelessBlock", blockID) + ret0, _ := ret[0].(block.Block) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDeferredValidator indicates an expected call of GetDeferredValidator. -func (mr *MockDiffMockRecorder) GetDeferredValidator(arg0, arg1 interface{}) *gomock.Call { +// GetStatelessBlock indicates an expected call of GetStatelessBlock. +func (mr *MockStateMockRecorder) GetStatelessBlock(blockID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockDiff)(nil).GetDeferredValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessBlock", reflect.TypeOf((*MockState)(nil).GetStatelessBlock), blockID) } -// GetNotDistributedValidatorReward mocks base method. -func (m *MockDiff) GetNotDistributedValidatorReward() (uint64, error) { +// GetSubnetOwner mocks base method. +func (m *MockState) GetSubnetOwner(subnetID ids.ID) (fx.Owner, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "GetSubnetOwner", subnetID) + ret0, _ := ret[0].(fx.Owner) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. -func (mr *MockDiffMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { +// GetSubnetOwner indicates an expected call of GetSubnetOwner. +func (mr *MockStateMockRecorder) GetSubnetOwner(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockDiff)(nil).GetNotDistributedValidatorReward)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockState)(nil).GetSubnetOwner), subnetID) } -// GetFeeDistribution mocks base method. -func (m *MockDiff) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { +// GetSubnetTransformation mocks base method. +func (m *MockState) GetSubnetTransformation(subnetID ids.ID) (*txs.Tx, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetFeeDistribution") - ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) + ret := m.ctrl.Call(m, "GetSubnetTransformation", subnetID) + ret0, _ := ret[0].(*txs.Tx) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetFeeDistribution indicates an expected call of GetFeeDistribution. -func (mr *MockDiffMockRecorder) GetFeeDistribution() *gomock.Call { +// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. +func (mr *MockStateMockRecorder) GetSubnetTransformation(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockDiff)(nil).GetFeeDistribution)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockState)(nil).GetSubnetTransformation), subnetID) } -// GetAllDepositOffers mocks base method. -func (m *MockDiff) GetAllDepositOffers() ([]*deposit.Offer, error) { +// GetSubnets mocks base method. +func (m *MockState) GetSubnets() ([]*txs.Tx, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAllDepositOffers") - ret0, _ := ret[0].([]*deposit.Offer) + ret := m.ctrl.Call(m, "GetSubnets") + ret0, _ := ret[0].([]*txs.Tx) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetAllDepositOffers indicates an expected call of GetAllDepositOffers. -func (mr *MockDiffMockRecorder) GetAllDepositOffers() *gomock.Call { +// GetSubnets indicates an expected call of GetSubnets. +func (mr *MockStateMockRecorder) GetSubnets() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockDiff)(nil).GetAllDepositOffers)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockState)(nil).GetSubnets)) } -// CaminoConfig mocks base method. -func (m *MockDiff) CaminoConfig() (*CaminoConfig, error) { +// GetTimestamp mocks base method. +func (m *MockState) GetTimestamp() time.Time { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CaminoConfig") - ret0, _ := ret[0].(*CaminoConfig) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "GetTimestamp") + ret0, _ := ret[0].(time.Time) + return ret0 } -// CaminoConfig indicates an expected call of CaminoConfig. -func (mr *MockDiffMockRecorder) CaminoConfig() *gomock.Call { +// GetTimestamp indicates an expected call of GetTimestamp. +func (mr *MockStateMockRecorder) GetTimestamp() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockDiff)(nil).CaminoConfig)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockState)(nil).GetTimestamp)) } -// GetCurrentDelegatorIterator mocks base method. -func (m *MockDiff) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { +// GetTx mocks base method. +func (m *MockState) GetTx(txID ids.ID) (*txs.Tx, status.Status, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) + ret := m.ctrl.Call(m, "GetTx", txID) + ret0, _ := ret[0].(*txs.Tx) + ret1, _ := ret[1].(status.Status) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetTx indicates an expected call of GetTx. +func (mr *MockStateMockRecorder) GetTx(txID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockState)(nil).GetTx), txID) +} + +// GetUTXO mocks base method. +func (m *MockState) GetUTXO(utxoID ids.ID) (*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUTXO", utxoID) + ret0, _ := ret[0].(*avax.UTXO) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *gomock.Call { +// GetUTXO indicates an expected call of GetUTXO. +func (mr *MockStateMockRecorder) GetUTXO(utxoID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentDelegatorIterator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockState)(nil).GetUTXO), utxoID) } -// GetCurrentStakerIterator mocks base method. -func (m *MockDiff) GetCurrentStakerIterator() (StakerIterator, error) { +// GetUptime mocks base method. +func (m *MockState) GetUptime(nodeID ids.NodeID, subnetID ids.ID) (time.Duration, time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentStakerIterator") - ret0, _ := ret[0].(StakerIterator) + ret := m.ctrl.Call(m, "GetUptime", nodeID, subnetID) + ret0, _ := ret[0].(time.Duration) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetUptime indicates an expected call of GetUptime. +func (mr *MockStateMockRecorder) GetUptime(nodeID, subnetID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUptime", reflect.TypeOf((*MockState)(nil).GetUptime), nodeID, subnetID) +} + +// LockedUTXOs mocks base method. +func (m *MockState) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) + ret0, _ := ret[0].([]*avax.UTXO) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. -func (mr *MockDiffMockRecorder) GetCurrentStakerIterator() *gomock.Call { +// LockedUTXOs indicates an expected call of LockedUTXOs. +func (mr *MockStateMockRecorder) LockedUTXOs(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockState)(nil).LockedUTXOs), arg0, arg1, arg2) +} + +// ModifyDeposit mocks base method. +func (m *MockState) ModifyDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ModifyDeposit", depositTxID, deposit) +} + +// ModifyDeposit indicates an expected call of ModifyDeposit. +func (mr *MockStateMockRecorder) ModifyDeposit(depositTxID, deposit any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockState)(nil).ModifyDeposit), depositTxID, deposit) +} + +// ModifyProposal mocks base method. +func (m *MockState) ModifyProposal(proposalID ids.ID, proposal dac.ProposalState) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ModifyProposal", proposalID, proposal) +} + +// ModifyProposal indicates an expected call of ModifyProposal. +func (mr *MockStateMockRecorder) ModifyProposal(proposalID, proposal any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockState)(nil).ModifyProposal), proposalID, proposal) +} + +// PruneAndIndex mocks base method. +func (m *MockState) PruneAndIndex(arg0 sync.Locker, arg1 logging.Logger) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PruneAndIndex", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// PruneAndIndex indicates an expected call of PruneAndIndex. +func (mr *MockStateMockRecorder) PruneAndIndex(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PruneAndIndex", reflect.TypeOf((*MockState)(nil).PruneAndIndex), arg0, arg1) +} + +// PutCurrentDelegator mocks base method. +func (m *MockState) PutCurrentDelegator(staker *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutCurrentDelegator", staker) +} + +// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. +func (mr *MockStateMockRecorder) PutCurrentDelegator(staker any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockState)(nil).PutCurrentDelegator), staker) +} + +// PutCurrentValidator mocks base method. +func (m *MockState) PutCurrentValidator(staker *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutCurrentValidator", staker) +} + +// PutCurrentValidator indicates an expected call of PutCurrentValidator. +func (mr *MockStateMockRecorder) PutCurrentValidator(staker any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockState)(nil).PutCurrentValidator), staker) +} + +// PutDeferredValidator mocks base method. +func (m *MockState) PutDeferredValidator(staker *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutDeferredValidator", staker) +} + +// PutDeferredValidator indicates an expected call of PutDeferredValidator. +func (mr *MockStateMockRecorder) PutDeferredValidator(staker any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockState)(nil).PutDeferredValidator), staker) +} + +// PutPendingDelegator mocks base method. +func (m *MockState) PutPendingDelegator(staker *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutPendingDelegator", staker) +} + +// PutPendingDelegator indicates an expected call of PutPendingDelegator. +func (mr *MockStateMockRecorder) PutPendingDelegator(staker any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockState)(nil).PutPendingDelegator), staker) +} + +// PutPendingValidator mocks base method. +func (m *MockState) PutPendingValidator(staker *Staker) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PutPendingValidator", staker) +} + +// PutPendingValidator indicates an expected call of PutPendingValidator. +func (mr *MockStateMockRecorder) PutPendingValidator(staker any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockState)(nil).PutPendingValidator), staker) +} + +// RemoveDeposit mocks base method. +func (m *MockState) RemoveDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RemoveDeposit", depositTxID, deposit) +} + +// RemoveDeposit indicates an expected call of RemoveDeposit. +func (mr *MockStateMockRecorder) RemoveDeposit(depositTxID, deposit any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockState)(nil).RemoveDeposit), depositTxID, deposit) } -// GetCurrentSupply mocks base method. -func (m *MockDiff) GetCurrentSupply(arg0 ids.ID) (uint64, error) { +// RemoveProposal mocks base method. +func (m *MockState) RemoveProposal(proposalID ids.ID, proposal dac.ProposalState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "RemoveProposal", proposalID, proposal) } -// GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockDiffMockRecorder) GetCurrentSupply(arg0 any) *gomock.Call { +// RemoveProposal indicates an expected call of RemoveProposal. +func (mr *MockStateMockRecorder) RemoveProposal(proposalID, proposal any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).GetCurrentSupply), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockState)(nil).RemoveProposal), proposalID, proposal) } -// GetCurrentValidator mocks base method. -func (m *MockDiff) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// RemoveProposalIDToFinish mocks base method. +func (m *MockState) RemoveProposalIDToFinish(arg0 ids.ID) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) } -// GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockDiffMockRecorder) GetCurrentValidator(arg0, arg1 any) *gomock.Call { +// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. +func (mr *MockStateMockRecorder) RemoveProposalIDToFinish(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockDiff)(nil).GetCurrentValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockState)(nil).RemoveProposalIDToFinish), arg0) } -// GetDelegateeReward mocks base method. -func (m *MockDiff) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { +// SetAddressStates mocks base method. +func (m *MockState) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetAddressStates", arg0, arg1) } -// GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockDiffMockRecorder) GetDelegateeReward(arg0, arg1 any) *gomock.Call { +// SetAddressStates indicates an expected call of SetAddressStates. +func (mr *MockStateMockRecorder) SetAddressStates(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).GetDelegateeReward), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockState)(nil).SetAddressStates), arg0, arg1) } -// GetPendingDelegatorIterator mocks base method. -func (m *MockDiff) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { +// SetBaseFee mocks base method. +func (m *MockState) SetBaseFee(arg0 uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetBaseFee", arg0) } -// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockDiffMockRecorder) GetPendingDelegatorIterator(arg0, arg1 any) *gomock.Call { +// SetBaseFee indicates an expected call of SetBaseFee. +func (mr *MockStateMockRecorder) SetBaseFee(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingDelegatorIterator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockState)(nil).SetBaseFee), arg0) } -// GetPendingStakerIterator mocks base method. -func (m *MockDiff) GetPendingStakerIterator() (StakerIterator, error) { +// SetClaimable mocks base method. +func (m *MockState) SetClaimable(ownerID ids.ID, claimable *Claimable) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetClaimable", ownerID, claimable) } -// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. -func (mr *MockDiffMockRecorder) GetPendingStakerIterator() *gomock.Call { +// SetClaimable indicates an expected call of SetClaimable. +func (mr *MockStateMockRecorder) SetClaimable(ownerID, claimable any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockState)(nil).SetClaimable), ownerID, claimable) } -// GetPendingValidator mocks base method. -func (m *MockDiff) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// SetCurrentSupply mocks base method. +func (m *MockState) SetCurrentSupply(subnetID ids.ID, cs uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetCurrentSupply", subnetID, cs) } -// GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockDiffMockRecorder) GetPendingValidator(arg0, arg1 any) *gomock.Call { +// SetCurrentSupply indicates an expected call of SetCurrentSupply. +func (mr *MockStateMockRecorder) SetCurrentSupply(subnetID, cs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockDiff)(nil).GetPendingValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockState)(nil).SetCurrentSupply), subnetID, cs) } -// GetSubnetOwner mocks base method. -func (m *MockDiff) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { +// SetDelegateeReward mocks base method. +func (m *MockState) SetDelegateeReward(subnetID ids.ID, nodeID ids.NodeID, amount uint64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) - ret0, _ := ret[0].(fx.Owner) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "SetDelegateeReward", subnetID, nodeID, amount) + ret0, _ := ret[0].(error) + return ret0 } -// GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockDiffMockRecorder) GetSubnetOwner(arg0 any) *gomock.Call { +// SetDelegateeReward indicates an expected call of SetDelegateeReward. +func (mr *MockStateMockRecorder) SetDelegateeReward(subnetID, nodeID, amount any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).GetSubnetOwner), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockState)(nil).SetDelegateeReward), subnetID, nodeID, amount) } -// GetSubnetTransformation mocks base method. -func (m *MockDiff) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { +// SetDepositOffer mocks base method. +func (m *MockState) SetDepositOffer(offer *deposit.Offer) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetDepositOffer", offer) } -// GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockDiffMockRecorder) GetSubnetTransformation(arg0 any) *gomock.Call { +// SetDepositOffer indicates an expected call of SetDepositOffer. +func (mr *MockStateMockRecorder) SetDepositOffer(offer any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).GetSubnetTransformation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockState)(nil).SetDepositOffer), offer) } -// GetTimestamp mocks base method. -func (m *MockDiff) GetTimestamp() time.Time { +// SetFeeDistribution mocks base method. +func (m *MockState) SetFeeDistribution(arg0 [3]uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTimestamp") - ret0, _ := ret[0].(time.Time) - return ret0 + m.ctrl.Call(m, "SetFeeDistribution", arg0) } -// GetTimestamp indicates an expected call of GetTimestamp. -func (mr *MockDiffMockRecorder) GetTimestamp() *gomock.Call { +// SetFeeDistribution indicates an expected call of SetFeeDistribution. +func (mr *MockStateMockRecorder) SetFeeDistribution(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockDiff)(nil).GetTimestamp)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockState)(nil).SetFeeDistribution), arg0) } -// GetTx mocks base method. -func (m *MockDiff) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { +// SetHeight mocks base method. +func (m *MockState) SetHeight(height uint64) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTx", arg0) - ret0, _ := ret[0].(*txs.Tx) - ret1, _ := ret[1].(status.Status) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + m.ctrl.Call(m, "SetHeight", height) } -// GetTx indicates an expected call of GetTx. -func (mr *MockDiffMockRecorder) GetTx(arg0 any) *gomock.Call { +// SetHeight indicates an expected call of SetHeight. +func (mr *MockStateMockRecorder) SetHeight(height any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockDiff)(nil).GetTx), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeight", reflect.TypeOf((*MockState)(nil).SetHeight), height) } -// GetUTXO mocks base method. -func (m *MockDiff) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { +// SetLastAccepted mocks base method. +func (m *MockState) SetLastAccepted(blkID ids.ID) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0) - ret0, _ := ret[0].(*avax.UTXO) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "SetLastAccepted", blkID) } -// GetUTXO indicates an expected call of GetUTXO. -func (mr *MockDiffMockRecorder) GetUTXO(arg0 any) *gomock.Call { +// SetLastAccepted indicates an expected call of SetLastAccepted. +func (mr *MockStateMockRecorder) SetLastAccepted(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockDiff)(nil).GetUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastAccepted", reflect.TypeOf((*MockState)(nil).SetLastAccepted), blkID) } -// PutCurrentDelegator mocks base method. -func (m *MockDiff) PutCurrentDelegator(arg0 *Staker) { +// SetMultisigAlias mocks base method. +func (m *MockState) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentDelegator", arg0) + m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) } -// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockDiffMockRecorder) PutCurrentDelegator(arg0 any) *gomock.Call { +// SetMultisigAlias indicates an expected call of SetMultisigAlias. +func (mr *MockStateMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).PutCurrentDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockState)(nil).SetMultisigAlias), arg0, arg1) } -// PutCurrentValidator mocks base method. -func (m *MockDiff) PutCurrentValidator(arg0 *Staker) { +// SetNotDistributedValidatorReward mocks base method. +func (m *MockState) SetNotDistributedValidatorReward(reward uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentValidator", arg0) + m.ctrl.Call(m, "SetNotDistributedValidatorReward", reward) } -// PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockDiffMockRecorder) PutCurrentValidator(arg0 any) *gomock.Call { +// SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. +func (mr *MockStateMockRecorder) SetNotDistributedValidatorReward(reward any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockDiff)(nil).PutCurrentValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockState)(nil).SetNotDistributedValidatorReward), reward) } -// PutPendingDelegator mocks base method. -func (m *MockDiff) PutPendingDelegator(arg0 *Staker) { +// SetShortIDLink mocks base method. +func (m *MockState) SetShortIDLink(id ids.ShortID, key ShortLinkKey, link *ids.ShortID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingDelegator", arg0) + m.ctrl.Call(m, "SetShortIDLink", id, key, link) } -// PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockDiffMockRecorder) PutPendingDelegator(arg0 any) *gomock.Call { +// SetShortIDLink indicates an expected call of SetShortIDLink. +func (mr *MockStateMockRecorder) SetShortIDLink(id, key, link any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockDiff)(nil).PutPendingDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockState)(nil).SetShortIDLink), id, key, link) } -// PutPendingValidator mocks base method. -func (m *MockDiff) PutPendingValidator(arg0 *Staker) { +// SetSubnetOwner mocks base method. +func (m *MockState) SetSubnetOwner(subnetID ids.ID, owner fx.Owner) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingValidator", arg0) + m.ctrl.Call(m, "SetSubnetOwner", subnetID, owner) } -// PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockDiffMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { +// SetSubnetOwner indicates an expected call of SetSubnetOwner. +func (mr *MockStateMockRecorder) SetSubnetOwner(subnetID, owner any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockDiff)(nil).PutPendingValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockState)(nil).SetSubnetOwner), subnetID, owner) } -// SetCurrentSupply mocks base method. -func (m *MockDiff) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { +// SetTimestamp mocks base method. +func (m *MockState) SetTimestamp(tm time.Time) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) + m.ctrl.Call(m, "SetTimestamp", tm) } -// SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockDiffMockRecorder) SetCurrentSupply(arg0, arg1 any) *gomock.Call { +// SetTimestamp indicates an expected call of SetTimestamp. +func (mr *MockStateMockRecorder) SetTimestamp(tm any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).SetCurrentSupply), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockState)(nil).SetTimestamp), tm) } -// SetDelegateeReward mocks base method. -func (m *MockDiff) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { +// SetUptime mocks base method. +func (m *MockState) SetUptime(nodeID ids.NodeID, subnetID ids.ID, upDuration time.Duration, lastUpdated time.Time) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "SetUptime", nodeID, subnetID, upDuration, lastUpdated) ret0, _ := ret[0].(error) return ret0 } -// SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockDiffMockRecorder) SetDelegateeReward(arg0, arg1, arg2 any) *gomock.Call { +// SetUptime indicates an expected call of SetUptime. +func (mr *MockStateMockRecorder) SetUptime(nodeID, subnetID, upDuration, lastUpdated any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).SetDelegateeReward), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUptime", reflect.TypeOf((*MockState)(nil).SetUptime), nodeID, subnetID, upDuration, lastUpdated) } -// SetSubnetOwner mocks base method. -func (m *MockDiff) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { +// ShouldPrune mocks base method. +func (m *MockState) ShouldPrune() (bool, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) + ret := m.ctrl.Call(m, "ShouldPrune") + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockDiffMockRecorder) SetSubnetOwner(arg0, arg1 any) *gomock.Call { +// ShouldPrune indicates an expected call of ShouldPrune. +func (mr *MockStateMockRecorder) ShouldPrune() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).SetSubnetOwner), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldPrune", reflect.TypeOf((*MockState)(nil).ShouldPrune)) } -// SetTimestamp mocks base method. -func (m *MockDiff) SetTimestamp(arg0 time.Time) { +// UTXOIDs mocks base method. +func (m *MockState) UTXOIDs(addr []byte, previous ids.ID, limit int) ([]ids.ID, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetTimestamp", arg0) + ret := m.ctrl.Call(m, "UTXOIDs", addr, previous, limit) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockDiffMockRecorder) SetTimestamp(arg0 any) *gomock.Call { +// UTXOIDs indicates an expected call of UTXOIDs. +func (mr *MockStateMockRecorder) UTXOIDs(addr, previous, limit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockDiff)(nil).SetTimestamp), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UTXOIDs", reflect.TypeOf((*MockState)(nil).UTXOIDs), addr, previous, limit) } -// MockState is a mock of State interface. -type MockState struct { +// MockDiff is a mock of Diff interface. +type MockDiff struct { ctrl *gomock.Controller - recorder *MockStateMockRecorder + recorder *MockDiffMockRecorder } -// MockStateMockRecorder is the mock recorder for MockState. -type MockStateMockRecorder struct { - mock *MockState +// MockDiffMockRecorder is the mock recorder for MockDiff. +type MockDiffMockRecorder struct { + mock *MockDiff } -// NewMockState creates a new mock instance. -func NewMockState(ctrl *gomock.Controller) *MockState { - mock := &MockState{ctrl: ctrl} - mock.recorder = &MockStateMockRecorder{mock} +// NewMockDiff creates a new mock instance. +func NewMockDiff(ctrl *gomock.Controller) *MockDiff { + mock := &MockDiff{ctrl: ctrl} + mock.recorder = &MockDiffMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockState) EXPECT() *MockStateMockRecorder { +func (m *MockDiff) EXPECT() *MockDiffMockRecorder { return m.recorder } -// Abort mocks base method. -func (m *MockState) Abort() { +// AddChain mocks base method. +func (m *MockDiff) AddChain(createChainTx *txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Abort") + m.ctrl.Call(m, "AddChain", createChainTx) } -// Abort indicates an expected call of Abort. -func (mr *MockStateMockRecorder) Abort() *gomock.Call { +// AddChain indicates an expected call of AddChain. +func (mr *MockDiffMockRecorder) AddChain(createChainTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Abort", reflect.TypeOf((*MockState)(nil).Abort)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockDiff)(nil).AddChain), createChainTx) } -// AddChain mocks base method. -func (m *MockState) AddChain(arg0 *txs.Tx) { +// AddDeposit mocks base method. +func (m *MockDiff) AddDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddChain", arg0) + m.ctrl.Call(m, "AddDeposit", depositTxID, deposit) } -// AddChain indicates an expected call of AddChain. -func (mr *MockStateMockRecorder) AddChain(arg0 any) *gomock.Call { +// AddDeposit indicates an expected call of AddDeposit. +func (mr *MockDiffMockRecorder) AddDeposit(depositTxID, deposit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddChain", reflect.TypeOf((*MockState)(nil).AddChain), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockDiff)(nil).AddDeposit), depositTxID, deposit) } -// SetDepositOffer mocks base method. -func (m *MockState) SetDepositOffer(arg0 *deposit.Offer) { +// AddProposal mocks base method. +func (m *MockDiff) AddProposal(proposalID ids.ID, proposal dac.ProposalState) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetDepositOffer", arg0) + m.ctrl.Call(m, "AddProposal", proposalID, proposal) } -// SetDepositOffer indicates an expected call of SetDepositOffer. -func (mr *MockStateMockRecorder) SetDepositOffer(arg0 interface{}) *gomock.Call { +// AddProposal indicates an expected call of AddProposal. +func (mr *MockDiffMockRecorder) AddProposal(proposalID, proposal any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockState)(nil).SetDepositOffer), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockDiff)(nil).AddProposal), proposalID, proposal) } -// AddRewardUTXO mocks base method. -func (m *MockState) AddRewardUTXO(arg0 ids.ID, arg1 *avax.UTXO) { +// AddProposalIDToFinish mocks base method. +func (m *MockDiff) AddProposalIDToFinish(proposalID ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddRewardUTXO", arg0, arg1) + m.ctrl.Call(m, "AddProposalIDToFinish", proposalID) } -// AddRewardUTXO indicates an expected call of AddRewardUTXO. -func (mr *MockStateMockRecorder) AddRewardUTXO(arg0, arg1 any) *gomock.Call { +// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. +func (mr *MockDiffMockRecorder) AddProposalIDToFinish(proposalID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockState)(nil).AddRewardUTXO), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockDiff)(nil).AddProposalIDToFinish), proposalID) } -// AddStatelessBlock mocks base method. -func (m *MockState) AddStatelessBlock(arg0 block.Block) { +// AddRewardUTXO mocks base method. +func (m *MockDiff) AddRewardUTXO(txID ids.ID, utxo *avax.UTXO) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddStatelessBlock", arg0) + m.ctrl.Call(m, "AddRewardUTXO", txID, utxo) } -// AddStatelessBlock indicates an expected call of AddStatelessBlock. -func (mr *MockStateMockRecorder) AddStatelessBlock(arg0 any) *gomock.Call { +// AddRewardUTXO indicates an expected call of AddRewardUTXO. +func (mr *MockDiffMockRecorder) AddRewardUTXO(txID, utxo any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddStatelessBlock", reflect.TypeOf((*MockState)(nil).AddStatelessBlock), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRewardUTXO", reflect.TypeOf((*MockDiff)(nil).AddRewardUTXO), txID, utxo) } // AddSubnet mocks base method. -func (m *MockState) AddSubnet(arg0 *txs.Tx) { +func (m *MockDiff) AddSubnet(createSubnetTx *txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnet", arg0) + m.ctrl.Call(m, "AddSubnet", createSubnetTx) } // AddSubnet indicates an expected call of AddSubnet. -func (mr *MockStateMockRecorder) AddSubnet(arg0 any) *gomock.Call { +func (mr *MockDiffMockRecorder) AddSubnet(createSubnetTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockState)(nil).AddSubnet), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnet", reflect.TypeOf((*MockDiff)(nil).AddSubnet), createSubnetTx) } // AddSubnetTransformation mocks base method. -func (m *MockState) AddSubnetTransformation(arg0 *txs.Tx) { +func (m *MockDiff) AddSubnetTransformation(transformSubnetTx *txs.Tx) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddSubnetTransformation", arg0) + m.ctrl.Call(m, "AddSubnetTransformation", transformSubnetTx) } // AddSubnetTransformation indicates an expected call of AddSubnetTransformation. -func (mr *MockStateMockRecorder) AddSubnetTransformation(arg0 any) *gomock.Call { +func (mr *MockDiffMockRecorder) AddSubnetTransformation(transformSubnetTx any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockState)(nil).AddSubnetTransformation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).AddSubnetTransformation), transformSubnetTx) } // AddTx mocks base method. -func (m *MockState) AddTx(arg0 *txs.Tx, arg1 status.Status) { +func (m *MockDiff) AddTx(tx *txs.Tx, status status.Status) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddTx", arg0, arg1) + m.ctrl.Call(m, "AddTx", tx, status) } // AddTx indicates an expected call of AddTx. -func (mr *MockStateMockRecorder) AddTx(arg0, arg1 any) *gomock.Call { +func (mr *MockDiffMockRecorder) AddTx(tx, status any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockState)(nil).AddTx), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTx", reflect.TypeOf((*MockDiff)(nil).AddTx), tx, status) } // AddUTXO mocks base method. -func (m *MockState) AddUTXO(arg0 *avax.UTXO) { +func (m *MockDiff) AddUTXO(utxo *avax.UTXO) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddUTXO", arg0) + m.ctrl.Call(m, "AddUTXO", utxo) } // AddUTXO indicates an expected call of AddUTXO. -func (mr *MockStateMockRecorder) AddUTXO(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockState)(nil).AddUTXO), arg0) -} - -// ApplyValidatorPublicKeyDiffs mocks base method. -func (m *MockState) ApplyValidatorPublicKeyDiffs(arg0 context.Context, arg1 map[ids.NodeID]*validators.GetValidatorOutput, arg2, arg3 uint64) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ApplyValidatorPublicKeyDiffs", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(error) - return ret0 -} - -// ApplyValidatorPublicKeyDiffs indicates an expected call of ApplyValidatorPublicKeyDiffs. -func (mr *MockStateMockRecorder) ApplyValidatorPublicKeyDiffs(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyValidatorPublicKeyDiffs", reflect.TypeOf((*MockState)(nil).ApplyValidatorPublicKeyDiffs), arg0, arg1, arg2, arg3) -} - -// ApplyValidatorWeightDiffs mocks base method. -func (m *MockState) ApplyValidatorWeightDiffs(arg0 context.Context, arg1 map[ids.NodeID]*validators.GetValidatorOutput, arg2, arg3 uint64, arg4 ids.ID) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ApplyValidatorWeightDiffs", arg0, arg1, arg2, arg3, arg4) - ret0, _ := ret[0].(error) - return ret0 -} - -// ApplyValidatorWeightDiffs indicates an expected call of ApplyValidatorWeightDiffs. -func (mr *MockStateMockRecorder) ApplyValidatorWeightDiffs(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyValidatorWeightDiffs", reflect.TypeOf((*MockState)(nil).ApplyValidatorWeightDiffs), arg0, arg1, arg2, arg3, arg4) -} - -// Checksum mocks base method. -func (m *MockState) Checksum() ids.ID { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Checksum") - ret0, _ := ret[0].(ids.ID) - return ret0 -} - -// Checksum indicates an expected call of Checksum. -func (mr *MockStateMockRecorder) Checksum() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Checksum", reflect.TypeOf((*MockState)(nil).Checksum)) -} - -// CaminoConfig mocks base method. -func (m *MockState) CaminoConfig() (*CaminoConfig, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CaminoConfig") - ret0, _ := ret[0].(*CaminoConfig) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CaminoConfig indicates an expected call of CaminoConfig. -func (mr *MockStateMockRecorder) CaminoConfig() *gomock.Call { +func (mr *MockDiffMockRecorder) AddUTXO(utxo any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockState)(nil).CaminoConfig)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddUTXO", reflect.TypeOf((*MockDiff)(nil).AddUTXO), utxo) } -// Close mocks base method. -func (m *MockState) Close() error { +// Apply mocks base method. +func (m *MockDiff) Apply(arg0 Chain) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") + ret := m.ctrl.Call(m, "Apply", arg0) ret0, _ := ret[0].(error) return ret0 } -// Close indicates an expected call of Close. -func (mr *MockStateMockRecorder) Close() *gomock.Call { +// Apply indicates an expected call of Apply. +func (mr *MockDiffMockRecorder) Apply(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockState)(nil).Close)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockDiff)(nil).Apply), arg0) } -// Commit mocks base method. -func (m *MockState) Commit() error { +// ApplyCaminoState mocks base method. +func (m *MockDiff) ApplyCaminoState(arg0 Chain) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Commit") + ret := m.ctrl.Call(m, "ApplyCaminoState", arg0) ret0, _ := ret[0].(error) return ret0 } -// Commit indicates an expected call of Commit. -func (mr *MockStateMockRecorder) Commit() *gomock.Call { +// ApplyCaminoState indicates an expected call of ApplyCaminoState. +func (mr *MockDiffMockRecorder) ApplyCaminoState(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockState)(nil).Commit)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyCaminoState", reflect.TypeOf((*MockDiff)(nil).ApplyCaminoState), arg0) } -// CommitBatch mocks base method. -func (m *MockState) CommitBatch() (database.Batch, error) { +// CaminoConfig mocks base method. +func (m *MockDiff) CaminoConfig() (*CaminoConfig, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CommitBatch") - ret0, _ := ret[0].(database.Batch) + ret := m.ctrl.Call(m, "CaminoConfig") + ret0, _ := ret[0].(*CaminoConfig) ret1, _ := ret[1].(error) return ret0, ret1 } -// CommitBatch indicates an expected call of CommitBatch. -func (mr *MockStateMockRecorder) CommitBatch() *gomock.Call { +// CaminoConfig indicates an expected call of CaminoConfig. +func (mr *MockDiffMockRecorder) CaminoConfig() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitBatch", reflect.TypeOf((*MockState)(nil).CommitBatch)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CaminoConfig", reflect.TypeOf((*MockDiff)(nil).CaminoConfig)) } // DeleteCurrentDelegator mocks base method. -func (m *MockState) DeleteCurrentDelegator(arg0 *Staker) { +func (m *MockDiff) DeleteCurrentDelegator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentDelegator", arg0) + m.ctrl.Call(m, "DeleteCurrentDelegator", staker) } // DeleteCurrentDelegator indicates an expected call of DeleteCurrentDelegator. -func (mr *MockStateMockRecorder) DeleteCurrentDelegator(arg0 any) *gomock.Call { +func (mr *MockDiffMockRecorder) DeleteCurrentDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockState)(nil).DeleteCurrentDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentDelegator), staker) } // DeleteCurrentValidator mocks base method. -func (m *MockState) DeleteCurrentValidator(arg0 *Staker) { +func (m *MockDiff) DeleteCurrentValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteCurrentValidator", arg0) + m.ctrl.Call(m, "DeleteCurrentValidator", staker) } // DeleteCurrentValidator indicates an expected call of DeleteCurrentValidator. -func (mr *MockStateMockRecorder) DeleteCurrentValidator(arg0 any) *gomock.Call { +func (mr *MockDiffMockRecorder) DeleteCurrentValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockState)(nil).DeleteCurrentValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCurrentValidator", reflect.TypeOf((*MockDiff)(nil).DeleteCurrentValidator), staker) } -// DeletePendingDelegator mocks base method. -func (m *MockState) DeletePendingDelegator(arg0 *Staker) { +// DeleteDeferredValidator mocks base method. +func (m *MockDiff) DeleteDeferredValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingDelegator", arg0) + m.ctrl.Call(m, "DeleteDeferredValidator", staker) } -// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. -func (mr *MockStateMockRecorder) DeletePendingDelegator(arg0 any) *gomock.Call { +// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. +func (mr *MockDiffMockRecorder) DeleteDeferredValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockState)(nil).DeletePendingDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockDiff)(nil).DeleteDeferredValidator), staker) } -// DeletePendingValidator mocks base method. -func (m *MockState) DeletePendingValidator(arg0 *Staker) { +// DeletePendingDelegator mocks base method. +func (m *MockDiff) DeletePendingDelegator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeletePendingValidator", arg0) + m.ctrl.Call(m, "DeletePendingDelegator", staker) } -// DeletePendingValidator indicates an expected call of DeletePendingValidator. -func (mr *MockStateMockRecorder) DeletePendingValidator(arg0 any) *gomock.Call { +// DeletePendingDelegator indicates an expected call of DeletePendingDelegator. +func (mr *MockDiffMockRecorder) DeletePendingDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockState)(nil).DeletePendingValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingDelegator", reflect.TypeOf((*MockDiff)(nil).DeletePendingDelegator), staker) } -// DeleteUTXO mocks base method. -func (m *MockState) DeleteUTXO(arg0 ids.ID) { +// DeletePendingValidator mocks base method. +func (m *MockDiff) DeletePendingValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteUTXO", arg0) + m.ctrl.Call(m, "DeletePendingValidator", staker) } -// DeleteUTXO indicates an expected call of DeleteUTXO. -func (mr *MockStateMockRecorder) DeleteUTXO(arg0 any) *gomock.Call { +// DeletePendingValidator indicates an expected call of DeletePendingValidator. +func (mr *MockDiffMockRecorder) DeletePendingValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockState)(nil).DeleteUTXO), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeletePendingValidator", reflect.TypeOf((*MockDiff)(nil).DeletePendingValidator), staker) } -// GetBlockIDAtHeight mocks base method. -func (m *MockState) GetBlockIDAtHeight(arg0 uint64) (ids.ID, error) { +// DeleteUTXO mocks base method. +func (m *MockDiff) DeleteUTXO(utxoID ids.ID) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockIDAtHeight", arg0) - ret0, _ := ret[0].(ids.ID) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "DeleteUTXO", utxoID) } -// GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *MockStateMockRecorder) GetBlockIDAtHeight(arg0 any) *gomock.Call { +// DeleteUTXO indicates an expected call of DeleteUTXO. +func (mr *MockDiffMockRecorder) DeleteUTXO(utxoID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*MockState)(nil).GetBlockIDAtHeight), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteUTXO", reflect.TypeOf((*MockDiff)(nil).DeleteUTXO), utxoID) } // GetAddressStates mocks base method. -func (m *MockState) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { +func (m *MockDiff) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAddressStates", arg0) ret0, _ := ret[0].(addrstate.AddressState) @@ -2352,13 +2562,13 @@ func (m *MockState) GetAddressStates(arg0 ids.ShortID) (addrstate.AddressState, } // GetAddressStates indicates an expected call of GetAddressStates. -func (mr *MockStateMockRecorder) GetAddressStates(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetAddressStates(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockState)(nil).GetAddressStates), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAddressStates", reflect.TypeOf((*MockDiff)(nil).GetAddressStates), arg0) } // GetAllDepositOffers mocks base method. -func (m *MockState) GetAllDepositOffers() ([]*deposit.Offer, error) { +func (m *MockDiff) GetAllDepositOffers() ([]*deposit.Offer, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAllDepositOffers") ret0, _ := ret[0].([]*deposit.Offer) @@ -2367,58 +2577,13 @@ func (m *MockState) GetAllDepositOffers() ([]*deposit.Offer, error) { } // GetAllDepositOffers indicates an expected call of GetAllDepositOffers. -func (mr *MockStateMockRecorder) GetAllDepositOffers() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockState)(nil).GetAllDepositOffers)) -} - -// GetChains mocks base method. -func (m *MockState) GetChains(arg0 ids.ID) ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChains", arg0) - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChains indicates an expected call of GetChains. -func (mr *MockStateMockRecorder) GetChains(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChains", reflect.TypeOf((*MockState)(nil).GetChains), arg0) -} - -// GetClaimable mocks base method. -func (m *MockState) GetClaimable(arg0 ids.ID) (*Claimable, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetClaimable", arg0) - ret0, _ := ret[0].(*Claimable) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetClaimable indicates an expected call of GetClaimable. -func (mr *MockStateMockRecorder) GetClaimable(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockState)(nil).GetClaimable), arg0) -} - -// GetProposal mocks base method. -func (m *MockState) GetProposal(arg0 ids.ID) (dac.ProposalState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposal", arg0) - ret0, _ := ret[0].(dac.ProposalState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetProposal indicates an expected call of GetProposal. -func (mr *MockStateMockRecorder) GetProposal(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetAllDepositOffers() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockState)(nil).GetProposal), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllDepositOffers", reflect.TypeOf((*MockDiff)(nil).GetAllDepositOffers)) } // GetBaseFee mocks base method. -func (m *MockState) GetBaseFee() (uint64, error) { +func (m *MockDiff) GetBaseFee() (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBaseFee") ret0, _ := ret[0].(uint64) @@ -2427,43 +2592,43 @@ func (m *MockState) GetBaseFee() (uint64, error) { } // GetBaseFee indicates an expected call of GetBaseFee. -func (mr *MockStateMockRecorder) GetBaseFee() *gomock.Call { +func (mr *MockDiffMockRecorder) GetBaseFee() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockState)(nil).GetBaseFee)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseFee", reflect.TypeOf((*MockDiff)(nil).GetBaseFee)) } -// GetFeeDistribution mocks base method. -func (m *MockState) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { +// GetClaimable mocks base method. +func (m *MockDiff) GetClaimable(ownerID ids.ID) (*Claimable, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetFeeDistribution") - ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) + ret := m.ctrl.Call(m, "GetClaimable", ownerID) + ret0, _ := ret[0].(*Claimable) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetFeeDistribution indicates an expected call of GetFeeDistribution. -func (mr *MockStateMockRecorder) GetFeeDistribution() *gomock.Call { +// GetClaimable indicates an expected call of GetClaimable. +func (mr *MockDiffMockRecorder) GetClaimable(ownerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockState)(nil).GetFeeDistribution)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClaimable", reflect.TypeOf((*MockDiff)(nil).GetClaimable), ownerID) } // GetCurrentDelegatorIterator mocks base method. -func (m *MockState) GetCurrentDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { +func (m *MockDiff) GetCurrentDelegatorIterator(subnetID ids.ID, nodeID ids.NodeID) (StakerIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", arg0, arg1) + ret := m.ctrl.Call(m, "GetCurrentDelegatorIterator", subnetID, nodeID) ret0, _ := ret[0].(StakerIterator) ret1, _ := ret[1].(error) return ret0, ret1 } // GetCurrentDelegatorIterator indicates an expected call of GetCurrentDelegatorIterator. -func (mr *MockStateMockRecorder) GetCurrentDelegatorIterator(arg0, arg1 any) *gomock.Call { +func (mr *MockDiffMockRecorder) GetCurrentDelegatorIterator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockState)(nil).GetCurrentDelegatorIterator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentDelegatorIterator), subnetID, nodeID) } // GetCurrentStakerIterator mocks base method. -func (m *MockState) GetCurrentStakerIterator() (StakerIterator, error) { +func (m *MockDiff) GetCurrentStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCurrentStakerIterator") ret0, _ := ret[0].(StakerIterator) @@ -2472,194 +2637,133 @@ func (m *MockState) GetCurrentStakerIterator() (StakerIterator, error) { } // GetCurrentStakerIterator indicates an expected call of GetCurrentStakerIterator. -func (mr *MockStateMockRecorder) GetCurrentStakerIterator() *gomock.Call { +func (mr *MockDiffMockRecorder) GetCurrentStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockState)(nil).GetCurrentStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetCurrentStakerIterator)) } // GetCurrentSupply mocks base method. -func (m *MockState) GetCurrentSupply(arg0 ids.ID) (uint64, error) { +func (m *MockDiff) GetCurrentSupply(subnetID ids.ID) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentSupply", arg0) + ret := m.ctrl.Call(m, "GetCurrentSupply", subnetID) ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } // GetCurrentSupply indicates an expected call of GetCurrentSupply. -func (mr *MockStateMockRecorder) GetCurrentSupply(arg0 any) *gomock.Call { +func (mr *MockDiffMockRecorder) GetCurrentSupply(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockState)(nil).GetCurrentSupply), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).GetCurrentSupply), subnetID) } // GetCurrentValidator mocks base method. -func (m *MockState) GetCurrentValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +func (m *MockDiff) GetCurrentValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentValidator", arg0, arg1) + ret := m.ctrl.Call(m, "GetCurrentValidator", subnetID, nodeID) ret0, _ := ret[0].(*Staker) ret1, _ := ret[1].(error) return ret0, ret1 } // GetCurrentValidator indicates an expected call of GetCurrentValidator. -func (mr *MockStateMockRecorder) GetCurrentValidator(arg0, arg1 any) *gomock.Call { +func (mr *MockDiffMockRecorder) GetCurrentValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockState)(nil).GetCurrentValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidator", reflect.TypeOf((*MockDiff)(nil).GetCurrentValidator), subnetID, nodeID) } -// GetDelegateeReward mocks base method. -func (m *MockState) GetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID) (uint64, error) { +// GetDeferredStakerIterator mocks base method. +func (m *MockDiff) GetDeferredStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDelegateeReward", arg0, arg1) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "GetDeferredStakerIterator") + ret0, _ := ret[0].(StakerIterator) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDelegateeReward indicates an expected call of GetDelegateeReward. -func (mr *MockStateMockRecorder) GetDelegateeReward(arg0, arg1 any) *gomock.Call { +// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. +func (mr *MockDiffMockRecorder) GetDeferredStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockState)(nil).GetDelegateeReward), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetDeferredStakerIterator)) } -// GetDeposit mocks base method. -func (m *MockState) GetDeposit(arg0 ids.ID) (*deposit.Deposit, error) { +// GetDeferredValidator mocks base method. +func (m *MockDiff) GetDeferredValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeposit", arg0) - ret0, _ := ret[0].(*deposit.Deposit) + ret := m.ctrl.Call(m, "GetDeferredValidator", subnetID, nodeID) + ret0, _ := ret[0].(*Staker) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDeposit indicates an expected call of GetDeposit. -func (mr *MockStateMockRecorder) GetDeposit(arg0 interface{}) *gomock.Call { +// GetDeferredValidator indicates an expected call of GetDeferredValidator. +func (mr *MockDiffMockRecorder) GetDeferredValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockState)(nil).GetDeposit), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockDiff)(nil).GetDeferredValidator), subnetID, nodeID) } -// GetNextToUnlockDepositTime mocks base method. -func (m *MockState) GetNextToUnlockDepositTime(arg0 set.Set[ids.ID]) (time.Time, error) { +// GetDelegateeReward mocks base method. +func (m *MockDiff) GetDelegateeReward(subnetID ids.ID, nodeID ids.NodeID) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", arg0) - ret0, _ := ret[0].(time.Time) + ret := m.ctrl.Call(m, "GetDelegateeReward", subnetID, nodeID) + ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. -func (mr *MockStateMockRecorder) GetNextToUnlockDepositTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockState)(nil).GetNextToUnlockDepositTime), arg0) -} - -// GetNextToUnlockDepositIDsAndTime mocks base method. -func (m *MockState) GetNextToUnlockDepositIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. -func (mr *MockStateMockRecorder) GetNextToUnlockDepositIDsAndTime(arg0 interface{}) *gomock.Call { +// GetDelegateeReward indicates an expected call of GetDelegateeReward. +func (mr *MockDiffMockRecorder) GetDelegateeReward(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockState)(nil).GetNextToUnlockDepositIDsAndTime), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).GetDelegateeReward), subnetID, nodeID) } -// GetNextProposalExpirationTime mocks base method. -func (m *MockState) GetNextProposalExpirationTime(arg0 set.Set[ids.ID]) (time.Time, error) { +// GetDeposit mocks base method. +func (m *MockDiff) GetDeposit(depositTxID ids.ID) (*deposit.Deposit, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", arg0) - ret0, _ := ret[0].(time.Time) + ret := m.ctrl.Call(m, "GetDeposit", depositTxID) + ret0, _ := ret[0].(*deposit.Deposit) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. -func (mr *MockStateMockRecorder) GetNextProposalExpirationTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockState)(nil).GetNextProposalExpirationTime), arg0) -} - -// GetNextToExpireProposalIDsAndTime mocks base method. -func (m *MockState) GetNextToExpireProposalIDsAndTime(arg0 set.Set[ids.ID]) ([]ids.ID, time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", arg0) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. -func (mr *MockStateMockRecorder) GetNextToExpireProposalIDsAndTime(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockState)(nil).GetNextToExpireProposalIDsAndTime), arg0) -} - -// GetProposalIDsToFinish mocks base method. -func (m *MockState) GetProposalIDsToFinish() ([]ids.ID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposalIDsToFinish") - ret0, _ := ret[0].([]ids.ID) - ret2, _ := ret[1].(error) - return ret0, ret2 -} - -// GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. -func (mr *MockStateMockRecorder) GetProposalIDsToFinish() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockState)(nil).GetProposalIDsToFinish)) -} - -// GetProposalIterator mocks base method. -func (m *MockState) GetProposalIterator() (ProposalsIterator, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposalIterator") - ret0, _ := ret[0].(ProposalsIterator) - ret2, _ := ret[1].(error) - return ret0, ret2 -} - -// GetProposalIterator indicates an expected call of GetProposalIterator. -func (mr *MockStateMockRecorder) GetProposalIterator() *gomock.Call { +// GetDeposit indicates an expected call of GetDeposit. +func (mr *MockDiffMockRecorder) GetDeposit(depositTxID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockState)(nil).GetProposalIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeposit", reflect.TypeOf((*MockDiff)(nil).GetDeposit), depositTxID) } // GetDepositOffer mocks base method. -func (m *MockState) GetDepositOffer(arg0 ids.ID) (*deposit.Offer, error) { +func (m *MockDiff) GetDepositOffer(offerID ids.ID) (*deposit.Offer, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDepositOffer", arg0) + ret := m.ctrl.Call(m, "GetDepositOffer", offerID) ret0, _ := ret[0].(*deposit.Offer) ret1, _ := ret[1].(error) return ret0, ret1 } // GetDepositOffer indicates an expected call of GetDepositOffer. -func (mr *MockStateMockRecorder) GetDepositOffer(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetDepositOffer(offerID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockState)(nil).GetDepositOffer), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDepositOffer", reflect.TypeOf((*MockDiff)(nil).GetDepositOffer), offerID) } -// GetLastAccepted mocks base method. -func (m *MockState) GetLastAccepted() ids.ID { +// GetFeeDistribution mocks base method. +func (m *MockDiff) GetFeeDistribution() ([dac.FeeDistributionFractionsCount]uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastAccepted") - ret0, _ := ret[0].(ids.ID) - return ret0 + ret := m.ctrl.Call(m, "GetFeeDistribution") + ret0, _ := ret[0].([dac.FeeDistributionFractionsCount]uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// GetLastAccepted indicates an expected call of GetLastAccepted. -func (mr *MockStateMockRecorder) GetLastAccepted() *gomock.Call { +// GetFeeDistribution indicates an expected call of GetFeeDistribution. +func (mr *MockDiffMockRecorder) GetFeeDistribution() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastAccepted", reflect.TypeOf((*MockState)(nil).GetLastAccepted)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeDistribution", reflect.TypeOf((*MockDiff)(nil).GetFeeDistribution)) } // GetMultisigAlias mocks base method. -func (m *MockState) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { +func (m *MockDiff) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetMultisigAlias", arg0) ret0, _ := ret[0].(*multisig.AliasWithNonce) @@ -2668,232 +2772,225 @@ func (m *MockState) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWithNonce } // GetMultisigAlias indicates an expected call of GetMultisigAlias. -func (mr *MockStateMockRecorder) GetMultisigAlias(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) GetMultisigAlias(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockState)(nil).GetMultisigAlias), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockDiff)(nil).GetMultisigAlias), arg0) } -// GetNotDistributedValidatorReward mocks base method. -func (m *MockState) GetNotDistributedValidatorReward() (uint64, error) { +// GetNextProposalExpirationTime mocks base method. +func (m *MockDiff) GetNextProposalExpirationTime(removedProposalIDs set.Set[ids.ID]) (time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "GetNextProposalExpirationTime", removedProposalIDs) + ret0, _ := ret[0].(time.Time) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. -func (mr *MockStateMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { +// GetNextProposalExpirationTime indicates an expected call of GetNextProposalExpirationTime. +func (mr *MockDiffMockRecorder) GetNextProposalExpirationTime(removedProposalIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockState)(nil).GetNotDistributedValidatorReward)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextProposalExpirationTime", reflect.TypeOf((*MockDiff)(nil).GetNextProposalExpirationTime), removedProposalIDs) } -// GetPendingDelegatorIterator mocks base method. -func (m *MockState) GetPendingDelegatorIterator(arg0 ids.ID, arg1 ids.NodeID) (StakerIterator, error) { +// GetNextToExpireProposalIDsAndTime mocks base method. +func (m *MockDiff) GetNextToExpireProposalIDsAndTime(removedProposalIDs set.Set[ids.ID]) ([]ids.ID, time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", arg0, arg1) - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "GetNextToExpireProposalIDsAndTime", removedProposalIDs) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. -func (mr *MockStateMockRecorder) GetPendingDelegatorIterator(arg0, arg1 any) *gomock.Call { +// GetNextToExpireProposalIDsAndTime indicates an expected call of GetNextToExpireProposalIDsAndTime. +func (mr *MockDiffMockRecorder) GetNextToExpireProposalIDsAndTime(removedProposalIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockState)(nil).GetPendingDelegatorIterator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToExpireProposalIDsAndTime", reflect.TypeOf((*MockDiff)(nil).GetNextToExpireProposalIDsAndTime), removedProposalIDs) } -// GetPendingStakerIterator mocks base method. -func (m *MockState) GetPendingStakerIterator() (StakerIterator, error) { +// GetNextToUnlockDepositIDsAndTime mocks base method. +func (m *MockDiff) GetNextToUnlockDepositIDsAndTime(removedDepositIDs set.Set[ids.ID]) ([]ids.ID, time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingStakerIterator") - ret0, _ := ret[0].(StakerIterator) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "GetNextToUnlockDepositIDsAndTime", removedDepositIDs) + ret0, _ := ret[0].([]ids.ID) + ret1, _ := ret[1].(time.Time) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. -func (mr *MockStateMockRecorder) GetPendingStakerIterator() *gomock.Call { +// GetNextToUnlockDepositIDsAndTime indicates an expected call of GetNextToUnlockDepositIDsAndTime. +func (mr *MockDiffMockRecorder) GetNextToUnlockDepositIDsAndTime(removedDepositIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockState)(nil).GetPendingStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositIDsAndTime", reflect.TypeOf((*MockDiff)(nil).GetNextToUnlockDepositIDsAndTime), removedDepositIDs) } -// GetPendingValidator mocks base method. -func (m *MockState) GetPendingValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// GetNextToUnlockDepositTime mocks base method. +func (m *MockDiff) GetNextToUnlockDepositTime(removedDepositIDs set.Set[ids.ID]) (time.Time, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPendingValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) + ret := m.ctrl.Call(m, "GetNextToUnlockDepositTime", removedDepositIDs) + ret0, _ := ret[0].(time.Time) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetPendingValidator indicates an expected call of GetPendingValidator. -func (mr *MockStateMockRecorder) GetPendingValidator(arg0, arg1 any) *gomock.Call { +// GetNextToUnlockDepositTime indicates an expected call of GetNextToUnlockDepositTime. +func (mr *MockDiffMockRecorder) GetNextToUnlockDepositTime(removedDepositIDs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockState)(nil).GetPendingValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNextToUnlockDepositTime", reflect.TypeOf((*MockDiff)(nil).GetNextToUnlockDepositTime), removedDepositIDs) } -// GetDeferredStakerIterator mocks base method. -func (m *MockState) GetDeferredStakerIterator() (StakerIterator, error) { +// GetNotDistributedValidatorReward mocks base method. +func (m *MockDiff) GetNotDistributedValidatorReward() (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredStakerIterator") - ret0, _ := ret[0].(StakerIterator) + ret := m.ctrl.Call(m, "GetNotDistributedValidatorReward") + ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDeferredStakerIterator indicates an expected call of GetDeferredStakerIterator. -func (mr *MockStateMockRecorder) GetDeferredStakerIterator() *gomock.Call { +// GetNotDistributedValidatorReward indicates an expected call of GetNotDistributedValidatorReward. +func (mr *MockDiffMockRecorder) GetNotDistributedValidatorReward() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredStakerIterator", reflect.TypeOf((*MockState)(nil).GetDeferredStakerIterator)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotDistributedValidatorReward", reflect.TypeOf((*MockDiff)(nil).GetNotDistributedValidatorReward)) } -// GetDeferredValidator mocks base method. -func (m *MockState) GetDeferredValidator(arg0 ids.ID, arg1 ids.NodeID) (*Staker, error) { +// GetPendingDelegatorIterator mocks base method. +func (m *MockDiff) GetPendingDelegatorIterator(subnetID ids.ID, nodeID ids.NodeID) (StakerIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDeferredValidator", arg0, arg1) - ret0, _ := ret[0].(*Staker) + ret := m.ctrl.Call(m, "GetPendingDelegatorIterator", subnetID, nodeID) + ret0, _ := ret[0].(StakerIterator) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetDeferredValidator indicates an expected call of GetDeferredValidator. -func (mr *MockStateMockRecorder) GetDeferredValidator(arg0, arg1 interface{}) *gomock.Call { +// GetPendingDelegatorIterator indicates an expected call of GetPendingDelegatorIterator. +func (mr *MockDiffMockRecorder) GetPendingDelegatorIterator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeferredValidator", reflect.TypeOf((*MockState)(nil).GetDeferredValidator), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingDelegatorIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingDelegatorIterator), subnetID, nodeID) } -// DeleteDeferredValidator mocks base method. -func (m *MockState) DeleteDeferredValidator(arg0 *Staker) { +// GetPendingStakerIterator mocks base method. +func (m *MockDiff) GetPendingStakerIterator() (StakerIterator, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "DeleteDeferredValidator", arg0) + ret := m.ctrl.Call(m, "GetPendingStakerIterator") + ret0, _ := ret[0].(StakerIterator) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// DeleteDeferredValidator indicates an expected call of DeleteDeferredValidator. -func (mr *MockStateMockRecorder) DeleteDeferredValidator(arg0 interface{}) *gomock.Call { +// GetPendingStakerIterator indicates an expected call of GetPendingStakerIterator. +func (mr *MockDiffMockRecorder) GetPendingStakerIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDeferredValidator", reflect.TypeOf((*MockState)(nil).DeleteDeferredValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingStakerIterator", reflect.TypeOf((*MockDiff)(nil).GetPendingStakerIterator)) } -// PutDeferredValidator mocks base method. -func (m *MockState) PutDeferredValidator(arg0 *Staker) { +// GetPendingValidator mocks base method. +func (m *MockDiff) GetPendingValidator(subnetID ids.ID, nodeID ids.NodeID) (*Staker, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutDeferredValidator", arg0) + ret := m.ctrl.Call(m, "GetPendingValidator", subnetID, nodeID) + ret0, _ := ret[0].(*Staker) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// PutDeferredValidator indicates an expected call of PutDeferredValidator. -func (mr *MockStateMockRecorder) PutDeferredValidator(arg0 interface{}) *gomock.Call { +// GetPendingValidator indicates an expected call of GetPendingValidator. +func (mr *MockDiffMockRecorder) GetPendingValidator(subnetID, nodeID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockState)(nil).PutDeferredValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPendingValidator", reflect.TypeOf((*MockDiff)(nil).GetPendingValidator), subnetID, nodeID) } -// GetRewardUTXOs mocks base method. -func (m *MockState) GetRewardUTXOs(arg0 ids.ID) ([]*avax.UTXO, error) { +// GetProposal mocks base method. +func (m *MockDiff) GetProposal(proposalID ids.ID) (dac.ProposalState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRewardUTXOs", arg0) - ret0, _ := ret[0].([]*avax.UTXO) + ret := m.ctrl.Call(m, "GetProposal", proposalID) + ret0, _ := ret[0].(dac.ProposalState) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetRewardUTXOs indicates an expected call of GetRewardUTXOs. -func (mr *MockStateMockRecorder) GetRewardUTXOs(arg0 any) *gomock.Call { +// GetProposal indicates an expected call of GetProposal. +func (mr *MockDiffMockRecorder) GetProposal(proposalID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardUTXOs", reflect.TypeOf((*MockState)(nil).GetRewardUTXOs), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockDiff)(nil).GetProposal), proposalID) } -// GetShortIDLink mocks base method. -func (m *MockState) GetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey) (ids.ShortID, error) { +// GetProposalIDsToFinish mocks base method. +func (m *MockDiff) GetProposalIDsToFinish() ([]ids.ID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetShortIDLink", arg0, arg1) - ret0, _ := ret[0].(ids.ShortID) + ret := m.ctrl.Call(m, "GetProposalIDsToFinish") + ret0, _ := ret[0].([]ids.ID) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetShortIDLink indicates an expected call of GetShortIDLink. -func (mr *MockStateMockRecorder) GetShortIDLink(arg0, arg1 interface{}) *gomock.Call { +// GetProposalIDsToFinish indicates an expected call of GetProposalIDsToFinish. +func (mr *MockDiffMockRecorder) GetProposalIDsToFinish() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockState)(nil).GetShortIDLink), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIDsToFinish", reflect.TypeOf((*MockDiff)(nil).GetProposalIDsToFinish)) } -// GetStartTime mocks base method. -func (m *MockState) GetStartTime(arg0 ids.NodeID, arg1 ids.ID) (time.Time, error) { +// GetProposalIterator mocks base method. +func (m *MockDiff) GetProposalIterator() (ProposalsIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStartTime", arg0, arg1) - ret0, _ := ret[0].(time.Time) + ret := m.ctrl.Call(m, "GetProposalIterator") + ret0, _ := ret[0].(ProposalsIterator) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetStartTime indicates an expected call of GetStartTime. -func (mr *MockStateMockRecorder) GetStartTime(arg0, arg1 any) *gomock.Call { +// GetProposalIterator indicates an expected call of GetProposalIterator. +func (mr *MockDiffMockRecorder) GetProposalIterator() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStartTime", reflect.TypeOf((*MockState)(nil).GetStartTime), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposalIterator", reflect.TypeOf((*MockDiff)(nil).GetProposalIterator)) } -// GetStatelessBlock mocks base method. -func (m *MockState) GetStatelessBlock(arg0 ids.ID) (block.Block, error) { +// GetShortIDLink mocks base method. +func (m *MockDiff) GetShortIDLink(id ids.ShortID, key ShortLinkKey) (ids.ShortID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStatelessBlock", arg0) - ret0, _ := ret[0].(block.Block) + ret := m.ctrl.Call(m, "GetShortIDLink", id, key) + ret0, _ := ret[0].(ids.ShortID) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetStatelessBlock indicates an expected call of GetStatelessBlock. -func (mr *MockStateMockRecorder) GetStatelessBlock(arg0 any) *gomock.Call { +// GetShortIDLink indicates an expected call of GetShortIDLink. +func (mr *MockDiffMockRecorder) GetShortIDLink(id, key any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatelessBlock", reflect.TypeOf((*MockState)(nil).GetStatelessBlock), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShortIDLink", reflect.TypeOf((*MockDiff)(nil).GetShortIDLink), id, key) } // GetSubnetOwner mocks base method. -func (m *MockState) GetSubnetOwner(arg0 ids.ID) (fx.Owner, error) { +func (m *MockDiff) GetSubnetOwner(subnetID ids.ID) (fx.Owner, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetOwner", arg0) + ret := m.ctrl.Call(m, "GetSubnetOwner", subnetID) ret0, _ := ret[0].(fx.Owner) ret1, _ := ret[1].(error) return ret0, ret1 } // GetSubnetOwner indicates an expected call of GetSubnetOwner. -func (mr *MockStateMockRecorder) GetSubnetOwner(arg0 any) *gomock.Call { +func (mr *MockDiffMockRecorder) GetSubnetOwner(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockState)(nil).GetSubnetOwner), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).GetSubnetOwner), subnetID) } // GetSubnetTransformation mocks base method. -func (m *MockState) GetSubnetTransformation(arg0 ids.ID) (*txs.Tx, error) { +func (m *MockDiff) GetSubnetTransformation(subnetID ids.ID) (*txs.Tx, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnetTransformation", arg0) + ret := m.ctrl.Call(m, "GetSubnetTransformation", subnetID) ret0, _ := ret[0].(*txs.Tx) ret1, _ := ret[1].(error) return ret0, ret1 } // GetSubnetTransformation indicates an expected call of GetSubnetTransformation. -func (mr *MockStateMockRecorder) GetSubnetTransformation(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockState)(nil).GetSubnetTransformation), arg0) -} - -// GetSubnets mocks base method. -func (m *MockState) GetSubnets() ([]*txs.Tx, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSubnets") - ret0, _ := ret[0].([]*txs.Tx) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSubnets indicates an expected call of GetSubnets. -func (mr *MockStateMockRecorder) GetSubnets() *gomock.Call { +func (mr *MockDiffMockRecorder) GetSubnetTransformation(subnetID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnets", reflect.TypeOf((*MockState)(nil).GetSubnets)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubnetTransformation", reflect.TypeOf((*MockDiff)(nil).GetSubnetTransformation), subnetID) } // GetTimestamp mocks base method. -func (m *MockState) GetTimestamp() time.Time { +func (m *MockDiff) GetTimestamp() time.Time { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetTimestamp") ret0, _ := ret[0].(time.Time) @@ -2901,15 +2998,15 @@ func (m *MockState) GetTimestamp() time.Time { } // GetTimestamp indicates an expected call of GetTimestamp. -func (mr *MockStateMockRecorder) GetTimestamp() *gomock.Call { +func (mr *MockDiffMockRecorder) GetTimestamp() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockState)(nil).GetTimestamp)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTimestamp", reflect.TypeOf((*MockDiff)(nil).GetTimestamp)) } // GetTx mocks base method. -func (m *MockState) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { +func (m *MockDiff) GetTx(txID ids.ID) (*txs.Tx, status.Status, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTx", arg0) + ret := m.ctrl.Call(m, "GetTx", txID) ret0, _ := ret[0].(*txs.Tx) ret1, _ := ret[1].(status.Status) ret2, _ := ret[2].(error) @@ -2917,58 +3014,28 @@ func (m *MockState) GetTx(arg0 ids.ID) (*txs.Tx, status.Status, error) { } // GetTx indicates an expected call of GetTx. -func (mr *MockStateMockRecorder) GetTx(arg0 any) *gomock.Call { +func (mr *MockDiffMockRecorder) GetTx(txID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockState)(nil).GetTx), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTx", reflect.TypeOf((*MockDiff)(nil).GetTx), txID) } // GetUTXO mocks base method. -func (m *MockState) GetUTXO(arg0 ids.ID) (*avax.UTXO, error) { +func (m *MockDiff) GetUTXO(utxoID ids.ID) (*avax.UTXO, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUTXO", arg0) + ret := m.ctrl.Call(m, "GetUTXO", utxoID) ret0, _ := ret[0].(*avax.UTXO) ret1, _ := ret[1].(error) return ret0, ret1 } // GetUTXO indicates an expected call of GetUTXO. -func (mr *MockStateMockRecorder) GetUTXO(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockState)(nil).GetUTXO), arg0) -} - -// GetUptime mocks base method. -func (m *MockState) GetUptime(arg0 ids.NodeID, arg1 ids.ID) (time.Duration, time.Time, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUptime", arg0, arg1) - ret0, _ := ret[0].(time.Duration) - ret1, _ := ret[1].(time.Time) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetUptime indicates an expected call of GetUptime. -func (mr *MockStateMockRecorder) GetUptime(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUptime", reflect.TypeOf((*MockState)(nil).GetUptime), arg0, arg1) -} - -// PruneAndIndex mocks base method. -func (m *MockState) PruneAndIndex(arg0 sync.Locker, arg1 logging.Logger) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PruneAndIndex", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// PruneAndIndex indicates an expected call of PruneAndIndex. -func (mr *MockStateMockRecorder) PruneAndIndex(arg0, arg1 any) *gomock.Call { +func (mr *MockDiffMockRecorder) GetUTXO(utxoID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PruneAndIndex", reflect.TypeOf((*MockState)(nil).PruneAndIndex), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUTXO", reflect.TypeOf((*MockDiff)(nil).GetUTXO), utxoID) } // LockedUTXOs mocks base method. -func (m *MockState) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { +func (m *MockDiff) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], arg2 locked.State) ([]*avax.UTXO, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LockedUTXOs", arg0, arg1, arg2) ret0, _ := ret[0].([]*avax.UTXO) @@ -2977,355 +3044,275 @@ func (m *MockState) LockedUTXOs(arg0 set.Set[ids.ID], arg1 set.Set[ids.ShortID], } // LockedUTXOs indicates an expected call of LockedUTXOs. -func (mr *MockStateMockRecorder) LockedUTXOs(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) LockedUTXOs(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockState)(nil).LockedUTXOs), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LockedUTXOs", reflect.TypeOf((*MockDiff)(nil).LockedUTXOs), arg0, arg1, arg2) } -// PutCurrentDelegator mocks base method. -func (m *MockState) PutCurrentDelegator(arg0 *Staker) { +// ModifyDeposit mocks base method. +func (m *MockDiff) ModifyDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentDelegator", arg0) + m.ctrl.Call(m, "ModifyDeposit", depositTxID, deposit) } -// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. -func (mr *MockStateMockRecorder) PutCurrentDelegator(arg0 any) *gomock.Call { +// ModifyDeposit indicates an expected call of ModifyDeposit. +func (mr *MockDiffMockRecorder) ModifyDeposit(depositTxID, deposit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockState)(nil).PutCurrentDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockDiff)(nil).ModifyDeposit), depositTxID, deposit) } -// PutCurrentValidator mocks base method. -func (m *MockState) PutCurrentValidator(arg0 *Staker) { +// ModifyProposal mocks base method. +func (m *MockDiff) ModifyProposal(proposalID ids.ID, proposal dac.ProposalState) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutCurrentValidator", arg0) + m.ctrl.Call(m, "ModifyProposal", proposalID, proposal) } -// PutCurrentValidator indicates an expected call of PutCurrentValidator. -func (mr *MockStateMockRecorder) PutCurrentValidator(arg0 any) *gomock.Call { +// ModifyProposal indicates an expected call of ModifyProposal. +func (mr *MockDiffMockRecorder) ModifyProposal(proposalID, proposal any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockState)(nil).PutCurrentValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockDiff)(nil).ModifyProposal), proposalID, proposal) } -// PutPendingDelegator mocks base method. -func (m *MockState) PutPendingDelegator(arg0 *Staker) { +// PutCurrentDelegator mocks base method. +func (m *MockDiff) PutCurrentDelegator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingDelegator", arg0) + m.ctrl.Call(m, "PutCurrentDelegator", staker) } -// PutPendingDelegator indicates an expected call of PutPendingDelegator. -func (mr *MockStateMockRecorder) PutPendingDelegator(arg0 any) *gomock.Call { +// PutCurrentDelegator indicates an expected call of PutCurrentDelegator. +func (mr *MockDiffMockRecorder) PutCurrentDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockState)(nil).PutPendingDelegator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentDelegator", reflect.TypeOf((*MockDiff)(nil).PutCurrentDelegator), staker) } -// PutPendingValidator mocks base method. -func (m *MockState) PutPendingValidator(arg0 *Staker) { +// PutCurrentValidator mocks base method. +func (m *MockDiff) PutCurrentValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "PutPendingValidator", arg0) + m.ctrl.Call(m, "PutCurrentValidator", staker) } -// PutPendingValidator indicates an expected call of PutPendingValidator. -func (mr *MockStateMockRecorder) PutPendingValidator(arg0 any) *gomock.Call { +// PutCurrentValidator indicates an expected call of PutCurrentValidator. +func (mr *MockDiffMockRecorder) PutCurrentValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockState)(nil).PutPendingValidator), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutCurrentValidator", reflect.TypeOf((*MockDiff)(nil).PutCurrentValidator), staker) } -// SetAddressStates mocks base method. -func (m *MockState) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { +// PutDeferredValidator mocks base method. +func (m *MockDiff) PutDeferredValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetAddressStates", arg0, arg1) + m.ctrl.Call(m, "PutDeferredValidator", staker) } -// SetAddressStates indicates an expected call of SetAddressStates. -func (mr *MockStateMockRecorder) SetAddressStates(arg0, arg1 interface{}) *gomock.Call { +// PutDeferredValidator indicates an expected call of PutDeferredValidator. +func (mr *MockDiffMockRecorder) PutDeferredValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockState)(nil).SetAddressStates), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeferredValidator", reflect.TypeOf((*MockDiff)(nil).PutDeferredValidator), staker) } -// SetClaimable mocks base method. -func (m *MockState) SetClaimable(arg0 ids.ID, arg1 *Claimable) { +// PutPendingDelegator mocks base method. +func (m *MockDiff) PutPendingDelegator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetClaimable", arg0, arg1) + m.ctrl.Call(m, "PutPendingDelegator", staker) } -// SetClaimable indicates an expected call of SetClaimable. -func (mr *MockStateMockRecorder) SetClaimable(arg0, arg1 interface{}) *gomock.Call { +// PutPendingDelegator indicates an expected call of PutPendingDelegator. +func (mr *MockDiffMockRecorder) PutPendingDelegator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockState)(nil).SetClaimable), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingDelegator", reflect.TypeOf((*MockDiff)(nil).PutPendingDelegator), staker) } -// AddProposal mocks base method. -func (m *MockState) AddProposal(arg0 ids.ID, arg1 dac.ProposalState) { +// PutPendingValidator mocks base method. +func (m *MockDiff) PutPendingValidator(staker *Staker) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposal", arg0, arg1) + m.ctrl.Call(m, "PutPendingValidator", staker) } -// AddProposal indicates an expected call of AddProposal. -func (mr *MockStateMockRecorder) AddProposal(arg0, arg1 interface{}) *gomock.Call { +// PutPendingValidator indicates an expected call of PutPendingValidator. +func (mr *MockDiffMockRecorder) PutPendingValidator(staker any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposal", reflect.TypeOf((*MockState)(nil).AddProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPendingValidator", reflect.TypeOf((*MockDiff)(nil).PutPendingValidator), staker) } -// ModifyProposal mocks base method. -func (m *MockState) ModifyProposal(arg0 ids.ID, arg1 dac.ProposalState) { +// RemoveDeposit mocks base method. +func (m *MockDiff) RemoveDeposit(depositTxID ids.ID, deposit *deposit.Deposit) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyProposal", arg0, arg1) + m.ctrl.Call(m, "RemoveDeposit", depositTxID, deposit) } -// ModifyProposal indicates an expected call of ModifyProposal. -func (mr *MockStateMockRecorder) ModifyProposal(arg0, arg1 interface{}) *gomock.Call { +// RemoveDeposit indicates an expected call of RemoveDeposit. +func (mr *MockDiffMockRecorder) RemoveDeposit(depositTxID, deposit any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyProposal", reflect.TypeOf((*MockState)(nil).ModifyProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockDiff)(nil).RemoveDeposit), depositTxID, deposit) } // RemoveProposal mocks base method. -func (m *MockState) RemoveProposal(arg0 ids.ID, arg1 dac.ProposalState) { +func (m *MockDiff) RemoveProposal(proposalID ids.ID, proposal dac.ProposalState) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposal", arg0, arg1) + m.ctrl.Call(m, "RemoveProposal", proposalID, proposal) } // RemoveProposal indicates an expected call of RemoveProposal. -func (mr *MockStateMockRecorder) RemoveProposal(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) RemoveProposal(proposalID, proposal any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockState)(nil).RemoveProposal), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposal", reflect.TypeOf((*MockDiff)(nil).RemoveProposal), proposalID, proposal) } -// AddProposalIDToFinish mocks base method. -func (m *MockState) AddProposalIDToFinish(arg0 ids.ID) { +// RemoveProposalIDToFinish mocks base method. +func (m *MockDiff) RemoveProposalIDToFinish(arg0 ids.ID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddProposalIDToFinish", arg0) + m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) } -// AddProposalIDToFinish indicates an expected call of AddProposalIDToFinish. -func (mr *MockStateMockRecorder) AddProposalIDToFinish(arg0 interface{}) *gomock.Call { +// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. +func (mr *MockDiffMockRecorder) RemoveProposalIDToFinish(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProposalIDToFinish", reflect.TypeOf((*MockState)(nil).AddProposalIDToFinish), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockDiff)(nil).RemoveProposalIDToFinish), arg0) } -// RemoveProposalIDToFinish mocks base method. -func (m *MockState) RemoveProposalIDToFinish(arg0 ids.ID) { +// SetAddressStates mocks base method. +func (m *MockDiff) SetAddressStates(arg0 ids.ShortID, arg1 addrstate.AddressState) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveProposalIDToFinish", arg0) + m.ctrl.Call(m, "SetAddressStates", arg0, arg1) } -// RemoveProposalIDToFinish indicates an expected call of RemoveProposalIDToFinish. -func (mr *MockStateMockRecorder) RemoveProposalIDToFinish(arg0 interface{}) *gomock.Call { +// SetAddressStates indicates an expected call of SetAddressStates. +func (mr *MockDiffMockRecorder) SetAddressStates(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProposalIDToFinish", reflect.TypeOf((*MockState)(nil).RemoveProposalIDToFinish), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddressStates", reflect.TypeOf((*MockDiff)(nil).SetAddressStates), arg0, arg1) } // SetBaseFee mocks base method. -func (m *MockState) SetBaseFee(arg0 uint64) { +func (m *MockDiff) SetBaseFee(arg0 uint64) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetBaseFee", arg0) } // SetBaseFee indicates an expected call of SetBaseFee. -func (mr *MockStateMockRecorder) SetBaseFee(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) SetBaseFee(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockState)(nil).SetBaseFee), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBaseFee", reflect.TypeOf((*MockDiff)(nil).SetBaseFee), arg0) } -// SetFeeDistribution mocks base method. -func (m *MockState) SetFeeDistribution(arg0 [dac.FeeDistributionFractionsCount]uint64) { +// SetClaimable mocks base method. +func (m *MockDiff) SetClaimable(ownerID ids.ID, claimable *Claimable) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetFeeDistribution", arg0) + m.ctrl.Call(m, "SetClaimable", ownerID, claimable) } -// SetFeeDistribution indicates an expected call of SetFeeDistribution. -func (mr *MockStateMockRecorder) SetFeeDistribution(arg0 interface{}) *gomock.Call { +// SetClaimable indicates an expected call of SetClaimable. +func (mr *MockDiffMockRecorder) SetClaimable(ownerID, claimable any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockState)(nil).SetFeeDistribution), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClaimable", reflect.TypeOf((*MockDiff)(nil).SetClaimable), ownerID, claimable) } // SetCurrentSupply mocks base method. -func (m *MockState) SetCurrentSupply(arg0 ids.ID, arg1 uint64) { +func (m *MockDiff) SetCurrentSupply(subnetID ids.ID, cs uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCurrentSupply", arg0, arg1) + m.ctrl.Call(m, "SetCurrentSupply", subnetID, cs) } // SetCurrentSupply indicates an expected call of SetCurrentSupply. -func (mr *MockStateMockRecorder) SetCurrentSupply(arg0, arg1 any) *gomock.Call { +func (mr *MockDiffMockRecorder) SetCurrentSupply(subnetID, cs any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockState)(nil).SetCurrentSupply), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCurrentSupply", reflect.TypeOf((*MockDiff)(nil).SetCurrentSupply), subnetID, cs) } // SetDelegateeReward mocks base method. -func (m *MockState) SetDelegateeReward(arg0 ids.ID, arg1 ids.NodeID, arg2 uint64) error { +func (m *MockDiff) SetDelegateeReward(subnetID ids.ID, nodeID ids.NodeID, amount uint64) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDelegateeReward", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "SetDelegateeReward", subnetID, nodeID, amount) ret0, _ := ret[0].(error) return ret0 } // SetDelegateeReward indicates an expected call of SetDelegateeReward. -func (mr *MockStateMockRecorder) SetDelegateeReward(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockState)(nil).SetDelegateeReward), arg0, arg1, arg2) -} - -// SetHeight mocks base method. -func (m *MockState) SetHeight(arg0 uint64) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetHeight", arg0) -} - -// SetHeight indicates an expected call of SetHeight. -func (mr *MockStateMockRecorder) SetHeight(arg0 any) *gomock.Call { +func (mr *MockDiffMockRecorder) SetDelegateeReward(subnetID, nodeID, amount any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeight", reflect.TypeOf((*MockState)(nil).SetHeight), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDelegateeReward", reflect.TypeOf((*MockDiff)(nil).SetDelegateeReward), subnetID, nodeID, amount) } -// SetLastAccepted mocks base method. -func (m *MockState) SetLastAccepted(arg0 ids.ID) { +// SetDepositOffer mocks base method. +func (m *MockDiff) SetDepositOffer(offer *deposit.Offer) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetLastAccepted", arg0) + m.ctrl.Call(m, "SetDepositOffer", offer) } -// SetLastAccepted indicates an expected call of SetLastAccepted. -func (mr *MockStateMockRecorder) SetLastAccepted(arg0 any) *gomock.Call { +// SetDepositOffer indicates an expected call of SetDepositOffer. +func (mr *MockDiffMockRecorder) SetDepositOffer(offer any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastAccepted", reflect.TypeOf((*MockState)(nil).SetLastAccepted), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDepositOffer", reflect.TypeOf((*MockDiff)(nil).SetDepositOffer), offer) } -// SetSubnetOwner mocks base method. -func (m *MockState) SetSubnetOwner(arg0 ids.ID, arg1 fx.Owner) { +// SetFeeDistribution mocks base method. +func (m *MockDiff) SetFeeDistribution(arg0 [3]uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetSubnetOwner", arg0, arg1) + m.ctrl.Call(m, "SetFeeDistribution", arg0) } -// SetSubnetOwner indicates an expected call of SetSubnetOwner. -func (mr *MockStateMockRecorder) SetSubnetOwner(arg0, arg1 any) *gomock.Call { +// SetFeeDistribution indicates an expected call of SetFeeDistribution. +func (mr *MockDiffMockRecorder) SetFeeDistribution(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockState)(nil).SetSubnetOwner), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetFeeDistribution", reflect.TypeOf((*MockDiff)(nil).SetFeeDistribution), arg0) } // SetMultisigAlias mocks base method. -func (m *MockState) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { +func (m *MockDiff) SetMultisigAlias(arg0 ids.ShortID, arg1 *multisig.AliasWithNonce) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetMultisigAlias", arg0, arg1) } // SetMultisigAlias indicates an expected call of SetMultisigAlias. -func (mr *MockStateMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { +func (mr *MockDiffMockRecorder) SetMultisigAlias(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockState)(nil).SetMultisigAlias), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMultisigAlias", reflect.TypeOf((*MockDiff)(nil).SetMultisigAlias), arg0, arg1) } // SetNotDistributedValidatorReward mocks base method. -func (m *MockState) SetNotDistributedValidatorReward(arg0 uint64) { +func (m *MockDiff) SetNotDistributedValidatorReward(reward uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetNotDistributedValidatorReward", arg0) + m.ctrl.Call(m, "SetNotDistributedValidatorReward", reward) } // SetNotDistributedValidatorReward indicates an expected call of SetNotDistributedValidatorReward. -func (mr *MockStateMockRecorder) SetNotDistributedValidatorReward(arg0 interface{}) *gomock.Call { +func (mr *MockDiffMockRecorder) SetNotDistributedValidatorReward(reward any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockState)(nil).SetNotDistributedValidatorReward), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotDistributedValidatorReward", reflect.TypeOf((*MockDiff)(nil).SetNotDistributedValidatorReward), reward) } // SetShortIDLink mocks base method. -func (m *MockState) SetShortIDLink(arg0 ids.ShortID, arg1 ShortLinkKey, arg2 *ids.ShortID) { +func (m *MockDiff) SetShortIDLink(id ids.ShortID, key ShortLinkKey, link *ids.ShortID) { m.ctrl.T.Helper() - m.ctrl.Call(m, "SetShortIDLink", arg0, arg1, arg2) + m.ctrl.Call(m, "SetShortIDLink", id, key, link) } // SetShortIDLink indicates an expected call of SetShortIDLink. -func (mr *MockStateMockRecorder) SetShortIDLink(arg0, arg1, arg2 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockState)(nil).SetShortIDLink), arg0, arg1, arg2) -} - -// SetTimestamp mocks base method. -func (m *MockState) SetTimestamp(arg0 time.Time) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetTimestamp", arg0) -} - -// SetTimestamp indicates an expected call of SetTimestamp. -func (mr *MockStateMockRecorder) SetTimestamp(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockState)(nil).SetTimestamp), arg0) -} - -// SetUptime mocks base method. -func (m *MockState) SetUptime(arg0 ids.NodeID, arg1 ids.ID, arg2 time.Duration, arg3 time.Time) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetUptime", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetUptime indicates an expected call of SetUptime. -func (mr *MockStateMockRecorder) SetUptime(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUptime", reflect.TypeOf((*MockState)(nil).SetUptime), arg0, arg1, arg2, arg3) -} - -// ShouldPrune mocks base method. -func (m *MockState) ShouldPrune() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ShouldPrune") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ShouldPrune indicates an expected call of ShouldPrune. -func (mr *MockStateMockRecorder) ShouldPrune() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldPrune", reflect.TypeOf((*MockState)(nil).ShouldPrune)) -} - -// UTXOIDs mocks base method. -func (m *MockState) UTXOIDs(arg0 []byte, arg1 ids.ID, arg2 int) ([]ids.ID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UTXOIDs", arg0, arg1, arg2) - ret0, _ := ret[0].([]ids.ID) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// UTXOIDs indicates an expected call of UTXOIDs. -func (mr *MockStateMockRecorder) UTXOIDs(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockDiffMockRecorder) SetShortIDLink(id, key, link any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UTXOIDs", reflect.TypeOf((*MockState)(nil).UTXOIDs), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetShortIDLink", reflect.TypeOf((*MockDiff)(nil).SetShortIDLink), id, key, link) } -// AddDeposit mocks base method. -func (m *MockState) AddDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddDeposit", arg0, arg1) -} - -// AddDeposit indicates an expected call of AddDeposit. -func (mr *MockStateMockRecorder) AddDeposit(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeposit", reflect.TypeOf((*MockState)(nil).AddDeposit), arg0, arg1) -} - -// ModifyDeposit mocks base method. -func (m *MockState) ModifyDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { +// SetSubnetOwner mocks base method. +func (m *MockDiff) SetSubnetOwner(subnetID ids.ID, owner fx.Owner) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ModifyDeposit", arg0, arg1) + m.ctrl.Call(m, "SetSubnetOwner", subnetID, owner) } -// ModifyDeposit indicates an expected call of ModifyDeposit. -func (mr *MockStateMockRecorder) ModifyDeposit(arg0, arg1 interface{}) *gomock.Call { +// SetSubnetOwner indicates an expected call of SetSubnetOwner. +func (mr *MockDiffMockRecorder) SetSubnetOwner(subnetID, owner any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyDeposit", reflect.TypeOf((*MockState)(nil).ModifyDeposit), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSubnetOwner", reflect.TypeOf((*MockDiff)(nil).SetSubnetOwner), subnetID, owner) } -// RemoveDeposit mocks base method. -func (m *MockState) RemoveDeposit(arg0 ids.ID, arg1 *deposit.Deposit) { +// SetTimestamp mocks base method. +func (m *MockDiff) SetTimestamp(tm time.Time) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveDeposit", arg0, arg1) + m.ctrl.Call(m, "SetTimestamp", tm) } -// RemoveDeposit indicates an expected call of RemoveDeposit. -func (mr *MockStateMockRecorder) RemoveDeposit(arg0, arg1 interface{}) *gomock.Call { +// SetTimestamp indicates an expected call of SetTimestamp. +func (mr *MockDiffMockRecorder) SetTimestamp(tm any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDeposit", reflect.TypeOf((*MockState)(nil).RemoveDeposit), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTimestamp", reflect.TypeOf((*MockDiff)(nil).SetTimestamp), tm) } // MockVersions is a mock of Versions interface. @@ -3352,16 +3339,16 @@ func (m *MockVersions) EXPECT() *MockVersionsMockRecorder { } // GetState mocks base method. -func (m *MockVersions) GetState(arg0 ids.ID) (Chain, bool) { +func (m *MockVersions) GetState(blkID ids.ID) (Chain, bool) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetState", arg0) + ret := m.ctrl.Call(m, "GetState", blkID) ret0, _ := ret[0].(Chain) ret1, _ := ret[1].(bool) return ret0, ret1 } // GetState indicates an expected call of GetState. -func (mr *MockVersionsMockRecorder) GetState(arg0 any) *gomock.Call { +func (mr *MockVersionsMockRecorder) GetState(blkID any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockVersions)(nil).GetState), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetState", reflect.TypeOf((*MockVersions)(nil).GetState), blkID) } diff --git a/vms/platformvm/state/state.go b/vms/platformvm/state/state.go index 143f03c26654..ea52459867a9 100644 --- a/vms/platformvm/state/state.go +++ b/vms/platformvm/state/state.go @@ -1853,7 +1853,7 @@ func (s *state) init(genesisBytes []byte) error { return err } - if err := s.caminoState.SyncGenesis(s, genesis); err != nil { + if err := s.caminoState.syncGenesis(s, genesis); err != nil { return err } diff --git a/vms/platformvm/state/test/camino_test_state.go b/vms/platformvm/state/test/camino_test_state.go index 5f9951b7c561..1f6c72f8e528 100644 --- a/vms/platformvm/state/test/camino_test_state.go +++ b/vms/platformvm/state/test/camino_test_state.go @@ -11,7 +11,6 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/vms/platformvm/api" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" @@ -21,7 +20,7 @@ import ( func State( t *testing.T, - validators validators.Manager, + cfg *config.Config, ctx *snow.Context, db database.Database, rewards reward.Calculator, @@ -34,7 +33,7 @@ func State( db, genesisBytes, prometheus.NewRegistry(), - validators, + cfg, execCfg, ctx, metrics.Noop, diff --git a/vms/platformvm/test/camino_defaults.go b/vms/platformvm/test/camino_defaults.go index 851aef57eff9..082d069eb6f3 100644 --- a/vms/platformvm/test/camino_defaults.go +++ b/vms/platformvm/test/camino_defaults.go @@ -4,8 +4,6 @@ package test import ( - "context" - "errors" "testing" "time" @@ -18,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/constants" @@ -47,9 +46,6 @@ const ( ) var ( - avaxAssetID = ids.ID{'C', 'A', 'M'} - cChainID = ids.ID{'C', '-', 'C', 'H', 'A', 'I', 'N'} - xChainID = ids.ID{'X', '-', 'C', 'H', 'A', 'I', 'N'} rewardConfig = reward.Config{ MaxConsumptionRate: .12 * reward.PercentDenominator, MinConsumptionRate: .10 * reward.PercentDenominator, @@ -76,11 +72,15 @@ func Config(t *testing.T, phase Phase) *config.Config { cortinaTime = mockable.MaxTime berlinTime = mockable.MaxTime cairoTime = mockable.MaxTime + durangoTime = mockable.MaxTime ) // always reset LatestForkTime (a package level variable) // to ensure test independence switch phase { + case PhaseDurango: + durangoTime = LatestPhaseTime + fallthrough case PhaseCairo: cairoTime = LatestPhaseTime fallthrough @@ -124,6 +124,7 @@ func Config(t *testing.T, phase Phase) *config.Config { CortinaTime: cortinaTime, BerlinPhaseTime: berlinTime, CairoPhaseTime: cairoTime, + DurangoTime: durangoTime, CaminoConfig: caminoconfig.Config{ DACProposalBondAmount: 100 * units.Avax, }, @@ -203,32 +204,7 @@ func Genesis(t *testing.T, avaxAssetID ids.ID, caminoGenesisConfig api.Camino, a func Context(t *testing.T) *snow.Context { t.Helper() - - aliaser := ids.NewAliaser() - require.NoError(t, aliaser.Alias(constants.PlatformChainID, "P")) - - ctx := snow.DefaultContextTest() - ctx.AVAXAssetID = avaxAssetID - ctx.ChainID = constants.PlatformChainID - ctx.XChainID = xChainID - ctx.CChainID = cChainID - ctx.BCLookup = aliaser - ctx.NetworkID = constants.UnitTestID - ctx.SubnetID = constants.PrimaryNetworkID - ctx.ValidatorState = &validators.TestState{ - GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) { - subnetID, ok := map[ids.ID]ids.ID{ - constants.PlatformChainID: ctx.SubnetID, - ctx.XChainID: ctx.SubnetID, - ctx.CChainID: ctx.SubnetID, - }[chainID] - if !ok { - return ids.Empty, errors.New("missing") - } - return subnetID, nil - }, - } - return ctx + return snowtest.Context(t, snowtest.PChainID) } func ContextWithSharedMemory(t *testing.T, db database.Database) *snow.Context { @@ -271,7 +247,7 @@ func Fx(t *testing.T, clk *mockable.Clock, log logging.Logger, isBootstrapped bo t.Helper() fxVMInt := &fxVMInt{ - registry: linearcodec.NewDefault(), + registry: linearcodec.NewDefault(time.Time{}), clk: clk, log: log, } diff --git a/vms/platformvm/test/camino_phase.go b/vms/platformvm/test/camino_phase.go index 8d96e075523e..922075bf3a33 100644 --- a/vms/platformvm/test/camino_phase.go +++ b/vms/platformvm/test/camino_phase.go @@ -4,6 +4,7 @@ package test import ( + "math" "testing" "time" @@ -24,6 +25,7 @@ const ( PhaseCortina Phase = 3 // avax, included into Berlin phase PhaseBerlin Phase = 3 PhaseCairo Phase = 4 + PhaseDurango Phase = math.MaxInt // avax ) // TODO @evlekht we might want to clean up sunrise/banff timestamps/relations later diff --git a/vms/platformvm/txs/builder/camino_builder_test.go b/vms/platformvm/txs/builder/camino_builder_test.go index 80a904450572..8c8a080bf29d 100644 --- a/vms/platformvm/txs/builder/camino_builder_test.go +++ b/vms/platformvm/txs/builder/camino_builder_test.go @@ -933,7 +933,7 @@ func TestNewRewardsImportTx(t *testing.T) { if utxo.Timestamp == 0 { toMarshal = utxo.UTXO } - utxoBytes, err := txs.Codec.Marshal(txs.Version, toMarshal) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, toMarshal) require.NoError(t, err) utxosBytes[i] = utxoBytes } diff --git a/vms/platformvm/txs/camino_add_deposit_offer_tx_test.go b/vms/platformvm/txs/camino_add_deposit_offer_tx_test.go index 53bb5b74d7c6..cf0d27d04704 100644 --- a/vms/platformvm/txs/camino_add_deposit_offer_tx_test.go +++ b/vms/platformvm/txs/camino_add_deposit_offer_tx_test.go @@ -11,6 +11,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/deposit" "github.com/ava-labs/avalanchego/vms/platformvm/locked" @@ -19,7 +20,7 @@ import ( ) func TestAddDepositOfferTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) owner1 := secp256k1fx.OutputOwners{Threshold: 1, Addrs: []ids.ShortID{{0, 0, 1}}} depositTxID := ids.ID{0, 1} creatorAddress := ids.ShortID{1} diff --git a/vms/platformvm/txs/camino_add_proposal_tx_test.go b/vms/platformvm/txs/camino_add_proposal_tx_test.go index b2258b0323c4..aac1b24b6b3c 100644 --- a/vms/platformvm/txs/camino_add_proposal_tx_test.go +++ b/vms/platformvm/txs/camino_add_proposal_tx_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/dac" "github.com/ava-labs/avalanchego/vms/platformvm/locked" @@ -18,18 +19,18 @@ import ( ) func TestAddProposalTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) owner1 := secp256k1fx.OutputOwners{Threshold: 1, Addrs: []ids.ShortID{{0, 0, 1}}} badProposal := &ProposalWrapper{Proposal: &dac.BaseFeeProposal{Options: []uint64{}}} - badProposalBytes, err := Codec.Marshal(Version, badProposal) + badProposalBytes, err := Codec.Marshal(CodecVersion, badProposal) require.NoError(t, err) proposal := &ProposalWrapper{Proposal: &dac.BaseFeeProposal{ End: 1, Options: []uint64{1}, }} - proposalBytes, err := Codec.Marshal(Version, proposal) + proposalBytes, err := Codec.Marshal(CodecVersion, proposal) require.NoError(t, err) baseTx := BaseTx{BaseTx: avax.BaseTx{ @@ -129,7 +130,7 @@ func TestAddProposalTxProposal(t *testing.T) { Start: 11, End: 12, Options: []uint64{555, 123, 7}, }} - proposalBytes, err := Codec.Marshal(Version, expectedProposal) + proposalBytes, err := Codec.Marshal(CodecVersion, expectedProposal) require.NoError(t, err) tx := &AddProposalTx{ diff --git a/vms/platformvm/txs/camino_add_vote_tx_test.go b/vms/platformvm/txs/camino_add_vote_tx_test.go index 01f07751c5c6..ff56b0e74940 100644 --- a/vms/platformvm/txs/camino_add_vote_tx_test.go +++ b/vms/platformvm/txs/camino_add_vote_tx_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/dac" "github.com/ava-labs/avalanchego/vms/platformvm/locked" @@ -17,15 +18,15 @@ import ( ) func TestAddVoteTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) owner1 := secp256k1fx.OutputOwners{Threshold: 1, Addrs: []ids.ShortID{{0, 0, 1}}} badVote := &VoteWrapper{Vote: &dac.DummyVote{ErrorStr: "test errr"}} - badVoteBytes, err := Codec.Marshal(Version, badVote) + badVoteBytes, err := Codec.Marshal(CodecVersion, badVote) require.NoError(t, err) vote := &VoteWrapper{Vote: &dac.DummyVote{}} - voteBytes, err := Codec.Marshal(Version, vote) + voteBytes, err := Codec.Marshal(CodecVersion, vote) require.NoError(t, err) baseTx := BaseTx{BaseTx: avax.BaseTx{ @@ -136,7 +137,7 @@ func TestAddVoteTxSyntacticVerify(t *testing.T) { func TestAddVoteTxVote(t *testing.T) { expectedVote := &VoteWrapper{Vote: &dac.DummyVote{ErrorStr: "some data"}} - voteBytes, err := Codec.Marshal(Version, expectedVote) + voteBytes, err := Codec.Marshal(CodecVersion, expectedVote) require.NoError(t, err) tx := &AddVoteTx{VotePayload: voteBytes} diff --git a/vms/platformvm/txs/camino_claim_tx_test.go b/vms/platformvm/txs/camino_claim_tx_test.go index 648fe948e260..2d81ed894a1d 100644 --- a/vms/platformvm/txs/camino_claim_tx_test.go +++ b/vms/platformvm/txs/camino_claim_tx_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/locked" "github.com/ava-labs/avalanchego/vms/platformvm/test/generate" @@ -16,7 +17,7 @@ import ( ) func TestClaimTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) owner1 := secp256k1fx.OutputOwners{Threshold: 1, Addrs: []ids.ShortID{{0, 0, 1}}} depositTxID := ids.ID{0, 1} claimableOwnerID1 := ids.ID{0, 2} diff --git a/vms/platformvm/txs/camino_deposit_tx_test.go b/vms/platformvm/txs/camino_deposit_tx_test.go index 5b4e0657b435..4d032c6ba7c8 100644 --- a/vms/platformvm/txs/camino_deposit_tx_test.go +++ b/vms/platformvm/txs/camino_deposit_tx_test.go @@ -11,6 +11,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/locked" "github.com/ava-labs/avalanchego/vms/platformvm/test/generate" @@ -18,7 +19,7 @@ import ( ) func TestDepositTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) owner1 := secp256k1fx.OutputOwners{Threshold: 1, Addrs: []ids.ShortID{{1}}} tests := map[string]struct { diff --git a/vms/platformvm/txs/camino_finish_proposals_tx_test.go b/vms/platformvm/txs/camino_finish_proposals_tx_test.go index 024fcb9ed102..2c8cda0056bb 100644 --- a/vms/platformvm/txs/camino_finish_proposals_tx_test.go +++ b/vms/platformvm/txs/camino_finish_proposals_tx_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/locked" "github.com/ava-labs/avalanchego/vms/platformvm/test/generate" @@ -16,7 +17,7 @@ import ( ) func TestFinishProposalsTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) owner1 := secp256k1fx.OutputOwners{Threshold: 1, Addrs: []ids.ShortID{{0, 0, 1}}} proposalID1 := ids.ID{1} diff --git a/vms/platformvm/txs/camino_multisig_alias_tx_test.go b/vms/platformvm/txs/camino_multisig_alias_tx_test.go index 3721f9f8c068..f5bfce4ba160 100644 --- a/vms/platformvm/txs/camino_multisig_alias_tx_test.go +++ b/vms/platformvm/txs/camino_multisig_alias_tx_test.go @@ -11,13 +11,14 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/multisig" "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) func TestMultisigAliasTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) memo := []byte("memo") bigMemo := make([]byte, 257) diff --git a/vms/platformvm/txs/camino_owner_id.go b/vms/platformvm/txs/camino_owner_id.go index 676b0f7226c4..04906b8a3a10 100644 --- a/vms/platformvm/txs/camino_owner_id.go +++ b/vms/platformvm/txs/camino_owner_id.go @@ -16,7 +16,7 @@ var errOutNotOwned = errors.New("out doesn't implement fx.Owned interface") // Returns hash of marshalled bytes of owner, which can be treated as owner ID. func GetOwnerID(owner interface{}) (ids.ID, error) { - ownerBytes, err := Codec.Marshal(Version, owner) + ownerBytes, err := Codec.Marshal(CodecVersion, owner) if err != nil { return ids.Empty, fmt.Errorf("couldn't marshal owner: %w", err) } diff --git a/vms/platformvm/txs/camino_register_node_tx_test.go b/vms/platformvm/txs/camino_register_node_tx_test.go index 073c9cfdbea6..9082904bfdfa 100644 --- a/vms/platformvm/txs/camino_register_node_tx_test.go +++ b/vms/platformvm/txs/camino_register_node_tx_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/locked" "github.com/ava-labs/avalanchego/vms/platformvm/test/generate" @@ -16,7 +17,7 @@ import ( ) func TestRegisterNodeTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) owner1 := secp256k1fx.OutputOwners{Threshold: 1, Addrs: []ids.ShortID{{0, 1}}} depositTxID := ids.ID{1} diff --git a/vms/platformvm/txs/camino_rewards_import_tx_test.go b/vms/platformvm/txs/camino_rewards_import_tx_test.go index 5a80e5bf5ebe..bfba38f23af2 100644 --- a/vms/platformvm/txs/camino_rewards_import_tx_test.go +++ b/vms/platformvm/txs/camino_rewards_import_tx_test.go @@ -9,13 +9,14 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/locked" "github.com/ava-labs/avalanchego/vms/platformvm/test/generate" ) func TestRewardsImportTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) tests := map[string]struct { tx *RewardsImportTx diff --git a/vms/platformvm/txs/camino_unlock_deposit_tx_test.go b/vms/platformvm/txs/camino_unlock_deposit_tx_test.go index 9e7ad8da5be0..52fb3ba51e3b 100644 --- a/vms/platformvm/txs/camino_unlock_deposit_tx_test.go +++ b/vms/platformvm/txs/camino_unlock_deposit_tx_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/locked" "github.com/ava-labs/avalanchego/vms/platformvm/test/generate" @@ -16,7 +17,7 @@ import ( ) func TestUnlockDepositTxSyntacticVerify(t *testing.T) { - ctx := defaultContext() + ctx := snowtest.Context(t, snowtest.PChainID) tests := map[string]struct { tx *UnlockDepositTx diff --git a/vms/platformvm/txs/codec.go b/vms/platformvm/txs/codec.go index c8688073d8bb..59ac2d252cc3 100644 --- a/vms/platformvm/txs/codec.go +++ b/vms/platformvm/txs/codec.go @@ -46,7 +46,7 @@ var ( // concurrently func InitCodec(durangoTime time.Time) error { c := linearcodec.NewCaminoDefault(durangoTime) - gc := linearcodec.NewCaminoCustomMaxLength(math.MaxInt32, time.Time{}) + gc := linearcodec.NewCaminoCustomMaxLength(time.Time{}, math.MaxInt32) errs := wrappers.Errs{} for _, c := range []linearcodec.CaminoCodec{c, gc} { diff --git a/vms/platformvm/txs/executor/camino_helpers_test.go b/vms/platformvm/txs/executor/camino_helpers_test.go index 33deb1afeaa1..2acbfb2f1e0d 100644 --- a/vms/platformvm/txs/executor/camino_helpers_test.go +++ b/vms/platformvm/txs/executor/camino_helpers_test.go @@ -53,7 +53,7 @@ func newCaminoEnvironment(t *testing.T, phase test.Phase, caminoGenesisConf api. rewards := reward.NewCalculator(config.RewardConfig) genesisBytes := test.Genesis(t, ctx.AVAXAssetID, caminoGenesisConf, nil) - baseState := testState.State(t, config.Validators, ctx, baseDB, rewards, genesisBytes) + baseState := testState.State(t, config, ctx, baseDB, rewards, genesisBytes) atomicUTXOs := avax.NewAtomicUTXOManager(ctx.SharedMemory, txs.Codec) uptimes := uptime.NewManager(baseState, clk) @@ -193,7 +193,7 @@ func newExecutorBackend( rewards := reward.NewCalculator(config.RewardConfig) genesisBytes := test.Genesis(t, ctx.AVAXAssetID, caminoGenesisConf, nil) - state := testState.State(t, config.Validators, ctx, baseDB, rewards, genesisBytes) + state := testState.State(t, config, ctx, baseDB, rewards, genesisBytes) if sharedMemory != nil { ctx.SharedMemory = &mutableSharedMemory{ diff --git a/vms/platformvm/txs/executor/camino_tx_executor.go b/vms/platformvm/txs/executor/camino_tx_executor.go index 9a65974c0335..c3530e1e8795 100644 --- a/vms/platformvm/txs/executor/camino_tx_executor.go +++ b/vms/platformvm/txs/executor/camino_tx_executor.go @@ -24,6 +24,7 @@ import ( as "github.com/ava-labs/avalanchego/vms/platformvm/addrstate" "github.com/ava-labs/avalanchego/vms/platformvm/config" dacProposals "github.com/ava-labs/avalanchego/vms/platformvm/dac" + deposits "github.com/ava-labs/avalanchego/vms/platformvm/deposit" "github.com/ava-labs/avalanchego/vms/platformvm/locked" "github.com/ava-labs/avalanchego/vms/platformvm/state" "github.com/ava-labs/avalanchego/vms/platformvm/treasury" @@ -31,8 +32,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/executor/dac" "github.com/ava-labs/avalanchego/vms/platformvm/utxo" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - - deposits "github.com/ava-labs/avalanchego/vms/platformvm/deposit" ) // Max number of items allowed in a page @@ -92,7 +91,6 @@ var ( errNestedMsigAlias = errors.New("nested msig aliases are not allowed") errProposalStartToEarly = errors.New("proposal start time is to early") errProposalToFarInFuture = fmt.Errorf("proposal start time is more than %s ahead of the current chain time", MaxFutureStartTime) - ErrProposalInactive = errors.New("proposal is inactive") errProposerCredentialMismatch = errors.New("proposer credential isn't matching") errWrongProposalBondAmount = errors.New("wrong proposal bond amount") errVoterCredentialMismatch = errors.New("voter credential isn't matching") @@ -206,9 +204,15 @@ func (e *CaminoStandardTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error return fmt.Errorf("%w: %w", errSignatureMissing, err) } + currentTimestamp := e.State.GetTimestamp() + // verify validator - duration := tx.Validator.Duration() + startTime := currentTimestamp + if !e.Backend.Config.IsDurangoActivated(currentTimestamp) { + startTime = tx.StartTime() + } + duration := tx.EndTime().Sub(startTime) switch { case tx.Validator.Wght < e.Backend.Config.MinValidatorStake: @@ -226,7 +230,6 @@ func (e *CaminoStandardTxExecutor) AddValidatorTx(tx *txs.AddValidatorTx) error } if e.Backend.Bootstrapped.Get() { - currentTimestamp := e.State.GetTimestamp() // Ensure the proposed validator starts after the current time startTime := tx.StartTime() if !currentTimestamp.Before(startTime) { @@ -450,7 +453,7 @@ func (e *CaminoStandardTxExecutor) wrapAtomicElementsForMultisig(tx *txs.ExportT UTXO: utxo, Aliases: aliases, } - bytes, err := txs.Codec.Marshal(txs.Version, wrappedUtxo) + bytes, err := txs.Codec.Marshal(txs.CodecVersion, wrappedUtxo) if err != nil { return err } @@ -1914,8 +1917,8 @@ func (e *CaminoStandardTxExecutor) AddVoteTx(tx *txs.AddVoteTx) error { return err } - if !proposal.IsActiveAt(chainTime) { - return ErrProposalInactive // should never happen, cause inactive proposals are removed from state + if err := proposal.VerifyActive(chainTime); err != nil { + return err // could happen, if proposal didn't start yet } // verify voter credential and address state (role) @@ -2412,7 +2415,7 @@ func getBaseFee(s state.Chain, cfg *config.Config) (uint64, error) { return 0, err } -// TODO@ remove nolint, when this func will be used. +// TODO @evlekht remove nolint, when this func will be used. // Currently its not used, cause we didn't implement P->C transport of proposal outcomes // like new base fee or new fee distribution or at least api that will provide this info. func getFeeDistribution(s state.Chain, cfg *config.Config) ([dacProposals.FeeDistributionFractionsCount]uint64, error) { //nolint:unused diff --git a/vms/platformvm/txs/executor/camino_tx_executor_test.go b/vms/platformvm/txs/executor/camino_tx_executor_test.go index 3e20435adbc2..01e44dbec8f5 100644 --- a/vms/platformvm/txs/executor/camino_tx_executor_test.go +++ b/vms/platformvm/txs/executor/camino_tx_executor_test.go @@ -170,6 +170,7 @@ func TestCaminoStandardTxExecutorAddValidatorTx(t *testing.T) { staker, err := state.NewCurrentStaker( tx.ID(), tx.Unsigned.(*txs.CaminoAddValidatorTx), + tx.Unsigned.(*txs.CaminoAddValidatorTx).StartTime(), 0, ) require.NoError(t, err) @@ -200,6 +201,7 @@ func TestCaminoStandardTxExecutorAddValidatorTx(t *testing.T) { staker, err := state.NewCurrentStaker( tx.ID(), tx.Unsigned.(*txs.CaminoAddValidatorTx), + tx.Unsigned.(*txs.CaminoAddValidatorTx).StartTime(), 0, ) require.NoError(t, err) @@ -351,6 +353,7 @@ func TestCaminoStandardTxExecutorAddSubnetValidatorTx(t *testing.T) { staker, err := state.NewCurrentStaker( addDSTx.ID(), addDSTx.Unsigned.(*txs.CaminoAddValidatorTx), + addDSTx.Unsigned.(*txs.CaminoAddValidatorTx).StartTime(), 0, ) require.NoError(t, err) @@ -374,6 +377,7 @@ func TestCaminoStandardTxExecutorAddSubnetValidatorTx(t *testing.T) { staker, err = state.NewCurrentStaker( subnetTx.ID(), subnetTx.Unsigned.(*txs.AddSubnetValidatorTx), + subnetTx.Unsigned.(*txs.AddSubnetValidatorTx).StartTime(), 0, ) require.NoError(t, err) @@ -1442,7 +1446,7 @@ func TestCaminoRewardValidatorTx(t *testing.T) { generateUTXOsAfterReward: func(txID ids.ID) []*avax.UTXO { return []*avax.UTXO{ generate.UTXO(txID, env.ctx.AVAXAssetID, test.ValidatorWeight, stakeOwners, ids.Empty, ids.Empty, true), - generate.UTXOWithIndex(unlockedUTXOTxID, 2, env.ctx.AVAXAssetID, test.PreFundedBalance, stakeOwners, ids.Empty, ids.Empty, true), + generate.UTXOWithIndex(unlockedUTXOTxID, 3, env.ctx.AVAXAssetID, test.PreFundedBalance, stakeOwners, ids.Empty, ids.Empty, true), } }, expectedErr: nil, @@ -3304,7 +3308,7 @@ func TestCaminoStandardTxExecutorDepositTx(t *testing.T) { // creating offer permission cred if tt.offerPermissionCred != nil { tx.Creds = append(tx.Creds, tt.offerPermissionCred(t)) - signedBytes, err := txs.Codec.Marshal(txs.Version, tx) + signedBytes, err := txs.Codec.Marshal(txs.CodecVersion, tx) require.NoError(t, err) tx.SetBytes(tx.Unsigned.Bytes(), signedBytes) } @@ -4876,7 +4880,7 @@ func TestCaminoStandardTxExecutorRewardsImportTx(t *testing.T) { } utxoID := utxo.InputID() utxoIDs[i] = utxoID[:] - utxoBytes, err := txs.Codec.Marshal(txs.Version, toMarshal) + utxoBytes, err := txs.Codec.Marshal(txs.CodecVersion, toMarshal) require.NoError(t, err) utxosBytes[i] = utxoBytes } @@ -5982,7 +5986,7 @@ func TestCaminoStandardTxExecutorAddProposalTx(t *testing.T) { proposalWrapper := &txs.ProposalWrapper{Proposal: &dac.GeneralProposal{ Start: 100, End: 100 + dac.GeneralProposalMinDuration, Options: [][]byte{{}}, }} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposalWrapper) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposalWrapper) require.NoError(t, err) baseTxWithBondAmt := func(bondAmt uint64) *txs.BaseTx { @@ -6092,7 +6096,7 @@ func TestCaminoStandardTxExecutorAddProposalTx(t *testing.T) { return s }, utx: func(cfg *config.Config) *txs.AddProposalTx { - proposalBytes, err := txs.Codec.Marshal(txs.Version, &txs.ProposalWrapper{Proposal: &dac.BaseFeeProposal{ + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, &txs.ProposalWrapper{Proposal: &dac.BaseFeeProposal{ Start: uint64(cfg.BerlinPhaseTime.Unix()) - 1, End: uint64(cfg.BerlinPhaseTime.Unix()) + 1, Options: []uint64{1}, @@ -6119,7 +6123,7 @@ func TestCaminoStandardTxExecutorAddProposalTx(t *testing.T) { }, utx: func(cfg *config.Config) *txs.AddProposalTx { startTime := uint64(cfg.BerlinPhaseTime.Add(MaxFutureStartTime).Unix() + 1) - proposalBytes, err := txs.Codec.Marshal(txs.Version, &txs.ProposalWrapper{Proposal: &dac.BaseFeeProposal{ + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, &txs.ProposalWrapper{Proposal: &dac.BaseFeeProposal{ Start: startTime, End: startTime + 1, Options: []uint64{1}, @@ -6150,7 +6154,7 @@ func TestCaminoStandardTxExecutorAddProposalTx(t *testing.T) { Start: 100, End: 100 + dac.AddMemberProposalDuration, Options: []uint64{1}, }, }} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposalWrapper) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposalWrapper) require.NoError(t, err) return &txs.AddProposalTx{ BaseTx: *baseTxWithBondAmt(cfg.CaminoConfig.DACProposalBondAmount), @@ -6178,7 +6182,7 @@ func TestCaminoStandardTxExecutorAddProposalTx(t *testing.T) { Start: 100, End: 100 + dac.AddMemberProposalDuration, ApplicantAddress: applicantAddress, }, }} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposalWrapper) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposalWrapper) require.NoError(t, err) return &txs.AddProposalTx{ BaseTx: *baseTxWithBondAmt(cfg.CaminoConfig.DACProposalBondAmount), @@ -6339,7 +6343,7 @@ func TestCaminoStandardTxExecutorAddProposalTx(t *testing.T) { Start: 100, End: 100 + dac.AddMemberProposalDuration, ApplicantAddress: applicantAddress, }, }} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposalWrapper) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposalWrapper) require.NoError(t, err) return &txs.AddProposalTx{ BaseTx: *baseTxWithBondAmt(cfg.CaminoConfig.DACProposalBondAmount), @@ -6398,7 +6402,7 @@ func TestCaminoStandardTxExecutorAddVoteTx(t *testing.T) { feeUTXO := generate.UTXO(ids.ID{1, 2, 3, 4, 5}, ctx.AVAXAssetID, test.TxFee, feeOwner, ids.Empty, ids.Empty, true) simpleVote := &txs.VoteWrapper{Vote: &dac.SimpleVote{OptionIndex: 0}} - voteBytes, err := txs.Codec.Marshal(txs.Version, simpleVote) + voteBytes, err := txs.Codec.Marshal(txs.CodecVersion, simpleVote) require.NoError(t, err) baseTx := txs.BaseTx{BaseTx: avax.BaseTx{ @@ -6511,7 +6515,7 @@ func TestCaminoStandardTxExecutorAddVoteTx(t *testing.T) { signers: [][]*secp256k1.PrivateKey{ {feeOwnerKey}, {voterKey1}, }, - expectedErr: ErrProposalInactive, + expectedErr: dac.ErrNotActive, }, "Proposal is not active yet": { state: func(t *testing.T, c *gomock.Controller, utx *txs.AddVoteTx, cfg *config.Config) *state.MockDiff { @@ -6533,7 +6537,7 @@ func TestCaminoStandardTxExecutorAddVoteTx(t *testing.T) { signers: [][]*secp256k1.PrivateKey{ {feeOwnerKey}, {voterKey1}, }, - expectedErr: ErrProposalInactive, + expectedErr: dac.ErrNotYetActive, }, "Voter isn't consortium member": { state: func(t *testing.T, c *gomock.Controller, utx *txs.AddVoteTx, cfg *config.Config) *state.MockDiff { @@ -6596,7 +6600,7 @@ func TestCaminoStandardTxExecutorAddVoteTx(t *testing.T) { }, utx: func(cfg *config.Config) *txs.AddVoteTx { vote := &txs.VoteWrapper{Vote: &dac.DummyVote{}} // not SimpleVote - voteBytes, err := txs.Codec.Marshal(txs.Version, vote) + voteBytes, err := txs.Codec.Marshal(txs.CodecVersion, vote) require.NoError(t, err) return &txs.AddVoteTx{ BaseTx: baseTx, @@ -6625,7 +6629,7 @@ func TestCaminoStandardTxExecutorAddVoteTx(t *testing.T) { }, utx: func(cfg *config.Config) *txs.AddVoteTx { simpleVote := &txs.VoteWrapper{Vote: &dac.SimpleVote{OptionIndex: 5}} // just 3 options in proposal - voteBytes, err := txs.Codec.Marshal(txs.Version, simpleVote) + voteBytes, err := txs.Codec.Marshal(txs.CodecVersion, simpleVote) require.NoError(t, err) return &txs.AddVoteTx{ BaseTx: baseTx, @@ -6750,7 +6754,7 @@ func TestCaminoStandardTxExecutorAddVoteTx(t *testing.T) { }, utx: func(cfg *config.Config) *txs.AddVoteTx { simpleVote := &txs.VoteWrapper{Vote: &dac.SimpleVote{OptionIndex: 1}} - voteBytes, err := txs.Codec.Marshal(txs.Version, simpleVote) + voteBytes, err := txs.Codec.Marshal(txs.CodecVersion, simpleVote) require.NoError(t, err) return &txs.AddVoteTx{ BaseTx: baseTx, diff --git a/vms/platformvm/txs/executor/dac/camino_dac_test.go b/vms/platformvm/txs/executor/dac/camino_dac_test.go index a9424c776755..693a6e3da0c0 100644 --- a/vms/platformvm/txs/executor/dac/camino_dac_test.go +++ b/vms/platformvm/txs/executor/dac/camino_dac_test.go @@ -11,7 +11,6 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -27,7 +26,7 @@ import ( ) func TestProposalVerifierBaseFeeProposal(t *testing.T) { - ctx := snow.DefaultContextTest() + ctx := test.Context(t) // TODO @evlekht replace with test.PhaseLast when cairo phase will be added as last defaultConfig := test.Config(t, test.PhaseCairo) @@ -40,7 +39,7 @@ func TestProposalVerifierBaseFeeProposal(t *testing.T) { bondUTXO := generate.UTXO(ids.ID{1, 2, 3, 4, 6}, ctx.AVAXAssetID, proposalBondAmt, bondOwner, ids.Empty, ids.Empty, true) proposal := &txs.ProposalWrapper{Proposal: &dac.BaseFeeProposal{End: 1, Options: []uint64{1}}} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposal) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposal) require.NoError(t, err) baseTx := txs.BaseTx{BaseTx: avax.BaseTx{ @@ -207,7 +206,7 @@ func TestProposalExecutorBaseFeeProposal(t *testing.T) { } func TestProposalVerifierAddMemberProposal(t *testing.T) { - ctx := snow.DefaultContextTest() + ctx := test.Context(t) defaultConfig := test.Config(t, test.PhaseLast) feeOwnerKey, _, feeOwner := generate.KeyAndOwner(t, test.Keys[0]) @@ -220,7 +219,7 @@ func TestProposalVerifierAddMemberProposal(t *testing.T) { bondUTXO := generate.UTXO(ids.ID{1, 2, 3, 4, 6}, ctx.AVAXAssetID, proposalBondAmt, bondOwner, ids.Empty, ids.Empty, true) proposal := &txs.ProposalWrapper{Proposal: &dac.AddMemberProposal{End: 1, ApplicantAddress: applicantAddress}} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposal) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposal) require.NoError(t, err) baseTx := txs.BaseTx{BaseTx: avax.BaseTx{ @@ -411,7 +410,7 @@ func TestProposalExecutorAddMemberProposal(t *testing.T) { } func TestProposalVerifierExcludeMemberProposal(t *testing.T) { - ctx := snow.DefaultContextTest() + ctx := test.Context(t) defaultConfig := test.Config(t, test.PhaseLast) feeOwnerKey, _, feeOwner := generate.KeyAndOwner(t, test.Keys[0]) @@ -427,7 +426,7 @@ func TestProposalVerifierExcludeMemberProposal(t *testing.T) { bondUTXO := generate.UTXO(ids.ID{1, 2, 3, 4, 6}, ctx.AVAXAssetID, proposalBondAmt, bondOwner, ids.Empty, ids.Empty, true) proposal := &txs.ProposalWrapper{Proposal: &dac.ExcludeMemberProposal{End: 1, MemberAddress: memberAddress}} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposal) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposal) require.NoError(t, err) baseTx := txs.BaseTx{BaseTx: avax.BaseTx{ @@ -891,7 +890,7 @@ func TestGetBondTxIDs(t *testing.T) { } func TestProposalVerifierFeeDistributionProposal(t *testing.T) { - ctx := snow.DefaultContextTest() + ctx := test.Context(t) defaultConfig := test.Config(t, test.PhaseLast) feeOwnerKey, _, feeOwner := generate.KeyAndOwner(t, test.Keys[0]) @@ -903,7 +902,7 @@ func TestProposalVerifierFeeDistributionProposal(t *testing.T) { bondUTXO := generate.UTXO(ids.ID{1, 2, 3, 4, 6}, ctx.AVAXAssetID, proposalBondAmt, bondOwner, ids.Empty, ids.Empty, true) proposal := &txs.ProposalWrapper{Proposal: &dac.FeeDistributionProposal{End: 1, Options: [][dac.FeeDistributionFractionsCount]uint64{{1}}}} - proposalBytes, err := txs.Codec.Marshal(txs.Version, proposal) + proposalBytes, err := txs.Codec.Marshal(txs.CodecVersion, proposal) require.NoError(t, err) baseTx := txs.BaseTx{BaseTx: avax.BaseTx{ diff --git a/vms/platformvm/utxo/camino_helpers_test.go b/vms/platformvm/utxo/camino_helpers_test.go index c0f4c0e2c3b8..2cbe4a42d7de 100644 --- a/vms/platformvm/utxo/camino_helpers_test.go +++ b/vms/platformvm/utxo/camino_helpers_test.go @@ -5,12 +5,12 @@ package utxo import ( "testing" + "time" "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/logging" @@ -43,7 +43,7 @@ func defaultCaminoHandler(t *testing.T) *caminoHandler { vm := &secp256k1fx.TestVM{ Clk: *clk, Log: logging.NoLog{}, - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), } fx := &secp256k1fx.Fx{} require.NoError(t, fx.InitializeVM(vm)) @@ -51,7 +51,7 @@ func defaultCaminoHandler(t *testing.T) *caminoHandler { return &caminoHandler{ handler: handler{ - ctx: snow.DefaultContextTest(), + ctx: test.Context(t), clk: clk, fx: fx, }, diff --git a/vms/platformvm/utxo/camino_locked_test.go b/vms/platformvm/utxo/camino_locked_test.go index 66acdb8a002c..b3d3281c6326 100644 --- a/vms/platformvm/utxo/camino_locked_test.go +++ b/vms/platformvm/utxo/camino_locked_test.go @@ -16,7 +16,6 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" @@ -155,12 +154,12 @@ func TestLock(t *testing.T) { require.NoError(t, fx.Bootstrapped()) config := test.Config(t, test.PhaseLast) - ctx := snow.DefaultContextTest() + ctx := test.Context(t) baseDB := versiondb.New(memdb.New()) rewardsCalc := reward.NewCalculator(config.RewardConfig) genesisBytes := test.Genesis(t, ctx.AVAXAssetID, api.Camino{}, nil) - testState := stateTest.State(t, config.Validators, ctx, baseDB, rewardsCalc, genesisBytes) + testState := stateTest.State(t, config, ctx, baseDB, rewardsCalc, genesisBytes) key, err := secp256k1.NewPrivateKey() require.NoError(t, err) diff --git a/vms/platformvm/utxo/camino_multisig_test.go b/vms/platformvm/utxo/camino_multisig_test.go index 56a5af26954c..c04ed7cb656a 100644 --- a/vms/platformvm/utxo/camino_multisig_test.go +++ b/vms/platformvm/utxo/camino_multisig_test.go @@ -5,6 +5,7 @@ package utxo import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -83,7 +84,7 @@ func TestUTXOWithMsigVerify(t *testing.T) { func TestUTXOWithMSigSerialized(t *testing.T) { // Create a new codec manager and linear codec instance manager := codec.NewDefaultManager() - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) // Register all relevant types with the codec errs := wrappers.Errs{} diff --git a/vms/platformvm/utxo/mock_verifier.go b/vms/platformvm/utxo/mock_verifier.go index 814df7878133..c8b9c6db15ac 100644 --- a/vms/platformvm/utxo/mock_verifier.go +++ b/vms/platformvm/utxo/mock_verifier.go @@ -55,7 +55,7 @@ func (m *MockVerifier) Unlock(arg0 state.Chain, arg1 []ids.ID, arg2 locked.State } // Unlock indicates an expected call of Unlock. -func (mr *MockVerifierMockRecorder) Unlock(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockVerifierMockRecorder) Unlock(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockVerifier)(nil).Unlock), arg0, arg1, arg2) } @@ -69,7 +69,7 @@ func (m *MockVerifier) VerifyLock(arg0 txs.UnsignedTx, arg1 avax.UTXOGetter, arg } // VerifyLock indicates an expected call of VerifyLock. -func (mr *MockVerifierMockRecorder) VerifyLock(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 interface{}) *gomock.Call { +func (mr *MockVerifierMockRecorder) VerifyLock(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyLock", reflect.TypeOf((*MockVerifier)(nil).VerifyLock), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } @@ -97,7 +97,7 @@ func (m *MockVerifier) VerifySpendUTXOs(arg0 avax.UTXOGetter, arg1 txs.UnsignedT } // VerifySpendUTXOs indicates an expected call of VerifySpendUTXOs. -func (mr *MockVerifierMockRecorder) VerifySpendUTXOs(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { +func (mr *MockVerifierMockRecorder) VerifySpendUTXOs(arg0, arg1, arg2, arg3, arg4, arg5, arg6 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifySpendUTXOs", reflect.TypeOf((*MockVerifier)(nil).VerifySpendUTXOs), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } @@ -111,7 +111,7 @@ func (m *MockVerifier) VerifyUnlockDeposit(arg0 avax.UTXOGetter, arg1 txs.Unsign } // VerifyUnlockDeposit indicates an expected call of VerifyUnlockDeposit. -func (mr *MockVerifierMockRecorder) VerifyUnlockDeposit(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call { +func (mr *MockVerifierMockRecorder) VerifyUnlockDeposit(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyUnlockDeposit", reflect.TypeOf((*MockVerifier)(nil).VerifyUnlockDeposit), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 24f31f5a6845..f81f71ac3106 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -210,7 +210,7 @@ func (vm *VM) Initialize( txExecutorBackend, validatorManager, ) - + txVerifier := network.NewLockedTxVerifier(&txExecutorBackend.Ctx.Lock, vm.manager) vm.Network, err = network.NewCamino( chainCtx.Log, @@ -224,6 +224,7 @@ func (vm *VM) Initialize( registerer, execConfig.Network, vm.txBuilder, + &txExecutorBackend.Ctx.Lock, ) if err != nil { return fmt.Errorf("failed to initialize network: %w", err) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index a0a8240c1c4e..a691fb88643b 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -1096,7 +1096,7 @@ func initTestRemoteProposerVM( } ctx := snowtest.Context(t, snowtest.CChainID) - ctx.NodeID = pTestNodeID + ctx.NodeID = pTestCert.NodeID ctx.ValidatorState = valState require.NoError(proVM.Initialize( diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 81527a3398ad..b59fff370415 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -249,7 +249,6 @@ func (p *postForkCommonComponents) buildChild( parentID, newTimestamp, pChainHeight, - p.vm.ctx.NodeID, p.vm.StakingCertLeaf, innerBlock.Bytes(), p.vm.ctx.ChainID, diff --git a/vms/proposervm/block/block.go b/vms/proposervm/block/block.go index c7125da52019..63fa930dcc8f 100644 --- a/vms/proposervm/block/block.go +++ b/vms/proposervm/block/block.go @@ -14,14 +14,12 @@ package block import ( - "crypto/x509" "errors" "fmt" "time" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/staking" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/wrappers" ) @@ -114,15 +112,7 @@ func (b *statelessBlock) initialize(bytes []byte, durangoTime time.Time) error { return fmt.Errorf("%w: %w", errInvalidCertificate, err) } - nodeIDBytes, err := secp256k1.RecoverSecp256PublicKey(tlsCert) - if err != nil { - return err - } - nodeID, err := ids.ToNodeID(nodeIDBytes) - if err != nil { - return err - } - b.proposer = nodeID + b.proposer = b.cert.NodeID return nil } diff --git a/vms/proposervm/block/build.go b/vms/proposervm/block/build.go index ab2973d372e2..dc3af0c3354c 100644 --- a/vms/proposervm/block/build.go +++ b/vms/proposervm/block/build.go @@ -55,7 +55,6 @@ func Build( parentID ids.ID, timestamp time.Time, pChainHeight uint64, - nodeID ids.NodeID, cert *staking.Certificate, blockBytes []byte, chainID ids.ID, @@ -71,7 +70,7 @@ func Build( }, timestamp: timestamp, cert: cert, - proposer: nodeID, + proposer: cert.NodeID, } var blockIntf SignedBlock = block diff --git a/vms/proposervm/block/build_test.go b/vms/proposervm/block/build_test.go index 2e54beade3c4..6a927d727e0e 100644 --- a/vms/proposervm/block/build_test.go +++ b/vms/proposervm/block/build_test.go @@ -36,14 +36,14 @@ func TestBuild(t *testing.T) { tlsCert, err := staking.NewTLSCert() require.NoError(err) - cert := staking.CertificateFromX509(tlsCert.Leaf) + cert, err := staking.CertificateFromX509(tlsCert.Leaf) + require.NoError(err) key := tlsCert.PrivateKey.(crypto.Signer) builtBlock, err := Build( parentID, timestamp, pChainHeight, - ids.EmptyNodeID, cert, innerBlockBytes, chainID, diff --git a/vms/proposervm/block/camino_test.go b/vms/proposervm/block/camino_test.go new file mode 100644 index 000000000000..2d507acafbf0 --- /dev/null +++ b/vms/proposervm/block/camino_test.go @@ -0,0 +1,113 @@ +// Copyright (C) 2023, Chain4Travel AG. All rights reserved. +// See the file LICENSE for licensing terms. + +package block + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/hex" + "fmt" + "math/big" + "testing" + "time" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/cryptobyte" + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/staking" + utilsSecp256k1 "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +) + +// Convinient way to run generateTestBlock. Comment out SkipNow before run. +func TestGenerateTestBlock(t *testing.T) { + t.SkipNow() + key, cert, err := generateTestKeyAndCertWithDupExt() + require.NoError(t, err) + blockHex, err := generateTestBlock(key, cert) + require.NoError(t, err) + t.Logf("generated block hex: %s\n", blockHex) +} + +// Creates block with given key and cert, then prints block bytes hex. This hex is used by tests in this package. +func generateTestBlock(key crypto.Signer, cert *staking.Certificate) (string, error) { + parentID := ids.ID{1} + timestamp := time.Unix(123, 0) + pChainHeight := uint64(2) + innerBlockBytes := []byte{3} + chainID := ids.ID{4} + + block, err := Build( + parentID, + timestamp, + pChainHeight, + cert, + innerBlockBytes, + chainID, + key, + ) + if err != nil { + return "", err + } + + blockBytes, err := Codec.Marshal(CodecVersion, block) + if err != nil { + return "", err + } + + return "00000000" + hex.EncodeToString(blockBytes), nil +} + +// Creates key and certificate with duplicated extensions. +func generateTestKeyAndCertWithDupExt() (crypto.Signer, *staking.Certificate, error) { + // Create RSA key to sign cert with + rsaKey, err := rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + return nil, nil, fmt.Errorf("couldn't generate rsa key: %w", err) + } + // Create SECP256K1 key to sign cert with + secpKey := utilsSecp256k1.RsaPrivateKeyToSecp256PrivateKey(rsaKey) + extension := utilsSecp256k1.SignRsaPublicKey(secpKey, &rsaKey.PublicKey) + + // Create self-signed staking cert + certTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(0), + NotBefore: time.Date(2000, time.January, 0, 0, 0, 0, 0, time.UTC), + NotAfter: time.Now().AddDate(100, 0, 0), + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment, + ExtraExtensions: []pkix.Extension{*extension, *extension}, + BasicConstraintsValid: true, + } + certBytes, err := x509.CreateCertificate(rand.Reader, certTemplate, certTemplate, &rsaKey.PublicKey, rsaKey) + if err != nil { + return nil, nil, fmt.Errorf("couldn't create certificate: %w", err) + } + + input := cryptobyte.String(certBytes) + if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) { + return nil, nil, staking.ErrMalformedCertificate + } + + tlsCert := tls.Certificate{ + Certificate: [][]byte{certBytes}, + PrivateKey: rsaKey, + Leaf: &x509.Certificate{ + Raw: input, + PublicKey: &rsaKey.PublicKey, + Extensions: certTemplate.ExtraExtensions, + }, + } + + cert, err := staking.CertificateFromX509(tlsCert.Leaf) + if err != nil { + return nil, nil, err + } + + return rsaKey, cert, nil +} diff --git a/vms/proposervm/block/parse_test.go b/vms/proposervm/block/parse_test.go index c448d33d5662..54c9af83ac16 100644 --- a/vms/proposervm/block/parse_test.go +++ b/vms/proposervm/block/parse_test.go @@ -19,8 +19,6 @@ import ( "testing" "time" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/codec" @@ -40,20 +38,14 @@ func TestParse(t *testing.T) { tlsCert, err := staking.NewTLSCert() require.NoError(err) - cert := staking.CertificateFromX509(tlsCert.Leaf) - key := tlsCert.PrivateKey.(crypto.Signer) - - nodeIDBytes, err := secp256k1.RecoverSecp256PublicKey(tlsCert.Leaf) - require.NoError(err) - - nodeID, err := ids.ToNodeID(nodeIDBytes) + cert, err := staking.CertificateFromX509(tlsCert.Leaf) require.NoError(err) + key := tlsCert.PrivateKey.(crypto.Signer) builtBlock, err := Build( parentID, timestamp, pChainHeight, - nodeID, cert, innerBlockBytes, chainID, @@ -80,7 +72,7 @@ func TestParse(t *testing.T) { func TestParseDuplicateExtension(t *testing.T) { require := require.New(t) - blockHex := "0000000000000100000000000000000000000000000000000000000000000000000000000000000000000000007b0000000000000002000004bd308204b9308202a1a003020102020100300d06092a864886f70d01010b050030003020170d3939313233313030303030305a180f32313232303830333233323835335a300030820222300d06092a864886f70d01010105000382020f003082020a0282020100c2b2de1c16924d9b9254a0d5b80a4bc5f9beaa4f4f40a0e4efb69eb9b55d7d37f8c82328c237d7c5b451f5427b487284fa3f365f9caa53c7fcfef8d7a461d743bd7d88129f2da62b877ebe9d6feabf1bd12923e6c12321382c782fc3bb6b6cb4986a937a1edc3814f4e621e1a62053deea8c7649e43edd97ab6b56315b00d9ab5026bb9c31fb042dc574ba83c54e720e0120fcba2e8a66b77839be3ece0d4a6383ef3f76aac952b49a15b65e18674cd1340c32cecbcbaf80ae45be001366cb56836575fb0ab51ea44bf7278817e99b6b180fdd110a49831a132968489822c56692161bbd372cf89d9b8ee5a734cff15303b3a960ee78d79e76662a701941d9ec084429f26707f767e9b1d43241c0e4f96655d95c1f4f4aa00add78eff6bf0a6982766a035bf0b465786632c5bb240788ca0fdf032d8815899353ea4bec5848fd30118711e5b356bde8a0da074cc25709623225e734ff5bd0cf65c40d9fd8fccf746d8f8f35145bcebcf378d2b086e57d78b11e84f47fa467c4d037f92bff6dd4e934e0189b58193f24c4222ffb72b5c06361cf68ca64345bc3e230cc0f40063ad5f45b1659c643662996328c2eeddcd760d6f7c9cbae081ccc065844f7ea78c858564a408979764de882793706acc67d88092790dff567ed914b03355330932616a0f26f994b963791f0b1dbd8df979db86d1ea490700a3120293c3c2b10bef10203010001a33c303a300e0603551d0f0101ff0404030204b030130603551d25040c300a06082b0601050507030230130603551d25040c300a06082b06010505070302300d06092a864886f70d01010b05000382020100a21a0d73ec9ef4eb39f810557ac70b0b775772b8bae5f42c98565bc50b5b2c57317aa9cb1da12f55d0aac7bb36a00cd4fd0d7384c4efa284b53520c5a3c4b8a65240b393eeab02c802ea146c0728c3481c9e8d3aaad9d4dd7607103dcfaa96da83460adbe18174ed5b71bde7b0a93d4fb52234a9ff54e3fd25c5b74790dfb090f2e59dc5907357f510cc3a0b70ccdb87aee214def794b316224f318b471ffa13b66e44b467670e881cb1628c99c048a503376d9b6d7b8eef2e7be47ff7d5c1d56221f4cf7fa2519b594cb5917815c64dc75d8d281bcc99b5a12899b08f2ca0f189857b64a1afc5963337f3dd6e79390e85221569f6dbbb13aadce06a3dfb5032f0cc454809627872cd7cd0cea5eba187723f07652c8abc3fc42bd62136fc66287f2cc19a7cb416923ad1862d7f820b55cacb65e43731cb6df780e2651e457a3438456aeeeb278ad9c0ad2e760f6c1cbe276eeb621c8a4e609b5f2d902beb3212e3e45df99497021ff536d0b56390c5d785a8bf7909f6b61bdc705d7d92ae22f58e7b075f164a0450d82d8286bf449072751636ab5185f59f518b845a75d112d6f7b65223479202cff67635e2ad88106bc8a0cc9352d87c5b182ac19a4680a958d814a093acf46730f87da0df6926291d02590f215041b44a0a1a32eeb3a52cddabc3d256689bace18a8d85e644cf9137cce3718f7caac1cb16ae06e874f4c701000000010300000200b8e3a4d9a4394bac714cb597f5ba1a81865185e35c782d0317e7abc0b52d49ff8e10f787bedf86f08148e3dbd2d2d478caa2a2893d31db7d5ee51339883fe84d3004440f16cb3797a7fab0f627d3ebd79217e995488e785cd6bb7b96b9d306f8109daa9cfc4162f9839f60fb965bcb3b56a5fa787549c153a4c80027398f73a617b90b7f24f437b140cd3ac832c0b75ec98b9423b275782988a9fd426937b8f82fbb0e88a622934643fb6335c1a080a4d13125544b04585d5f5295be7cd2c8be364246ea3d5df3e837b39a85074575a1fa2f4799050460110bdfb20795c8a9172a20f61b95e1c5c43eccd0c2c155b67385366142c63409cb3fb488e7aba6c8930f7f151abf1c24a54bd21c3f7a06856ea9db35beddecb30d2c61f533a3d0590bdbb438c6f2a2286dfc3c71b383354f0abad72771c2cc3687b50c2298783e53857cf26058ed78d0c1cf53786eb8d006a058ee3c85a7b2b836b5d03ef782709ce8f2725548e557b3de45a395a669a15f1d910e97015d22ac70020cab7e2531e8b1f739b023b49e742203e9e19a7fe0053826a9a2fe2e118d3b83498c2cb308573202ad41aa4a390aee4b6b5dd2164e5c5cd1b5f68b7d5632cf7dbb9a9139663c9aac53a74b2c6fc73cad80e228a186ba027f6f32f0182d62503e04fcced385f2e7d2e11c00940622ebd533b4d144689082f9777e5b16c36f9af9066e0ad6564d43" + blockHex := "0000000000000100000000000000000000000000000000000000000000000000000000000000000000000000007b000000000000000200000549308205453082032da003020102020100300d06092a864886f70d01010b050030003020170d3939313233313030303030305a180f32313234303331383134303631345a300030820222300d06092a864886f70d01010105000382020f003082020a0282020100d26e5f3da1caab11ce37919f7e307ee7c3c994498e78a7b8ab54c1c7c5246cb72b29a8fe1288f0938860bdca7335a885c645dcb7bc53cf80775945533cb9d46548f0038ae15ba63c5dcbab1600b42abaf70f467054cced3cd17142c031c43626b10db7986ad858581f6ead5185b77102602fdf2c7e2cddb7c7f11d8d461e3022c0b853ee18a5a93f18b321c8391c745be4c36d5c1759ab8b0bf6779e36529af4b3fcd924b1a33bdc0d807d47bc20040d32f11f1210f3088d55a7282ea07c59da0442805998bcb50ffe98420fc9835d6e664d25e6e41766761588e0fbfc6dacdb9c724f877c28dc45e79aecc4fa5fc24b238aa4512fd7823879edff32073ef8f34c8e609605014712254c4a7cf50f8b35d406e587e5b24a5f75d43d43c57591ee8b2c9ad1c2044c581dac3227e2d404e1e9af4674e762fc125c169b9a1b254a485d656f5c91d0388b956ad52cdac520b701555c2fe0e09087b6bbcffda981a58d8e98456af6a69ae24127ee7b438e24c67d88872f2363b505ac427c49e1592c2436de5ec245fac56cc24111b8a38a24e0bdfbef7627d6ca27af96d6b20d6fecb032dee7f3a459dc34730f290fda40f0eea1024c9b2a087b0055fdbc1621d9a9d87dd4b356b7caf121ba00022bf8a87711ca39583890128d01333b9ddb0ec4447c5bb0c85c6b295b2481f3a8f86b45536b3d15a0582fd3ac780ab01739fd6cd4d70203010001a381c73081c4300e0603551d0f0101ff0404030204b0300c0603551d130101ff04023000305106092a864886f70d0109150101ff04411cd3184187185ef0be03549b4c5d9b9d7592fd75eebfbd3de12c71e7360e2776543cf4edf4dbb5d674f61c58841abad64fb1e0ca0c24255d119fd658387cf2b800305106092a864886f70d0109150101ff04411cd3184187185ef0be03549b4c5d9b9d7592fd75eebfbd3de12c71e7360e2776543cf4edf4dbb5d674f61c58841abad64fb1e0ca0c24255d119fd658387cf2b800300d06092a864886f70d01010b050003820201001cf95b768b37bde828ca239e739a4229bacff2c53eb09e6b7f1499cb5157851b51ebdb45f5a94a3d0dc16c3d844ce57bb1f551b9bb6f92bcbdc08a7692e98ac257e594696a6f124df3b8a230a2f6ea34a8dd996516993cd91a2c0993e2c77f73454e77ee0f9d9a191f0a1d6b6b1bec901a1466bc0bcf781aa2e96bc65abc20bb2f5643829d811c50af8360022ee1da37f14d3e46e3d23e17fab57a847f7f3ba685090abf16d548c275654ab832935ecc73d496159078e124223314d0e2d8fc9f27426c8fbe6721684d205bac75d955ee71dd8ce6a1ae3c94da7c87c9c3126f9ae4715cbcccb1a9213357c0115e89e9b8d31cc9bbe0ad7e41e25d7473bdc30eaa541228182f650f53b952bdac8c4e9e5f3ceebe5858d85dd58431eb9dba5e4ff28f4212dd9c5ebf6abcae5dcad6b5f09144befb5a7c3f02c0ba5bff781c3acedc22c1cde635a39fb245bcf9f514949fac8321d6ec054377dbc1b24839caaabc29e3884c4de84523e6fa549253b691f6b5c7bdba6a410dc176c765ca14a499ef01916742138fc8156f2c14e4a122e581d1b6ca79e82dfd015b13c38011e248d25e0daccbe266dafbdff3f4ec99227c56795fe75d0d32876d054e5d124d873bebbaeff57ecb9f35146e97f7683809a615c54b89a8b21d0120cfedf133d4253ab9ae521106d245b50de8163b3e97b2e9eae63a72fc283d73b086e35b83fff3cb3d60000000010300000200032444fef47bcd6f77f9b5890a51a1de3b52269d476a04506727aa20b61dc535d09511c4c403058e2fdd7ee5d751b1b6153c4d02f07bf60988be15bf3ff6469bcfde45bdf12e979879d9537586b7394df60ca465f5facdac1722570b5f51f1eb2e8fa20c46a390d4319555d1a39a289563de511d36d517ecdb21b02f76a76d518a6b0eb40d15544f6d1b2e7fd70108af12260e6eaca8efbb2e254b5a3bcf486da1ebabace68c42c13a2a8f04cc626711f0b26f2d66bd0b451b5b4db474364b2dea51b93a41c9c676c00f54e30d4ddad249faa851bf7e99a5dc1b6431c0f79fc4748fb8fa299ad0eb8d92b24aa083f6d93f60384bccc980fc7ba957b71068977eedb7da7884d8a969fb84f3ef921055d63ceebde7c45ead163e19f6425668ff5c205f8368d4df57179efd64312ea4ddcbbabc1e99438e8d2bd05c5728edf505b9caf87cc07ec19f8b457667fc402d0bf53b437b7079c57bbd1dc004950d016440a178061582d4f5431dcb7f7be3b44c085ea982938800272bb140a1aa53208c849c342cb534bad44d06fddb156c0429b9afa920d765dbf9fd09a9dfc9adcb8abe6e238d1a586ffb8164f05e44822d6130662a358d0ed54c0031fe48f0157d211d307a5ef423a7bea821c0886f562140d0347fb429cc978e69a3fe6733a373224acaccf9cbbd5574f5157c78cf2c1623d8f984efd730f7a9a553058073672d49a0" blockBytes, err := hex.DecodeString(blockHex) require.NoError(err) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index e4ba0449f1be..efe03d5a2c32 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -86,7 +86,6 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { ids.Empty, // refer unknown parent time.Time{}, 0, // pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, innerOracleBlk.Bytes(), proVM.ctx.ChainID, @@ -289,7 +288,6 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { ids.Empty, // refer unknown parent proVM.Time(), pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, @@ -429,7 +427,6 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { parentBlk.ID(), newTime, pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, @@ -454,7 +451,6 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { parentBlk.ID(), beforeWinStart, pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, @@ -476,7 +472,6 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { parentBlk.ID(), atWindowStart, pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, @@ -497,7 +492,6 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { parentBlk.ID(), afterWindowStart, pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, @@ -534,7 +528,6 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { parentBlk.ID(), afterSubWinEnd, pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, @@ -636,7 +629,6 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { parentBlk.ID(), proVM.Time(), parentBlkPChainHeight-1, - proVM.ctx.NodeID, proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, @@ -1242,7 +1234,6 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { postForkOracleBlk.ID(), postForkOracleBlk.Timestamp().Add(proposer.WindowDuration), postForkOracleBlk.PChainHeight(), - proVM.ctx.NodeID, proVM.StakingCertLeaf, oracleCoreBlk.opts[0].Bytes(), proVM.ctx.ChainID, diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 986dd582617c..cf269a39691a 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -368,7 +368,6 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { coreGenBlk.ID(), coreBlk.Timestamp(), 0, // pChainHeight - proVM.ctx.NodeID, proVM.StakingCertLeaf, coreBlk.Bytes(), proVM.ctx.ChainID, @@ -784,7 +783,6 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { firstBlock.ID(), // refer unknown parent firstBlock.Timestamp(), 0, // pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, coreBlk.opts[0].Bytes(), proVM.ctx.ChainID, diff --git a/vms/proposervm/state/block_state_test.go b/vms/proposervm/state/block_state_test.go index 570104be2ab8..8efe014bd11c 100644 --- a/vms/proposervm/state/block_state_test.go +++ b/vms/proposervm/state/block_state_test.go @@ -27,8 +27,6 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/vms/proposervm/block" - - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" ) func testBlockState(a *require.Assertions, bs BlockState) { @@ -41,19 +39,14 @@ func testBlockState(a *require.Assertions, bs BlockState) { tlsCert, err := staking.NewTLSCert() a.NoError(err) - cert := staking.CertificateFromX509(tlsCert.Leaf) + cert, err := staking.CertificateFromX509(tlsCert.Leaf) key := tlsCert.PrivateKey.(crypto.Signer) - - nodeIDBytes, err := secp256k1.RecoverSecp256PublicKey(tlsCert.Leaf) - a.NoError(err) - nodeID, err := ids.ToNodeID(nodeIDBytes) a.NoError(err) b, err := block.Build( parentID, timestamp, pChainHeight, - nodeID, cert, innerBlockBytes, chainID, @@ -111,7 +104,7 @@ func TestGetBlockWithUncachedBlock(t *testing.T) { block: blk, } - bytes, err := c.Marshal(version, &blkWrapper) + bytes, err := Codec.Marshal(CodecVersion, &blkWrapper) a.NoError(err) blkID := blk.ID() @@ -133,20 +126,15 @@ func initCommonTestData(a *require.Assertions) (database.Database, BlockState, b chainID := ids.ID{4} tlsCert, _ := staking.NewTLSCert() - cert := staking.CertificateFromX509(tlsCert.Leaf) + cert, err := staking.CertificateFromX509(tlsCert.Leaf) + a.NoError(err) key := tlsCert.PrivateKey.(crypto.Signer) - nodeIDBytes, err := secp256k1.RecoverSecp256PublicKey(tlsCert.Leaf) - a.NoError(err) - nodeID, err := ids.ToNodeID(nodeIDBytes) - a.NoError(err) - blk, err := block.Build( parentID, timestamp, pChainHeight, - nodeID, cert, innerBlockBytes, chainID, diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 6eecfd2156f9..bdef0e7b3221 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -93,7 +93,7 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { ) ctx := snowtest.Context(t, snowtest.CChainID) - ctx.NodeID = NodeIDFromCert(pTestCert) + ctx.NodeID = pTestCert.NodeID require.NoError(vm.Initialize( context.Background(), @@ -200,7 +200,6 @@ func TestStateSyncGetOngoingSyncStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.ctx.NodeID, vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, @@ -286,7 +285,6 @@ func TestStateSyncGetLastStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.ctx.NodeID, vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, @@ -375,7 +373,6 @@ func TestStateSyncGetStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.ctx.NodeID, vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, @@ -449,7 +446,6 @@ func TestParseStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.ctx.NodeID, vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, @@ -505,7 +501,6 @@ func TestStateSummaryAccept(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.ctx.NodeID, vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, @@ -586,7 +581,6 @@ func TestStateSummaryAcceptOlderBlock(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.ctx.NodeID, vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 5ee9ed9bc66b..c6bef64e86ad 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -1,3 +1,13 @@ +// Copyright (C) 2022, Chain4Travel AG. All rights reserved. +// +// This file is a derived work, based on ava-labs code whose +// original notices appear below. +// +// It is distributed under the same license conditions as the +// original code from which it is derived. +// +// Much love to the original authors for their work. +// ********************************************************** // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index ff125fc8036d..40abbc98316e 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -30,7 +30,6 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/network/peer" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" @@ -40,12 +39,10 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/hashing" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" "github.com/ava-labs/avalanchego/vms/proposervm/state" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" statelessblock "github.com/ava-labs/avalanchego/vms/proposervm/block" ) @@ -60,7 +57,6 @@ type fullVM struct { } var ( - pTestNodeID ids.NodeID pTestSigner crypto.Signer pTestCert *staking.Certificate @@ -82,12 +78,7 @@ func init() { panic(err) } pTestSigner = tlsCert.PrivateKey.(crypto.Signer) - pTestCert = staking.CertificateFromX509(tlsCert.Leaf) - nodeIDBytes, err := secp256k1.RecoverSecp256PublicKey(tlsCert.Leaf) - if err != nil { - panic(err) - } - pTestNodeID, err = ids.ToNodeID(nodeIDBytes) + pTestCert, err = staking.CertificateFromX509(tlsCert.Leaf) if err != nil { panic(err) } @@ -205,7 +196,7 @@ func initTestProposerVM( } ctx := snowtest.Context(t, ids.ID{1}) - ctx.NodeID = pTestNodeID + ctx.NodeID = pTestCert.NodeID ctx.ValidatorState = valState db := prefixdb.New([]byte{0}, memdb.New()) @@ -594,7 +585,6 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { proVM.preferred, proVM.Time(), 100, // pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, @@ -644,7 +634,6 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { proVM.preferred, blkTimestamp, 100, // pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, @@ -664,7 +653,6 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { proVM.preferred, blkTimestamp, 200, // pChainHeight, - proVM.ctx.NodeID, proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, @@ -1003,7 +991,7 @@ func TestExpiredBuildBlock(t *testing.T) { } ctx := snowtest.Context(t, snowtest.CChainID) - ctx.NodeID = NodeIDFromCert(pTestCert) + ctx.NodeID = pTestCert.NodeID ctx.ValidatorState = valState toEngine := make(chan common.Message, 1) @@ -1298,7 +1286,7 @@ func TestInnerVMRollback(t *testing.T) { } ctx := snowtest.Context(t, snowtest.CChainID) - ctx.NodeID = NodeIDFromCert(pTestCert) + ctx.NodeID = pTestCert.NodeID ctx.ValidatorState = valState coreVM.InitializeF = func( @@ -1967,7 +1955,7 @@ func TestRejectedHeightNotIndexed(t *testing.T) { } ctx := snowtest.Context(t, snowtest.CChainID) - ctx.NodeID = NodeIDFromCert(pTestCert) + ctx.NodeID = pTestCert.NodeID ctx.ValidatorState = valState require.NoError(proVM.Initialize( @@ -2177,7 +2165,7 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { } ctx := snowtest.Context(t, snowtest.CChainID) - ctx.NodeID = NodeIDFromCert(pTestCert) + ctx.NodeID = pTestCert.NodeID ctx.ValidatorState = valState require.NoError(proVM.Initialize( @@ -2328,7 +2316,7 @@ func TestVMInnerBlkCache(t *testing.T) { } ctx := snowtest.Context(t, snowtest.CChainID) - ctx.NodeID = NodeIDFromCert(pTestCert) + ctx.NodeID = pTestCert.NodeID require.NoError(vm.Initialize( context.Background(), @@ -2354,7 +2342,6 @@ func TestVMInnerBlkCache(t *testing.T) { ids.GenerateTestID(), // parent time.Time{}, // timestamp 1, // pChainHeight, - vm.ctx.NodeID, vm.StakingCertLeaf, // cert blkNearTipInnerBytes, // inner blk bytes vm.ctx.ChainID, // chain ID @@ -2570,7 +2557,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { } snowCtx := snowtest.Context(t, snowtest.CChainID) - snowCtx.NodeID = NodeIDFromCert(pTestCert) + snowCtx.NodeID = pTestCert.NodeID require.NoError(vm.Initialize( context.Background(), @@ -2729,7 +2716,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { } ctx := snowtest.Context(t, snowtest.CChainID) - ctx.NodeID = NodeIDFromCert(pTestCert) + ctx.NodeID = pTestCert.NodeID ctx.ValidatorState = &validators.TestState{ T: t, GetMinimumHeightF: func(context.Context) (uint64, error) { @@ -2941,9 +2928,3 @@ func TestHistoricalBlockDeletion(t *testing.T) { issueBlock() requireNumHeights(newNumHistoricalBlocks) } - -func NodeIDFromCert(cert *staking.Certificate) ids.NodeID { - return hashing.ComputeHash160Array( - hashing.ComputeHash256(cert.Raw), - ) -} diff --git a/vms/secp256k1fx/camino_credential_test.go b/vms/secp256k1fx/camino_credential_test.go index 89e698430a10..d69ee7b70980 100644 --- a/vms/secp256k1fx/camino_credential_test.go +++ b/vms/secp256k1fx/camino_credential_test.go @@ -5,6 +5,7 @@ package secp256k1fx import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -29,7 +30,7 @@ func TestMultisigCredentialUnordered(t *testing.T) { func TestMultisigCredentialSerialize(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(0, c)) diff --git a/vms/secp256k1fx/camino_fx_test.go b/vms/secp256k1fx/camino_fx_test.go index 491b87daa483..89ec12634b97 100644 --- a/vms/secp256k1fx/camino_fx_test.go +++ b/vms/secp256k1fx/camino_fx_test.go @@ -313,7 +313,7 @@ func TestCollectMultisigAliases(t *testing.T) { func defaultFx(t *testing.T) *Fx { require := require.New(t) vm := TestVM{ - Codec: linearcodec.NewDefault(), + Codec: linearcodec.NewDefault(time.Time{}), Log: logging.NoLog{}, } date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC) diff --git a/vms/secp256k1fx/camino_transfer_output_test.go b/vms/secp256k1fx/camino_transfer_output_test.go index e39ffb1d867e..a6ea8de92d7f 100644 --- a/vms/secp256k1fx/camino_transfer_output_test.go +++ b/vms/secp256k1fx/camino_transfer_output_test.go @@ -5,6 +5,7 @@ package secp256k1fx import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -54,7 +55,7 @@ func TestCrossOutputVerifyEmpty(t *testing.T) { func TestCrossOutputSerialize(t *testing.T) { require := require.New(t) - c := linearcodec.NewDefault() + c := linearcodec.NewDefault(time.Time{}) m := codec.NewDefaultManager() require.NoError(m.RegisterCodec(0, c)) diff --git a/vms/secp256k1fx/mock_alias_getter.go b/vms/secp256k1fx/mock_alias_getter.go index 9c49c53717b0..247ca869ebb7 100644 --- a/vms/secp256k1fx/mock_alias_getter.go +++ b/vms/secp256k1fx/mock_alias_getter.go @@ -1,8 +1,10 @@ -// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - // Code generated by MockGen. DO NOT EDIT. // Source: github.com/ava-labs/avalanchego/vms/secp256k1fx (interfaces: AliasGetter) +// +// Generated by this command: +// +// mockgen -package=secp256k1fx -destination=vms/secp256k1fx/mock_alias_getter.go github.com/ava-labs/avalanchego/vms/secp256k1fx AliasGetter +// // Package secp256k1fx is a generated GoMock package. package secp256k1fx @@ -48,7 +50,7 @@ func (m *MockAliasGetter) GetMultisigAlias(arg0 ids.ShortID) (*multisig.AliasWit } // GetMultisigAlias indicates an expected call of GetMultisigAlias. -func (mr *MockAliasGetterMockRecorder) GetMultisigAlias(arg0 interface{}) *gomock.Call { +func (mr *MockAliasGetterMockRecorder) GetMultisigAlias(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMultisigAlias", reflect.TypeOf((*MockAliasGetter)(nil).GetMultisigAlias), arg0) } From e1562a56010777306fc5023ee1eadba31cd85486 Mon Sep 17 00:00:00 2001 From: evlekht Date: Mon, 22 Jul 2024 14:50:27 +0400 Subject: [PATCH 267/267] tmp ci for review --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 82f2c785bf9e..cef348721ffb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,7 @@ name: Tests on: pull_request: - branches: [chain4travel, dev] + branches: [chain4travel, dev, evlekht/new-dev-c19] workflow_dispatch: merge_group: types: [checks_requested]