node: update solana watcher to use new solana-go version (#1760)

* node: remove the replace directive for solana-go

This commit that necessitated the fork:

    25b9f3025b

Has been merged upstream:

    9a01ac4f45

We need to pull in the latest solana-go to get support for MaxSupportedTransactionVersion.

* node: upgrade solana-go

This is the output from:

    go get -u github.com/gagliardetto/solana-go

It is required for the MaxSupportedTransactionVersion from:

    6ead48adf2

Co-authored-by: Jeff Schroeder <jeffschroeder@computer.org>
This commit is contained in:
bruce-riley 2022-10-24 12:22:56 -05:00 committed by GitHub
parent e45e04bb09
commit ed41a9a4ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 288 additions and 236 deletions

View File

@ -11,7 +11,7 @@ require (
github.com/dgraph-io/badger/v3 v3.2103.1 github.com/dgraph-io/badger/v3 v3.2103.1
github.com/diamondburned/arikawa/v3 v3.0.0-rc.2 github.com/diamondburned/arikawa/v3 v3.0.0-rc.2
github.com/ethereum/go-ethereum v1.10.21 github.com/ethereum/go-ethereum v1.10.21
github.com/gagliardetto/solana-go v0.3.5-0.20210727215348-0cf016734976 github.com/gagliardetto/solana-go v1.6.0
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
@ -34,20 +34,20 @@ require (
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0
github.com/tendermint/tendermint v0.34.14 github.com/tendermint/tendermint v0.34.14
github.com/tidwall/gjson v1.8.1 github.com/tidwall/gjson v1.14.3
go.uber.org/zap v1.22.0 go.uber.org/zap v1.23.0
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e golang.org/x/crypto v0.0.0-20221012134737-56aed061732a
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab golang.org/x/sys v0.1.0
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac golang.org/x/time v0.0.0-20220609170525-579cf78fd858
google.golang.org/api v0.58.0 google.golang.org/api v0.99.0
google.golang.org/genproto v0.0.0-20211019152133-63b7e35f4404 google.golang.org/genproto v0.0.0-20221018160656-63c7b68cfc55
google.golang.org/grpc v1.45.0 google.golang.org/grpc v1.50.1
google.golang.org/protobuf v1.28.1 google.golang.org/protobuf v1.28.1
) )
require ( require (
cloud.google.com/go/logging v1.4.2 cloud.google.com/go/logging v1.4.2
cloud.google.com/go/pubsub v1.17.1 cloud.google.com/go/pubsub v1.25.1
github.com/algorand/go-algorand-sdk v1.15.0 github.com/algorand/go-algorand-sdk v1.15.0
github.com/benbjohnson/clock v1.3.0 github.com/benbjohnson/clock v1.3.0
github.com/blendle/zapdriver v1.3.1 github.com/blendle/zapdriver v1.3.1
@ -57,13 +57,16 @@ require (
) )
require ( require (
cloud.google.com/go v0.97.0 // indirect cloud.google.com/go v0.104.0 // indirect
contrib.go.opencensus.io/exporter/stackdriver v0.13.4 // indirect cloud.google.com/go/compute v1.10.0 // indirect
filippo.io/edwards25519 v1.0.0-beta.2 // indirect cloud.google.com/go/iam v0.5.0 // indirect
contrib.go.opencensus.io/exporter/stackdriver v0.13.14 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
github.com/algorand/go-codec/codec v1.1.8 // indirect github.com/algorand/go-codec/codec v1.1.8 // indirect
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd v0.22.1 // indirect github.com/btcsuite/btcd v0.22.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
@ -78,36 +81,39 @@ require (
github.com/deckarep/golang-set v1.8.0 // indirect github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dfuse-io/binary v0.0.0-20210216024852-4ae6830a495d // indirect
github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect github.com/dfuse-io/logging v0.0.0-20210109005628-b97a57253f70 // indirect
github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/docker/go-units v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect
github.com/elastic/gosigar v0.14.2 // indirect github.com/elastic/gosigar v0.14.2 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/flynn/noise v1.0.0 // indirect github.com/flynn/noise v1.0.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect github.com/francoispqt/gojay v1.2.13 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/gagliardetto/binary v0.7.2 // indirect
github.com/gagliardetto/treeout v0.1.4 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-stack/stack v1.8.0 // indirect github.com/go-stack/stack v1.8.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.3 // indirect github.com/gogo/protobuf v1.3.3 // indirect
github.com/golang/glog v0.0.0-20210429001901-424d2337a529 // indirect github.com/golang/glog v0.0.0-20210429001901-424d2337a529 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/flatbuffers v1.12.0 // indirect github.com/google/flatbuffers v1.12.0 // indirect
github.com/google/go-cmp v0.5.8 // indirect github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.0.0 // indirect github.com/google/go-querystring v1.0.0 // indirect
github.com/google/gopacket v1.1.19 // indirect github.com/google/gopacket v1.1.19 // indirect
github.com/googleapis/gax-go/v2 v2.1.1 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.6.0 // indirect
github.com/gorilla/schema v1.2.0 // indirect github.com/gorilla/schema v1.2.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
github.com/holiman/uint256 v1.2.0 // indirect github.com/holiman/uint256 v1.2.0 // indirect
github.com/huin/goupnp v1.0.3 // indirect github.com/huin/goupnp v1.0.3 // indirect
@ -122,7 +128,7 @@ require (
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect github.com/jbenet/goprocess v0.1.4 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.15.1 // indirect github.com/klauspost/compress v1.15.11 // indirect
github.com/klauspost/cpuid/v2 v2.1.0 // indirect github.com/klauspost/cpuid/v2 v2.1.0 // indirect
github.com/koron/go-ssdp v0.0.3 // indirect github.com/koron/go-ssdp v0.0.3 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect
@ -146,6 +152,7 @@ require (
github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect
github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect github.com/mattn/go-pointer v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect
@ -158,6 +165,7 @@ require (
github.com/mitchellh/mapstructure v1.4.2 // indirect github.com/mitchellh/mapstructure v1.4.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect
github.com/multiformats/go-base32 v0.0.4 // indirect github.com/multiformats/go-base32 v0.0.4 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
@ -193,11 +201,12 @@ require (
github.com/spf13/afero v1.6.0 // indirect github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.3.1 // indirect github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/streamingfast/logging v0.0.0-20220813175024-b4fbb0e893df // indirect
github.com/subosito/gotenv v1.2.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 // indirect
github.com/tidwall/match v1.0.3 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.1.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect github.com/tklauser/numcpus v0.2.2 // indirect
github.com/tyler-smith/go-bip39 v1.0.2 // indirect github.com/tyler-smith/go-bip39 v1.0.2 // indirect
@ -208,13 +217,13 @@ require (
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.8.0 // indirect
go.uber.org/ratelimit v0.2.0 // indirect go.uber.org/ratelimit v0.2.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect golang.org/x/net v0.0.0-20221017152216-f25eb7ecb193 // indirect
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect golang.org/x/sync v0.1.0 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/term v0.0.0-20221017184919-83659145692c // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.4.0 // indirect
golang.org/x/tools v0.1.12 // indirect golang.org/x/tools v0.1.12 // indirect
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
gopkg.in/ini.v1 v1.63.2 // indirect gopkg.in/ini.v1 v1.63.2 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
@ -225,10 +234,6 @@ require (
nhooyr.io/websocket v1.8.6 // indirect nhooyr.io/websocket v1.8.6 // indirect
) )
// Temporary fork that adds GetConfirmedTransactionWithOpts. Can be removed
// once Solana mainnet has upgraded to v1.7.x.
replace github.com/gagliardetto/solana-go => github.com/certusone/solana-go v0.3.7-0.20210729105530-67b495e4e529
// Needed for cosmos-sdk based chains. See // Needed for cosmos-sdk based chains. See
// https://github.com/cosmos/cosmos-sdk/issues/10925 for more details. // https://github.com/cosmos/cosmos-sdk/issues/10925 for more details.
replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@ import (
"github.com/certusone/wormhole/node/pkg/db" "github.com/certusone/wormhole/node/pkg/db"
gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1" gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1" nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1"
solwatcher "github.com/certusone/wormhole/node/pkg/watchers/solana"
"github.com/gagliardetto/solana-go" "github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/rpc" "github.com/gagliardetto/solana-go/rpc"
"github.com/wormhole-foundation/wormhole/sdk" "github.com/wormhole-foundation/wormhole/sdk"
@ -262,15 +263,20 @@ func fetchTxSeq(ctx context.Context, c *rpc.Client, sig solana.Signature) (*rpc.
return nil, 0, nil return nil, 0, nil
} }
func process(tx *rpc.TransactionWithMeta) (*solana.PublicKey, error) { func process(txRpc *rpc.TransactionWithMeta) (*solana.PublicKey, error) {
program, err := solana.PublicKeyFromBase58(*solanaAddr) program, err := solana.PublicKeyFromBase58(*solanaAddr)
if err != nil { if err != nil {
log.Fatalf("Invalid program address: %v", err) log.Fatalf("Invalid program address: %v", err)
} }
signature := tx.Transaction.Signatures[0] tx, err := txRpc.GetTransaction()
if err != nil {
log.Fatalf("Failed to unmarshal transaction: %v", err)
}
signature := tx.Signatures[0]
var programIndex uint16 var programIndex uint16
for n, key := range tx.Transaction.Message.AccountKeys { for n, key := range tx.Message.AccountKeys {
if key.Equals(program) { if key.Equals(program) {
programIndex = uint16(n) programIndex = uint16(n)
} }
@ -281,10 +287,16 @@ func process(tx *rpc.TransactionWithMeta) (*solana.PublicKey, error) {
log.Printf("found Wormhole tx in %s", signature) log.Printf("found Wormhole tx in %s", signature)
txs := make([]solana.CompiledInstruction, 0, len(tx.Transaction.Message.Instructions)) txs := make([]solana.CompiledInstruction, 0, len(tx.Message.Instructions))
txs = append(txs, tx.Transaction.Message.Instructions...) txs = append(txs, tx.Message.Instructions...)
for _, inner := range tx.Meta.InnerInstructions { for _, inner := range txRpc.Meta.InnerInstructions {
txs = append(txs, inner.Instructions...) for _, instRpc := range inner.Instructions {
inst, err := solwatcher.ConvertRpcInstruction(instRpc)
if err != nil {
log.Fatalf("Failed to unmarshal inner instruction: %v", err)
}
txs = append(txs, inst)
}
} }
for _, inst := range txs { for _, inst := range txs {
@ -294,7 +306,7 @@ func process(tx *rpc.TransactionWithMeta) (*solana.PublicKey, error) {
if inst.Data[0] != postMessageInstructionID { if inst.Data[0] != postMessageInstructionID {
continue continue
} }
acc := tx.Transaction.Message.AccountKeys[inst.Accounts[1]] acc := tx.Message.AccountKeys[inst.Accounts[1]]
return &acc, nil return &acc, nil
} }

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"math"
"time" "time"
"github.com/certusone/wormhole/node/pkg/common" "github.com/certusone/wormhole/node/pkg/common"
@ -248,11 +249,14 @@ func (s *SolanaWatcher) fetchBlock(ctx context.Context, logger *zap.Logger, slot
defer cancel() defer cancel()
start := time.Now() start := time.Now()
rewards := false rewards := false
out, err := s.rpcClient.GetConfirmedBlockWithOpts(rCtx, slot, &rpc.GetConfirmedBlockOpts{
Encoding: "json", maxSupportedTransactionVersion := uint64(0)
TransactionDetails: "full", out, err := s.rpcClient.GetBlockWithOpts(rCtx, slot, &rpc.GetBlockOpts{
Rewards: &rewards, Encoding: "base64", // solana-go doesn't support json encoding.
Commitment: s.commitment, TransactionDetails: "full",
Rewards: &rewards,
Commitment: s.commitment,
MaxSupportedTransactionVersion: &maxSupportedTransactionVersion,
}) })
queryLatency.WithLabelValues(s.networkName, "get_confirmed_block", string(s.commitment)).Observe(time.Since(start).Seconds()) queryLatency.WithLabelValues(s.networkName, "get_confirmed_block", string(s.commitment)).Observe(time.Since(start).Seconds())
@ -290,10 +294,8 @@ func (s *SolanaWatcher) fetchBlock(ctx context.Context, logger *zap.Logger, slot
} }
if out == nil { if out == nil {
solanaConnectionErrors.WithLabelValues(s.networkName, string(s.commitment), "get_confirmed_block_error").Inc() // Per the API, nil just means the block is not confirmed.
logger.Error("nil response when requesting block", zap.Error(err), zap.Uint64("slot", slot), logger.Info("block is not yet finalized", zap.Uint64("slot", slot))
zap.String("commitment", string(s.commitment)))
p2p.DefaultRegistry.AddErrorCount(s.chainID, 1)
return false return false
} }
@ -304,10 +306,15 @@ func (s *SolanaWatcher) fetchBlock(ctx context.Context, logger *zap.Logger, slot
zap.String("commitment", string(s.commitment))) zap.String("commitment", string(s.commitment)))
OUTER: OUTER:
for _, tx := range out.Transactions { for _, txRpc := range out.Transactions {
signature := tx.Transaction.Signatures[0] tx, err := txRpc.GetTransaction()
if err != nil {
logger.Error("failed to unmarshal transaction", zap.Error(err))
continue
}
signature := tx.Signatures[0]
var programIndex uint16 var programIndex uint16
for n, key := range tx.Transaction.Message.AccountKeys { for n, key := range tx.Message.AccountKeys {
if key.Equals(s.contract) { if key.Equals(s.contract) {
programIndex = uint16(n) programIndex = uint16(n)
} }
@ -316,7 +323,7 @@ OUTER:
continue continue
} }
if tx.Meta.Err != nil { if txRpc.Meta.Err != nil {
logger.Debug("skipping failed Wormhole transaction", logger.Debug("skipping failed Wormhole transaction",
zap.Stringer("signature", signature), zap.Stringer("signature", signature),
zap.Uint64("slot", slot), zap.Uint64("slot", slot),
@ -330,7 +337,7 @@ OUTER:
zap.String("commitment", string(s.commitment))) zap.String("commitment", string(s.commitment)))
// Find top-level instructions // Find top-level instructions
for i, inst := range tx.Transaction.Message.Instructions { for i, inst := range tx.Message.Instructions {
found, err := s.processInstruction(ctx, logger, slot, inst, programIndex, tx, signature, i) found, err := s.processInstruction(ctx, logger, slot, inst, programIndex, tx, signature, i)
if err != nil { if err != nil {
logger.Error("malformed Wormhole instruction", logger.Error("malformed Wormhole instruction",
@ -350,8 +357,8 @@ OUTER:
// Call GetConfirmedTransaction to get at innerTransactions // Call GetConfirmedTransaction to get at innerTransactions
rCtx, cancel := context.WithTimeout(ctx, rpcTimeout) rCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
start := time.Now() start := time.Now()
tr, err := s.rpcClient.GetConfirmedTransactionWithOpts(rCtx, signature, &rpc.GetTransactionOpts{ tr, err := s.rpcClient.GetTransaction(rCtx, signature, &rpc.GetTransactionOpts{
Encoding: "json", Encoding: "base64", // solana-go doesn't support json encoding.
Commitment: s.commitment, Commitment: s.commitment,
}) })
cancel() cancel()
@ -374,8 +381,20 @@ OUTER:
zap.Duration("took", time.Since(start))) zap.Duration("took", time.Since(start)))
for _, inner := range tr.Meta.InnerInstructions { for _, inner := range tr.Meta.InnerInstructions {
for i, inst := range inner.Instructions { for i, instRpc := range inner.Instructions {
_, err := s.processInstruction(ctx, logger, slot, inst, programIndex, tx, signature, i) inst, err := ConvertRpcInstruction(instRpc)
if err != nil {
logger.Error("failed to unmarshal inner instruction",
zap.Error(err),
zap.Int("idx", i),
zap.Stringer("signature", signature),
zap.Uint64("slot", slot),
)
continue
}
_, err = s.processInstruction(ctx, logger, slot, inst, programIndex, tx, signature, i)
if err != nil { if err != nil {
logger.Error("malformed Wormhole instruction", logger.Error("malformed Wormhole instruction",
zap.Error(err), zap.Error(err),
@ -398,7 +417,7 @@ OUTER:
return true return true
} }
func (s *SolanaWatcher) processInstruction(ctx context.Context, logger *zap.Logger, slot uint64, inst solana.CompiledInstruction, programIndex uint16, tx rpc.TransactionWithMeta, signature solana.Signature, idx int) (bool, error) { func (s *SolanaWatcher) processInstruction(ctx context.Context, logger *zap.Logger, slot uint64, inst solana.CompiledInstruction, programIndex uint16, tx *solana.Transaction, signature solana.Signature, idx int) (bool, error) {
if inst.ProgramIDIndex != programIndex { if inst.ProgramIDIndex != programIndex {
return false, nil return false, nil
} }
@ -435,7 +454,7 @@ func (s *SolanaWatcher) processInstruction(ctx context.Context, logger *zap.Logg
} }
// The second account in a well-formed Wormhole instruction is the VAA program account. // The second account in a well-formed Wormhole instruction is the VAA program account.
acc := tx.Transaction.Message.AccountKeys[inst.Accounts[1]] acc := tx.Message.AccountKeys[inst.Accounts[1]]
logger.Info("fetching VAA account", zap.Stringer("acc", acc), logger.Info("fetching VAA account", zap.Stringer("acc", acc),
zap.Stringer("signature", signature), zap.Uint64("slot", slot), zap.Int("idx", idx)) zap.Stringer("signature", signature), zap.Uint64("slot", slot), zap.Int("idx", idx))
@ -601,3 +620,16 @@ func ParseMessagePublicationAccount(data []byte) (*MessagePublicationAccount, er
return prop, nil return prop, nil
} }
// ConvertRpcInstruction converts an rpc.CompiledInstruction into a solana.CompiledInstruction.
func ConvertRpcInstruction(instRpc rpc.CompiledInstruction) (solana.CompiledInstruction, error) {
var accounts []uint16
for _, a := range instRpc.Accounts {
if a > math.MaxUint16 || a < 0 {
return solana.CompiledInstruction{}, fmt.Errorf("account %d will not fit in a uint16", a)
}
accounts = append(accounts, uint16(a))
}
return solana.CompiledInstruction{ProgramIDIndex: instRpc.ProgramIDIndex, Accounts: accounts, Data: instRpc.Data}, nil
}