Skip to content

Commit

Permalink
Get signature endpoint: alternative PR with different packaging (#507)
Browse files Browse the repository at this point in the history
* base warp backend

* add signature caching

* add docs

* error handling

* pr fixes

* basic signature request

* hash unsigned message for key

* implement new Request and RequestHandler interfaces

* signature handler impl without constructing one

* fix import

* quick pr fixes and merge

* quick pr fixes and merge

* save signature instead of whole msg

* use avaGO cache

* rename warpBackend and docs

* fix nits

* Update plugin/evm/warp_backend.go

Co-authored-by: aaronbuchwald <aaron.buchwald56@gmail.com>

* Update plugin/evm/warp_backend.go

Co-authored-by: aaronbuchwald <aaron.buchwald56@gmail.com>

* fix pr nits

* pr fixes and testing

* type check for caching

* handlers and request before tests

* fix imports

* signature handler with stats and test

* use memdb and remove extra test

* remove unused

* fix imports

* fix imports

* nit

* update license year

* use require noError

* saving message in db and pr fixes

* create noop signature handler and refactor code handler

* get signature endpoint

* add api arg to evm client

* Update sync/handlers/handler.go

Co-authored-by: aaronbuchwald <aaron.buchwald56@gmail.com>

* update backend return value

* refactor handlers to network handler

* change constructor of handler stats

* pr cleanups

* warp api

* initialize warp backend

* build fix

* wip

* warp api follows eth api pattern

* cleanup and comments

* clean up response

* fix warp client return type

* nits for get-signature-endpoint (#502)

Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
Co-authored-by: aaronbuchwald <aaron.buchwald56@gmail.com>
Co-authored-by: Ceyhun Onur <ceyhun.onur@avalabs.org>
Co-authored-by: cam-schultz <78878559+cam-schultz@users.noreply.github.com>

* resolve merge conflict

* warp: Group packages for symmetry w/ sync

* more reshuffle

* more shuffle

* pr comments

* fix

* update to []byte

* update svc return type

* rename arg

* fix type

* add stats pkg

---------

Co-authored-by: Matthew Lam <matthew.lam@avalabs.org>
Co-authored-by: aaronbuchwald <aaron.buchwald56@gmail.com>
Co-authored-by: cam-schultz <camschultz32@gmail.com>
Co-authored-by: Ceyhun Onur <ceyhun.onur@avalabs.org>
Co-authored-by: cam-schultz <78878559+cam-schultz@users.noreply.github.com>
  • Loading branch information
6 people authored Feb 10, 2023
1 parent 8343e42 commit 38ad7f5
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 86 deletions.
22 changes: 0 additions & 22 deletions handlers/stats/mock_stats.go

This file was deleted.

38 changes: 0 additions & 38 deletions handlers/stats/stats.go

This file was deleted.

1 change: 1 addition & 0 deletions plugin/evm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type Config struct {

// Subnet EVM APIs
SnowmanAPIEnabled bool `json:"snowman-api-enabled"`
WarpAPIEnabled bool `json:"warp-api-enabled"`
AdminAPIEnabled bool `json:"admin-api-enabled"`
AdminAPIDir string `json:"admin-api-dir"`

Expand Down
21 changes: 10 additions & 11 deletions handlers/handler.go → plugin/evm/network_handler.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
// (c) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package handlers
package evm

import (
"context"

"github.com/ava-labs/avalanchego/codec"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/subnet-evm/handlers/stats"
warpHandlers "github.com/ava-labs/subnet-evm/handlers/warp"
"github.com/ava-labs/subnet-evm/metrics"
"github.com/ava-labs/subnet-evm/plugin/evm/message"
"github.com/ava-labs/subnet-evm/sync/handlers"
syncHandlers "github.com/ava-labs/subnet-evm/sync/handlers"
syncStats "github.com/ava-labs/subnet-evm/sync/handlers/stats"
"github.com/ava-labs/subnet-evm/trie"
warpHandlers "github.com/ava-labs/subnet-evm/warp/handlers"
)

var _ message.RequestHandler = &networkHandler{}
Expand All @@ -26,18 +25,18 @@ type networkHandler struct {
signatureRequestHandler warpHandlers.SignatureRequestHandler
}

// NewNetworkHandler constructs the handler for serving network requests.
func NewNetworkHandler(
provider handlers.SyncDataProvider,
// newNetworkHandler constructs the handler for serving network requests.
func newNetworkHandler(
provider syncHandlers.SyncDataProvider,
evmTrieDB *trie.Database,
networkCodec codec.Manager,
) message.RequestHandler {
handlerStats := stats.NewHandlerStats(metrics.Enabled)
syncStats := syncStats.NewHandlerStats(metrics.Enabled)
return &networkHandler{
// State sync handlers
stateTrieLeafsRequestHandler: syncHandlers.NewLeafsRequestHandler(evmTrieDB, provider, networkCodec, handlerStats),
blockRequestHandler: syncHandlers.NewBlockRequestHandler(provider, networkCodec, handlerStats),
codeRequestHandler: syncHandlers.NewCodeRequestHandler(evmTrieDB.DiskDB(), networkCodec, handlerStats),
stateTrieLeafsRequestHandler: syncHandlers.NewLeafsRequestHandler(evmTrieDB, provider, networkCodec, syncStats),
blockRequestHandler: syncHandlers.NewBlockRequestHandler(provider, networkCodec, syncStats),
codeRequestHandler: syncHandlers.NewCodeRequestHandler(evmTrieDB.DiskDB(), networkCodec, syncStats),

// TODO: initialize actual signature request handler when warp is ready
signatureRequestHandler: &warpHandlers.NoopSignatureRequestHandler{},
Expand Down
31 changes: 26 additions & 5 deletions plugin/evm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"time"

avalanchegoMetrics "github.com/ava-labs/avalanchego/api/metrics"
"github.com/ava-labs/subnet-evm/handlers"
"github.com/prometheus/client_golang/prometheus"

"github.com/ava-labs/subnet-evm/commontype"
Expand All @@ -36,6 +35,7 @@ import (
statesyncclient "github.com/ava-labs/subnet-evm/sync/client"
"github.com/ava-labs/subnet-evm/sync/client/stats"
"github.com/ava-labs/subnet-evm/trie"
"github.com/ava-labs/subnet-evm/warp"

// Force-load tracer engine to trigger registration
//
Expand Down Expand Up @@ -81,9 +81,10 @@ const (
// and fail verification
maxFutureBlockTime = 10 * time.Second

decidedCacheSize = 100
missingCacheSize = 50
unverifiedCacheSize = 50
decidedCacheSize = 100
missingCacheSize = 50
unverifiedCacheSize = 50
warpSignatureCacheSize = 500

// Prefixes for metrics gatherers
ethMetricsPrefix = "eth"
Expand All @@ -102,6 +103,7 @@ var (
lastAcceptedKey = []byte("last_accepted_key")
acceptedPrefix = []byte("snowman_accepted")
metadataPrefix = []byte("metadata")
warpPrefix = []byte("warp")
ethDBPrefix = []byte("ethdb")
)

Expand Down Expand Up @@ -177,6 +179,10 @@ type VM struct {
// block.
acceptedBlockDB database.Database

// [warpDB] is used to store warp message signatures
// set to a prefixDB with the prefix [warpPrefix]
warpDB database.Database

toEngine chan<- commonEng.Message

syntacticBlockValidator BlockValidator
Expand Down Expand Up @@ -206,6 +212,10 @@ type VM struct {
// State sync server and client
StateSyncServer
StateSyncClient

// Avalanche Warp Messaging backend
// Used to serve BLS signatures of warp messages over RPC
warpBackend warp.WarpBackend
}

/*
Expand Down Expand Up @@ -274,6 +284,7 @@ func (vm *VM) Initialize(
vm.db = versiondb.New(baseDB)
vm.acceptedBlockDB = prefixdb.New(acceptedPrefix, vm.db)
vm.metadataDB = prefixdb.New(metadataPrefix, vm.db)
vm.warpDB = prefixdb.New(warpPrefix, vm.db)

if vm.config.InspectDatabase {
start := time.Now()
Expand Down Expand Up @@ -415,6 +426,9 @@ func (vm *VM) Initialize(
vm.Network = peer.NewNetwork(appSender, vm.networkCodec, message.CrossChainCodec, chainCtx.NodeID, vm.config.MaxOutboundActiveRequests, vm.config.MaxOutboundActiveCrossChainRequests)
vm.client = peer.NewNetworkClient(vm.Network)

// initialize warp backend
vm.warpBackend = warp.NewWarpBackend(vm.ctx, vm.warpDB, warpSignatureCacheSize)

if err := vm.initializeChain(lastAcceptedHash, vm.ethConfig); err != nil {
return err
}
Expand Down Expand Up @@ -606,7 +620,7 @@ func (vm *VM) setAppRequestHandlers() {
},
)

networkHandler := handlers.NewNetworkHandler(vm.blockChain, evmTrieDB, vm.networkCodec)
networkHandler := newNetworkHandler(vm.blockChain, evmTrieDB, vm.networkCodec)
vm.Network.SetRequestHandler(networkHandler)
}

Expand Down Expand Up @@ -795,6 +809,13 @@ func (vm *VM) CreateHandlers(context.Context) (map[string]*commonEng.HTTPHandler
enabledAPIs = append(enabledAPIs, "snowman")
}

if vm.config.WarpAPIEnabled {
if err := handler.RegisterName("warp", &warp.WarpAPI{Backend: vm.warpBackend}); err != nil {
return nil, err
}
enabledAPIs = append(enabledAPIs, "warp")
}

log.Info(fmt.Sprintf("Enabled APIs: %s", strings.Join(enabledAPIs, ", ")))
apis[ethRPCEndpoint] = &commonEng.HTTPHandler{
LockOptions: commonEng.NoLock,
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// (c) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package warp
package handlers

import (
"context"
"time"

"github.com/ava-labs/avalanchego/codec"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/subnet-evm/handlers/warp/stats"
"github.com/ava-labs/subnet-evm/plugin/evm/message"
"github.com/ava-labs/subnet-evm/plugin/evm/warp"
"github.com/ava-labs/subnet-evm/warp"
"github.com/ava-labs/subnet-evm/warp/handlers/stats"
"github.com/ethereum/go-ethereum/log"
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// (c) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package warp
package handlers

import (
"context"
Expand All @@ -14,9 +14,9 @@ import (
"github.com/ava-labs/avalanchego/utils/crypto/bls"
"github.com/ava-labs/avalanchego/utils/hashing"
"github.com/ava-labs/avalanchego/vms/platformvm/teleporter"
"github.com/ava-labs/subnet-evm/handlers/stats"
"github.com/ava-labs/subnet-evm/plugin/evm/message"
"github.com/ava-labs/subnet-evm/plugin/evm/warp"
"github.com/ava-labs/subnet-evm/warp"
"github.com/ava-labs/subnet-evm/warp/handlers/stats"
"github.com/stretchr/testify/require"
)

Expand All @@ -38,20 +38,20 @@ func TestSignatureHandler(t *testing.T) {
require.NoError(t, err)
unknownMessageID := ids.GenerateTestID()

mockHandlerStats := &stats.MockHandlerStats{}
mockHandlerStats := &stats.MockSignatureRequestHandlerStats{}
signatureRequestHandler := NewSignatureRequestHandler(warpBackend, message.Codec, mockHandlerStats)

tests := map[string]struct {
setup func() (request message.SignatureRequest, expectedResponse []byte)
verifyStats func(t *testing.T, stats *stats.MockHandlerStats)
verifyStats func(t *testing.T, stats *stats.MockSignatureRequestHandlerStats)
}{
"normal": {
setup: func() (request message.SignatureRequest, expectedResponse []byte) {
return message.SignatureRequest{
MessageID: messageID,
}, signature[:]
},
verifyStats: func(t *testing.T, stats *stats.MockHandlerStats) {
verifyStats: func(t *testing.T, stats *stats.MockSignatureRequestHandlerStats) {
require.EqualValues(t, 1, mockHandlerStats.SignatureRequestCount)
require.EqualValues(t, 1, mockHandlerStats.SignatureRequestHit)
require.EqualValues(t, 0, mockHandlerStats.SignatureRequestMiss)
Expand All @@ -64,7 +64,7 @@ func TestSignatureHandler(t *testing.T) {
MessageID: unknownMessageID,
}, nil
},
verifyStats: func(t *testing.T, stats *stats.MockHandlerStats) {
verifyStats: func(t *testing.T, stats *stats.MockSignatureRequestHandlerStats) {
require.EqualValues(t, 1, mockHandlerStats.SignatureRequestCount)
require.EqualValues(t, 1, mockHandlerStats.SignatureRequestMiss)
require.EqualValues(t, 0, mockHandlerStats.SignatureRequestHit)
Expand Down
File renamed without changes.
45 changes: 45 additions & 0 deletions warp/warp_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// (c) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package warp

import (
"context"
"fmt"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/subnet-evm/rpc"
"github.com/ethereum/go-ethereum/common/hexutil"
)

var _ WarpClient = (*warpClient)(nil)

type WarpClient interface {
GetSignature(ctx context.Context, messageID ids.ID) ([]byte, error)
}

// warpClient implementation for interacting with EVM [chain]
type warpClient struct {
client *rpc.Client
}

// NewWarpClient returns a WarpClient for interacting with EVM [chain]
func NewWarpClient(uri, chain string) (WarpClient, error) {
client, err := rpc.Dial(fmt.Sprintf("%s/ext/bc/%s/rpc", uri, chain))
if err != nil {
return nil, fmt.Errorf("failed to dial client. err: %w", err)
}
return &warpClient{
client: client,
}, nil
}

// GetSignature requests the BLS signature associated with a messageID
func (c *warpClient) GetSignature(ctx context.Context, messageID ids.ID) ([]byte, error) {
var res hexutil.Bytes
err := c.client.CallContext(ctx, &res, "warp_getSignature", messageID)
if err != nil {
return nil, fmt.Errorf("call to warp_getSignature failed. err: %w", err)
}
return res, err
}
26 changes: 26 additions & 0 deletions warp/warp_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// (c) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package warp

import (
"context"
"fmt"

"github.com/ava-labs/avalanchego/ids"
"github.com/ethereum/go-ethereum/common/hexutil"
)

// WarpAPI introduces snowman specific functionality to the evm
type WarpAPI struct {
Backend WarpBackend
}

// GetSignature returns the BLS signature associated with a messageID.
func (api *WarpAPI) GetSignature(ctx context.Context, messageID ids.ID) (hexutil.Bytes, error) {
signature, err := api.Backend.GetSignature(ctx, messageID)
if err != nil {
return nil, fmt.Errorf("failed to get signature for with error %w", err)
}
return signature[:], nil
}

0 comments on commit 38ad7f5

Please sign in to comment.