Skip to content

Commit

Permalink
CCQ: Reorg code into a query package (#3112)
Browse files Browse the repository at this point in the history
* CCQ: Reorg code into a query package

* Make requestTimeout public
  • Loading branch information
bruce-riley authored Jun 22, 2023
1 parent e8c561a commit 7c5b3f9
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 179 deletions.
53 changes: 27 additions & 26 deletions node/cmd/guardiand/node.go

Large diffs are not rendered by default.

39 changes: 20 additions & 19 deletions node/hack/query/send_req.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/certusone/wormhole/node/pkg/p2p"
gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1"
"github.com/certusone/wormhole/node/pkg/query"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common/hexutil"
ethCrypto "github.com/ethereum/go-ethereum/crypto"
Expand Down Expand Up @@ -181,7 +182,7 @@ func main() {
}

methods := []string{"name", "totalSupply"}
callData := []*common.EthCallData{}
callData := []*query.EthCallData{}
to, _ := hex.DecodeString("0d500b1d8e8ef31e21c99d1db9a6444d3adf1270")

for _, method := range methods {
Expand All @@ -190,7 +191,7 @@ func main() {
panic(err)
}

callData = append(callData, &common.EthCallData{
callData = append(callData, &query.EthCallData{
To: to,
Data: data,
})
Expand All @@ -211,7 +212,7 @@ func main() {
// block := "0x9999bac44d09a7f69ee7941819b0a19c59ccb1969640cc513be09ef95ed2d8e2"

// Start of query creation...
callRequest := &common.EthCallQueryRequest{
callRequest := &query.EthCallQueryRequest{
BlockId: hexutil.EncodeBig(blockNum),
CallData: callData,
}
Expand All @@ -228,7 +229,7 @@ func main() {

// Second request...
blockNum = blockNum.Sub(blockNum, big.NewInt(5))
callRequest2 := &common.EthCallQueryRequest{
callRequest2 := &query.EthCallQueryRequest{
BlockId: hexutil.EncodeBig(blockNum),
CallData: callData,
}
Expand All @@ -239,7 +240,7 @@ func main() {
// Now, want to send a single query with multiple requests...
logger.Info("Starting multiquery test in 5...")
time.Sleep(time.Second * 5)
multiCallRequest := []*common.EthCallQueryRequest{callRequest, callRequest2}
multiCallRequest := []*query.EthCallQueryRequest{callRequest, callRequest2}
multQueryRequest := createQueryRequestWithMultipleRequests(multiCallRequest)
sendQueryAndGetRsp(multQueryRequest, sk, th, ctx, logger, sub, wethAbi, methods)

Expand All @@ -264,10 +265,10 @@ const (
GuardianKeyArmoredBlock = "WORMHOLE GUARDIAN PRIVATE KEY"
)

func createQueryRequest(callRequest *common.EthCallQueryRequest) *common.QueryRequest {
queryRequest := &common.QueryRequest{
func createQueryRequest(callRequest *query.EthCallQueryRequest) *query.QueryRequest {
queryRequest := &query.QueryRequest{
Nonce: rand.Uint32(),
PerChainQueries: []*common.PerChainQueryRequest{
PerChainQueries: []*query.PerChainQueryRequest{
{
ChainId: 5,
Query: callRequest,
Expand All @@ -277,31 +278,31 @@ func createQueryRequest(callRequest *common.EthCallQueryRequest) *common.QueryRe
return queryRequest
}

func createQueryRequestWithMultipleRequests(callRequests []*common.EthCallQueryRequest) *common.QueryRequest {
perChainQueries := []*common.PerChainQueryRequest{}
func createQueryRequestWithMultipleRequests(callRequests []*query.EthCallQueryRequest) *query.QueryRequest {
perChainQueries := []*query.PerChainQueryRequest{}
for _, req := range callRequests {
perChainQueries = append(perChainQueries, &common.PerChainQueryRequest{
perChainQueries = append(perChainQueries, &query.PerChainQueryRequest{
ChainId: 5,
Query: req,
})
}

queryRequest := &common.QueryRequest{
queryRequest := &query.QueryRequest{
Nonce: rand.Uint32(),
PerChainQueries: perChainQueries,
}
return queryRequest
}

func sendQueryAndGetRsp(queryRequest *common.QueryRequest, sk *ecdsa.PrivateKey, th *pubsub.Topic, ctx context.Context, logger *zap.Logger, sub *pubsub.Subscription, wethAbi abi.ABI, methods []string) {
func sendQueryAndGetRsp(queryRequest *query.QueryRequest, sk *ecdsa.PrivateKey, th *pubsub.Topic, ctx context.Context, logger *zap.Logger, sub *pubsub.Subscription, wethAbi abi.ABI, methods []string) {
queryRequestBytes, err := queryRequest.Marshal()
if err != nil {
panic(err)
}
numQueries := len(queryRequest.PerChainQueries)

// Sign the query request using our private key.
digest := common.QueryRequestDigest(common.UnsafeDevNet, queryRequestBytes)
digest := query.QueryRequestDigest(common.UnsafeDevNet, queryRequestBytes)
sig, err := ethCrypto.Sign(digest.Bytes(), sk)
if err != nil {
panic(err)
Expand Down Expand Up @@ -348,7 +349,7 @@ func sendQueryAndGetRsp(queryRequest *common.QueryRequest, sk *ecdsa.PrivateKey,
switch m := msg.Message.(type) {
case *gossipv1.GossipMessage_SignedQueryResponse:
logger.Info("query response received", zap.Any("response", m.SignedQueryResponse))
var response common.QueryResponsePublication
var response query.QueryResponsePublication
err := response.Unmarshal(m.SignedQueryResponse.QueryResponse)
if err != nil {
logger.Warn("failed to unmarshal response", zap.Error(err))
Expand All @@ -366,17 +367,17 @@ func sendQueryAndGetRsp(queryRequest *common.QueryRequest, sk *ecdsa.PrivateKey,
for index := range response.PerChainResponses {
logger.Info("per chain query response index", zap.Int("index", index))

var localCallData []*common.EthCallData
var localCallData []*query.EthCallData
switch ecq := queryRequest.PerChainQueries[index].Query.(type) {
case *common.EthCallQueryRequest:
case *query.EthCallQueryRequest:
localCallData = ecq.CallData
default:
panic("unsupported query type")
}

var localResp *common.EthCallQueryResponse
var localResp *query.EthCallQueryResponse
switch ecq := response.PerChainResponses[index].Response.(type) {
case *common.EthCallQueryResponse:
case *query.EthCallQueryResponse:
localResp = ecq
default:
panic("unsupported query type")
Expand Down
19 changes: 10 additions & 9 deletions node/hack/query/test/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/certusone/wormhole/node/pkg/p2p"
gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1"
"github.com/certusone/wormhole/node/pkg/query"
"github.com/ethereum/go-ethereum/accounts/abi"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -185,21 +186,21 @@ func TestCrossChainQuery(t *testing.T) {
}
to, _ := hex.DecodeString("DDb64fE46a91D46ee29420539FC25FD07c5FEa3E") // WETH

callData := []*common.EthCallData{
callData := []*query.EthCallData{
{
To: to,
Data: data,
},
}

callRequest := &common.EthCallQueryRequest{
callRequest := &query.EthCallQueryRequest{
BlockId: hexutil.EncodeBig(blockNum),
CallData: callData,
}

queryRequest := &common.QueryRequest{
queryRequest := &query.QueryRequest{
Nonce: 1,
PerChainQueries: []*common.PerChainQueryRequest{
PerChainQueries: []*query.PerChainQueryRequest{
{
ChainId: 2,
Query: callRequest,
Expand All @@ -213,7 +214,7 @@ func TestCrossChainQuery(t *testing.T) {
}

// Sign the query request using our private key.
digest := common.QueryRequestDigest(common.UnsafeDevNet, queryRequestBytes)
digest := query.QueryRequestDigest(common.UnsafeDevNet, queryRequestBytes)
sig, err := ethCrypto.Sign(digest.Bytes(), sk)
if err != nil {
panic(err)
Expand Down Expand Up @@ -260,13 +261,13 @@ func TestCrossChainQuery(t *testing.T) {
switch m := msg.Message.(type) {
case *gossipv1.GossipMessage_SignedQueryResponse:
logger.Info("query response received", zap.Any("response", m.SignedQueryResponse))
var response common.QueryResponsePublication
var response query.QueryResponsePublication
err := response.Unmarshal(m.SignedQueryResponse.QueryResponse)
if err != nil {
logger.Fatal("failed to unmarshal response", zap.Error(err))
}
if bytes.Equal(response.Request.QueryRequest, queryRequestBytes) && bytes.Equal(response.Request.Signature, sig) {
digest := common.GetQueryResponseDigestFromBytes(m.SignedQueryResponse.QueryResponse)
digest := query.GetQueryResponseDigestFromBytes(m.SignedQueryResponse.QueryResponse)
signerBytes, err := ethCrypto.Ecrecover(digest.Bytes(), m.SignedQueryResponse.Signature)
if err != nil {
logger.Fatal("failed to verify signature on response",
Expand Down Expand Up @@ -296,9 +297,9 @@ func TestCrossChainQuery(t *testing.T) {
break
}

var pcq *common.EthCallQueryResponse
var pcq *query.EthCallQueryResponse
switch ecq := response.PerChainResponses[0].Response.(type) {
case *common.EthCallQueryResponse:
case *query.EthCallQueryResponse:
pcq = ecq
default:
panic("unsupported query type")
Expand Down
7 changes: 4 additions & 3 deletions node/pkg/p2p/p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/certusone/wormhole/node/pkg/accountant"
node_common "github.com/certusone/wormhole/node/pkg/common"
"github.com/certusone/wormhole/node/pkg/governor"
"github.com/certusone/wormhole/node/pkg/query"
"github.com/certusone/wormhole/node/pkg/version"
"github.com/ethereum/go-ethereum/common"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
Expand Down Expand Up @@ -157,7 +158,7 @@ func Run(
ibcFeaturesFunc func() string,
ccqEnabled bool,
signedQueryReqC chan<- *gossipv1.SignedQueryRequest,
queryResponseReadC <-chan *node_common.QueryResponsePublication,
queryResponseReadC <-chan *query.QueryResponsePublication,
) func(ctx context.Context) error {
if components == nil {
components = DefaultComponents()
Expand Down Expand Up @@ -427,7 +428,7 @@ func Run(
logger.Error("failed to marshal query response", zap.Error(err), zap.String("component", "ccqp2p"))
continue
}
digest := node_common.GetQueryResponseDigestFromBytes(msgBytes)
digest := query.GetQueryResponseDigestFromBytes(msgBytes)
sig, err := ethcrypto.Sign(digest.Bytes(), gk)
if err != nil {
panic(err)
Expand Down Expand Up @@ -605,7 +606,7 @@ func Run(
case *gossipv1.GossipMessage_SignedQueryRequest:
if signedQueryReqC != nil {
if ccqEnabled {
if err := node_common.PostSignedQueryRequest(signedQueryReqC, m.SignedQueryRequest); err != nil {
if err := query.PostSignedQueryRequest(signedQueryReqC, m.SignedQueryRequest); err != nil {
logger.Warn("failed to handle query request", zap.Error(err), zap.String("component", "ccqp2p"))
}
} else {
Expand Down
58 changes: 58 additions & 0 deletions node/pkg/query/helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package query

import (
"crypto/ecdsa"
"fmt"
"io"
"os"

nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1"

ethCrypto "github.com/ethereum/go-ethereum/crypto"
"golang.org/x/crypto/openpgp/armor" //nolint
"google.golang.org/protobuf/proto"
)

const (
GuardianKeyArmoredBlock = "WORMHOLE GUARDIAN PRIVATE KEY"
)

// loadGuardianKey loads a serialized guardian key from disk.
func loadGuardianKey(filename string) (*ecdsa.PrivateKey, error) {
f, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("failed to open file: %w", err)
}

p, err := armor.Decode(f)
if err != nil {
return nil, fmt.Errorf("failed to read armored file: %w", err)
}

if p.Type != GuardianKeyArmoredBlock {
return nil, fmt.Errorf("invalid block type: %s", p.Type)
}

b, err := io.ReadAll(p.Body)
if err != nil {
return nil, fmt.Errorf("failed to read file: %w", err)
}

var m nodev1.GuardianKey
err = proto.Unmarshal(b, &m)
if err != nil {
return nil, fmt.Errorf("failed to deserialize protobuf: %w", err)
}

gk, err := ethCrypto.ToECDSA(m.Data)
if err != nil {
return nil, fmt.Errorf("failed to deserialize raw key data: %w", err)
}

return gk, nil
}

func makeChannelPair[T any](cap int) (<-chan T, chan<- T) {
out := make(chan T, cap)
return out, out
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package common
package query

import (
"encoding/hex"
Expand Down
Loading

0 comments on commit 7c5b3f9

Please sign in to comment.