node/watchers/solana: additional safety check

This commit is contained in:
Evan Gray 2023-11-08 13:09:15 -05:00 committed by Evan Gray
parent 0da1f37874
commit 85e785a132
1 changed files with 26 additions and 9 deletions

View File

@ -1,6 +1,7 @@
package solana package solana
import ( import (
"bytes"
"context" "context"
"errors" "errors"
"fmt" "fmt"
@ -94,18 +95,24 @@ type (
MessagePublicationAccount struct { MessagePublicationAccount struct {
VaaVersion uint8 VaaVersion uint8
// Borsh does not seem to support booleans, so 0=false / 1=true // Borsh does not seem to support booleans, so 0=false / 1=true
ConsistencyLevel uint8 ConsistencyLevel uint8
VaaTime uint32 EmitterAuthority vaa.Address
VaaSignatureAccount vaa.Address MessageStatus uint8
SubmissionTime uint32 Gap [3]byte
Nonce uint32 SubmissionTime uint32
Sequence uint64 Nonce uint32
EmitterChain uint16 Sequence uint64
EmitterAddress vaa.Address EmitterChain uint16
Payload []byte EmitterAddress vaa.Address
Payload []byte
} }
) )
var (
emptyAddressBytes = vaa.Address{}.Bytes()
emptyGapBytes = []byte{0, 0, 0}
)
var ( var (
solanaConnectionErrors = promauto.NewCounterVec( solanaConnectionErrors = promauto.NewCounterVec(
prometheus.CounterOpts{ prometheus.CounterOpts{
@ -815,6 +822,16 @@ func (s *SolanaWatcher) processMessageAccount(logger *zap.Logger, data []byte, a
return return
} }
// SECURITY: ensure these fields are zeroed out. in the legacy solana program they were always zero, and in the 2023 rewrite they are zeroed once the account is finalized
if !bytes.Equal(proposal.EmitterAuthority.Bytes(), emptyAddressBytes) || proposal.MessageStatus != 0 || !bytes.Equal(proposal.Gap[:], emptyGapBytes) {
solanaAccountSkips.WithLabelValues(s.networkName, "unfinalized_account").Inc()
logger.Error(
"account is not finalized",
zap.Stringer("account", acc),
zap.Binary("data", data))
return
}
var txHash eth_common.Hash var txHash eth_common.Hash
copy(txHash[:], acc[:]) copy(txHash[:], acc[:])