Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: skip solana unsupported transaction version #3206

Merged
merged 8 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# CHANGELOG

## Unreleased

### Features

### Tests

### Refactor

### Fixes

* [3206](https://github.com/zeta-chain/node/pull/3206) - skip Solana unsupported transaction version to not block inbound observation

## v23.0.0

### Features
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/emicklei/proto v1.11.1
github.com/ethereum/go-ethereum v1.13.15
github.com/fatih/color v1.14.1
github.com/gagliardetto/solana-go v1.10.0
github.com/gagliardetto/solana-go v1.12.0
github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.4
github.com/gorilla/mux v1.8.0
Expand Down Expand Up @@ -282,7 +282,7 @@ require (
github.com/zondax/hid v0.9.2 // indirect
github.com/zondax/ledger-go v0.14.3 // indirect
go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect
go.mongodb.org/mongo-driver v1.11.0 // indirect
go.mongodb.org/mongo-driver v1.12.2 // indirect
go.nhat.io/matcher/v2 v2.0.0 // indirect
go.nhat.io/wait v0.1.0 // indirect
go.opencensus.io v0.24.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvS
github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY=
github.com/gagliardetto/solana-go v1.10.0 h1:lDuHGC+XLxw9j8fCHBZM9tv4trI0PVhev1m9NAMaIdM=
github.com/gagliardetto/solana-go v1.10.0/go.mod h1:afBEcIRrDLJst3lvAahTr63m6W2Ns6dajZxe2irF7Jg=
github.com/gagliardetto/solana-go v1.12.0 h1:rzsbilDPj6p+/DOPXBMLhwMZeBgeRuXjm5zQFCoXgsg=
github.com/gagliardetto/solana-go v1.12.0/go.mod h1:l/qqqIN6qJJPtxW/G1PF4JtcE3Zg2vD2EliZrr9Gn5k=
github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw=
github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok=
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8=
Expand Down Expand Up @@ -1501,7 +1503,9 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
Expand Down Expand Up @@ -1545,6 +1549,8 @@ go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5/go.mod h1:eW0HG9/o
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE=
go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
go.mongodb.org/mongo-driver v1.12.2 h1:gbWY1bJkkmUB9jjZzcdhOL8O85N9H+Vvsf2yFN0RDws=
go.mongodb.org/mongo-driver v1.12.2/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
go.nhat.io/aferomock v0.4.0 h1:gs3nJzIqAezglUuaPfautAmZwulwRWLcfSSzdK4YCC0=
go.nhat.io/aferomock v0.4.0/go.mod h1:msi5MDOtJ/AroUa/lDc3jVGOILM4SKP//4yBRImOvkI=
go.nhat.io/grpcmock v0.25.0 h1:zk03vvA60w7UrnurZbqL4wxnjmJz1Kuyb7ig2MF+n4c=
Expand Down
23 changes: 0 additions & 23 deletions pkg/crypto/privkey.go

This file was deleted.

67 changes: 0 additions & 67 deletions pkg/crypto/privkey_test.go

This file was deleted.

23 changes: 17 additions & 6 deletions zetaclient/chains/solana/observer/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,28 @@

// process successfully signature only
if sig.Err == nil {
txResult, err := ob.solClient.GetTransaction(ctx, sig.Signature, &rpc.GetTransactionOpts{})
maxTxVersion := rpc.MaxSupportedTransactionVersion0
txResult, skip, err := solanarpc.GetTransactionWithMaxVersion(
ctx,
ob.solClient,
sig.Signature,
&maxTxVersion,
)

Check warning on line 109 in zetaclient/chains/solana/observer/inbound.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/solana/observer/inbound.go#L103-L109

Added lines #L103 - L109 were not covered by tests
if err != nil {
// we have to re-scan this signature on next ticker
return errors.Wrapf(err, "error GetTransaction for chain %d sig %s", chainID, sigString)
}

// filter inbound events and vote
err = ob.FilterInboundEventsAndVote(ctx, txResult)
if err != nil {
// we have to re-scan this signature on next ticker
return errors.Wrapf(err, "error FilterInboundEventAndVote for chain %d sig %s", chainID, sigString)
switch {
case skip:
ob.Logger().Inbound.Warn().Msgf("ObserveInbound: skip unsupported transaction sig %s", sigString)
ws4charlie marked this conversation as resolved.
Show resolved Hide resolved
default:
// filter inbound events and vote
err = ob.FilterInboundEventsAndVote(ctx, txResult)
if err != nil {
// we have to re-scan this signature on next ticker
return errors.Wrapf(err, "error FilterInboundEventAndVote for chain %d sig %s", chainID, sigString)
}

Check warning on line 124 in zetaclient/chains/solana/observer/inbound.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/solana/observer/inbound.go#L115-L124

Added lines #L115 - L124 were not covered by tests
}
}

Expand Down
24 changes: 24 additions & 0 deletions zetaclient/chains/solana/rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import (
"context"
"strings"
"time"

"github.com/gagliardetto/solana-go"
Expand All @@ -18,6 +19,10 @@
// RPCAlertLatency is the default threshold for RPC latency to be considered unhealthy and trigger an alert.
// The 'HEALTH_CHECK_SLOT_DISTANCE' is default to 150 slots, which is 150 * 0.4s = 60s
RPCAlertLatency = time.Duration(60) * time.Second

// ErrorCodeUnsupportedTransactionVersion
// see: https://github.com/solana-labs/solana/blob/master/rpc/src/rpc.rs#L7276
ErrorCodeUnsupportedTransactionVersion = "-32015"
ws4charlie marked this conversation as resolved.
Show resolved Hide resolved
)

// GetFirstSignatureForAddress searches the first signature for the given address.
Expand Down Expand Up @@ -122,6 +127,25 @@
return allSignatures, nil
}

// GetTransactionWithMaxVersion fetches a transaction with the given signature and max version.
func GetTransactionWithMaxVersion(
ws4charlie marked this conversation as resolved.
Show resolved Hide resolved
ctx context.Context,
client interfaces.SolanaRPCClient,
signature solana.Signature,
maxTxVersion *uint64,
) (*rpc.GetTransactionResult, bool, error) {
txResult, err := client.GetTransaction(ctx, signature, &rpc.GetTransactionOpts{
MaxSupportedTransactionVersion: maxTxVersion,
})

// skip unsupported transaction version error
if err != nil && strings.Contains(err.Error(), ErrorCodeUnsupportedTransactionVersion) {
return nil, true, nil
}

Check warning on line 144 in zetaclient/chains/solana/rpc/rpc.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/solana/rpc/rpc.go#L136-L144

Added lines #L136 - L144 were not covered by tests

return txResult, false, err

Check warning on line 146 in zetaclient/chains/solana/rpc/rpc.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/solana/rpc/rpc.go#L146

Added line #L146 was not covered by tests
}

// CheckRPCStatus checks the RPC status of the solana chain
func CheckRPCStatus(ctx context.Context, client interfaces.SolanaRPCClient, privnet bool) (time.Time, error) {
// query solana health (always return "ok" unless --trusted-validator is provided)
Expand Down
33 changes: 33 additions & 0 deletions zetaclient/chains/solana/rpc/rpc_live_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,44 @@ func Test_SolanaRPCLive(t *testing.T) {
return
}

LiveTest_GetTransactionWithVersion(t)
LiveTest_GetFirstSignatureForAddress(t)
LiveTest_GetSignaturesForAddressUntil(t)
LiveTest_CheckRPCStatus(t)
}

func LiveTest_GetTransactionWithVersion(t *testing.T) {
// create a Solana devnet RPC client
client := solanarpc.New(solanarpc.DevNet_RPC)

// example transaction of version "0"
// https://explorer.solana.com/tx/Wqgj7hAaUUSfLzieN912G7GxyGHijzBZgY135NtuFtPRjevK8DnYjWwQZy7LAKFQZu582wsjuab2QP27VMUJzAi?cluster=devnet
txSig := solana.MustSignatureFromBase58(
"Wqgj7hAaUUSfLzieN912G7GxyGHijzBZgY135NtuFtPRjevK8DnYjWwQZy7LAKFQZu582wsjuab2QP27VMUJzAi",
)

t.Run("should get the transaction if the version is supported", func(t *testing.T) {
ctx := context.Background()
txResult, skip, err := rpc.GetTransactionWithMaxVersion(
ctx,
client,
txSig,
&solanarpc.MaxSupportedTransactionVersion0,
)
require.NoError(t, err)
require.NotNil(t, txResult)
require.False(t, skip)
})

t.Run("should skip the transaction if the version is not supported", func(t *testing.T) {
ctx := context.Background()
txResult, skip, err := rpc.GetTransactionWithMaxVersion(ctx, client, txSig, nil)
require.NoError(t, err)
ws4charlie marked this conversation as resolved.
Show resolved Hide resolved
require.Nil(t, txResult)
require.True(t, skip)
})
}

func LiveTest_GetFirstSignatureForAddress(t *testing.T) {
// create a Solana devnet RPC client
client := solanarpc.New(solanarpc.DevNet_RPC)
Expand Down
4 changes: 2 additions & 2 deletions zetaclient/chains/solana/signer/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"github.com/zeta-chain/node/pkg/chains"
"github.com/zeta-chain/node/pkg/coin"
contracts "github.com/zeta-chain/node/pkg/contracts/solana"
"github.com/zeta-chain/node/pkg/crypto"
"github.com/zeta-chain/node/x/crosschain/types"
observertypes "github.com/zeta-chain/node/x/observer/types"
"github.com/zeta-chain/node/zetaclient/chains/base"
Expand Down Expand Up @@ -86,10 +85,11 @@ func NewSigner(

// construct Solana private key if present
if relayerKey != nil {
signer.relayerKey, err = crypto.SolanaPrivateKeyFromString(relayerKey.PrivateKey)
privKey, err := solana.PrivateKeyFromBase58(relayerKey.PrivateKey)
if err != nil {
return nil, errors.Wrap(err, "unable to construct solana private key")
}
signer.relayerKey = &privKey
logger.Std.Info().Msgf("Solana relayer address: %s", signer.relayerKey.PublicKey())
} else {
logger.Std.Info().Msg("Solana relayer key is not provided")
Expand Down
5 changes: 3 additions & 2 deletions zetaclient/keys/relayer_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"path/filepath"

"github.com/gagliardetto/solana-go"
"github.com/pkg/errors"

"github.com/zeta-chain/node/pkg/chains"
Expand All @@ -23,7 +24,7 @@ func (rk RelayerKey) ResolveAddress(network chains.Network) (string, string, err

switch network {
case chains.Network_solana:
privKey, err := crypto.SolanaPrivateKeyFromString(rk.PrivateKey)
privKey, err := solana.PrivateKeyFromBase58(rk.PrivateKey)
if err != nil {
return "", "", errors.Wrap(err, "unable to construct solana private key")
}
Expand Down Expand Up @@ -128,7 +129,7 @@ func ReadRelayerKeyFromFile(fileName string) (*RelayerKey, error) {
func IsRelayerPrivateKeyValid(privateKey string, network chains.Network) bool {
switch network {
case chains.Network_solana:
_, err := crypto.SolanaPrivateKeyFromString(privateKey)
_, err := solana.PrivateKeyFromBase58(privateKey)
if err != nil {
return false
}
Expand Down
Loading