From f4aced7cff9149ce6ccf9edfb0ee02167b22cb19 Mon Sep 17 00:00:00 2001 From: Tyler Ruppert <{ID}+{username}@users.noreply.github.com> Date: Fri, 1 Sep 2023 14:27:28 -0600 Subject: [PATCH 1/2] Fix signing of gravity batches This was put off because I didn't fully understand how Compass hashed batches before comparing signatures. Now, I've come back to this and fixed it to sign exactly like Compass expects. The test used here is using a real example, to ensure it works exactly as expected. --- x/gravity/types/batch.go | 14 +++--- x/gravity/types/batch_test.go | 94 ++++++++++++++++------------------- 2 files changed, 50 insertions(+), 58 deletions(-) diff --git a/x/gravity/types/batch.go b/x/gravity/types/batch.go index b32f58f0..ab97563e 100644 --- a/x/gravity/types/batch.go +++ b/x/gravity/types/batch.go @@ -238,12 +238,14 @@ func (i InternalOutgoingTxBatch) GetCheckpoint(turnstoneID string) ([]byte, erro // deadline {Type: whoops.Must(abi.NewType("uint256", "", nil))}, // methodName - {Type: whoops.Must(abi.NewType("bytes32", "", nil))}, + //{Type: whoops.Must(abi.NewType("bytes32", "", nil))}, } var turnstoneBytes32 [32]byte copy(turnstoneBytes32[:], turnstoneID) + method := abi.NewMethod("batch_call", "batch_call", abi.Function, "", false, false, arguments, abi.Arguments{}) + methodNameBytes := []uint8("batch_call") var batchMethodName [32]uint8 copy(batchMethodName[:], methodNameBytes) @@ -257,7 +259,7 @@ func (i InternalOutgoingTxBatch) GetCheckpoint(turnstoneID string) ([]byte, erro } args := struct { - Receiver []gethcommon.Address `json:"receiver"` + Receiver []gethcommon.Address Amount []*big.Int }{ Receiver: txDestinations, @@ -270,7 +272,6 @@ func (i InternalOutgoingTxBatch) GetCheckpoint(turnstoneID string) ([]byte, erro big.NewInt(int64(i.BatchNonce)), turnstoneBytes32, big.NewInt(int64(i.BatchTimeout)), - batchMethodName, ) // this should never happen outside of test since any case that could crash on encoding // should be filtered above. @@ -278,8 +279,7 @@ func (i InternalOutgoingTxBatch) GetCheckpoint(turnstoneID string) ([]byte, erro return nil, sdkerrors.Wrap(err, fmt.Sprintf("Error packing checkpoint! %s/n", err)) } - // we hash the resulting encoded bytes discarding the first 4 bytes these 4 bytes are the constant - // method name 'checkpoint'. If you were to replace the checkpoint constant in this code you would - // then need to adjust how many bytes you truncate off the front to get the output of abi.encode() - return crypto.Keccak256Hash(abiEncodedBatch[4:]).Bytes(), nil + abiEncodedBatch = append(method.ID[:], abiEncodedBatch...) + + return crypto.Keccak256(abiEncodedBatch), nil } diff --git a/x/gravity/types/batch_test.go b/x/gravity/types/batch_test.go index 62462ed1..b41a2d9e 100644 --- a/x/gravity/types/batch_test.go +++ b/x/gravity/types/batch_test.go @@ -1,53 +1,45 @@ package types -//// TODO: making these test work (with a new hash from compass) will prove useful -// -//import ( -// "encoding/hex" -// "testing" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -// "github.com/stretchr/testify/assert" -// "github.com/stretchr/testify/require" -//) -// -//// TODO : Come back and fix this test once I have checkpointing done -//// TestOutgoingTxBatchCheckpointGold1 tests an outgoing tx batch checkpoint -//// nolint: exhaustruct -//func TestOutgoingTxBatchCheckpoint(t *testing.T) { -// senderAddr, err := sdk.AccAddressFromHexUnsafe("527FBEE652609AB150F0AEE9D61A2F76CFC4A73E") -// require.NoError(t, err) -// var ( -// erc20Addr = "0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e" -// ) -// erc20Address, err := NewEthAddress(erc20Addr) -// require.NoError(t, err) -// destAddress, err := NewEthAddress("0x9FC9C2DfBA3b6cF204C37a5F690619772b926e39") -// require.NoError(t, err) -// src := OutgoingTxBatch{ -// BatchNonce: 1, -// BatchTimeout: 2111, -// Transactions: []OutgoingTransferTx{ -// { -// Id: 0x1, -// Sender: senderAddr.String(), -// DestAddress: destAddress.GetAddress().Hex(), -// Erc20Token: ERC20Token{ -// Amount: sdk.NewInt(0x1), -// Contract: erc20Address.GetAddress().Hex(), -// ChainReferenceId: "test-chain", -// }, -// }, -// }, -// TokenContract: erc20Address.GetAddress().Hex(), -// } -// -// ourHash := src.GetCheckpoint("foo") -// -// // hash from bridge contract -// goldHash := "0xa3a7ee0a363b8ad2514e7ee8f110d7449c0d88f3b0913c28c1751e6e0079a9b2"[2:] -// // The function used to compute the "gold hash" above is in /solidity/test/updateValsetAndSubmitBatch.ts -// // Be aware that every time that you run the above .ts file, it will use a different tokenContractAddress and thus compute -// // a different hash. -// assert.Equal(t, goldHash, hex.EncodeToString(ourHash)) -//} +import ( + "encoding/hex" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestOutgoingTxBatchCheckpointGold1 tests an outgoing tx batch checkpoint +// nolint: exhaustruct +func TestOutgoingTxBatchCheckpoint(t *testing.T) { + config := sdk.GetConfig() + config.SetBech32PrefixForAccount("paloma", "pub") + config.SetBech32PrefixForValidator("palomavaloper", "valoperpub") + + src := OutgoingTxBatch{ + BatchNonce: 10, + BatchTimeout: 1693598120, + Transactions: []OutgoingTransferTx{ + { + Id: 4, + Sender: "paloma1rxdhpk85wju9z9kqf6m0wq0rkty7gpjhey4wd2", + DestAddress: "0xE3cD54d29CBf35648EDcf53D6a344bd4B88DA059", + Erc20Token: ERC20Token{ + Amount: sdk.NewInt(10000000), + Contract: "0x28E9e9bfedEd29747FCc33ccA25b4B75f05E434B", + ChainReferenceId: "bnb-main", + }, + }, + }, + TokenContract: "0x28E9e9bfedEd29747FCc33ccA25b4B75f05E434B", + } + + actualHash, err := src.GetCheckpoint("5270") + require.NoError(t, err) + + actualHashHex := hex.EncodeToString(actualHash) + // hash from bridge contract + expectedHash := "0xcab79faf47d1556c5b273afb063ab1889461e35bc6403e410af240cefdb0fd8e"[2:] + + assert.Equal(t, expectedHash, actualHashHex) +} From ee8bfa844b4196f9a29553d00d2b217b80113a35 Mon Sep 17 00:00:00 2001 From: Tyler Ruppert <{ID}+{username}@users.noreply.github.com> Date: Fri, 1 Sep 2023 14:30:42 -0600 Subject: [PATCH 2/2] remove commented out code --- x/gravity/types/batch.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/gravity/types/batch.go b/x/gravity/types/batch.go index ab97563e..304d9d26 100644 --- a/x/gravity/types/batch.go +++ b/x/gravity/types/batch.go @@ -237,8 +237,6 @@ func (i InternalOutgoingTxBatch) GetCheckpoint(turnstoneID string) ([]byte, erro {Type: whoops.Must(abi.NewType("bytes32", "", nil))}, // deadline {Type: whoops.Must(abi.NewType("uint256", "", nil))}, - // methodName - //{Type: whoops.Must(abi.NewType("bytes32", "", nil))}, } var turnstoneBytes32 [32]byte