Skip to content

Commit

Permalink
feat(nexus)!: add source tx hash to message struct (axelarnetwork#1907)
Browse files Browse the repository at this point in the history
* feat(nexus)!: add source tx hash to message struct
  • Loading branch information
cjcobb23 authored Mar 29, 2023
1 parent 89a87d8 commit 7b87d40
Show file tree
Hide file tree
Showing 25 changed files with 292 additions and 148 deletions.
2 changes: 1 addition & 1 deletion client/docs/static/openapi/index.html

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions client/docs/static/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10626,6 +10626,12 @@ paths:
NOTE: The amount field is an Int which implements the custom method

signatures required by gogoproto.
source_tx_id:
type: string
format: byte
source_tx_index:
type: string
format: uint64
default:
description: An unexpected error response
content:
Expand Down Expand Up @@ -39460,6 +39466,12 @@ components:

NOTE: The amount field is an Int which implements the custom method
signatures required by gogoproto.
source_tx_id:
type: string
format: byte
source_tx_index:
type: string
format: uint64
axelar.nexus.exported.v1beta1.GeneralMessage.Status:
type: string
enum:
Expand Down Expand Up @@ -39866,6 +39878,12 @@ components:
NOTE: The amount field is an Int which implements the custom method

signatures required by gogoproto.
source_tx_id:
type: string
format: byte
source_tx_index:
type: string
format: uint64
axelar.nexus.v1beta1.RecipientAddressResponse:
type: object
properties:
Expand Down
18 changes: 18 additions & 0 deletions client/docs/static/swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11667,6 +11667,12 @@ paths:
custom method

signatures required by gogoproto.
source_tx_id:
type: string
format: byte
source_tx_index:
type: string
format: uint64
default:
description: An unexpected error response
schema:
Expand Down Expand Up @@ -42791,6 +42797,12 @@ definitions:

NOTE: The amount field is an Int which implements the custom method
signatures required by gogoproto.
source_tx_id:
type: string
format: byte
source_tx_index:
type: string
format: uint64
axelar.nexus.exported.v1beta1.GeneralMessage.Status:
type: string
enum:
Expand Down Expand Up @@ -43200,6 +43212,12 @@ definitions:
method

signatures required by gogoproto.
source_tx_id:
type: string
format: byte
source_tx_index:
type: string
format: uint64
axelar.nexus.v1beta1.RecipientAddressResponse:
type: object
properties:
Expand Down
2 changes: 1 addition & 1 deletion client/docs/statik/statik.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docs/proto/proto-docs.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.19
require (
github.com/armon/go-metrics v0.4.1
github.com/axelarnetwork/tm-events v0.0.0-20221019195821-9a3f03bc6ca6
github.com/axelarnetwork/utils v0.0.0-20221213003031-66c703710da3
github.com/axelarnetwork/utils v0.0.0-20230323010430-23cd3a751b04
github.com/btcsuite/btcd v0.22.1
github.com/btcsuite/btcd/btcec/v2 v2.2.0
github.com/cosmos/cosmos-sdk v0.45.11
Expand Down
2 changes: 2 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions proto/axelar/nexus/exported/v1beta1/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,6 @@ message GeneralMessage {
bytes payload_hash = 4;
Status status = 5;
cosmos.base.v1beta1.Coin asset = 6;
bytes source_tx_id = 7 [ (gogoproto.customname) = "SourceTxID" ];
uint64 source_tx_index = 8;
}
3 changes: 2 additions & 1 deletion x/axelarnet/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ func (s msgServer) CallContract(c context.Context, req *types.CallContractReques
// axelar gateway expects keccak256 hashes for payloads
payloadHash := crypto.Keccak256(req.Payload)

msg := nexus.NewGeneralMessage(s.nexus.GenerateMessageID(ctx), sender, recipient, payloadHash, nexus.Sent, nil)
msgID, txID, nonce := s.nexus.GenerateMessageID(ctx)
msg := nexus.NewGeneralMessage(msgID, sender, recipient, payloadHash, nexus.Sent, txID, nonce, nil)
if err := s.nexus.SetNewMessage(ctx, msg); err != nil {
return nil, sdkerrors.Wrap(err, "failed to add general message")
}
Expand Down
4 changes: 2 additions & 2 deletions x/axelarnet/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1245,10 +1245,10 @@ func TestHandleCallContract(t *testing.T) {
ibcK := keeper.NewIBCKeeper(k, &mock.IBCTransferKeeperMock{}, &mock.ChannelKeeperMock{})
server = keeper.NewMsgServerImpl(k, nexusK, &mock.BankKeeperMock{}, &mock.AccountKeeperMock{}, ibcK)
count := 0
nexusK.GenerateMessageIDFunc = func(ctx sdk.Context) string {
nexusK.GenerateMessageIDFunc = func(ctx sdk.Context) (string, []byte, uint64) {
count++
hash := sha256.Sum256(ctx.TxBytes())
return fmt.Sprintf("%s-%x", hex.EncodeToString(hash[:]), count)
return fmt.Sprintf("%s-%x", hex.EncodeToString(hash[:]), count), hash[:], uint64(count)
}
})

Expand Down
8 changes: 6 additions & 2 deletions x/axelarnet/message_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func validateMessage(ctx sdk.Context, ibcK keeper.IBCKeeper, n types.Nexus, b ty
}

func handleMessage(ctx sdk.Context, n types.Nexus, b types.BankKeeper, sourceAddress nexus.CrossChainAddress, msg Message, token keeper.Coin) error {
id := n.GenerateMessageID(ctx)
id, txID, nonce := n.GenerateMessageID(ctx)

// ignore token for call contract
_, err := deductFee(ctx, b, msg.Fee, token, id)
Expand All @@ -233,6 +233,8 @@ func handleMessage(ctx sdk.Context, n types.Nexus, b types.BankKeeper, sourceAdd
recipient,
crypto.Keccak256Hash(msg.Payload).Bytes(),
nexus.Approved,
txID,
nonce,
nil,
)

Expand All @@ -250,7 +252,7 @@ func handleMessage(ctx sdk.Context, n types.Nexus, b types.BankKeeper, sourceAdd
}

func handleMessageWithToken(ctx sdk.Context, n types.Nexus, b types.BankKeeper, sourceAddress nexus.CrossChainAddress, msg Message, token keeper.Coin) error {
id := n.GenerateMessageID(ctx)
id, txID, nonce := n.GenerateMessageID(ctx)

token, err := deductFee(ctx, b, msg.Fee, token, id)
if err != nil {
Expand All @@ -269,6 +271,8 @@ func handleMessageWithToken(ctx sdk.Context, n types.Nexus, b types.BankKeeper,
recipient,
crypto.Keccak256Hash(msg.Payload).Bytes(),
nexus.Approved,
txID,
nonce,
&token.Coin,
)

Expand Down
12 changes: 6 additions & 6 deletions x/axelarnet/message_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ func TestHandleMessage(t *testing.T) {
return fmt.Errorf("module not found")
}
},
GenerateMessageIDFunc: func(ctx sdk.Context) string {
GenerateMessageIDFunc: func(ctx sdk.Context) (string, []byte, uint64) {
hash := sha256.Sum256(ctx.TxBytes())
return fmt.Sprintf("%s-%d", hex.EncodeToString(hash[:]), 0)
return fmt.Sprintf("%s-%d", hex.EncodeToString(hash[:]), 0), hash[:], 0
},
RateLimitTransferFunc: func(ctx sdk.Context, chain nexus.ChainName, asset sdk.Coin, direction nexus.TransferDirection) error {
return nil
Expand Down Expand Up @@ -487,9 +487,9 @@ func TestHandleMessageWithToken(t *testing.T) {
GetChainByNativeAssetFunc: func(ctx sdk.Context, asset string) (nexus.Chain, bool) {
return srcChain, true
},
GenerateMessageIDFunc: func(ctx sdk.Context) string {
GenerateMessageIDFunc: func(ctx sdk.Context) (string, []byte, uint64) {
hash := sha256.Sum256(ctx.TxBytes())
return fmt.Sprintf("%s-%d", hex.EncodeToString(hash[:]), 0)
return fmt.Sprintf("%s-%d", hex.EncodeToString(hash[:]), 0), hash[:], 0
},
RateLimitTransferFunc: func(ctx sdk.Context, chain nexus.ChainName, asset sdk.Coin, direction nexus.TransferDirection) error {
return nil
Expand Down Expand Up @@ -702,9 +702,9 @@ func TestHandleSendToken(t *testing.T) {
EnqueueTransferFunc: func(ctx sdk.Context, senderChain nexus.Chain, recipient nexus.CrossChainAddress, asset sdk.Coin) (nexus.TransferID, error) {
return nexustestutils.RandomTransferID(), nil
},
GenerateMessageIDFunc: func(ctx sdk.Context) string {
GenerateMessageIDFunc: func(ctx sdk.Context) (string, []byte, uint64) {
hash := sha256.Sum256(ctx.TxBytes())
return fmt.Sprintf("%s-%d", hex.EncodeToString(hash[:]), 0)
return fmt.Sprintf("%s-%d", hex.EncodeToString(hash[:]), 0), hash[:], 0
},
RateLimitTransferFunc: func(ctx sdk.Context, chain nexus.ChainName, asset sdk.Coin, direction nexus.TransferDirection) error {
return nil
Expand Down
2 changes: 1 addition & 1 deletion x/axelarnet/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ type Nexus interface {
SetMessageSent(ctx sdk.Context, id string) error
SetMessageExecuted(ctx sdk.Context, id string) error
SetMessageFailed(ctx sdk.Context, id string) error
GenerateMessageID(ctx sdk.Context) string
GenerateMessageID(ctx sdk.Context) (string, []byte, uint64)
ValidateAddress(ctx sdk.Context, address nexus.CrossChainAddress) error
}

Expand Down
6 changes: 3 additions & 3 deletions x/axelarnet/types/mock/expected_keepers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions x/evm/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ func setMessageToNexus(ctx sdk.Context, n types.Nexus, event types.Event, asset
recipient,
e.ContractCall.PayloadHash.Bytes(),
nexus.Approved,
event.TxID.Bytes(),
event.Index,
nil,
)

Expand All @@ -244,6 +246,8 @@ func setMessageToNexus(ctx sdk.Context, n types.Nexus, event types.Event, asset
recipient,
e.ContractCallWithToken.PayloadHash.Bytes(),
nexus.Approved,
event.TxID.Bytes(),
event.Index,
asset,
)
default:
Expand Down Expand Up @@ -602,9 +606,7 @@ func validateMessage(ctx sdk.Context, ck types.ChainKeeper, n types.Nexus, m typ

func handleMessage(ctx sdk.Context, ck types.ChainKeeper, chainID sdk.Int, keyID multisig.KeyID, msg nexus.GeneralMessage) {

dummyTxID := common.BytesToHash(make([]byte, common.HashLength))

cmd := types.NewApproveContractCallCommandGeneric(chainID, keyID, common.HexToAddress(msg.GetDestinationAddress()), common.BytesToHash(msg.PayloadHash), dummyTxID, msg.GetSourceChain(), msg.GetSourceAddress(), 0, msg.ID)
cmd := types.NewApproveContractCallCommandGeneric(chainID, keyID, common.HexToAddress(msg.GetDestinationAddress()), common.BytesToHash(msg.PayloadHash), common.BytesToHash(msg.SourceTxID), msg.GetSourceChain(), msg.GetSourceAddress(), msg.SourceTxIndex, msg.ID)
funcs.MustNoErr(ck.EnqueueCommand(ctx, cmd))

events.Emit(ctx, &types.ContractCallApproved{
Expand All @@ -625,10 +627,9 @@ func handleMessage(ctx sdk.Context, ck types.ChainKeeper, chainID sdk.Int, keyID
}

func handleMessageWithToken(ctx sdk.Context, ck types.ChainKeeper, chainID sdk.Int, keyID multisig.KeyID, msg nexus.GeneralMessage) {
dummyTxID := common.BytesToHash(make([]byte, common.HashLength))
token := ck.GetERC20TokenByAsset(ctx, msg.Asset.GetDenom())

cmd := types.NewApproveContractCallWithMintGeneric(chainID, keyID, dummyTxID, msg, token.GetDetails().Symbol)
cmd := types.NewApproveContractCallWithMintGeneric(chainID, keyID, common.BytesToHash(msg.SourceTxID), msg.SourceTxIndex, msg, token.GetDetails().Symbol)
funcs.MustNoErr(ck.EnqueueCommand(ctx, cmd))

events.Emit(ctx, &types.ContractCallWithMintApproved{
Expand Down
4 changes: 2 additions & 2 deletions x/evm/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestHandleGeneralMessage(t *testing.T) {
asset := rand.Coin()

givenMessage := Given("a message", func() {
msg = nexus.NewGeneralMessage(evmTestUtils.RandomHash().Hex(), sender, receiver, evmCrypto.Keccak256(payload), nexus.Approved, nil)
msg = nexus.NewGeneralMessage(evmTestUtils.RandomHash().Hex(), sender, receiver, evmCrypto.Keccak256(payload), nexus.Approved, evmTestUtils.RandomHash().Bytes()[:], uint64(rand.I64Between(0, 10000)), nil)

ctx, _, n, multisigKeeper, _, destinationCk = setup()
n.SetMessageFailedFunc = func(ctx sdk.Context, id string) error {
Expand Down Expand Up @@ -280,7 +280,7 @@ func TestHandleGeneralMessages(t *testing.T) {
destChain.Module = types.ModuleName
sender := nexus.CrossChainAddress{Chain: srcChain, Address: evmTestUtils.RandomAddress().Hex()}
receiver := nexus.CrossChainAddress{Chain: destChain, Address: evmTestUtils.RandomAddress().Hex()}
msg := nexus.NewGeneralMessage(evmTestUtils.RandomHash().Hex(), sender, receiver, evmTestUtils.RandomHash().Bytes(), nexus.Sent, nil)
msg := nexus.NewGeneralMessage(evmTestUtils.RandomHash().Hex(), sender, receiver, evmTestUtils.RandomHash().Bytes(), nexus.Sent, evmTestUtils.RandomHash().Bytes()[:], uint64(rand.I64Between(0, 10000)), nil)
msgs = append(msgs, msg)
}
return msgs
Expand Down
3 changes: 2 additions & 1 deletion x/evm/types/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ func NewApproveContractCallWithMintGeneric(
chainID sdk.Int,
keyID multisig.KeyID,
sourceTxID common.Hash,
sourceEventIndex uint64,
message nexus.GeneralMessage,
symbol string,
) Command {
Expand All @@ -198,7 +199,7 @@ func NewApproveContractCallWithMintGeneric(
return Command{
ID: commandID,
Type: COMMAND_TYPE_APPROVE_CONTRACT_CALL_WITH_MINT,
Params: createApproveContractCallWithMintParamsGeneric(contractAddress, payloadHash, sourceTxID, message.Sender, 0, message.Asset.Amount.BigInt(), symbol),
Params: createApproveContractCallWithMintParamsGeneric(contractAddress, payloadHash, sourceTxID, message.Sender, sourceEventIndex, message.Asset.Amount.BigInt(), symbol),
KeyID: keyID,
MaxGasCost: approveContractCallWithMintMaxGasCost,
}
Expand Down
15 changes: 7 additions & 8 deletions x/evm/types/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,25 @@ func TestNewApproveContractCallCommandFromGeneralMessage(t *testing.T) {
chainID := sdk.NewInt(1)
keyID := multisigTestutils.KeyID()
payload := rand.BytesBetween(64, 1000)
txHash := common.BytesToHash(rand.Bytes(32))
txID := common.BytesToHash(rand.Bytes(32))
payloadHash := crypto.Keccak256(payload)
eventIndex := 0
eventIndex := uint64(rand.I64Between(33, 256))
srcChain := nexus.Chain{Name: nexus.ChainName(rand.StrBetween(16, 32)), Module: types.ModuleName}
destChain := nexus.Chain{Name: nexus.ChainName(rand.StrBetween(8, 64)), Module: types.ModuleName}
sender := nexus.CrossChainAddress{Chain: srcChain, Address: rand.AccAddr().String()}
receiver := nexus.CrossChainAddress{Chain: destChain, Address: testutils.RandomAddress().Hex()}
msg := nexus.NewGeneralMessage(txHash.Hex(), sender, receiver, payloadHash, nexus.Approved, nil)
msg := nexus.NewGeneralMessage(txID.Hex(), sender, receiver, payloadHash, nexus.Approved, txID[:], eventIndex, nil)

actual := types.NewApproveContractCallCommandGeneric(chainID, keyID,
common.HexToAddress(msg.GetDestinationAddress()), common.BytesToHash(msg.PayloadHash), common.BytesToHash(make([]byte, common.HashLength)), msg.GetSourceChain(), msg.GetSourceAddress(), uint64(eventIndex), msg.ID)
common.HexToAddress(msg.GetDestinationAddress()), common.BytesToHash(msg.PayloadHash), common.BytesToHash(msg.SourceTxID), msg.GetSourceChain(), msg.GetSourceAddress(), msg.SourceTxIndex, msg.ID)
// abi encoding pads strings to lengths divisible by 32
sourceChainPadded := []byte(msg.GetSourceChain().String())
for len(sourceChainPadded)%32 != 0 {
sourceChainPadded = append(sourceChainPadded, 0)
}

dummyTxId := common.BytesToHash(make([]byte, common.HashLength))
expected := strings.ToLower(fmt.Sprintf("00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000%s%s%s000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%x%s00000000000000000000000000000000000000000000000000000000000000%x%s00000000000000000000000000000000000000000000000000000000000000",
msg.GetDestinationAddress()[2:], hex.EncodeToString(payloadHash), dummyTxId.Hex()[2:], len(msg.GetSourceChain()), hex.EncodeToString([]byte(sourceChainPadded)), len(msg.GetSourceAddress()), hex.EncodeToString([]byte(msg.GetSourceAddress()))))
expected := strings.ToLower(fmt.Sprintf("00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000%s%s%s00000000000000000000000000000000000000000000000000000000000000%x00000000000000000000000000000000000000000000000000000000000000%x%s00000000000000000000000000000000000000000000000000000000000000%x%s00000000000000000000000000000000000000000000000000000000000000",
msg.GetDestinationAddress()[2:], hex.EncodeToString(payloadHash), common.BytesToHash(msg.SourceTxID).Hex()[2:], msg.SourceTxIndex, len(msg.GetSourceChain()), hex.EncodeToString([]byte(sourceChainPadded)), len(msg.GetSourceAddress()), hex.EncodeToString([]byte(msg.GetSourceAddress()))))

assert.Equal(t, expected, hex.EncodeToString(actual.Params))

Expand All @@ -58,7 +57,7 @@ func TestNewApproveContractCallCommandFromGeneralMessage(t *testing.T) {
assert.Equal(t, msg.GetSourceAddress(), actualSourceAddress)
assert.Equal(t, msg.GetDestinationAddress(), actualContractAddress.Hex())
assert.Equal(t, common.BytesToHash(payloadHash), actualPayloadHash)
assert.Equal(t, dummyTxId, actualSourceTxID)
assert.Equal(t, common.BytesToHash(msg.SourceTxID), actualSourceTxID)
assert.Equal(t, uint64(eventIndex), actualSourceEventIndex.Uint64())

}
Expand Down
2 changes: 2 additions & 0 deletions x/nexus/exported/testutils/rand.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ func RandomMessage(statuses ...exported.GeneralMessage_Status) exported.GeneralM
RandomCrossChainAddress(),
rand.Bytes(32),
rand.Of(statuses...),
rand.Bytes(32),
uint64(rand.I64Between(0, 10000)),
&coin,
)
}
Loading

0 comments on commit 7b87d40

Please sign in to comment.