From 5e215d4384fe58489496dc1edb6d4ac4e4854329 Mon Sep 17 00:00:00 2001 From: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:41:42 -0400 Subject: [PATCH 1/3] Add SDK Router message handling (#316) Co-authored-by: Stephen Buttolph --- peer/network.go | 96 +++++++++++++++++------------------------ peer/network_test.go | 100 +++++++++++++++++++++++++++++++++++-------- plugin/evm/vm.go | 6 ++- scripts/versions.sh | 2 +- 4 files changed, 128 insertions(+), 76 deletions(-) diff --git a/peer/network.go b/peer/network.go index 7ad1a795b6..68efd3ef46 100644 --- a/peer/network.go +++ b/peer/network.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/codec" "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/snow/validators" "github.com/ava-labs/avalanchego/utils" @@ -87,6 +88,7 @@ type network struct { outstandingRequestHandlers map[uint32]message.ResponseHandler // maps avalanchego requestID => message.ResponseHandler activeAppRequests *semaphore.Weighted // controls maximum number of active outbound requests activeCrossChainRequests *semaphore.Weighted // controls maximum number of active outbound cross chain requests + router *p2p.Router // handles messages being sent to the generic networking SDK appSender common.AppSender // avalanchego AppSender for sending messages codec codec.Manager // Codec used for parsing messages crossChainCodec codec.Manager // Codec used for parsing cross chain messages @@ -99,11 +101,18 @@ type network struct { // Set to true when Shutdown is called, after which all operations on this // struct are no-ops. + // + // Invariant: Even though `closed` is an atomic, `lock` is required to be + // held when sending requests to guarantee that the network isn't closed + // during these calls. This is because closing the network cancels all + // outstanding requests, which means we must guarantee never to register a + // request that will never be fulfilled or cancelled. closed utils.Atomic[bool] } -func NewNetwork(appSender common.AppSender, codec codec.Manager, crossChainCodec codec.Manager, self ids.NodeID, maxActiveAppRequests int64, maxActiveCrossChainRequests int64) Network { +func NewNetwork(router *p2p.Router, appSender common.AppSender, codec codec.Manager, crossChainCodec codec.Manager, self ids.NodeID, maxActiveAppRequests int64, maxActiveCrossChainRequests int64) Network { return &network{ + router: router, appSender: appSender, codec: codec, crossChainCodec: crossChainCodec, @@ -172,10 +181,7 @@ func (n *network) sendAppRequest(nodeID ids.NodeID, request []byte, responseHand log.Debug("sending request to peer", "nodeID", nodeID, "requestLen", len(request)) n.peers.TrackPeer(nodeID) - // generate requestID - requestID := n.requestIDGen - n.requestIDGen++ - + requestID := n.nextRequestID() n.outstandingRequestHandlers[requestID] = responseHandler nodeIDs := set.NewSet[ids.NodeID](1) @@ -209,10 +215,7 @@ func (n *network) SendCrossChainRequest(chainID ids.ID, request []byte, handler return nil } - // generate requestID - requestID := n.requestIDGen - n.requestIDGen++ - + requestID := n.nextRequestID() n.outstandingRequestHandlers[requestID] = handler // Send cross chain request to [chainID]. @@ -272,19 +275,12 @@ func (n *network) CrossChainAppRequest(ctx context.Context, requestingChainID id // If [requestID] is not known, this function will emit a log and return a nil error. // If the response handler returns an error it is propagated as a fatal error. func (n *network) CrossChainAppRequestFailed(ctx context.Context, respondingChainID ids.ID, requestID uint32) error { - n.lock.Lock() - defer n.lock.Unlock() - - if n.closed.Get() { - return nil - } - log.Debug("received CrossChainAppRequestFailed from chain", "respondingChainID", respondingChainID, "requestID", requestID) handler, exists := n.markRequestFulfilled(requestID) if !exists { - // Should never happen since the engine should be managing outstanding requests - log.Error("received CrossChainAppRequestFailed to unknown request", "respondingChainID", respondingChainID, "requestID", requestID) + // Can happen after the network has been closed. + log.Debug("received CrossChainAppRequestFailed to unknown request", "respondingChainID", respondingChainID, "requestID", requestID) return nil } @@ -299,19 +295,12 @@ func (n *network) CrossChainAppRequestFailed(ctx context.Context, respondingChai // If [requestID] is not known, this function will emit a log and return a nil error. // If the response handler returns an error it is propagated as a fatal error. func (n *network) CrossChainAppResponse(ctx context.Context, respondingChainID ids.ID, requestID uint32, response []byte) error { - n.lock.Lock() - defer n.lock.Unlock() - - if n.closed.Get() { - return nil - } - log.Debug("received CrossChainAppResponse from responding chain", "respondingChainID", respondingChainID, "requestID", requestID) handler, exists := n.markRequestFulfilled(requestID) if !exists { - // Should never happen since the engine should be managing outstanding requests - log.Error("received CrossChainAppResponse to unknown request", "respondingChainID", respondingChainID, "requestID", requestID, "responseLen", len(response)) + // Can happen after the network has been closed. + log.Debug("received CrossChainAppResponse to unknown request", "respondingChainID", respondingChainID, "requestID", requestID, "responseLen", len(response)) return nil } @@ -335,8 +324,8 @@ func (n *network) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID u var req message.Request if _, err := n.codec.Unmarshal(request, &req); err != nil { - log.Debug("failed to unmarshal app request", "nodeID", nodeID, "requestID", requestID, "requestLen", len(request), "err", err) - return nil + log.Debug("forwarding AppRequest to SDK router", "nodeID", nodeID, "requestID", requestID, "requestLen", len(request), "err", err) + return n.router.AppRequest(ctx, nodeID, requestID, deadline, request) } bufferedDeadline, err := calculateTimeUntilDeadline(deadline, n.appStats) @@ -366,21 +355,13 @@ func (n *network) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID u // Error returned by this function is expected to be treated as fatal by the engine // If [requestID] is not known, this function will emit a log and return a nil error. // If the response handler returns an error it is propagated as a fatal error. -func (n *network) AppResponse(_ context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { - n.lock.Lock() - defer n.lock.Unlock() - - if n.closed.Get() { - return nil - } - +func (n *network) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { log.Debug("received AppResponse from peer", "nodeID", nodeID, "requestID", requestID) handler, exists := n.markRequestFulfilled(requestID) if !exists { - // Should never happen since the engine should be managing outstanding requests - log.Error("received AppResponse to unknown request", "nodeID", nodeID, "requestID", requestID, "responseLen", len(response)) - return nil + log.Debug("forwarding AppResponse to SDK router", "nodeID", nodeID, "requestID", requestID, "responseLen", len(response)) + return n.router.AppResponse(ctx, nodeID, requestID, response) } // We must release the slot @@ -395,21 +376,13 @@ func (n *network) AppResponse(_ context.Context, nodeID ids.NodeID, requestID ui // - request times out before a response is provided // error returned by this function is expected to be treated as fatal by the engine // returns error only when the response handler returns an error -func (n *network) AppRequestFailed(_ context.Context, nodeID ids.NodeID, requestID uint32) error { - n.lock.Lock() - defer n.lock.Unlock() - - if n.closed.Get() { - return nil - } - +func (n *network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { log.Debug("received AppRequestFailed from peer", "nodeID", nodeID, "requestID", requestID) handler, exists := n.markRequestFulfilled(requestID) if !exists { - // Should never happen since the engine should be managing outstanding requests - log.Error("received AppRequestFailed to unknown request", "nodeID", nodeID, "requestID", requestID) - return nil + log.Debug("forwarding AppRequestFailed to SDK router", "nodeID", nodeID, "requestID", requestID) + return n.router.AppRequestFailed(ctx, nodeID, requestID) } // We must release the slot @@ -442,8 +415,11 @@ func calculateTimeUntilDeadline(deadline time.Time, stats stats.RequestHandlerSt // markRequestFulfilled fetches the handler for [requestID] and marks the request with [requestID] as having been fulfilled. // This is called by either [AppResponse] or [AppRequestFailed]. -// Assumes that the write lock is held. +// Assumes that the write lock is not held. func (n *network) markRequestFulfilled(requestID uint32) (message.ResponseHandler, bool) { + n.lock.Lock() + defer n.lock.Unlock() + handler, exists := n.outstandingRequestHandlers[requestID] if !exists { return nil, false @@ -467,10 +443,6 @@ func (n *network) Gossip(gossip []byte) error { // error returned by this function is expected to be treated as fatal by the engine // returns error if request could not be parsed as message.Request or when the requestHandler returns an error func (n *network) AppGossip(_ context.Context, nodeID ids.NodeID, gossipBytes []byte) error { - if n.closed.Get() { - return nil - } - var gossipMsg message.GossipMessage if _, err := n.codec.Unmarshal(gossipBytes, &gossipMsg); err != nil { log.Debug("could not parse app gossip", "nodeID", nodeID, "gossipLen", len(gossipBytes), "err", err) @@ -564,3 +536,15 @@ func (n *network) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) { n.peers.TrackBandwidth(nodeID, bandwidth) } + +// invariant: peer/network must use explicitly even request ids. +// for this reason, [n.requestID] is initialized as zero and incremented by 2. +// This is for backwards-compatibility while the SDK router exists with the +// legacy coreth handlers to avoid a (very) narrow edge case where request ids +// can overlap, resulting in a dropped timeout. +func (n *network) nextRequestID() uint32 { + next := n.requestIDGen + n.requestIDGen += 2 + + return next +} diff --git a/peer/network_test.go b/peer/network_test.go index 0e2125c758..329c76af7e 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -12,7 +12,9 @@ import ( "testing" "time" + "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" ethcommon "github.com/ethereum/go-ethereum/common" @@ -48,11 +50,13 @@ var ( _ message.CrossChainRequest = &ExampleCrossChainRequest{} _ message.CrossChainRequestHandler = &testCrossChainHandler{} + + _ p2p.Handler = &testSDKHandler{} ) func TestNetworkDoesNotConnectToItself(t *testing.T) { selfNodeID := ids.GenerateTestNodeID() - n := NewNetwork(nil, nil, nil, selfNodeID, 1, 1) + n := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), nil, nil, nil, selfNodeID, 1, 1) assert.NoError(t, n.Connected(context.Background(), selfNodeID, defaultPeerVersion)) assert.EqualValues(t, 0, n.Size()) } @@ -88,7 +92,7 @@ func TestRequestAnyRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) client := NewNetworkClient(net) nodeID := ids.GenerateTestNodeID() @@ -163,7 +167,7 @@ func TestRequestRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) client := NewNetworkClient(net) @@ -243,7 +247,7 @@ func TestAppRequestOnShutdown(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) client := NewNetworkClient(net) nodeID := ids.GenerateTestNodeID() require.NoError(t, net.Connected(context.Background(), nodeID, defaultPeerVersion)) @@ -292,7 +296,7 @@ func TestRequestMinVersion(t *testing.T) { // passing nil as codec works because the net.AppRequest is never called crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 16) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 16) client := NewNetworkClient(net) requestMessage := TestMessage{Message: "this is a request"} requestBytes, err := message.RequestToBytes(codecManager, requestMessage) @@ -355,7 +359,7 @@ func TestOnRequestHonoursDeadline(t *testing.T) { processingDuration: 500 * time.Millisecond, } - net = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetRequestHandler(requestHandler) nodeID := ids.GenerateTestNodeID() @@ -395,7 +399,7 @@ func TestGossip(t *testing.T) { } gossipHandler := &testGossipHandler{} - clientNetwork = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + clientNetwork = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(gossipHandler) assert.NoError(t, clientNetwork.Connected(context.Background(), nodeID, defaultPeerVersion)) @@ -422,7 +426,7 @@ func TestHandleInvalidMessages(t *testing.T) { requestID := uint32(1) sender := testAppSender{} - clientNetwork := NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + clientNetwork := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(message.NoopMempoolGossipHandler{}) clientNetwork.SetRequestHandler(&testRequestHandler{}) @@ -456,12 +460,11 @@ func TestHandleInvalidMessages(t *testing.T) { assert.NoError(t, clientNetwork.AppRequest(context.Background(), nodeID, requestID, time.Now().Add(time.Second), garbageResponse)) assert.NoError(t, clientNetwork.AppRequest(context.Background(), nodeID, requestID, time.Now().Add(time.Second), emptyResponse)) assert.NoError(t, clientNetwork.AppRequest(context.Background(), nodeID, requestID, time.Now().Add(time.Second), nilResponse)) - assert.NoError(t, clientNetwork.AppResponse(context.Background(), nodeID, requestID, gossipMsg)) - assert.NoError(t, clientNetwork.AppResponse(context.Background(), nodeID, requestID, requestMessage)) - assert.NoError(t, clientNetwork.AppResponse(context.Background(), nodeID, requestID, garbageResponse)) - assert.NoError(t, clientNetwork.AppResponse(context.Background(), nodeID, requestID, emptyResponse)) - assert.NoError(t, clientNetwork.AppResponse(context.Background(), nodeID, requestID, nilResponse)) - assert.NoError(t, clientNetwork.AppRequestFailed(context.Background(), nodeID, requestID)) + assert.ErrorIs(t, p2p.ErrUnrequestedResponse, clientNetwork.AppResponse(context.Background(), nodeID, requestID, gossipMsg)) + assert.ErrorIs(t, p2p.ErrUnrequestedResponse, clientNetwork.AppResponse(context.Background(), nodeID, requestID, requestMessage)) + assert.ErrorIs(t, p2p.ErrUnrequestedResponse, clientNetwork.AppResponse(context.Background(), nodeID, requestID, garbageResponse)) + assert.ErrorIs(t, p2p.ErrUnrequestedResponse, clientNetwork.AppResponse(context.Background(), nodeID, requestID, emptyResponse)) + assert.ErrorIs(t, p2p.ErrUnrequestedResponse, clientNetwork.AppResponse(context.Background(), nodeID, requestID, nilResponse)) } func TestNetworkPropagatesRequestHandlerError(t *testing.T) { @@ -472,7 +475,7 @@ func TestNetworkPropagatesRequestHandlerError(t *testing.T) { requestID := uint32(1) sender := testAppSender{} - clientNetwork := NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + clientNetwork := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(message.NoopMempoolGossipHandler{}) clientNetwork.SetRequestHandler(&testRequestHandler{err: errors.New("fail")}) // Return an error from the request handler @@ -512,7 +515,7 @@ func TestCrossChainAppRequest(t *testing.T) { }, } - net = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) client := NewNetworkClient(net) @@ -567,7 +570,7 @@ func TestCrossChainRequestRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, TestMessage{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) client := NewNetworkClient(net) @@ -627,7 +630,7 @@ func TestCrossChainRequestOnShutdown(t *testing.T) { } codecManager := buildCodec(t, TestMessage{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) client := NewNetworkClient(net) exampleCrossChainRequest := ExampleCrossChainRequest{ @@ -648,6 +651,48 @@ func TestCrossChainRequestOnShutdown(t *testing.T) { require.True(t, called) } +func TestSDKRouting(t *testing.T) { + require := require.New(t) + sender := &testAppSender{ + sendAppRequestFn: func(s set.Set[ids.NodeID], u uint32, bytes []byte) error { + return nil + }, + sendAppResponseFn: func(id ids.NodeID, u uint32, bytes []byte) error { + return nil + }, + } + protocol := 0 + handler := &testSDKHandler{} + router := p2p.NewRouter(logging.NoLog{}, sender) + _, err := router.RegisterAppProtocol(uint64(protocol), handler, nil) + require.NoError(err) + + networkCodec := codec.NewManager(0) + crossChainCodec := codec.NewManager(0) + + network := NewNetwork( + router, + nil, + networkCodec, + crossChainCodec, + ids.EmptyNodeID, + 1, + 1, + ) + + nodeID := ids.GenerateTestNodeID() + foobar := append([]byte{byte(protocol)}, []byte("foobar")...) + err = network.AppRequest(context.Background(), nodeID, 0, time.Time{}, foobar) + require.NoError(err) + require.True(handler.appRequested) + + err = network.AppResponse(context.Background(), ids.GenerateTestNodeID(), 0, foobar) + require.ErrorIs(err, p2p.ErrUnrequestedResponse) + + err = network.AppRequestFailed(context.Background(), nodeID, 0) + require.ErrorIs(err, p2p.ErrUnrequestedResponse) +} + func buildCodec(t *testing.T, types ...interface{}) codec.Manager { codecManager := codec.NewDefaultManager() c := linearcodec.NewDefault() @@ -843,3 +888,22 @@ type testCrossChainHandler struct { func (t *testCrossChainHandler) HandleCrossChainRequest(ctx context.Context, requestingChainID ids.ID, requestID uint32, exampleRequest message.CrossChainRequest) ([]byte, error) { return t.codec.Marshal(message.Version, ExampleCrossChainResponse{Response: "this is an example response"}) } + +type testSDKHandler struct { + appRequested bool +} + +func (t *testSDKHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) error { + // TODO implement me + panic("implement me") +} + +func (t *testSDKHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, error) { + t.appRequested = true + return nil, nil +} + +func (t *testSDKHandler) CrossChainAppRequest(ctx context.Context, chainID ids.ID, deadline time.Time, requestBytes []byte) ([]byte, error) { + // TODO implement me + panic("implement me") +} diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index aed4e6c846..a5987345a4 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -16,6 +16,7 @@ import ( "time" avalanchegoMetrics "github.com/ava-labs/avalanchego/api/metrics" + "github.com/ava-labs/avalanchego/network/p2p" avalanchegoConstants "github.com/ava-labs/avalanchego/utils/constants" "github.com/prometheus/client_golang/prometheus" @@ -206,6 +207,8 @@ type VM struct { client peer.NetworkClient networkCodec codec.Manager + router *p2p.Router + // Metrics multiGatherer avalanchegoMetrics.MultiGatherer @@ -432,8 +435,9 @@ func (vm *VM) Initialize( } // initialize peer network + vm.router = p2p.NewRouter(vm.ctx.Log, appSender) vm.networkCodec = message.Codec - vm.Network = peer.NewNetwork(appSender, vm.networkCodec, message.CrossChainCodec, chainCtx.NodeID, vm.config.MaxOutboundActiveRequests, vm.config.MaxOutboundActiveCrossChainRequests) + vm.Network = peer.NewNetwork(vm.router, appSender, vm.networkCodec, message.CrossChainCodec, chainCtx.NodeID, vm.config.MaxOutboundActiveRequests, vm.config.MaxOutboundActiveCrossChainRequests) vm.client = peer.NewNetworkClient(vm.Network) // initialize warp backend diff --git a/scripts/versions.sh b/scripts/versions.sh index 7ff6edf37c..4ca36f6044 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.9'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.9-rc.4'} AVALANCHEGO_VERSION=${AVALANCHEGO_VERSION:-$AVALANCHE_VERSION} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} From 816ade1399726f2c5b693008e4cc14ba4c59f951 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Sun, 17 Sep 2023 13:53:02 +0300 Subject: [PATCH 2/3] revert avago version bump --- scripts/versions.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/versions.sh b/scripts/versions.sh index 4ca36f6044..7ff6edf37c 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.9-rc.4'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.9'} AVALANCHEGO_VERSION=${AVALANCHEGO_VERSION:-$AVALANCHE_VERSION} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} From 3aacbc9795a0cf6185019f06b9c0e425a4262d49 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Tue, 19 Sep 2023 04:03:24 +0300 Subject: [PATCH 3/3] Fix hanging requests after Shutdown (#326) (#859) * Fix hanging requests after Shutdown (#326) * fix requests hanging after shutdown * fix build --------- Signed-off-by: Stephen Buttolph Co-authored-by: Stephen Buttolph * Bump avago rc (#860) * Update to 1.10.10-rc.2 (#328) * update to avalanchego 1.10.10-rc.2 * nits * nit * add batchsize * increase timeout dynamically --------- Co-authored-by: Joshua Kim <20001595+joshua-kim@users.noreply.github.com> --------- --- .../workflows/auto-generated-code-checker.yml | 2 +- .github/workflows/bench.yml | 2 +- .github/workflows/ci.yml | 6 +-- .github/workflows/release.yml | 2 +- Dockerfile | 4 +- README.md | 2 +- accounts/abi/bind/bind_test.go | 2 +- .../precompilebind/precompile_bind_test.go | 2 +- go.mod | 4 +- go.sum | 4 +- peer/network.go | 2 + peer/network_test.go | 47 ++++++++++++++----- plugin/evm/vm.go | 7 ++- scripts/build.sh | 2 +- scripts/versions.sh | 2 +- tests/utils/runner/network_manager.go | 4 +- warp/backend.go | 5 +- 17 files changed, 66 insertions(+), 33 deletions(-) diff --git a/.github/workflows/auto-generated-code-checker.yml b/.github/workflows/auto-generated-code-checker.yml index dab1938bbe..f8d372d3f0 100644 --- a/.github/workflows/auto-generated-code-checker.yml +++ b/.github/workflows/auto-generated-code-checker.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.19.12' + go-version: '~1.20.8' check-latest: true - shell: bash run: scripts/mock.gen.sh diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 0f16ad67de..c6a67b266f 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.19.12' + go-version: '~1.20.8' check-latest: true - run: go mod download shell: bash diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a38ca086fe..1ac7f92a04 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: shell: bash - uses: actions/setup-go@v3 with: - go-version: '~1.19.12' + go-version: '~1.20.8' check-latest: true - name: golangci-lint uses: golangci/golangci-lint-action@v3 @@ -34,7 +34,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-go@v3 with: - go-version: '~1.19.12' + go-version: '~1.20.8' check-latest: true - run: go mod download shell: bash @@ -66,7 +66,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.19.12' + go-version: '~1.20.8' check-latest: true - name: Use Node.js uses: actions/setup-node@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 873007a464..402eef6bb5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: '~1.19.12' + go-version: '~1.20.8' check-latest: true - name: Set up arm64 cross compiler run: | diff --git a/Dockerfile b/Dockerfile index fd15d9e603..13fdd428f2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ ARG AVALANCHE_VERSION # ============= Compilation Stage ================ -FROM golang:1.19.12-bullseye AS builder +FROM golang:1.20.8-bullseye AS builder WORKDIR /build @@ -14,7 +14,7 @@ WORKDIR /build COPY go.mod go.sum avalanchego* ./ # Download avalanche dependencies using go mod -RUN go mod download && go mod tidy -compat=1.19 +RUN go mod download && go mod tidy -compat=1.20 # Copy the code into the container COPY . . diff --git a/README.md b/README.md index ec948fff37..c006c0873c 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ To support these changes, there have been a number of changes to the SubnetEVM b ### Clone Subnet-evm -First install Go 1.19.12 or later. Follow the instructions [here](https://golang.org/doc/install). You can verify by running `go version`. +First install Go 1.20.8 or later. Follow the instructions [here](https://golang.org/doc/install). You can verify by running `go version`. Set `$GOPATH` environment variable properly for Go to look for Go Workspaces. Please read [this](https://go.dev/doc/gopath_code) for details. You can verify by running `echo $GOPATH`. diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 1cda835f6b..049c77b2c5 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -2137,7 +2137,7 @@ func golangBindings(t *testing.T, overload bool) { if out, err := replacer.CombinedOutput(); err != nil { t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out) } - tidier := exec.Command(gocmd, "mod", "tidy", "-compat=1.19") + tidier := exec.Command(gocmd, "mod", "tidy", "-compat=1.20") tidier.Dir = pkg if out, err := tidier.CombinedOutput(); err != nil { t.Fatalf("failed to tidy Go module file: %v\n%s", err, out) diff --git a/accounts/abi/bind/precompilebind/precompile_bind_test.go b/accounts/abi/bind/precompilebind/precompile_bind_test.go index 4af5b78295..cffeb79c06 100644 --- a/accounts/abi/bind/precompilebind/precompile_bind_test.go +++ b/accounts/abi/bind/precompilebind/precompile_bind_test.go @@ -592,7 +592,7 @@ func TestPrecompileBind(t *testing.T) { if out, err := replacer.CombinedOutput(); err != nil { t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out) } - tidier := exec.Command(gocmd, "mod", "tidy", "-compat=1.19") + tidier := exec.Command(gocmd, "mod", "tidy", "-compat=1.20") tidier.Dir = pkg if out, err := tidier.CombinedOutput(); err != nil { t.Fatalf("failed to tidy Go module file: %v\n%s", err, out) diff --git a/go.mod b/go.mod index 69419295cc..bafd8111b1 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/ava-labs/subnet-evm -go 1.19 +go 1.20 require ( github.com/VictoriaMetrics/fastcache v1.10.0 github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 - github.com/ava-labs/avalanchego v1.10.9 + github.com/ava-labs/avalanchego v1.10.10-rc.2 github.com/cespare/cp v0.1.0 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index 1b5b91a244..c5291c99c7 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,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/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724 h1:ptqFgQtJ5DyLb2lvuvawLJNlvo1A1qv+JXYTneNeg14= github.com/ava-labs/avalanche-network-runner v1.7.2-0.20230825150237-723bc7b31724/go.mod h1:euKHwZ77sGvGfhVj4v9WPM4jD2b5N80ldE2XHqO7lwA= -github.com/ava-labs/avalanchego v1.10.9 h1:qxhp3YoD2Wm/iIKP6Wb1isbkUPWmIrJxWgivDoL0obM= -github.com/ava-labs/avalanchego v1.10.9/go.mod h1:C8R5uiltpc8MQ62ixxgODR+15mesWF0aAw3H+Qrl9Iw= +github.com/ava-labs/avalanchego v1.10.10-rc.2 h1:nlHc1JwKb5TEc9oqPU2exvOpazhxr11N2ym/LzYxv4k= +github.com/ava-labs/avalanchego v1.10.10-rc.2/go.mod h1:BN97sZppDSvIMIfEjrLTjdPTFkGLkb0ISJHEcoxMMNk= github.com/ava-labs/coreth v0.12.5-rc.3 h1:cpmC+fSZMsO4gaFWqXHzAHrJACf05u5HPAYmwh7nmkU= github.com/ava-labs/coreth v0.12.5-rc.3/go.mod h1:HI+jTIflnDFBd0bledgkgid1Uurwr8q1h7zb3LsFsSo= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/peer/network.go b/peer/network.go index 68efd3ef46..d6176ea391 100644 --- a/peer/network.go +++ b/peer/network.go @@ -175,6 +175,7 @@ func (n *network) SendAppRequest(nodeID ids.NodeID, request []byte, responseHand // Assumes write lock is held func (n *network) sendAppRequest(nodeID ids.NodeID, request []byte, responseHandler message.ResponseHandler) error { if n.closed.Get() { + n.activeAppRequests.Release(1) return nil } @@ -212,6 +213,7 @@ func (n *network) SendCrossChainRequest(chainID ids.ID, request []byte, handler defer n.lock.Unlock() if n.closed.Get() { + n.activeCrossChainRequests.Release(1) return nil } diff --git a/peer/network_test.go b/peer/network_test.go index 329c76af7e..3ad5e11831 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/set" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/subnet-evm/plugin/evm/message" "github.com/stretchr/testify/assert" @@ -56,7 +57,7 @@ var ( func TestNetworkDoesNotConnectToItself(t *testing.T) { selfNodeID := ids.GenerateTestNodeID() - n := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), nil, nil, nil, selfNodeID, 1, 1) + n := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), nil, nil, nil, selfNodeID, 1, 1) assert.NoError(t, n.Connected(context.Background(), selfNodeID, defaultPeerVersion)) assert.EqualValues(t, 0, n.Size()) } @@ -92,7 +93,7 @@ func TestRequestAnyRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) client := NewNetworkClient(net) nodeID := ids.GenerateTestNodeID() @@ -167,7 +168,7 @@ func TestRequestRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) client := NewNetworkClient(net) @@ -247,7 +248,7 @@ func TestAppRequestOnShutdown(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) client := NewNetworkClient(net) nodeID := ids.GenerateTestNodeID() require.NoError(t, net.Connected(context.Background(), nodeID, defaultPeerVersion)) @@ -296,7 +297,7 @@ func TestRequestMinVersion(t *testing.T) { // passing nil as codec works because the net.AppRequest is never called crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 16) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 16) client := NewNetworkClient(net) requestMessage := TestMessage{Message: "this is a request"} requestBytes, err := message.RequestToBytes(codecManager, requestMessage) @@ -359,7 +360,7 @@ func TestOnRequestHonoursDeadline(t *testing.T) { processingDuration: 500 * time.Millisecond, } - net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetRequestHandler(requestHandler) nodeID := ids.GenerateTestNodeID() @@ -399,7 +400,7 @@ func TestGossip(t *testing.T) { } gossipHandler := &testGossipHandler{} - clientNetwork = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + clientNetwork = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(gossipHandler) assert.NoError(t, clientNetwork.Connected(context.Background(), nodeID, defaultPeerVersion)) @@ -426,7 +427,7 @@ func TestHandleInvalidMessages(t *testing.T) { requestID := uint32(1) sender := testAppSender{} - clientNetwork := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + clientNetwork := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(message.NoopMempoolGossipHandler{}) clientNetwork.SetRequestHandler(&testRequestHandler{}) @@ -475,7 +476,7 @@ func TestNetworkPropagatesRequestHandlerError(t *testing.T) { requestID := uint32(1) sender := testAppSender{} - clientNetwork := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + clientNetwork := NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) clientNetwork.SetGossipHandler(message.NoopMempoolGossipHandler{}) clientNetwork.SetRequestHandler(&testRequestHandler{err: errors.New("fail")}) // Return an error from the request handler @@ -515,7 +516,7 @@ func TestCrossChainAppRequest(t *testing.T) { }, } - net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) client := NewNetworkClient(net) @@ -570,7 +571,7 @@ func TestCrossChainRequestRequestsRoutingAndResponse(t *testing.T) { codecManager := buildCodec(t, TestMessage{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) client := NewNetworkClient(net) @@ -630,7 +631,7 @@ func TestCrossChainRequestOnShutdown(t *testing.T) { } codecManager := buildCodec(t, TestMessage{}) crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2p.NewRouter(logging.NoLog{}, nil, prometheus.NewRegistry(), ""), sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) client := NewNetworkClient(net) exampleCrossChainRequest := ExampleCrossChainRequest{ @@ -651,6 +652,26 @@ func TestCrossChainRequestOnShutdown(t *testing.T) { require.True(t, called) } +func TestNetworkAppRequestAfterShutdown(t *testing.T) { + require := require.New(t) + + net := NewNetwork(nil, nil, nil, nil, ids.EmptyNodeID, 1, 0) + net.Shutdown() + + require.NoError(net.SendAppRequest(ids.GenerateTestNodeID(), nil, nil)) + require.NoError(net.SendAppRequest(ids.GenerateTestNodeID(), nil, nil)) +} + +func TestNetworkCrossChainAppRequestAfterShutdown(t *testing.T) { + require := require.New(t) + + net := NewNetwork(nil, nil, nil, nil, ids.EmptyNodeID, 0, 1) + net.Shutdown() + + require.NoError(net.SendCrossChainRequest(ids.GenerateTestID(), nil, nil)) + require.NoError(net.SendCrossChainRequest(ids.GenerateTestID(), nil, nil)) +} + func TestSDKRouting(t *testing.T) { require := require.New(t) sender := &testAppSender{ @@ -663,7 +684,7 @@ func TestSDKRouting(t *testing.T) { } protocol := 0 handler := &testSDKHandler{} - router := p2p.NewRouter(logging.NoLog{}, sender) + router := p2p.NewRouter(logging.NoLog{}, sender, prometheus.NewRegistry(), "") _, err := router.RegisterAppProtocol(uint64(protocol), handler, nil) require.NoError(err) diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index a5987345a4..20d8deb73a 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -211,6 +211,7 @@ type VM struct { // Metrics multiGatherer avalanchegoMetrics.MultiGatherer + sdkMetrics *prometheus.Registry bootstrapped bool @@ -435,7 +436,7 @@ func (vm *VM) Initialize( } // initialize peer network - vm.router = p2p.NewRouter(vm.ctx.Log, appSender) + vm.router = p2p.NewRouter(vm.ctx.Log, appSender, vm.sdkMetrics, "p2p") vm.networkCodec = message.Codec vm.Network = peer.NewNetwork(vm.router, appSender, vm.networkCodec, message.CrossChainCodec, chainCtx.NodeID, vm.config.MaxOutboundActiveRequests, vm.config.MaxOutboundActiveCrossChainRequests) vm.client = peer.NewNetworkClient(vm.Network) @@ -461,6 +462,7 @@ func (vm *VM) Initialize( } func (vm *VM) initializeMetrics() error { + vm.sdkMetrics = prometheus.NewRegistry() vm.multiGatherer = avalanchegoMetrics.NewMultiGatherer() // If metrics are enabled, register the default metrics regitry if metrics.Enabled { @@ -468,6 +470,9 @@ func (vm *VM) initializeMetrics() error { if err := vm.multiGatherer.Register(ethMetricsPrefix, gatherer); err != nil { return err } + if err := vm.multiGatherer.Register("sdk", vm.sdkMetrics); err != nil { + return err + } // Register [multiGatherer] after registerers have been registered to it if err := vm.ctx.Metrics.Register(vm.multiGatherer); err != nil { return err diff --git a/scripts/build.sh b/scripts/build.sh index f4a006eb07..d18be270ee 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -4,7 +4,7 @@ set -o errexit set -o nounset set -o pipefail -go_version_minimum="1.19.12" +go_version_minimum="1.20.8" go_version() { go version | sed -nE -e 's/[^0-9.]+([0-9.]+).+/\1/p' diff --git a/scripts/versions.sh b/scripts/versions.sh index 7ff6edf37c..838ded5005 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.9'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'v1.10.10-rc.2'} AVALANCHEGO_VERSION=${AVALANCHEGO_VERSION:-$AVALANCHE_VERSION} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} diff --git a/tests/utils/runner/network_manager.go b/tests/utils/runner/network_manager.go index ec79ee1e5f..81b7d9dcaf 100644 --- a/tests/utils/runner/network_manager.go +++ b/tests/utils/runner/network_manager.go @@ -220,7 +220,9 @@ func (n *NetworkManager) StartDefaultNetwork(ctx context.Context) (<-chan struct // Uses [execPath] as the AvalancheGo binary execution path for any started nodes. // Note: this assumes that the default network has already been constructed. func (n *NetworkManager) SetupNetwork(ctx context.Context, execPath string, blockchainSpecs []*rpcpb.BlockchainSpec) error { - cctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + // timeout according to how many blockchains we're creating + timeout := 2 * time.Minute * time.Duration(len(blockchainSpecs)) + cctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() if err := n.init(); err != nil { return err diff --git a/warp/backend.go b/warp/backend.go index 15ba70629b..0b6867c10f 100644 --- a/warp/backend.go +++ b/warp/backend.go @@ -12,11 +12,14 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/crypto/bls" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + "github.com/ava-labs/subnet-evm/ethdb" "github.com/ethereum/go-ethereum/log" ) var _ WarpBackend = &warpBackend{} +const batchSize = ethdb.IdealBatchSize + // WarpBackend tracks signature eligible warp messages and provides an interface to fetch them. // The backend is also used to query for warp message signatures by the signature request handler. type WarpBackend interface { @@ -53,7 +56,7 @@ func NewWarpBackend(snowCtx *snow.Context, db database.Database, cacheSize int) func (w *warpBackend) Clear() error { w.signatureCache.Flush() - return database.Clear(w.db, w.db) + return database.Clear(w.db, batchSize) } func (w *warpBackend) AddMessage(unsignedMessage *avalancheWarp.UnsignedMessage) error {