diff --git a/go.mod b/go.mod index 7a5de639cd..b76bae82b9 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21.12 require ( github.com/VictoriaMetrics/fastcache v1.12.1 - github.com/ava-labs/avalanchego v1.11.11-0.20240805202431-479145a6602d + github.com/ava-labs/avalanchego v1.11.11-0.20240813203340-ab83fb41528d github.com/cespare/cp v0.1.0 github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 github.com/davecgh/go-spew v1.1.1 @@ -54,7 +54,7 @@ require ( require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect - github.com/ava-labs/coreth v0.13.8-0.20240802110637-b3e5088d062d // indirect + github.com/ava-labs/coreth v0.13.8-fixed-genesis-upgrade.0.20240813194342-7635a96aa180 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect diff --git a/go.sum b/go.sum index 549db74bb0..37eaffff74 100644 --- a/go.sum +++ b/go.sum @@ -56,10 +56,10 @@ github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/avalanchego v1.11.11-0.20240805202431-479145a6602d h1:T8sDX5uo7zSEjwDtVccS1WtzuC3pRXs9NXYbmGGagJ4= -github.com/ava-labs/avalanchego v1.11.11-0.20240805202431-479145a6602d/go.mod h1:9e0UPXJboybmgFjeTj+SFbK4ugbrdG4t68VdiUW5oQ8= -github.com/ava-labs/coreth v0.13.8-0.20240802110637-b3e5088d062d h1:klPTcKVvqfA2KSKaRvQAO56Pd4XAqGhwgMTQ6/W+w7w= -github.com/ava-labs/coreth v0.13.8-0.20240802110637-b3e5088d062d/go.mod h1:tXDujonxXFOF6oK5HS2EmgtSXJK3Gy6RpZxb5WzR9rM= +github.com/ava-labs/avalanchego v1.11.11-0.20240813203340-ab83fb41528d h1:LyrKJL9avIIxBY3uTcS2dFtUMBFmI2QpAgG6qYTdA6s= +github.com/ava-labs/avalanchego v1.11.11-0.20240813203340-ab83fb41528d/go.mod h1:UkyrRDXK2E15Lq2abyae2Pt+JsWvgsg1pe0/AtoMyAM= +github.com/ava-labs/coreth v0.13.8-fixed-genesis-upgrade.0.20240813194342-7635a96aa180 h1:6aIHp7wbyGVYdhHVQUbG7BEcbCMEQ5SYopPPJyipyvk= +github.com/ava-labs/coreth v0.13.8-fixed-genesis-upgrade.0.20240813194342-7635a96aa180/go.mod h1:/wNBVq7J7wlC2Kbov7kk6LV5xZvau7VF9zwTVOeyAjY= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= diff --git a/peer/client.go b/peer/client.go index d40e1a268a..d295f62e38 100644 --- a/peer/client.go +++ b/peer/client.go @@ -30,10 +30,6 @@ type NetworkClient interface { // Returns response bytes, and ErrRequestFailed if the request should be retried. SendAppRequest(ctx context.Context, nodeID ids.NodeID, request []byte) ([]byte, error) - // SendCrossChainRequest sends a request to a specific blockchain running on this node. - // Returns response bytes, and ErrRequestFailed if the request failed. - SendCrossChainRequest(ctx context.Context, chainID ids.ID, request []byte) ([]byte, error) - // TrackBandwidth should be called for each valid request with the bandwidth // (length of response divided by request time), and with 0 if the response is invalid. TrackBandwidth(nodeID ids.NodeID, bandwidth float64) @@ -77,16 +73,6 @@ func (c *client) SendAppRequest(ctx context.Context, nodeID ids.NodeID, request return waitingHandler.WaitForResult(ctx) } -// SendCrossChainRequest synchronously sends request to the specified chainID -// Returns response bytes and ErrRequestFailed if the request should be retried. -func (c *client) SendCrossChainRequest(ctx context.Context, chainID ids.ID, request []byte) ([]byte, error) { - waitingHandler := newWaitingResponseHandler() - if err := c.network.SendCrossChainRequest(ctx, chainID, request, waitingHandler); err != nil { - return nil, err - } - return waitingHandler.WaitForResult(ctx) -} - func (c *client) TrackBandwidth(nodeID ids.NodeID, bandwidth float64) { c.network.TrackBandwidth(nodeID, bandwidth) } diff --git a/peer/network.go b/peer/network.go index 0be14af280..13e3cc6220 100644 --- a/peer/network.go +++ b/peer/network.go @@ -51,9 +51,6 @@ type Network interface { // SendAppRequest sends message to given nodeID, notifying handler when there's a response or timeout SendAppRequest(ctx context.Context, nodeID ids.NodeID, message []byte, handler message.ResponseHandler) error - // SendCrossChainRequest sends a message to given chainID notifying handler when there's a response or timeout - SendCrossChainRequest(ctx context.Context, chainID ids.ID, message []byte, handler message.ResponseHandler) error - // Shutdown stops all peer channel listeners and marks the node to have stopped // n.Start() can be called again but the peers will have to be reconnected // by calling OnPeerConnected for each peer @@ -65,9 +62,6 @@ type Network interface { // SetRequestHandler sets the provided request handler as the request handler SetRequestHandler(handler message.RequestHandler) - // SetCrossChainHandler sets the provided cross chain request handler as the cross chain request handler - SetCrossChainRequestHandler(handler message.CrossChainRequestHandler) - // Size returns the size of the network in number of connected peers Size() uint32 @@ -89,17 +83,13 @@ type network struct { requestIDGen uint32 // requestID counter used to track outbound requests 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 p2pNetwork *p2p.Network - 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 - appRequestHandler message.RequestHandler // maps request type => handler - crossChainRequestHandler message.CrossChainRequestHandler // maps cross chain request type => handler - gossipHandler message.GossipHandler // maps gossip type => handler - peers *peerTracker // tracking of peers & bandwidth - appStats stats.RequestHandlerStats // Provide request handler metrics - crossChainStats stats.RequestHandlerStats // Provide cross chain request handler metrics + appSender common.AppSender // avalanchego AppSender for sending messages + codec codec.Manager // Codec used for parsing messages + appRequestHandler message.RequestHandler // maps request type => handler + gossipHandler message.GossipHandler // maps gossip type => handler + peers *peerTracker // tracking of peers & bandwidth + appStats stats.RequestHandlerStats // Provide request handler metrics // Set to true when Shutdown is called, after which all operations on this // struct are no-ops. @@ -112,22 +102,18 @@ type network struct { closed utils.Atomic[bool] } -func NewNetwork(p2pNetwork *p2p.Network, appSender common.AppSender, codec codec.Manager, crossChainCodec codec.Manager, self ids.NodeID, maxActiveAppRequests int64, maxActiveCrossChainRequests int64) Network { +func NewNetwork(p2pNetwork *p2p.Network, appSender common.AppSender, codec codec.Manager, self ids.NodeID, maxActiveAppRequests int64) Network { return &network{ appSender: appSender, codec: codec, - crossChainCodec: crossChainCodec, self: self, outstandingRequestHandlers: make(map[uint32]message.ResponseHandler), activeAppRequests: semaphore.NewWeighted(maxActiveAppRequests), - activeCrossChainRequests: semaphore.NewWeighted(maxActiveCrossChainRequests), p2pNetwork: p2pNetwork, gossipHandler: message.NoopMempoolGossipHandler{}, appRequestHandler: message.NoopRequestHandler{}, - crossChainRequestHandler: message.NoopCrossChainRequestHandler{}, peers: NewPeerTracker(), appStats: stats.NewRequestHandlerStats(), - crossChainStats: stats.NewCrossChainRequestHandlerStats(), } } @@ -225,141 +211,6 @@ func (n *network) sendAppRequest(ctx context.Context, nodeID ids.NodeID, request return nil } -// SendCrossChainRequest sends request message bytes to specified chainID and adds [handler] to [outstandingRequestHandlers] -// so that it can be invoked when the network receives either a response or failure message. -// Returns an error if [appSender] is unable to make the request. -func (n *network) SendCrossChainRequest(ctx context.Context, chainID ids.ID, request []byte, handler message.ResponseHandler) error { - // Take a slot from total [activeCrossChainRequests] and block until a slot becomes available. - if err := n.activeCrossChainRequests.Acquire(ctx, 1); err != nil { - return errAcquiringSemaphore - } - - n.lock.Lock() - defer n.lock.Unlock() - - if n.closed.Get() { - n.activeCrossChainRequests.Release(1) - return nil - } - - // If the context was cancelled, we can skip sending this request. - if err := ctx.Err(); err != nil { - n.activeCrossChainRequests.Release(1) - return err - } - - requestID := n.nextRequestID() - n.outstandingRequestHandlers[requestID] = handler - - // Send cross chain request to [chainID]. - // On failure, release the slot from [activeCrossChainRequests] and delete - // request from [outstandingRequestHandlers]. - // - // Cancellation is removed from this context to avoid erroring unexpectedly. - // SendCrossChainAppRequest should be non-blocking and any error other than - // context cancellation is unexpected. - // - // This guarantees that the network should never receive an unexpected - // CrossChainAppResponse. - ctxWithoutCancel := context.WithoutCancel(ctx) - if err := n.appSender.SendCrossChainAppRequest(ctxWithoutCancel, chainID, requestID, request); err != nil { - log.Error( - "request to chain failed", - "chainID", chainID, - "requestID", requestID, - "requestLen", len(request), - "error", err, - ) - - n.activeCrossChainRequests.Release(1) - delete(n.outstandingRequestHandlers, requestID) - return err - } - - log.Debug("sent request message to chain", "chainID", chainID, "crossChainRequestID", requestID) - return nil -} - -// CrossChainAppRequest notifies the VM when another chain in the network requests for data. -// Send a CrossChainAppResponse to [chainID] in response to a valid message using the same -// [requestID] before the deadline. -func (n *network) CrossChainAppRequest(ctx context.Context, requestingChainID ids.ID, requestID uint32, deadline time.Time, request []byte) error { - if n.closed.Get() { - return nil - } - - log.Debug("received CrossChainAppRequest from chain", "requestingChainID", requestingChainID, "requestID", requestID, "requestLen", len(request)) - - var req message.CrossChainRequest - if _, err := n.crossChainCodec.Unmarshal(request, &req); err != nil { - log.Debug("failed to unmarshal CrossChainAppRequest", "requestingChainID", requestingChainID, "requestID", requestID, "requestLen", len(request), "err", err) - return nil - } - - bufferedDeadline, err := calculateTimeUntilDeadline(deadline, n.crossChainStats) - if err != nil { - log.Debug("deadline to process CrossChainAppRequest has expired, skipping", "requestingChainID", requestingChainID, "requestID", requestID, "err", err) - return nil - } - - log.Debug("processing incoming CrossChainAppRequest", "requestingChainID", requestingChainID, "requestID", requestID, "req", req) - handleCtx, cancel := context.WithDeadline(context.Background(), bufferedDeadline) - defer cancel() - - responseBytes, err := req.Handle(handleCtx, requestingChainID, requestID, n.crossChainRequestHandler) - switch { - case err != nil && err != context.DeadlineExceeded: - return err // Return a fatal error - case responseBytes != nil: - return n.appSender.SendCrossChainAppResponse(ctx, requestingChainID, requestID, responseBytes) // Propagate fatal error - default: - return nil - } -} - -// CrossChainAppRequestFailed can be called by the avalanchego -> VM in following cases: -// - respondingChain doesn't exist -// - invalid CrossChainAppResponse from respondingChain -// - invalid CrossChainRequest was sent to respondingChain -// - request times out before a response is provided -// 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, _ *common.AppError) error { - log.Debug("received CrossChainAppRequestFailed from chain", "respondingChainID", respondingChainID, "requestID", requestID) - - handler, exists := n.markRequestFulfilled(requestID) - if !exists { - // Can happen after the network has been closed. - log.Debug("received CrossChainAppRequestFailed to unknown request", "respondingChainID", respondingChainID, "requestID", requestID) - return nil - } - - // We must release the slot - n.activeCrossChainRequests.Release(1) - - return handler.OnFailure() -} - -// CrossChainAppResponse is invoked when there is a -// response received from [respondingChainID] regarding a request the VM sent out -// 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 { - log.Debug("received CrossChainAppResponse from responding chain", "respondingChainID", respondingChainID, "requestID", requestID) - - handler, exists := n.markRequestFulfilled(requestID) - if !exists { - // Can happen after the network has been closed. - log.Debug("received CrossChainAppResponse to unknown request", "respondingChainID", respondingChainID, "requestID", requestID, "responseLen", len(response)) - return nil - } - - // We must release the slot - n.activeCrossChainRequests.Release(1) - - return handler.OnResponse(response) -} - // AppRequest is called by avalanchego -> VM when there is an incoming AppRequest from a peer // error returned by this function is expected to be treated as fatal by the engine // returns error if the requestHandler returns an error @@ -443,7 +294,7 @@ func (n *network) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, reque // calculateTimeUntilDeadline calculates the time until deadline and drops it if we missed he deadline to response. // This function updates metrics for both app requests and cross chain requests. -// This is called by either [AppRequest] or [CrossChainAppRequest]. +// This is called by [AppRequest]. func calculateTimeUntilDeadline(deadline time.Time, stats stats.RequestHandlerStats) (time.Time, error) { // calculate how much time is left until the deadline timeTillDeadline := time.Until(deadline) @@ -560,13 +411,6 @@ func (n *network) SetRequestHandler(handler message.RequestHandler) { n.appRequestHandler = handler } -func (n *network) SetCrossChainRequestHandler(handler message.CrossChainRequestHandler) { - n.lock.Lock() - defer n.lock.Unlock() - - n.crossChainRequestHandler = handler -} - func (n *network) Size() uint32 { n.lock.RLock() defer n.lock.RUnlock() diff --git a/peer/network_test.go b/peer/network_test.go index 2ebcf6775a..d93439b22b 100644 --- a/peer/network_test.go +++ b/peer/network_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/enginetest" "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/stretchr/testify/assert" @@ -51,9 +50,6 @@ var ( _ message.GossipMessage = HelloGossip{} _ message.GossipHandler = &testGossipHandler{} - _ message.CrossChainRequest = &ExampleCrossChainRequest{} - _ message.CrossChainRequestHandler = &testCrossChainHandler{} - _ p2p.Handler = &testSDKHandler{} ) @@ -61,7 +57,7 @@ func TestNetworkDoesNotConnectToItself(t *testing.T) { selfNodeID := ids.GenerateTestNodeID() p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - n := NewNetwork(p2pNetwork, nil, nil, nil, selfNodeID, 1, 1) + n := NewNetwork(p2pNetwork, nil, nil, selfNodeID, 1) assert.NoError(t, n.Connected(context.Background(), selfNodeID, defaultPeerVersion)) assert.EqualValues(t, 0, n.Size()) } @@ -96,10 +92,9 @@ func TestRequestAnyRequestsRoutingAndResponse(t *testing.T) { } codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) + net = NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 16) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) client := NewNetworkClient(net) nodeID := ids.GenerateTestNodeID() @@ -140,8 +135,6 @@ func TestRequestAnyRequestsRoutingAndResponse(t *testing.T) { func TestAppRequestOnCtxCancellation(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - sender := testAppSender{ sendAppRequestFn: func(_ context.Context, nodes set.Set[ids.NodeID], requestID uint32, requestBytes []byte) error { return nil @@ -153,7 +146,7 @@ func TestAppRequestOnCtxCancellation(t *testing.T) { p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - net := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net := NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 1) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) requestMessage := HelloRequest{Message: "this is a request"} @@ -204,10 +197,9 @@ func TestRequestRequestsRoutingAndResponse(t *testing.T) { } codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 16, 16) + net = NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 16) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) client := NewNetworkClient(net) @@ -286,10 +278,9 @@ func TestAppRequestOnShutdown(t *testing.T) { } codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 1) client := NewNetworkClient(net) nodeID := ids.GenerateTestNodeID() require.NoError(t, net.Connected(context.Background(), nodeID, defaultPeerVersion)) @@ -312,8 +303,6 @@ func TestAppRequestOnShutdown(t *testing.T) { func TestAppRequestAnyOnCtxCancellation(t *testing.T) { codecManager := buildCodec(t, HelloRequest{}, HelloResponse{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - type reqInfo struct { nodeID ids.NodeID requestID uint32 @@ -340,7 +329,7 @@ func TestAppRequestAnyOnCtxCancellation(t *testing.T) { p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - net := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net := NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 1) net.SetRequestHandler(&HelloGreetingRequestHandler{codec: codecManager}) assert.NoError(t, net.Connected( @@ -393,7 +382,6 @@ func TestRequestMinVersion(t *testing.T) { callNum := uint32(0) nodeID := ids.GenerateTestNodeID() codecManager := buildCodec(t, TestMessage{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) var net Network sender := testAppSender{ @@ -419,7 +407,7 @@ func TestRequestMinVersion(t *testing.T) { // passing nil as codec works because the net.AppRequest is never called p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 16) + net = NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 1) client := NewNetworkClient(net) requestMessage := TestMessage{Message: "this is a request"} requestBytes, err := message.RequestToBytes(codecManager, requestMessage) @@ -476,8 +464,6 @@ func TestOnRequestHonoursDeadline(t *testing.T) { } codecManager := buildCodec(t, TestMessage{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - requestBytes, err := marshalStruct(codecManager, TestMessage{Message: "hello there"}) assert.NoError(t, err) @@ -487,7 +473,7 @@ func TestOnRequestHonoursDeadline(t *testing.T) { p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + net = NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 1) net.SetRequestHandler(requestHandler) nodeID := ids.GenerateTestNodeID() @@ -507,8 +493,6 @@ func TestOnRequestHonoursDeadline(t *testing.T) { func TestHandleInvalidMessages(t *testing.T) { codecManager := buildCodec(t, HelloGossip{}, TestMessage{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - nodeID := ids.GenerateTestNodeID() requestID := uint32(1) sender := &enginetest.Sender{ @@ -518,7 +502,7 @@ func TestHandleInvalidMessages(t *testing.T) { } p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, sender, prometheus.NewRegistry(), "") require.NoError(t, err) - clientNetwork := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + clientNetwork := NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 1) clientNetwork.SetGossipHandler(message.NoopMempoolGossipHandler{}) clientNetwork.SetRequestHandler(&testRequestHandler{}) @@ -561,15 +545,13 @@ func TestHandleInvalidMessages(t *testing.T) { func TestNetworkPropagatesRequestHandlerError(t *testing.T) { codecManager := buildCodec(t, TestMessage{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - nodeID := ids.GenerateTestNodeID() requestID := uint32(1) sender := testAppSender{} p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") require.NoError(t, err) - clientNetwork := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) + clientNetwork := NewNetwork(p2pNetwork, sender, codecManager, ids.EmptyNodeID, 1) clientNetwork.SetGossipHandler(message.NoopMempoolGossipHandler{}) clientNetwork.SetRequestHandler(&testRequestHandler{err: errors.New("fail")}) // Return an error from the request handler @@ -585,226 +567,16 @@ func TestNetworkPropagatesRequestHandlerError(t *testing.T) { assert.Error(t, clientNetwork.AppRequest(context.Background(), nodeID, requestID, time.Now().Add(time.Second), requestMessage)) } -func TestCrossChainAppRequest(t *testing.T) { - var net Network - codecManager := buildCodec(t, TestMessage{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - - sender := testAppSender{ - sendCrossChainAppRequestFn: func(requestingChainID ids.ID, requestID uint32, requestBytes []byte) error { - go func() { - if err := net.CrossChainAppRequest(context.Background(), requestingChainID, requestID, time.Now().Add(5*time.Second), requestBytes); err != nil { - panic(err) - } - }() - return nil - }, - sendCrossChainAppResponseFn: func(respondingChainID ids.ID, requestID uint32, responseBytes []byte) error { - go func() { - if err := net.CrossChainAppResponse(context.Background(), respondingChainID, requestID, responseBytes); err != nil { - panic(err) - } - }() - return nil - }, - } - - p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") - require.NoError(t, err) - net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) - net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) - client := NewNetworkClient(net) - - exampleCrossChainRequest := ExampleCrossChainRequest{ - Message: "hello this is an example request", - } - - crossChainRequest, err := buildCrossChainRequest(crossChainCodecManager, exampleCrossChainRequest) - assert.NoError(t, err) - - chainID := ids.ID(ethcommon.BytesToHash([]byte{1, 2, 3, 4, 5})) - responseBytes, err := client.SendCrossChainRequest(context.Background(), chainID, crossChainRequest) - assert.NoError(t, err) - - var response ExampleCrossChainResponse - if _, err = crossChainCodecManager.Unmarshal(responseBytes, &response); err != nil { - t.Fatal("unexpected error during unmarshal", err) - } - assert.Equal(t, "this is an example response", response.Response) -} - -func TestCrossChainAppRequestOnCtxCancellation(t *testing.T) { - codecManager := buildCodec(t, TestMessage{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - - sender := testAppSender{ - sendCrossChainAppRequestFn: func(requestingChainID ids.ID, requestID uint32, requestBytes []byte) error { - return nil - }, - sendCrossChainAppResponseFn: func(respondingChainID ids.ID, requestID uint32, responseBytes []byte) error { - return nil - }, - } - - p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") - require.NoError(t, err) - net := NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) - net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) - - exampleCrossChainRequest := ExampleCrossChainRequest{ - Message: "hello this is an example request", - } - - crossChainRequest, err := buildCrossChainRequest(crossChainCodecManager, exampleCrossChainRequest) - assert.NoError(t, err) - - chainID := ids.ID(ethcommon.BytesToHash([]byte{1, 2, 3, 4, 5})) - ctx, cancel := context.WithCancel(context.Background()) - // cancel context prior to sending - cancel() - client := NewNetworkClient(net) - _, err = client.SendCrossChainRequest(ctx, chainID, crossChainRequest) - assert.ErrorIs(t, err, context.Canceled) -} - -func TestCrossChainRequestRequestsRoutingAndResponse(t *testing.T) { - var ( - callNum uint32 - senderWg sync.WaitGroup - net Network - ) - - sender := testAppSender{ - sendCrossChainAppRequestFn: func(requestingChainID ids.ID, requestID uint32, requestBytes []byte) error { - senderWg.Add(1) - go func() { - defer senderWg.Done() - if err := net.CrossChainAppRequest(context.Background(), requestingChainID, requestID, time.Now().Add(5*time.Second), requestBytes); err != nil { - panic(err) - } - }() - return nil - }, - sendCrossChainAppResponseFn: func(respondingChainID ids.ID, requestID uint32, responseBytes []byte) error { - senderWg.Add(1) - go func() { - defer senderWg.Done() - if err := net.CrossChainAppResponse(context.Background(), respondingChainID, requestID, responseBytes); err != nil { - panic(err) - } - atomic.AddUint32(&callNum, 1) - }() - return nil - }, - } - - codecManager := buildCodec(t, TestMessage{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") - require.NoError(t, err) - net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) - net.SetCrossChainRequestHandler(&testCrossChainHandler{codec: crossChainCodecManager}) - client := NewNetworkClient(net) - - exampleCrossChainRequest := ExampleCrossChainRequest{ - Message: "hello this is an example request", - } - - chainID := ids.ID(ethcommon.BytesToHash([]byte{1, 2, 3, 4, 5})) - defer net.Shutdown() - - totalRequests := 500 - numCallsPerRequest := 1 // on sending response - totalCalls := totalRequests * numCallsPerRequest - - var requestWg sync.WaitGroup - requestWg.Add(totalCalls) - - for i := 0; i < totalCalls; i++ { - go func() { - defer requestWg.Done() - crossChainRequest, err := buildCrossChainRequest(crossChainCodecManager, exampleCrossChainRequest) - assert.NoError(t, err) - responseBytes, err := client.SendCrossChainRequest(context.Background(), chainID, crossChainRequest) - assert.NoError(t, err) - assert.NotNil(t, responseBytes) - - var response ExampleCrossChainResponse - if _, err = crossChainCodecManager.Unmarshal(responseBytes, &response); err != nil { - panic(fmt.Errorf("unexpected error during unmarshal: %w", err)) - } - assert.Equal(t, "this is an example response", response.Response) - }() - } - - requestWg.Wait() - senderWg.Wait() - assert.Equal(t, totalCalls, int(atomic.LoadUint32(&callNum))) -} - -func TestCrossChainRequestOnShutdown(t *testing.T) { - var ( - net Network - wg sync.WaitGroup - called bool - ) - sender := testAppSender{ - sendCrossChainAppRequestFn: func(requestingChainID ids.ID, requestID uint32, requestBytes []byte) error { - wg.Add(1) - go func() { - called = true - // shutdown the network here to ensure any outstanding requests are handled as failed - net.Shutdown() - wg.Done() - }() // this is on a goroutine to avoid a deadlock since calling Shutdown takes the lock. - return nil - }, - } - codecManager := buildCodec(t, TestMessage{}) - crossChainCodecManager := buildCodec(t, ExampleCrossChainRequest{}, ExampleCrossChainResponse{}) - p2pNetwork, err := p2p.NewNetwork(logging.NoLog{}, nil, prometheus.NewRegistry(), "") - require.NoError(t, err) - net = NewNetwork(p2pNetwork, sender, codecManager, crossChainCodecManager, ids.EmptyNodeID, 1, 1) - client := NewNetworkClient(net) - - exampleCrossChainRequest := ExampleCrossChainRequest{ - Message: "hello this is an example request", - } - chainID := ids.ID(ethcommon.BytesToHash([]byte{1, 2, 3, 4, 5})) - - wg.Add(1) - go func() { - defer wg.Done() - crossChainRequest, err := buildCrossChainRequest(crossChainCodecManager, exampleCrossChainRequest) - require.NoError(t, err) - responseBytes, err := client.SendCrossChainRequest(context.Background(), chainID, crossChainRequest) - require.ErrorIs(t, err, ErrRequestFailed) - require.Nil(t, responseBytes) - }() - wg.Wait() - require.True(t, called) -} - func TestNetworkAppRequestAfterShutdown(t *testing.T) { require := require.New(t) - net := NewNetwork(nil, nil, nil, nil, ids.EmptyNodeID, 1, 0) + net := NewNetwork(nil, nil, nil, ids.EmptyNodeID, 1) net.Shutdown() require.NoError(net.SendAppRequest(context.Background(), ids.GenerateTestNodeID(), nil, nil)) require.NoError(net.SendAppRequest(context.Background(), 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(context.Background(), ids.GenerateTestID(), nil, nil)) - require.NoError(net.SendCrossChainRequest(context.Background(), ids.GenerateTestID(), nil, nil)) -} - func TestNetworkRouting(t *testing.T) { require := require.New(t) sender := &testAppSender{ @@ -822,17 +594,7 @@ func TestNetworkRouting(t *testing.T) { require.NoError(p2pNetwork.AddHandler(uint64(protocol), handler)) networkCodec := codec.NewManager(0) - crossChainCodec := codec.NewManager(0) - - network := NewNetwork( - p2pNetwork, - nil, - networkCodec, - crossChainCodec, - ids.EmptyNodeID, - 1, - 1, - ) + network := NewNetwork(p2pNetwork, nil, networkCodec, ids.EmptyNodeID, 1) nodeID := ids.GenerateTestNodeID() foobar := append([]byte{byte(protocol)}, []byte("foobar")...) @@ -867,24 +629,10 @@ func buildGossip(codec codec.Manager, msg message.GossipMessage) ([]byte, error) return codec.Marshal(message.Version, &msg) } -func buildCrossChainRequest(codec codec.Manager, msg message.CrossChainRequest) ([]byte, error) { - return codec.Marshal(message.Version, &msg) -} - type testAppSender struct { - sendCrossChainAppRequestFn func(ids.ID, uint32, []byte) error - sendCrossChainAppResponseFn func(ids.ID, uint32, []byte) error - sendAppRequestFn func(context.Context, set.Set[ids.NodeID], uint32, []byte) error - sendAppResponseFn func(ids.NodeID, uint32, []byte) error - sendAppGossipFn func(common.SendConfig, []byte) error -} - -func (t testAppSender) SendCrossChainAppRequest(_ context.Context, chainID ids.ID, requestID uint32, appRequestBytes []byte) error { - return t.sendCrossChainAppRequestFn(chainID, requestID, appRequestBytes) -} - -func (t testAppSender) SendCrossChainAppResponse(_ context.Context, chainID ids.ID, requestID uint32, appResponseBytes []byte) error { - return t.sendCrossChainAppResponseFn(chainID, requestID, appResponseBytes) + sendAppRequestFn func(context.Context, set.Set[ids.NodeID], uint32, []byte) error + sendAppResponseFn func(ids.NodeID, uint32, []byte) error + sendAppGossipFn func(common.SendConfig, []byte) error } func (t testAppSender) SendAppRequest(ctx context.Context, nodeIDs set.Set[ids.NodeID], requestID uint32, message []byte) error { @@ -903,10 +651,6 @@ func (t testAppSender) SendAppError(ctx context.Context, nodeID ids.NodeID, requ panic("not implemented") } -func (t testAppSender) SendCrossChainAppError(ctx context.Context, chainID ids.ID, requestID uint32, errorCode int32, errorMessage string) error { - panic("not implemented") -} - type HelloRequest struct { Message string `serialize:"true"` } @@ -1018,35 +762,6 @@ func (r *testRequestHandler) handleTestRequest(ctx context.Context, _ ids.NodeID return r.response, r.err } -type ExampleCrossChainRequest struct { - Message string `serialize:"true"` -} - -func (e ExampleCrossChainRequest) Handle(ctx context.Context, requestingChainID ids.ID, requestID uint32, handler message.CrossChainRequestHandler) ([]byte, error) { - return handler.(*testCrossChainHandler).HandleCrossChainRequest(ctx, requestingChainID, requestID, e) -} - -func (e ExampleCrossChainRequest) String() string { - return fmt.Sprintf("TestMessage(%s)", e.Message) -} - -type ExampleCrossChainResponse struct { - Response string `serialize:"true"` -} - -type TestCrossChainRequestHandler interface { - HandleCrossChainRequest(ctx context.Context, requestingchainID ids.ID, requestID uint32, exampleRequest message.CrossChainRequest) ([]byte, error) -} - -type testCrossChainHandler struct { - message.CrossChainRequestHandler - codec codec.Manager -} - -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 } @@ -1060,8 +775,3 @@ func (t *testSDKHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, dead 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/peer/stats/stats.go b/peer/stats/stats.go index e29a26e614..7f82f887d3 100644 --- a/peer/stats/stats.go +++ b/peer/stats/stats.go @@ -34,10 +34,3 @@ func NewRequestHandlerStats() RequestHandlerStats { droppedRequests: metrics.GetOrRegisterCounter("net_req_deadline_dropped", nil), } } - -func NewCrossChainRequestHandlerStats() RequestHandlerStats { - return &requestHandlerStats{ - timeUntilDeadline: metrics.GetOrRegisterTimer("net_cross_chain_req_time_until_deadline", nil), - droppedRequests: metrics.GetOrRegisterCounter("net_cross_chain_req_deadline_dropped", nil), - } -} diff --git a/plugin/evm/config.go b/plugin/evm/config.go index 3f3d06e023..47b342537c 100644 --- a/plugin/evm/config.go +++ b/plugin/evm/config.go @@ -16,41 +16,40 @@ import ( ) const ( - defaultAcceptorQueueLimit = 64 // Provides 2 minutes of buffer (2s block target) for a commit delay - defaultPruningEnabled = true - defaultCommitInterval = 4096 - defaultTrieCleanCache = 512 - defaultTrieDirtyCache = 512 - defaultTrieDirtyCommitTarget = 20 - defaultTriePrefetcherParallelism = 16 - defaultSnapshotCache = 256 - defaultSyncableCommitInterval = defaultCommitInterval * 4 - defaultSnapshotWait = false - defaultRpcGasCap = 50_000_000 // Default to 50M Gas Limit - defaultRpcTxFeeCap = 100 // 100 AVAX - defaultMetricsExpensiveEnabled = true - defaultApiMaxDuration = 0 // Default to no maximum API call duration - defaultWsCpuRefillRate = 0 // Default to no maximum WS CPU usage - defaultWsCpuMaxStored = 0 // Default to no maximum WS CPU usage - defaultMaxBlocksPerRequest = 0 // Default to no maximum on the number of blocks per getLogs request - defaultContinuousProfilerFrequency = 15 * time.Minute - defaultContinuousProfilerMaxFiles = 5 - defaultPushGossipPercentStake = .9 - defaultPushGossipNumValidators = 100 - defaultPushGossipNumPeers = 0 - defaultPushRegossipNumValidators = 10 - defaultPushRegossipNumPeers = 0 - defaultPushGossipFrequency = 100 * time.Millisecond - defaultPullGossipFrequency = 1 * time.Second - defaultRegossipFrequency = 30 * time.Second - defaultOfflinePruningBloomFilterSize uint64 = 512 // Default size (MB) for the offline pruner to use - defaultLogLevel = "info" - defaultLogJSONFormat = false - defaultMaxOutboundActiveRequests = 16 - defaultMaxOutboundActiveCrossChainRequests = 64 - defaultPopulateMissingTriesParallelism = 1024 - defaultStateSyncServerTrieCache = 64 // MB - defaultAcceptedCacheSize = 32 // blocks + defaultAcceptorQueueLimit = 64 // Provides 2 minutes of buffer (2s block target) for a commit delay + defaultPruningEnabled = true + defaultCommitInterval = 4096 + defaultTrieCleanCache = 512 + defaultTrieDirtyCache = 512 + defaultTrieDirtyCommitTarget = 20 + defaultTriePrefetcherParallelism = 16 + defaultSnapshotCache = 256 + defaultSyncableCommitInterval = defaultCommitInterval * 4 + defaultSnapshotWait = false + defaultRpcGasCap = 50_000_000 // Default to 50M Gas Limit + defaultRpcTxFeeCap = 100 // 100 AVAX + defaultMetricsExpensiveEnabled = true + defaultApiMaxDuration = 0 // Default to no maximum API call duration + defaultWsCpuRefillRate = 0 // Default to no maximum WS CPU usage + defaultWsCpuMaxStored = 0 // Default to no maximum WS CPU usage + defaultMaxBlocksPerRequest = 0 // Default to no maximum on the number of blocks per getLogs request + defaultContinuousProfilerFrequency = 15 * time.Minute + defaultContinuousProfilerMaxFiles = 5 + defaultPushGossipPercentStake = .9 + defaultPushGossipNumValidators = 100 + defaultPushGossipNumPeers = 0 + defaultPushRegossipNumValidators = 10 + defaultPushRegossipNumPeers = 0 + defaultPushGossipFrequency = 100 * time.Millisecond + defaultPullGossipFrequency = 1 * time.Second + defaultRegossipFrequency = 30 * time.Second + defaultOfflinePruningBloomFilterSize uint64 = 512 // Default size (MB) for the offline pruner to use + defaultLogLevel = "info" + defaultLogJSONFormat = false + defaultMaxOutboundActiveRequests = 16 + defaultPopulateMissingTriesParallelism = 1024 + defaultStateSyncServerTrieCache = 64 // MB + defaultAcceptedCacheSize = 32 // blocks // defaultStateSyncMinBlocks is the minimum number of blocks the blockchain // should be ahead of local last accepted to perform state sync. @@ -178,8 +177,7 @@ type Config struct { OfflinePruningDataDirectory string `json:"offline-pruning-data-directory"` // VM2VM network - MaxOutboundActiveRequests int64 `json:"max-outbound-active-requests"` - MaxOutboundActiveCrossChainRequests int64 `json:"max-outbound-active-cross-chain-requests"` + MaxOutboundActiveRequests int64 `json:"max-outbound-active-requests"` // Sync settings StateSyncEnabled bool `json:"state-sync-enabled"` @@ -276,7 +274,6 @@ func (c *Config) SetDefaults() { c.LogLevel = defaultLogLevel c.LogJSONFormat = defaultLogJSONFormat c.MaxOutboundActiveRequests = defaultMaxOutboundActiveRequests - c.MaxOutboundActiveCrossChainRequests = defaultMaxOutboundActiveCrossChainRequests c.PopulateMissingTriesParallelism = defaultPopulateMissingTriesParallelism c.StateSyncServerTrieCache = defaultStateSyncServerTrieCache c.StateSyncCommitInterval = defaultSyncableCommitInterval diff --git a/plugin/evm/gossip.go b/plugin/evm/gossip.go index e239c7b74f..05270f7a65 100644 --- a/plugin/evm/gossip.go +++ b/plugin/evm/gossip.go @@ -87,9 +87,6 @@ func (t txGossipHandler) AppGossip(ctx context.Context, nodeID ids.NodeID, gossi func (t txGossipHandler) AppRequest(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, *common.AppError) { return t.appRequestHandler.AppRequest(ctx, nodeID, deadline, requestBytes) } -func (t txGossipHandler) CrossChainAppRequest(context.Context, ids.ID, time.Time, []byte) ([]byte, error) { - return nil, nil -} func NewGossipEthTxPool(mempool *txpool.TxPool, registerer prometheus.Registerer) (*GossipEthTxPool, error) { bloom, err := gossip.NewBloomFilter(registerer, "eth_tx_bloom_filter", txGossipBloomMinTargetElements, txGossipBloomTargetFalsePositiveRate, txGossipBloomResetFalsePositiveRate) diff --git a/plugin/evm/message/codec.go b/plugin/evm/message/codec.go index 23597313a0..9ae2112b1a 100644 --- a/plugin/evm/message/codec.go +++ b/plugin/evm/message/codec.go @@ -16,8 +16,7 @@ const ( ) var ( - Codec codec.Manager - CrossChainCodec codec.Manager + Codec codec.Manager ) func init() { @@ -51,20 +50,4 @@ func init() { if errs.Errored() { panic(errs.Err) } - - CrossChainCodec = codec.NewManager(maxMessageSize) - ccc := linearcodec.NewDefault() - - errs = wrappers.Errs{} - errs.Add( - // CrossChainRequest Types - ccc.RegisterType(EthCallRequest{}), - ccc.RegisterType(EthCallResponse{}), - - CrossChainCodec.RegisterCodec(Version, ccc), - ) - - if errs.Errored() { - panic(errs.Err) - } } diff --git a/plugin/evm/message/cross_chain_handler.go b/plugin/evm/message/cross_chain_handler.go deleted file mode 100644 index a6ec17305e..0000000000 --- a/plugin/evm/message/cross_chain_handler.go +++ /dev/null @@ -1,81 +0,0 @@ -// (c) 2021-2022, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package message - -import ( - "context" - "encoding/json" - - "github.com/ava-labs/avalanchego/codec" - "github.com/ava-labs/avalanchego/ids" - - "github.com/ava-labs/subnet-evm/internal/ethapi" - "github.com/ava-labs/subnet-evm/rpc" - - "github.com/ethereum/go-ethereum/log" -) - -var _ CrossChainRequestHandler = &crossChainHandler{} - -// crossChainHandler implements the CrossChainRequestHandler interface -type crossChainHandler struct { - backend ethapi.Backend - crossChainCodec codec.Manager -} - -// NewCrossChainHandler creates and returns a new instance of CrossChainRequestHandler -func NewCrossChainHandler(b ethapi.Backend, codec codec.Manager) CrossChainRequestHandler { - return &crossChainHandler{ - backend: b, - crossChainCodec: codec, - } -} - -// HandleEthCallRequests returns an encoded EthCallResponse to the given [ethCallRequest] -// This function executes EVM Call against the state associated with [rpc.AcceptedBlockNumber] with the given -// transaction call object [ethCallRequest]. -// This function does not return an error as errors are treated as FATAL to the node. -func (c *crossChainHandler) HandleEthCallRequest(ctx context.Context, requestingChainID ids.ID, requestID uint32, ethCallRequest EthCallRequest) ([]byte, error) { - lastAcceptedBlockNumber := rpc.BlockNumber(c.backend.LastAcceptedBlock().NumberU64()) - lastAcceptedBlockNumberOrHash := rpc.BlockNumberOrHash{BlockNumber: &lastAcceptedBlockNumber} - - transactionArgs := ethapi.TransactionArgs{} - err := json.Unmarshal(ethCallRequest.RequestArgs, &transactionArgs) - if err != nil { - log.Error("error occurred with JSON unmarshalling ethCallRequest.RequestArgs", "err", err) - return nil, nil - } - - result, err := ethapi.DoCall( - ctx, - c.backend, - transactionArgs, - lastAcceptedBlockNumberOrHash, - nil, - nil, - c.backend.RPCEVMTimeout(), - c.backend.RPCGasCap()) - if err != nil { - log.Error("error occurred with EthCall", "err", err, "transactionArgs", ethCallRequest.RequestArgs, "blockNumberOrHash", lastAcceptedBlockNumberOrHash) - return nil, nil - } - - executionResult, err := json.Marshal(&result) - if err != nil { - log.Error("error occurred with JSON marshalling result", "err", err) - return nil, nil - } - - response := EthCallResponse{ - ExecutionResult: executionResult, - } - - responseBytes, err := c.crossChainCodec.Marshal(Version, response) - if err != nil { - log.Error("error occurred with marshalling EthCallResponse", "err", err, "EthCallResponse", response) - return nil, nil - } - - return responseBytes, nil -} diff --git a/plugin/evm/message/eth_call_request.go b/plugin/evm/message/eth_call_request.go deleted file mode 100644 index 69d1139a2b..0000000000 --- a/plugin/evm/message/eth_call_request.go +++ /dev/null @@ -1,33 +0,0 @@ -// (c) 2021-2022, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package message - -import ( - "context" - "fmt" - - "github.com/ava-labs/avalanchego/ids" -) - -var _ CrossChainRequest = EthCallRequest{} - -// EthCallRequest has the JSON Data necessary to execute a new EVM call on the blockchain -type EthCallRequest struct { - RequestArgs []byte `serialize:"true"` -} - -// EthCallResponse represents the JSON return value of the executed EVM call -type EthCallResponse struct { - ExecutionResult []byte `serialize:"true"` -} - -// String converts EthCallRequest to a string -func (e EthCallRequest) String() string { - return fmt.Sprintf("%#v", e) -} - -// Handle returns the encoded EthCallResponse by executing EVM call with the given EthCallRequest -func (e EthCallRequest) Handle(ctx context.Context, requestingChainID ids.ID, requestID uint32, handler CrossChainRequestHandler) ([]byte, error) { - return handler.HandleEthCallRequest(ctx, requestingChainID, requestID, e) -} diff --git a/plugin/evm/message/handler.go b/plugin/evm/message/handler.go index bb1fd3f05e..d1e83d7883 100644 --- a/plugin/evm/message/handler.go +++ b/plugin/evm/message/handler.go @@ -12,9 +12,8 @@ import ( ) var ( - _ GossipHandler = NoopMempoolGossipHandler{} - _ RequestHandler = NoopRequestHandler{} - _ CrossChainRequestHandler = NoopCrossChainRequestHandler{} + _ GossipHandler = NoopMempoolGossipHandler{} + _ RequestHandler = NoopRequestHandler{} ) // GossipHandler handles incoming gossip messages @@ -72,14 +71,3 @@ func (NoopRequestHandler) HandleMessageSignatureRequest(ctx context.Context, nod func (NoopRequestHandler) HandleBlockSignatureRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, signatureRequest BlockSignatureRequest) ([]byte, error) { return nil, nil } - -// CrossChainRequestHandler interface handles incoming requests from another chain -type CrossChainRequestHandler interface { - HandleEthCallRequest(ctx context.Context, requestingchainID ids.ID, requestID uint32, ethCallRequest EthCallRequest) ([]byte, error) -} - -type NoopCrossChainRequestHandler struct{} - -func (NoopCrossChainRequestHandler) HandleEthCallRequest(ctx context.Context, requestingchainID ids.ID, requestID uint32, ethCallRequest EthCallRequest) ([]byte, error) { - return nil, nil -} diff --git a/plugin/evm/message/request.go b/plugin/evm/message/request.go index 6b5831f9df..2aadf5a902 100644 --- a/plugin/evm/message/request.go +++ b/plugin/evm/message/request.go @@ -34,13 +34,3 @@ func BytesToRequest(codec codec.Manager, requestBytes []byte) (Request, error) { func RequestToBytes(codec codec.Manager, request Request) ([]byte, error) { return codec.Marshal(Version, &request) } - -// CrossChainRequest represents the interface a cross chain request should implement -type CrossChainRequest interface { - // CrossChainRequest should implement String() for logging. - fmt.Stringer - - // Handle allows [CrossChainRequest] to call respective methods on handler to handle - // this particular request type - Handle(ctx context.Context, requestingChainID ids.ID, requestID uint32, handler CrossChainRequestHandler) ([]byte, error) -} diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index 49f3924ec1..2c6dfd55b9 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -477,7 +477,7 @@ func (vm *VM) Initialize( } vm.validators = p2p.NewValidators(p2pNetwork.Peers, vm.ctx.Log, vm.ctx.SubnetID, vm.ctx.ValidatorState, maxValidatorSetStaleness) vm.networkCodec = message.Codec - vm.Network = peer.NewNetwork(p2pNetwork, appSender, vm.networkCodec, message.CrossChainCodec, chainCtx.NodeID, vm.config.MaxOutboundActiveRequests, vm.config.MaxOutboundActiveCrossChainRequests) + vm.Network = peer.NewNetwork(p2pNetwork, appSender, vm.networkCodec, chainCtx.NodeID, vm.config.MaxOutboundActiveRequests) vm.client = peer.NewNetworkClient(vm.Network) // Initialize warp backend @@ -626,7 +626,6 @@ func (vm *VM) initializeHandlers() { vm.Network.AddHandler(p2p.SignatureRequestHandlerID, warpHandler) vm.setAppRequestHandlers() - vm.setCrossChainAppRequestHandler() } func (vm *VM) initChainState(lastAcceptedBlock *types.Block) error { @@ -812,13 +811,6 @@ func (vm *VM) setAppRequestHandlers() { vm.Network.SetRequestHandler(networkHandler) } -// setCrossChainAppRequestHandler sets the request handlers for the VM to serve cross chain -// requests. -func (vm *VM) setCrossChainAppRequestHandler() { - crossChainRequestHandler := message.NewCrossChainHandler(vm.eth.APIBackend, message.CrossChainCodec) - vm.Network.SetCrossChainRequestHandler(crossChainRequestHandler) -} - // Shutdown implements the snowman.ChainVM interface func (vm *VM) Shutdown(context.Context) error { if vm.ctx == nil { diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go index 15a359f42d..14f76c22c4 100644 --- a/plugin/evm/vm_test.go +++ b/plugin/evm/vm_test.go @@ -18,7 +18,6 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" @@ -42,7 +41,6 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/components/chain" - "github.com/ava-labs/subnet-evm/accounts/abi" accountKeystore "github.com/ava-labs/subnet-evm/accounts/keystore" "github.com/ava-labs/subnet-evm/commontype" "github.com/ava-labs/subnet-evm/consensus/dummy" @@ -51,10 +49,8 @@ import ( "github.com/ava-labs/subnet-evm/core/txpool" "github.com/ava-labs/subnet-evm/core/types" "github.com/ava-labs/subnet-evm/eth" - "github.com/ava-labs/subnet-evm/internal/ethapi" "github.com/ava-labs/subnet-evm/metrics" "github.com/ava-labs/subnet-evm/params" - "github.com/ava-labs/subnet-evm/plugin/evm/message" "github.com/ava-labs/subnet-evm/precompile/allowlist" "github.com/ava-labs/subnet-evm/precompile/contracts/deployerallowlist" "github.com/ava-labs/subnet-evm/precompile/contracts/feemanager" @@ -3049,155 +3045,6 @@ func TestSkipChainConfigCheckCompatible(t *testing.T) { require.NoError(t, reinitVM.Shutdown(context.Background())) } -func TestCrossChainMessagestoVM(t *testing.T) { - crossChainCodec := message.CrossChainCodec - require := require.New(t) - - // the following is based on this contract: - // contract T { - // event received(address sender, uint amount, bytes memo); - // event receivedAddr(address sender); - // - // function receive(bytes calldata memo) external payable returns (string memory res) { - // emit received(msg.sender, msg.value, memo); - // emit receivedAddr(msg.sender); - // return "hello world"; - // } - // } - - const abiBin = `0x608060405234801561001057600080fd5b506102a0806100206000396000f3fe60806040526004361061003b576000357c010000000000000000000000000000000000000000000000000000000090048063a69b6ed014610040575b600080fd5b6100b76004803603602081101561005657600080fd5b810190808035906020019064010000000081111561007357600080fd5b82018360208201111561008557600080fd5b803590602001918460018302840111640100000000831117156100a757600080fd5b9091929391929390505050610132565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100f75780820151818401526020810190506100dc565b50505050905090810190601f1680156101245780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60607f75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed33348585604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060405180910390a17f46923992397eac56cf13058aced2a1871933622717e27b24eabc13bf9dd329c833604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a16040805190810160405280600b81526020017f68656c6c6f20776f726c6400000000000000000000000000000000000000000081525090509291505056fea165627a7a72305820ff0c57dad254cfeda48c9cfb47f1353a558bccb4d1bc31da1dae69315772d29e0029` - const abiJSON = `[ { "constant": false, "inputs": [ { "name": "memo", "type": "bytes" } ], "name": "receive", "outputs": [ { "name": "res", "type": "string" } ], "payable": true, "stateMutability": "payable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "memo", "type": "bytes" } ], "name": "received", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" } ], "name": "receivedAddr", "type": "event" } ]` - parsed, err := abi.JSON(strings.NewReader(abiJSON)) - require.NoErrorf(err, "could not parse abi: %v") - - calledSendCrossChainAppResponseFn := false - issuer, vm, _, appSender := GenesisVM(t, true, genesisJSONSubnetEVM, "", "") - - defer func() { - err := vm.Shutdown(context.Background()) - require.NoError(err) - }() - - appSender.SendCrossChainAppResponseF = func(ctx context.Context, respondingChainID ids.ID, requestID uint32, responseBytes []byte) { - calledSendCrossChainAppResponseFn = true - - var response message.EthCallResponse - if _, err = crossChainCodec.Unmarshal(responseBytes, &response); err != nil { - require.NoErrorf(err, "unexpected error during unmarshal: %w") - } - - result := core.ExecutionResult{} - err = json.Unmarshal(response.ExecutionResult, &result) - require.NoError(err) - require.NotNil(result.ReturnData) - - finalResult, err := parsed.Unpack("receive", result.ReturnData) - require.NoError(err) - require.NotNil(finalResult) - require.Equal("hello world", finalResult[0]) - } - - newTxPoolHeadChan := make(chan core.NewTxPoolReorgEvent, 1) - vm.txPool.SubscribeNewReorgEvent(newTxPoolHeadChan) - - tx := types.NewTransaction(uint64(0), testEthAddrs[1], firstTxAmount, 21000, big.NewInt(testMinGasPrice), nil) - signedTx, err := types.SignTx(tx, types.NewEIP155Signer(vm.chainConfig.ChainID), testKeys[0]) - require.NoError(err) - - txErrors := vm.txPool.AddRemotesSync([]*types.Transaction{signedTx}) - for _, err := range txErrors { - require.NoError(err) - } - - <-issuer - - blk1, err := vm.BuildBlock(context.Background()) - require.NoError(err) - - err = blk1.Verify(context.Background()) - require.NoError(err) - - err = vm.SetPreference(context.Background(), blk1.ID()) - require.NoError(err) - - err = blk1.Accept(context.Background()) - require.NoError(err) - - newHead := <-newTxPoolHeadChan - if newHead.Head.Hash() != common.Hash(blk1.ID()) { - t.Fatalf("Expected new block to match") - } - - lastAcceptedID, err := vm.LastAccepted(context.Background()) - require.NoError(err) - - if lastAcceptedID != blk1.ID() { - t.Fatalf("Expected last accepted blockID to be the accepted block: %s, but found %s", blk1.ID(), lastAcceptedID) - } - - contractTx := types.NewContractCreation(1, common.Big0, 200000, big.NewInt(testMinGasPrice), common.FromHex(abiBin)) - contractSignedTx, err := types.SignTx(contractTx, types.NewEIP155Signer(vm.chainConfig.ChainID), testKeys[0]) - require.NoError(err) - - errs := vm.txPool.AddRemotesSync([]*types.Transaction{contractSignedTx}) - for _, err := range errs { - require.NoError(err) - } - testAddr := testEthAddrs[0] - contractAddress := crypto.CreateAddress(testAddr, 1) - - <-issuer - - blk2, err := vm.BuildBlock(context.Background()) - require.NoError(err) - - err = blk2.Verify(context.Background()) - require.NoError(err) - - err = vm.SetPreference(context.Background(), blk2.ID()) - require.NoError(err) - - err = blk2.Accept(context.Background()) - require.NoError(err) - - newHead = <-newTxPoolHeadChan - if newHead.Head.Hash() != common.Hash(blk2.ID()) { - t.Fatalf("Expected new block to match") - } - - lastAcceptedID, err = vm.LastAccepted(context.Background()) - require.NoError(err) - - if lastAcceptedID != blk2.ID() { - t.Fatalf("Expected last accepted blockID to be the accepted block: %s, but found %s", blk2.ID(), lastAcceptedID) - } - - input, err := parsed.Pack("receive", []byte("X")) - require.NoError(err) - - data := hexutil.Bytes(input) - - requestArgs, err := json.Marshal(ðapi.TransactionArgs{ - To: &contractAddress, - Data: &data, - }) - require.NoError(err) - - var ethCallRequest message.CrossChainRequest = message.EthCallRequest{ - RequestArgs: requestArgs, - } - - crossChainRequest, err := crossChainCodec.Marshal(message.Version, ðCallRequest) - require.NoError(err) - - requestingChainID := ids.ID(common.BytesToHash([]byte{1, 2, 3, 4, 5})) - - // we need all items in the acceptor queue to be processed before we process a cross chain request - vm.blockChain.DrainAcceptorQueue() - err = vm.Network.CrossChainAppRequest(context.Background(), requestingChainID, 1, time.Now().Add(60*time.Second), crossChainRequest) - require.NoError(err) - require.True(calledSendCrossChainAppResponseFn, "sendCrossChainAppResponseFn was not called") -} func TestParentBeaconRootBlock(t *testing.T) { tests := []struct { name string diff --git a/scripts/versions.sh b/scripts/versions.sh index 56fb885f83..432a1746e7 100644 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -4,7 +4,7 @@ # shellcheck disable=SC2034 # Don't export them as they're used in the context of other calls -AVALANCHE_VERSION=${AVALANCHE_VERSION:-'479145a6'} +AVALANCHE_VERSION=${AVALANCHE_VERSION:-'ab83fb41'} GINKGO_VERSION=${GINKGO_VERSION:-'v2.2.0'} # This won't be used, but it's here to make code syncs easier diff --git a/sync/client/mock_network.go b/sync/client/mock_network.go index 8e17e3eefa..07558e37ad 100644 --- a/sync/client/mock_network.go +++ b/sync/client/mock_network.go @@ -78,10 +78,6 @@ func (t *mockNetwork) Gossip([]byte) error { panic("not implemented") // we don't care about this function for this test } -func (t *mockNetwork) SendCrossChainRequest(ctx context.Context, chainID ids.ID, request []byte) ([]byte, error) { - panic("not implemented") // we don't care about this function for this test -} - func (t *mockNetwork) mockResponse(times uint8, callback func(), response []byte) { t.response = make([][]byte, times) for i := uint8(0); i < times; i++ { diff --git a/warp/handlers/signature_request_p2p.go b/warp/handlers/signature_request_p2p.go index ecc72305af..0728f8b808 100644 --- a/warp/handlers/signature_request_p2p.go +++ b/warp/handlers/signature_request_p2p.go @@ -146,15 +146,6 @@ func (s *SignatureRequestHandlerP2P) GetBlockSignature(blockID ids.ID) ([bls.Sig return s.backend.GetBlockSignature(blockID) } -func (s *SignatureRequestHandlerP2P) CrossChainAppRequest( - ctx context.Context, - chainID ids.ID, - deadline time.Time, - requestBytes []byte, -) ([]byte, error) { - return nil, nil -} - func (s *SignatureRequestHandlerP2P) AppGossip( ctx context.Context, nodeID ids.NodeID, gossipBytes []byte) { }