Implement PostedMessage fetching in the client
Change-Id: I8b59cdbfaf37212e187257cf46674086ad96d19d
This commit is contained in:
parent
d84b61fda5
commit
02d7257ff5
|
@ -49,6 +49,7 @@ require (
|
|||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/multiformats/go-multiaddr v0.3.1
|
||||
github.com/near/borsh-go v0.3.0
|
||||
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/peterh/liner v1.2.1 // indirect
|
||||
|
|
|
@ -1009,6 +1009,8 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
|
|||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/near/borsh-go v0.3.0 h1:+DvG7eApOD3KrHIh7TwZvYzhXUF/OzMTC6aRTUEtW+8=
|
||||
github.com/near/borsh-go v0.3.0/go.mod h1:NeMochZp7jN/pYFuxLkrZtmLqbADmnp/y1+/dL+AsyQ=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
|
||||
|
|
|
@ -12,6 +12,7 @@ type MessagePublication struct {
|
|||
Timestamp time.Time
|
||||
|
||||
Nonce uint32
|
||||
Sequence uint64
|
||||
EmitterChain vaa.ChainID
|
||||
EmitterAddress vaa.Address
|
||||
Payload []byte
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package ethereum
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/certusone/wormhole/bridge/pkg/common"
|
||||
"github.com/certusone/wormhole/bridge/pkg/p2p"
|
||||
gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1"
|
||||
|
@ -14,9 +11,9 @@ import (
|
|||
"github.com/dfuse-io/solana-go/rpc"
|
||||
eth_common "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/near/borsh-go"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"go.uber.org/zap"
|
||||
"math/big"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -115,13 +112,10 @@ func (s *SolanaWatcher) Run(ctx context.Context) error {
|
|||
accounts, err := rpcClient.GetProgramAccounts(rCtx, s.bridge, &rpc.GetProgramAccountsOpts{
|
||||
Commitment: rpc.CommitmentMax, // TODO: deprecated, use Finalized
|
||||
Filters: []rpc.RPCFilter{
|
||||
{
|
||||
DataSize: 1184, // Search for MessagePublicationAccount accounts
|
||||
},
|
||||
{
|
||||
Memcmp: &rpc.RPCFilterMemcmp{
|
||||
Offset: 1140, // Offset of VaaTime
|
||||
Bytes: solana.Base58{0, 0, 0, 0}, // VAA time is 0 when no VAA is present
|
||||
Offset: 0, // Offset of VaaTime
|
||||
Bytes: solana.Base58{'m', 's', 'g'}, // Prefix of the posted message accounts
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -151,7 +145,7 @@ func (s *SolanaWatcher) Run(ctx context.Context) error {
|
|||
}
|
||||
|
||||
// VAA submitted
|
||||
if proposal.VaaTime.Unix() != 0 {
|
||||
if proposal.VaaTime != 0 {
|
||||
solanaAccountSkips.WithLabelValues("is_submitted_vaa").Inc()
|
||||
continue
|
||||
}
|
||||
|
@ -160,17 +154,13 @@ func (s *SolanaWatcher) Run(ctx context.Context) error {
|
|||
copy(txHash[:], acc.Pubkey[:])
|
||||
|
||||
lock := &common.MessagePublication{
|
||||
TxHash: txHash,
|
||||
Timestamp: proposal.LockupTime,
|
||||
Nonce: proposal.Nonce,
|
||||
SourceAddress: proposal.SourceAddress,
|
||||
TargetAddress: proposal.ForeignAddress,
|
||||
SourceChain: vaa.ChainIDSolana,
|
||||
TargetChain: proposal.ToChainID,
|
||||
TokenChain: proposal.Asset.Chain,
|
||||
TokenAddress: proposal.Asset.Address,
|
||||
TokenDecimals: proposal.Asset.Decimals,
|
||||
Amount: proposal.Amount,
|
||||
TxHash: txHash,
|
||||
Timestamp: time.Unix(int64(proposal.SubmissionTime), 0),
|
||||
Nonce: proposal.Nonce,
|
||||
Sequence: proposal.Sequence,
|
||||
EmitterChain: proposal.EmitterChain,
|
||||
EmitterAddress: proposal.EmitterAddress,
|
||||
Payload: proposal.Payload,
|
||||
}
|
||||
|
||||
solanaLockupsConfirmed.Inc()
|
||||
|
@ -193,10 +183,11 @@ func (s *SolanaWatcher) Run(ctx context.Context) error {
|
|||
type (
|
||||
MessagePublicationAccount struct {
|
||||
VaaVersion uint8
|
||||
VaaTime time.Time
|
||||
VaaTime uint32
|
||||
VaaSignatureAccount vaa.Address
|
||||
SubmissionTime time.Time
|
||||
SubmissionTime uint32
|
||||
Nonce uint32
|
||||
Sequence uint64
|
||||
EmitterChain vaa.ChainID
|
||||
EmitterAddress vaa.Address
|
||||
Payload []byte
|
||||
|
@ -205,49 +196,9 @@ type (
|
|||
|
||||
func ParseTransferOutProposal(data []byte) (*MessagePublicationAccount, error) {
|
||||
prop := &MessagePublicationAccount{}
|
||||
r := bytes.NewBuffer(data)
|
||||
|
||||
// Skip initialized bool
|
||||
r.Next(1)
|
||||
|
||||
if err := binary.Read(r, binary.LittleEndian, &prop.VaaVersion); err != nil {
|
||||
return nil, fmt.Errorf("failed to read to vaa version: %w", err)
|
||||
if err := borsh.Deserialize(prop, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var vaaTime uint32
|
||||
if err := binary.Read(r, binary.LittleEndian, &vaaTime); err != nil {
|
||||
return nil, fmt.Errorf("failed to read vaa time: %w", err)
|
||||
}
|
||||
prop.VaaTime = time.Unix(int64(vaaTime), 0)
|
||||
|
||||
if n, err := r.Read(prop.VaaSignatureAccount[:]); err != nil || n != 32 {
|
||||
return nil, fmt.Errorf("failed to read signature account: %w", err)
|
||||
}
|
||||
|
||||
var submissionTime uint32
|
||||
if err := binary.Read(r, binary.LittleEndian, &submissionTime); err != nil {
|
||||
return nil, fmt.Errorf("failed to read lockup time: %w", err)
|
||||
}
|
||||
prop.SubmissionTime = time.Unix(int64(submissionTime), 0)
|
||||
|
||||
if err := binary.Read(r, binary.LittleEndian, &prop.Nonce); err != nil {
|
||||
return nil, fmt.Errorf("failed to read nonce: %w", err)
|
||||
}
|
||||
|
||||
if err := binary.Read(r, binary.LittleEndian, &prop.EmitterChain); err != nil {
|
||||
return nil, fmt.Errorf("failed to read emitter chain: %w", err)
|
||||
}
|
||||
|
||||
if n, err := r.Read(prop.EmitterAddress[:]); err != nil || n != 32 {
|
||||
return nil, fmt.Errorf("failed to read emitter address: %w", err)
|
||||
}
|
||||
|
||||
payload := make([]byte, 1000)
|
||||
n, err := r.Read(payload)
|
||||
if err != nil || n == 0 {
|
||||
return nil, fmt.Errorf("failed to read vaa: %w", err)
|
||||
}
|
||||
prop.Payload = payload[:n]
|
||||
|
||||
return prop, nil
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ type (
|
|||
Timestamp time.Time
|
||||
// Nonce of the VAA
|
||||
Nonce uint32
|
||||
// Sequence of the VAA
|
||||
Sequence uint64
|
||||
// EmitterChain the VAA was emitted on
|
||||
EmitterChain ChainID
|
||||
// EmitterAddress of the contract that emitted the Message
|
||||
|
@ -36,7 +38,7 @@ type (
|
|||
}
|
||||
|
||||
// ChainID of a Wormhole chain
|
||||
ChainID uint8
|
||||
ChainID uint16
|
||||
// Action of a VAA
|
||||
Action uint8
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
use crate::{
|
||||
api::ForeignAddress,
|
||||
api::{
|
||||
ForeignAddress,
|
||||
PostMessage,
|
||||
PostMessageData,
|
||||
},
|
||||
vaa::{
|
||||
DeserializeGovernancePayload,
|
||||
DeserializePayload,
|
||||
|
@ -26,6 +30,11 @@ use std::{
|
|||
io::{
|
||||
Cursor,
|
||||
Read,
|
||||
Write,
|
||||
},
|
||||
ops::{
|
||||
Deref,
|
||||
DerefMut,
|
||||
},
|
||||
str::FromStr,
|
||||
};
|
||||
|
@ -104,8 +113,52 @@ impl Owned for SignatureSet {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct PostedMessage(pub PostedMessageData);
|
||||
|
||||
impl BorshSerialize for PostedMessage {
|
||||
fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
writer.write(&['m' as u8, 's' as u8, 'g' as u8]);
|
||||
BorshSerialize::serialize(&self.0, writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl BorshDeserialize for PostedMessage {
|
||||
fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
|
||||
Ok(PostedMessage(
|
||||
<PostedMessageData as BorshDeserialize>::deserialize(&mut &buf[3..])?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for PostedMessage {
|
||||
type Target = PostedMessageData;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { std::mem::transmute(&self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for PostedMessage {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { std::mem::transmute(&mut self.0) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PostedMessage {
|
||||
fn default() -> Self {
|
||||
PostedMessage(PostedMessageData::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for PostedMessage {
|
||||
fn clone(&self) -> Self {
|
||||
PostedMessage(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, BorshSerialize, BorshDeserialize, Clone)]
|
||||
pub struct PostedMessage {
|
||||
pub struct PostedMessageData {
|
||||
/// Header of the posted VAA
|
||||
pub vaa_version: u8,
|
||||
|
||||
|
|
Loading…
Reference in New Issue