Skip to content

Commit

Permalink
Node/Solana: Refine search of log msgs for WH possible transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
bruce-riley committed Sep 9, 2024
1 parent 3bb068a commit 8bbb33a
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 9 deletions.
31 changes: 22 additions & 9 deletions node/pkg/watchers/solana/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func NewSolanaWatcher(
wsUrl: wsUrl,
contract: contractAddress,
rawContract: rawContract,
whLogPrefix: fmt.Sprintf("Program %s", rawContract),
whLogPrefix: createWhLogPrefix(rawContract),
msgObservedLogLevel: msgObservedLogLevel,
msgC: msgC,
obsvReqC: obsvReqC,
Expand Down Expand Up @@ -593,13 +593,9 @@ func (s *SolanaWatcher) fetchBlock(ctx context.Context, logger *zap.Logger, slot
continue
}

// If the logs don't contain the contract address, skip the transaction.
// ex: "Program 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 invoke [2]",
var possiblyWormhole bool
for i := 0; i < len(txRpc.Meta.LogMessages) && !possiblyWormhole; i++ {
possiblyWormhole = strings.HasPrefix(txRpc.Meta.LogMessages[i], s.whLogPrefix)
}
if !possiblyWormhole {
// If the logs don't contain the contract address followed by a sequence number, skip the transaction.
// ex: "Program 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 invoke [2]", "Program log: Sequence: 937184".
if !isPossibleWormholeMessage(s.whLogPrefix, txRpc.Meta.LogMessages) {
continue
}

Expand Down Expand Up @@ -668,6 +664,23 @@ func (s *SolanaWatcher) fetchBlock(ctx context.Context, logger *zap.Logger, slot
return true
}

func isPossibleWormholeMessage(whLogPrefix string, logMessages []string) bool {
for idx := 0; idx < len(logMessages); idx++ {
if strings.HasPrefix(logMessages[idx], whLogPrefix) {
for idx1 := idx + 1; idx1 < len(logMessages); idx1++ {
if strings.HasPrefix(logMessages[idx1], "Program log: Sequence:") {
return true
}
}
}
}
return false
}

func createWhLogPrefix(rawContract string) string {
return fmt.Sprintf("Program %s invoke", rawContract)
}

func (s *SolanaWatcher) processParsedTransaction(ctx context.Context, logger *zap.Logger, parsedTxResult *rpc.GetParsedTransactionResult, signature solana.Signature, slot uint64, isReobservation bool) {
foundContract := false
for _, key := range parsedTxResult.Transaction.Message.AccountKeys {
Expand Down Expand Up @@ -899,7 +912,7 @@ func (s *SolanaWatcher) processAccountSubscriptionData(_ context.Context, logger
if value.Account.Owner != s.rawContract {
// We got a message for the wrong contract on the websocket... uncomfortable...
solanaConnectionErrors.WithLabelValues(s.networkName, string(s.commitment), "invalid_websocket_account").Inc()
return errors.New("Update for account with wrong owner")
return errors.New("update for account with wrong owner")
}

data, err = base64.StdEncoding.DecodeString(value.Account.Data[0])
Expand Down
155 changes: 155 additions & 0 deletions node/pkg/watchers/solana/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,158 @@ func TestVerifyConstants(t *testing.T) {
assert.Equal(t, SolanaAccountLen, solana.PublicKeyLength)
assert.Equal(t, SolanaSignatureLen, len(solana.Signature{}))
}

var whLogPrefixForMainnet = createWhLogPrefix("worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth")
var whLogPrefixForTestnet = createWhLogPrefix("3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5")

func TestIsPossibleWormholeMessageSuccess(t *testing.T) {
// These are actual logs see in mainnet on 8/29/2024.
logs := []string{
"Program 3vxKRPwUTiEkeUVyoZ9MXFe1V71sRLbLqu1gRYaWmehQ invoke [1]",
"Program log: Instruction: TransferWrappedTokensWithRelay",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: InitializeAccount3",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4214 of 189385 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: Transfer",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 162844 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: Approve",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2904 of 153570 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb invoke [2]",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [3]",
"Program log: Instruction: Burn",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4790 of 91730 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program 11111111111111111111111111111111 invoke [3]",
"Program 11111111111111111111111111111111 success",
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth invoke [3]",
"Program log: Sequence: 937184",
"Program 11111111111111111111111111111111 invoke [4]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [4]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [4]",
"Program 11111111111111111111111111111111 success",
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth consumed 27141 of 74067 compute units",
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth success",
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb consumed 87537 of 133116 compute units",
"Program wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb success",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
"Program log: Instruction: CloseAccount",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3015 of 42346 compute units",
"Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
"Program 3vxKRPwUTiEkeUVyoZ9MXFe1V71sRLbLqu1gRYaWmehQ consumed 186778 of 224134 compute units",
"Program 3vxKRPwUTiEkeUVyoZ9MXFe1V71sRLbLqu1gRYaWmehQ success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
}

assert.True(t, isPossibleWormholeMessage(whLogPrefixForMainnet, logs))
}

func TestIsPossibleWormholeMessageFailNoLogs(t *testing.T) {
// These are actual logs see in mainnet on 8/29/2024.
logs := []string{}

assert.False(t, isPossibleWormholeMessage(whLogPrefixForMainnet, logs))
}

func TestIsPossibleWormholeMessageFailNoWormhole(t *testing.T) {
// These are actual logs see in mainnet on 8/29/2024.
logs := []string{
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
}

assert.False(t, isPossibleWormholeMessage(whLogPrefixForMainnet, logs))
}

func TestIsPossibleWormholeMessageFailNoSequence(t *testing.T) {
// These are actual logs see in mainnet on 8/29/2024.
logs := []string{
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth invoke [1]",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth consumed 37058 of 500000 compute units",
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
}

assert.False(t, isPossibleWormholeMessage(whLogPrefixForMainnet, logs))
}

func TestIsPossibleWormholeMessageFailAtEnd(t *testing.T) {
// Note: I altered these logs to create this test. I don't know if this could ever happen.
logs := []string{
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth consumed 37058 of 500000 compute units",
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program ComputeBudget111111111111111111111111111111 invoke [1]",
"Program ComputeBudget111111111111111111111111111111 success",
"Program worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth invoke [1]",
}

assert.False(t, isPossibleWormholeMessage(whLogPrefixForMainnet, logs))
}

func TestIsPossibleWormholeMessageForSolanaRewriteSuccess(t *testing.T) {
// These are actual logs see in testnet on 8/30/2024.
logs := []string{
"Program 4cmLyfxkgj2rGkPnXXJG8uroGvoSqsgigAsB3ACci2x7 invoke [1]",
"Program log: Instruction: WithdrawNative",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program log: ctx.accounts.wormhole_program : 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5",
"Program log: ctx.accounts.wormhole_bridge : 6bi4JGDoRwUs9TYBuvoA7dUVyikTJDrJsJU1ew6KVLiu",
"Program log: ctx.accounts.wormhole_message : DzKjuonZWoBjc9VcrtBBXwnEXA248Ma6fjUp1hgez9yg",
"Program log: ctx.accounts.custom_wormhole_emitter : F7thxxU2rLuXBj8xxzA39K63oZALrFuYRkCPUpQVhRb3",
"Program log: ctx.accounts.custom_wormhole_sequence : FEDW1vsFoGbQkaw9gbwuEZEsSwXLHcAKBVesXnmYNQnU",
"Program log: ctx.accounts.depositor : 3X1PnDdoyMdzLEoEy2TAhw8i1zC1F4ipNsxJHotnzCKK",
"Program log: ctx.accounts.wormhole_fee_collector : 7s3a1ycs16d6SNDumaRtjcoyMaTDZPavzgsmS3uUZYWX",
"Program 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 invoke [2]",
"Program log: Instruction: LegacyPostMessage",
"Program 11111111111111111111111111111111 invoke [3]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [3]",
"Program 11111111111111111111111111111111 success",
"Program log: Sequence: 26",
"Program 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 consumed 36772 of 68261 compute units",
"Program 3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5 success",
"Program 4cmLyfxkgj2rGkPnXXJG8uroGvoSqsgigAsB3ACci2x7 consumed 169398 of 200000 compute units",
"Program 4cmLyfxkgj2rGkPnXXJG8uroGvoSqsgigAsB3ACci2x7 success",
}

assert.True(t, isPossibleWormholeMessage(whLogPrefixForTestnet, logs))
}

0 comments on commit 8bbb33a

Please sign in to comment.