Skip to content
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
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

## v29.0.4

### Fixes
* [3711](https://github.com/zeta-chain/node/pull/3711) - fix TON call_data parsing

## v29.0.3

### Fixes
Expand Down
86 changes: 74 additions & 12 deletions pkg/contracts/ton/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,42 @@ func TestParsing(t *testing.T) {

assert.Equal(t, longCallData, depositAndCall2.CallData)
})
})

t.Run("Deposit and call ABI", func(t *testing.T) {
// ARRANGE
// Given a tx
tx, fx := getFixtureTX(t, "07-deposit-and-call-abi")

// Given a gateway contract
gw := NewGateway(ton.MustParseAccountID(fx.Account))

// ACT
parsedTX, err := gw.ParseTransaction(tx)

// ASSERT
require.NoError(t, err)

// Check tx props
assert.Equal(t, int(OpDepositAndCall), int(parsedTX.Operation))

// Check deposit and call
depositAndCall, err := parsedTX.DepositAndCall()
assert.NoError(t, err)

const (
expectedSender = "0:74a36900b786949a60c95ee20a56e583f908f2e957f3ffcb1e9770cc9edd408d"
zevmRecipient = "0x13ad4f89050E83e8F485BB8349b40d3b89833790"
expectedDeposit = 94_800_000 // 0.1 TON - tx fee

// cast abi-encode "fn(string)" "ZETA ON TON YEAH"
callData = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000105a455441204f4e20544f4e205945414800000000000000000000000000000000"
)

assert.Equal(t, expectedSender, depositAndCall.Sender.ToRaw())
assert.Equal(t, expectedDeposit, int(depositAndCall.Amount.Uint64()))
assert.Equal(t, zevmRecipient, depositAndCall.Recipient.Hex())
assert.Equal(t, callData, "0x"+hex.EncodeToString(depositAndCall.CallData))
})

t.Run("Withdrawal", func(t *testing.T) {
Expand Down Expand Up @@ -363,23 +398,50 @@ func TestFixtures(t *testing.T) {
}

func TestSnakeData(t *testing.T) {
for _, tt := range []string{
"Hello world",
"123",
strings.Repeat(`ZetaChain `, 300),
string(readFixtureFile(t, "testdata/long-call-data.txt")),
h2b := func(raw string) []byte {
b, err := hex.DecodeString(strings.TrimPrefix(raw, "0x"))
require.NoError(t, err)

return b
}

for _, tt := range []struct {
name string
data []byte
}{
{name: "simple", data: []byte("123")},
{name: "hello world", data: []byte("Hello world")},
{name: "zeta repeated 10 times", data: []byte(strings.Trim(strings.Repeat("ZetaChain ", 10), " "))},
{name: "zeta repeated 50 times", data: []byte(strings.Trim(strings.Repeat("ZetaChain ", 50), " "))},
{name: "long call data text", data: readFixtureFile(t, "testdata/long-call-data.txt")},
{
// cast abi-encode "fn(string)" "ping-pong"
name: "abi call data 1",
data: h2b("0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000970696e672d706f6e670000000000000000000000000000000000000000000000"),
},
{
// cast abi-encode "swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline)" 123 456 "[0x0E0E08C73CD5019d6CAc98311Fa18edf98b70428,0x0E0E08C73CD5019d6CAc98311Fa18edf98b70428]" 0x0E0E08C73CD5019d6CAc98311Fa18edf98b70428 999
name: "abi call data 2",
data: h2b("0x000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000001c800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000e0e08c73cd5019d6cac98311fa18edf98b7042800000000000000000000000000000000000000000000000000000000000003e700000000000000000000000000000000000000000000000000000000000000020000000000000000000000000e0e08c73cd5019d6cac98311fa18edf98b704280000000000000000000000000e0e08c73cd5019d6cac98311fa18edf98b70428"),
},
} {
a := []byte(tt)
t.Run(tt.name, func(t *testing.T) {
a := tt.data

cell, err := MarshalSnakeCell(a)
require.NoError(t, err)
cell, err := MarshalSnakeCell(a)
require.NoError(t, err)

b, err := UnmarshalSnakeCell(cell)
require.NoError(t, err)
b, err := UnmarshalSnakeCell(cell)
require.NoError(t, err)

t.Logf(string(b))
if len(a) != len(b) {
t.Logf("Lengths are not equal. Want %d, got %d.\nA:\n```%s```\n\nB:\n```%s```", len(a), len(b), a, b)
t.Logf("Last 8 bytes: A: %v; B: %v", a[len(a)-8:], b[len(b)-8:])
t.FailNow()
}

assert.Equal(t, a, b, tt)
require.Equal(t, a, b)
})
}
}

Expand Down
8 changes: 8 additions & 0 deletions pkg/contracts/ton/testdata/07-deposit-and-call-abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"account": "0:7a4d41496726aadb227cf4d313c95912f1fe6cc742c18ebde306ff59881d8816",
"boc": "b5ee9c7201020b010002610003b577a4d41496726aadb227cf4d313c95912f1fe6cc742c18ebde306ff59881d881600001d6a51f8d1c369b56b434771bae9ffdb2fb89e92636ae70d553bd402ae6c4fd1d295190dab9600001d6a488dee4167d3098c0003467eeedc80102030201e004050082729b5c859fe411dadead92b195050b191945d0caf6b345a83dfd6d47d0914492da083ff08d3226242e92e2b7ed236ab69f78e2cdf3795d1545c57f8c766a2d82480217046389017d784018670b8411090a01f16800e946d2016f0d2934c192bdc414adcb07f211e5d2afe7ff963d2ee1993dba811b001e93505259c9aab6c89f3d34c4f25644bc7f9b31d0b063af78c1bfd6620762059017d78400060f33b400003ad4a3f1a384cfa6131800000033000000000000000009d6a7c4828741f47a42ddc1a4da069dc4c19bc840060101df0700c0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000105a455441204f4e20544f4e205945414800000000000000000000000000000000015de003d26a0a4b393556d913e7a6989e4ac8978ff3663a160c75ef1837facc40ec40b000003ad4a3f1a388cfa61318c0080010405a6888034f5880009e44824c0f42400000000000000000da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006fc9838d604c1c6b00000000000002000000000003ef0faad6f5e8c20c1fa610ba5f37243e73c948cb3a884e95dbbb64fc5498411c40900d8c",
"description": "Deposit 0.1 TON and provide abi-encoded payload https://testnet.tonviewer.com/transaction/7e6c401f5ec817df8bd9f4d101f72ccd0c196d19d63c0ff9dbb8f807510be932",
"hash": "7e6c401f5ec817df8bd9f4d101f72ccd0c196d19d63c0ff9dbb8f807510be932",
"logicalTime": 32342479000003,
"test": true
}
15 changes: 6 additions & 9 deletions pkg/contracts/ton/tlb.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package ton

import (
"bytes"

"cosmossdk.io/math"
eth "github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
Expand Down Expand Up @@ -34,22 +32,21 @@ func UnmarshalSnakeCell(cell *boc.Cell) ([]byte, error) {
return nil, err
}

cd := boc.BitString(sd)
bitString := boc.BitString(sd)
n := bitString.BitsAvailableForRead() / 8

// TLB operates with bits, so we (might) need to trim some "leftovers" (null chars)
return bytes.Trim(cd.Buffer(), "\x00"), nil
return bitString.ReadBytes(n)
}

// MarshalSnakeCell encodes []byte to TLB using snake-cell encoding
func MarshalSnakeCell(data []byte) (*boc.Cell, error) {
b := boc.NewCell()
bs := boc.NewBitString(len(data) * 8)

wrapped := tlb.Bytes(data)
if err := wrapped.MarshalTLB(b, &tlb.Encoder{}); err != nil {
if err := bs.WriteBytes(data); err != nil {
return nil, err
}

return b, nil
return MarshalTLB(tlb.SnakeData(bs))
}

// UnmarshalEVMAddress decodes eth.Address from BOC
Expand Down