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: use the ZEVM address pulled from memo as Receiver in MsgVoteInbound #3267

Merged
merged 5 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions e2e/e2etests/test_solana_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestSolanaDeposit(r *runner.E2ERunner, args []string) {
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, sig.String(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "solana_deposit")
utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined)
require.Equal(r, cctx.GetCurrentOutboundParam().Receiver, r.EVMAddress().Hex())

// get ERC20 SOL balance after deposit
balanceAfter, err := r.SOLZRC20.BalanceOf(&bind.CallOpts{}, r.EVMAddress())
Expand Down
1 change: 1 addition & 0 deletions e2e/e2etests/test_solana_deposit_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func TestSolanaDepositAndCall(r *runner.E2ERunner, args []string) {
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, sig.String(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "solana_deposit_and_call")
utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined)
require.Equal(r, cctx.GetCurrentOutboundParam().Receiver, contractAddr.Hex())

// check if example contract has been called, bar value should be set to amount
utils.MustHaveCalledExampleContractWithMsg(r, contract, depositAmount, data)
Expand Down
1 change: 1 addition & 0 deletions e2e/e2etests/test_spl_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func TestSPLDeposit(r *runner.E2ERunner, args []string) {
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, sig.String(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "solana_deposit_spl")
utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined)
require.Equal(r, cctx.GetCurrentOutboundParam().Receiver, r.EVMAddress().Hex())

// verify balances are updated
pdaBalanceAfter, err := r.SolanaClient.GetTokenAccountBalance(r.Ctx, pdaAta, rpc.CommitmentFinalized)
Expand Down
1 change: 1 addition & 0 deletions e2e/e2etests/test_spl_deposit_and_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func TestSPLDepositAndCall(r *runner.E2ERunner, args []string) {
cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, sig.String(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "solana_deposit_spl_and_call")
utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined)
require.Equal(r, cctx.GetCurrentOutboundParam().Receiver, contractAddr.Hex())

// check if example contract has been called, bar value should be set to amount
utils.MustHaveCalledExampleContractWithMsg(r, contract, big.NewInt(int64(amount)), data)
Expand Down
20 changes: 17 additions & 3 deletions zetaclient/chains/solana/observer/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
solanarpc "github.com/zeta-chain/node/zetaclient/chains/solana/rpc"
"github.com/zeta-chain/node/zetaclient/compliance"
zctx "github.com/zeta-chain/node/zetaclient/context"
"github.com/zeta-chain/node/zetaclient/logs"
clienttypes "github.com/zeta-chain/node/zetaclient/types"
"github.com/zeta-chain/node/zetaclient/zetacore"
)
Expand Down Expand Up @@ -213,7 +214,7 @@
events = append(events, &clienttypes.InboundEvent{
SenderChainID: ob.Chain().ChainId,
Sender: deposit.Sender,
Receiver: deposit.Sender, // receiver is pulled out from memo
Receiver: "", // receiver will be pulled out from memo later
TxOrigin: deposit.Sender,
Amount: deposit.Amount,
Memo: deposit.Memo,
Expand Down Expand Up @@ -241,7 +242,7 @@
events = append(events, &clienttypes.InboundEvent{
SenderChainID: ob.Chain().ChainId,
Sender: deposit.Sender,
Receiver: deposit.Sender, // receiver is pulled out from memo
Receiver: "", // receiver will be pulled out from memo later

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

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/solana/observer/inbound.go#L245

Added line #L245 was not covered by tests
TxOrigin: deposit.Sender,
Amount: deposit.Amount,
Memo: deposit.Memo,
Expand Down Expand Up @@ -277,11 +278,24 @@
return nil
}

// prepare logger fields
lf := map[string]any{
logs.FieldMethod: "BuildInboundVoteMsgFromEvent",
logs.FieldTx: event.TxHash,
}

// decode event memo bytes to get the receiver
err := event.DecodeMemo()
if err != nil {
ob.Logger().Inbound.Info().Fields(lf).Msgf("invalid memo bytes: %s", hex.EncodeToString(event.Memo))
return nil
}

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

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/solana/observer/inbound.go#L290-L292

Added lines #L290 - L292 were not covered by tests

return zetacore.GetInboundVoteMessage(
event.Sender,
event.SenderChainID,
event.Sender,
event.Sender,
event.Receiver,
ob.ZetacoreClient().Chain().ChainId,
cosmosmath.NewUint(event.Amount),
hex.EncodeToString(event.Memo),
Expand Down
8 changes: 5 additions & 3 deletions zetaclient/chains/solana/observer/inbound_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func Test_FilterInboundEvents(t *testing.T) {
eventExpected := &clienttypes.InboundEvent{
SenderChainID: chain.ChainId,
Sender: sender,
Receiver: sender,
Receiver: "",
TxOrigin: sender,
Amount: 100000000,
Memo: expectedMemo,
Expand Down Expand Up @@ -124,11 +124,13 @@ func Test_BuildInboundVoteMsgFromEvent(t *testing.T) {

t.Run("should return vote msg for valid event", func(t *testing.T) {
sender := sample.SolanaAddress(t)
memo := sample.EthAddress().Bytes()
event := sample.InboundEvent(chain.ChainId, sender, sender, 1280, []byte(memo))
receiver := sample.EthAddress()
event := sample.InboundEvent(chain.ChainId, sender, "", 1280, receiver.Bytes())

msg := ob.BuildInboundVoteMsgFromEvent(event)
require.NotNil(t, msg)
require.Equal(t, sender, msg.Sender)
require.Equal(t, receiver.Hex(), msg.Receiver)
})
t.Run("should return nil msg if sender is restricted", func(t *testing.T) {
sender := sample.SolanaAddress(t)
Expand Down
31 changes: 31 additions & 0 deletions zetaclient/types/event.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package types

import (
"bytes"
"encoding/hex"

"github.com/pkg/errors"

"github.com/zeta-chain/node/pkg/coin"
"github.com/zeta-chain/node/pkg/constant"
"github.com/zeta-chain/node/pkg/crypto"
"github.com/zeta-chain/node/pkg/memo"
)

// InboundEvent represents an inbound event
Expand Down Expand Up @@ -41,3 +49,26 @@
// Asset is the asset of the inbound
Asset string
}

// DecodeMemo decodes the receiver from the memo bytes
func (event *InboundEvent) DecodeMemo() error {
// skip decoding donation tx as it won't go through zetacore
if bytes.Equal(event.Memo, []byte(constant.DonationMessage)) {
return nil
}

Check warning on line 58 in zetaclient/types/event.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/types/event.go#L57-L58

Added lines #L57 - L58 were not covered by tests

// decode receiver address from memo
parsedAddress, _, err := memo.DecodeLegacyMemoHex(hex.EncodeToString(event.Memo))
if err != nil { // unreachable code
return errors.Wrap(err, "invalid memo hex")
}

Check warning on line 64 in zetaclient/types/event.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/types/event.go#L63-L64

Added lines #L63 - L64 were not covered by tests

// ensure the receiver is valid
if crypto.IsEmptyAddress(parsedAddress) {
return errors.New("got empty receiver address from memo")
}

Check warning on line 69 in zetaclient/types/event.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/types/event.go#L68-L69

Added lines #L68 - L69 were not covered by tests

event.Receiver = parsedAddress.Hex()

return nil
}
Loading