Skip to content

Commit ee397b6

Browse files
authored
TON Accessor - CCIP event queries (#105)
* feat: CCIPMessageSent * fix: orphan service cfg * fix: lp query clean up wip * chore: tidy * fix: interface * fix: remove redundant methods * chore: minor refactoring * chore: add placeholder * chore: accessor test wip * chore: send manually * fix: gaslimit * chore: testing ccip send * fix: exit code 5 * chore: ccip send debugging wip * chore: revert helper usage * fix: manual fee token update * chore: add comments * fix: inline msg in binding, query offsets * chore: MsgsBetweenSeqNums case * chore: clean up * chore: remove nil checks * chore: use ccip send helper * fix: ccip send helper * chore: add comment * fix: add lane helper * fix: import * fix: indexer as txparser * chore: missing commit * feat: cursor based filter query * fix: comment * fix: extraArgs as ccip bytes * feat: bind events * fix: query interface * fix: remove unnecessary prevalidation * chore: remove comment * chore: remove comments * fix: nil pointer, add comments * chore: repeated fq config * chore: name * fix: comment
1 parent bdff7c6 commit ee397b6

File tree

19 files changed

+1118
-640
lines changed

19 files changed

+1118
-640
lines changed

cmd/chainlink-ton/default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ in
1818
];
1919

2020
# pin the vendor hash (update using 'pkgs.lib.fakeHash')
21-
vendorHash = "sha256-3ADpTHOZxiQpRi38kgOrEsB4hfz7ap8ss4gZATAtYJU=";
21+
vendorHash = "sha256-tt10/4h7+c9v7XLcQiWgcBUywELVGxMorA4sNnJLJT0=";
2222

2323
# postInstall script to write version and rev to share folder
2424
postInstall = ''

deployment/ccip/cs_test_helpers.go

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package ops
22

33
import (
4+
"encoding/binary"
5+
"encoding/hex"
46
"fmt"
57
"math/big"
68
"testing"
@@ -34,6 +36,42 @@ const ChainSelEVMTest90000001 = 909606746561742123
3436
// TODO: use address.NewNoneAddress() instead?
3537
var TonTokenAddr = address.MustParseRawAddr("0:0000000000000000000000000000000000000000000000000000000000000000")
3638

39+
// DefaultFeeQuoterDestChainConfig returns a default fee quoter config for TON CCIP testing
40+
func DefaultFeeQuoterDestChainConfig(configEnabled bool, destChainSelector ...uint64) feequoter.DestChainConfig {
41+
familySelector, _ := hex.DecodeString(v1_6.TVMFamilySelector)
42+
if len(destChainSelector) > 0 {
43+
destFamily, _ := chainsel.GetSelectorFamily(destChainSelector[0])
44+
switch destFamily {
45+
case chainsel.FamilyEVM:
46+
familySelector, _ = hex.DecodeString(v1_6.EVMFamilySelector)
47+
case chainsel.FamilySolana:
48+
familySelector, _ = hex.DecodeString(v1_6.SVMFamilySelector)
49+
case chainsel.FamilyAptos:
50+
familySelector, _ = hex.DecodeString(v1_6.AptosFamilySelector)
51+
}
52+
}
53+
return feequoter.DestChainConfig{
54+
IsEnabled: configEnabled,
55+
MaxNumberOfTokensPerMsg: 0,
56+
MaxDataBytes: 100,
57+
MaxPerMsgGasLimit: 100,
58+
DestGasOverhead: 0,
59+
DestGasPerPayloadByteBase: 0,
60+
DestGasPerPayloadByteHigh: 0,
61+
DestGasPerPayloadByteThreshold: 0,
62+
DestDataAvailabilityOverheadGas: 0,
63+
DestGasPerDataAvailabilityByte: 0,
64+
ChainFamilySelector: binary.BigEndian.Uint32(familySelector),
65+
EnforceOutOfOrder: false,
66+
DefaultTokenFeeUsdCents: 0,
67+
DefaultTokenDestGasOverhead: 0,
68+
DefaultTxGasLimit: 1,
69+
GasMultiplierWeiPerEth: 0,
70+
GasPriceStalenessThreshold: 0,
71+
NetworkFeeUsdCents: 0,
72+
}
73+
}
74+
3775
func DeployChainContractsToTonCS(t *testing.T, env cldf.Environment, chainSelector uint64) commonchangeset.ConfiguredChangeSet {
3876
tonChain := env.BlockChains.TonChains()[chainSelector]
3977
deployer := tonChain.Wallet
@@ -85,6 +123,7 @@ func AddLaneTONChangesets(env *cldf.Environment, from, to uint64, fromFamily, to
85123
RMNVerificationDisabled: true,
86124
},
87125
Selector: from,
126+
GasPrice: gasPrices[from],
88127
},
89128
}
90129
case chainsel.FamilyTon:
@@ -94,6 +133,14 @@ func AddLaneTONChangesets(env *cldf.Environment, from, to uint64, fromFamily, to
94133
AllowListEnabled: false,
95134
},
96135
Selector: from,
136+
GasPrice: gasPrices[from],
137+
TokenPrices: map[*address.Address]*big.Int{
138+
tonTokenAddr: big.NewInt(99),
139+
},
140+
FeeQuoterDestChainConfig: DefaultFeeQuoterDestChainConfig(true, to),
141+
TokenTransferFeeConfigs: map[uint64]feequoter.UpdateTokenTransferFeeConfig{
142+
// TODO:
143+
},
97144
}
98145
default:
99146
env.Logger.Fatalf("Unsupported source chain family: %v", fromFamily)
@@ -130,41 +177,21 @@ func AddLaneTONChangesets(env *cldf.Environment, from, to uint64, fromFamily, to
130177
NetworkFeeUSDCents: 10,
131178
},
132179
},
133-
OnRampVersion: []byte{1, 6, 0},
180+
OnRampVersion: []byte{1, 6, 1},
134181
}
135182
case chainsel.FamilyTon:
136-
src = config.TonChainDefinition{
183+
dest = config.TonChainDefinition{
137184
ConnectionConfig: v1_6.ConnectionConfig{
138185
RMNVerificationDisabled: true,
139186
AllowListEnabled: false,
140187
},
141-
Selector: from,
188+
Selector: to,
142189
GasPrice: big.NewInt(1e17),
143190
TokenPrices: map[*address.Address]*big.Int{
144191
tonTokenAddr: big.NewInt(99),
145192
},
146-
FeeQuoterDestChainConfig: feequoter.DestChainConfig{ // minimal valid config
147-
IsEnabled: true,
148-
MaxNumberOfTokensPerMsg: 0,
149-
MaxDataBytes: 100,
150-
MaxPerMsgGasLimit: 100,
151-
DestGasOverhead: 0,
152-
DestGasPerPayloadByteBase: 0,
153-
DestGasPerPayloadByteHigh: 0,
154-
DestGasPerPayloadByteThreshold: 0,
155-
DestDataAvailabilityOverheadGas: 0,
156-
DestGasPerDataAvailabilityByte: 0,
157-
DestDataAvailabilityMultiplierBps: 0,
158-
ChainFamilySelector: 0,
159-
EnforceOutOfOrder: false,
160-
DefaultTokenFeeUsdCents: 0,
161-
DefaultTokenDestGasOverhead: 0,
162-
DefaultTxGasLimit: 1,
163-
GasMultiplierWeiPerEth: 0,
164-
GasPriceStalenessThreshold: 0,
165-
NetworkFeeUsdCents: 0,
166-
},
167-
TokenTransferFeeConfigs: map[uint64]feequoter.UpdateTokenTransferFeeConfig{
193+
FeeQuoterDestChainConfig: DefaultFeeQuoterDestChainConfig(true, to),
194+
TokenTransferFeeConfigs: map[uint64]feequoter.UpdateTokenTransferFeeConfig{
168195
// TODO:
169196
},
170197
}
@@ -174,6 +201,7 @@ func AddLaneTONChangesets(env *cldf.Environment, from, to uint64, fromFamily, to
174201
}
175202

176203
laneConfig := config.UpdateTonLanesConfig{
204+
EVMMCMSConfig: &proposalutils.TimelockConfig{},
177205
TonMCMSConfig: &proposalutils.TimelockConfig{
178206
MinDelay: time.Second,
179207
MCMSAction: mcmstypes.TimelockActionSchedule,
@@ -217,13 +245,13 @@ func SendTonRequest(
217245
msg := cfg.Message.(TonSendRequest)
218246
routerAddr := state.TonChains[cfg.SourceChain].Router
219247

220-
// TODO Skipping token amounts setup for now, and in the future for supporting token transfers
221248
ccipSend := router.CCIPSend{
222249
QueryID: msg.QueryID,
223250
DestChainSelector: cfg.DestChain,
224251
Receiver: msg.Receiver,
225252
Data: msg.Data,
226253
FeeToken: msg.FeeToken,
254+
TokenAmounts: nil, // TODO: add token amounts when token transfer enabled
227255
ExtraArgs: msg.ExtraArgs,
228256
}
229257

@@ -235,9 +263,11 @@ func SendTonRequest(
235263
walletMsg := &wallet.Message{
236264
Mode: wallet.PayGasSeparately, // TODO: wallet.IgnoreErrors ?
237265
InternalMessage: &tlb.InternalMessage{
238-
Bounce: true,
239-
DstAddr: &routerAddr,
240-
Body: ccipSendCell,
266+
IHRDisabled: true,
267+
Bounce: false,
268+
DstAddr: &routerAddr,
269+
Amount: tlb.MustFromTON("1.0"), // TODO:
270+
Body: ccipSendCell,
241271
},
242272
}
243273

@@ -247,6 +277,10 @@ func SendTonRequest(
247277
return nil, fmt.Errorf("failed to send transaction: %w", err)
248278
}
249279

280+
if receivedMsg.ExitCode != 0 {
281+
return nil, fmt.Errorf("transaction failed: with exitcode %d: %s", receivedMsg.ExitCode, receivedMsg.ExitCode.Describe())
282+
}
283+
250284
e.Logger.Infow("transaction sent", "blockID", blockID, "receivedMsg", receivedMsg)
251285
err = receivedMsg.WaitForTrace(clientConn)
252286
if err != nil {

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ require (
99
github.com/gagliardetto/solana-go v1.12.0
1010
github.com/pelletier/go-toml/v2 v2.2.4
1111
github.com/smartcontractkit/chain-selectors v1.0.62
12-
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana
13-
github.com/smartcontractkit/chainlink-common v0.9.1-0.20250813153002-a1a613c0f2a8
12+
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20250814153237-9a6c5a35e950
13+
github.com/smartcontractkit/chainlink-common v0.9.1-0.20250813154823-1652ea0f0500
1414
github.com/smartcontractkit/libocr v0.0.0-20250707144819-babe0ec4e358
1515
github.com/stretchr/testify v1.10.0
1616
github.com/xssnick/tonutils-go v1.13.0
@@ -31,6 +31,7 @@ require (
3131
github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.1 // indirect
3232
github.com/cloudevents/sdk-go/v2 v2.16.1 // indirect
3333
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
34+
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
3435
github.com/fatih/color v1.18.0 // indirect
3536
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
3637
github.com/gabriel-vasile/mimetype v1.4.8 // indirect

go.sum

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
4040
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4141
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
4242
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
43+
github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM=
44+
github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
4345
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
4446
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
4547
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
@@ -300,10 +302,10 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
300302
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
301303
github.com/smartcontractkit/chain-selectors v1.0.62 h1:KWLEyKQXHxGGHIlUfLrzjYldlB8hBjRZi9GP49WtgYs=
302304
github.com/smartcontractkit/chain-selectors v1.0.62/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8=
303-
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana h1:ICWYnxVdoh0ds3CPNml7K4L0xt3Jn1cFnOHcLH9q0Z0=
304-
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana/go.mod h1:zPpo78Fv3zQE3WVZFEqRiRNER9QHaCzl+HNeTSaS0kE=
305-
github.com/smartcontractkit/chainlink-common v0.9.1-0.20250813153002-a1a613c0f2a8 h1:WiVXfD/JYxAgTzakhETobIdVqcYLZtdycsZ7v3U8/sc=
306-
github.com/smartcontractkit/chainlink-common v0.9.1-0.20250813153002-a1a613c0f2a8/go.mod h1:OYfK10oQCJVQEdBmA2J1FC9gq+bp9497LcD88T0q+lw=
305+
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20250814153237-9a6c5a35e950 h1:yXa5OYB2huog8enmrF4ACIFKh+grJiCclas+qP8wfTw=
306+
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20250814153237-9a6c5a35e950/go.mod h1://SdVNO8EApDtkB+iaexDScAnapRAvcGbxgF3H6ixhY=
307+
github.com/smartcontractkit/chainlink-common v0.9.1-0.20250813154823-1652ea0f0500 h1:kCwCIfWLVy87vKiAqewzfVzk9+RQY0TzIE2FHax6stQ=
308+
github.com/smartcontractkit/chainlink-common v0.9.1-0.20250813154823-1652ea0f0500/go.mod h1:OYfK10oQCJVQEdBmA2J1FC9gq+bp9497LcD88T0q+lw=
307309
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.1 h1:ca2z5OXgnbBPQRxpwXwBLJsUA1+cAp5ncfW4Ssvd6eY=
308310
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.1/go.mod h1:NZv/qKYGFRnkjOYBouajnDfFoZ+WDa6H2KNmSf1dnKc=
309311
github.com/smartcontractkit/chainlink-common/pkg/values v0.0.0-20250806152407-159881c7589c h1:QaImySzrLcGzQc4wCF2yDqqb73jA3+9EIqybgx8zT4w=

integration-tests/deployment/cs_test.go

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
chain_selectors "github.com/smartcontractkit/chain-selectors"
1313
"github.com/stretchr/testify/require"
1414

15-
ops "github.com/smartcontractkit/chainlink-ton/deployment/ccip"
15+
ton_ops "github.com/smartcontractkit/chainlink-ton/deployment/ccip"
1616
"github.com/smartcontractkit/chainlink-ton/deployment/ccip/config"
1717
tonstate "github.com/smartcontractkit/chainlink-ton/deployment/state"
1818

@@ -24,6 +24,10 @@ import (
2424
"github.com/smartcontractkit/chainlink-ton/pkg/ccip/bindings/feequoter"
2525
"github.com/smartcontractkit/chainlink-ton/pkg/ccip/chainaccessor"
2626
"github.com/smartcontractkit/chainlink-ton/pkg/ccip/codec"
27+
"github.com/smartcontractkit/chainlink-ton/pkg/logpoller"
28+
inmemorystore "github.com/smartcontractkit/chainlink-ton/pkg/logpoller/backend/db/inmemory"
29+
"github.com/smartcontractkit/chainlink-ton/pkg/logpoller/backend/loader/account"
30+
"github.com/smartcontractkit/chainlink-ton/pkg/logpoller/backend/txparser"
2731

2832
"github.com/xssnick/tonutils-go/address"
2933
"github.com/xssnick/tonutils-go/tlb"
@@ -56,15 +60,15 @@ func TestDeploy(t *testing.T) {
5660
// memory environment doesn't block on funding so changesets can execute before the env is fully ready, manually call fund so we block here
5761
test_utils.FundWallets(t, tonChain.Client, []*address.Address{deployer.Address()}, []tlb.Coins{tlb.MustFromTON("1000")})
5862

59-
cs := ops.DeployChainContractsToTonCS(t, env, chainSelector)
63+
cs := ton_ops.DeployChainContractsToTonCS(t, env, chainSelector)
6064
env, _, err := commonchangeset.ApplyChangesets(t, env, []commonchangeset.ConfiguredChangeSet{cs})
6165
require.NoError(t, err, "failed to deploy ccip")
6266

6367
// TODO: LINK token deployment
64-
linkAddr := ops.TonTokenAddr
68+
linkAddr := ton_ops.TonTokenAddr
6569

6670
env, _, err = commonchangeset.ApplyChangesets(t, env, []commonchangeset.ConfiguredChangeSet{
67-
commonchangeset.Configure(ops.AddTonLanes{}, config.UpdateTonLanesConfig{
71+
commonchangeset.Configure(ton_ops.AddTonLanes{}, config.UpdateTonLanesConfig{
6872
EVMMCMSConfig: &proposalutils.TimelockConfig{},
6973
TonMCMSConfig: &proposalutils.TimelockConfig{},
7074
Lanes: []config.LaneConfig{
@@ -77,31 +81,11 @@ func TestDeploy(t *testing.T) {
7781
Selector: chainSelector,
7882
GasPrice: big.NewInt(1e17),
7983
TokenPrices: map[*address.Address]*big.Int{
80-
ops.TonTokenAddr: big.NewInt(99),
84+
ton_ops.TonTokenAddr: big.NewInt(99),
8185
},
82-
FeeQuoterDestChainConfig: feequoter.DestChainConfig{ // minimal valid config
83-
IsEnabled: true,
84-
MaxNumberOfTokensPerMsg: 0,
85-
MaxDataBytes: 100,
86-
MaxPerMsgGasLimit: 100,
87-
DestGasOverhead: 0,
88-
DestGasPerPayloadByteBase: 0,
89-
DestGasPerPayloadByteHigh: 0,
90-
DestGasPerPayloadByteThreshold: 0,
91-
DestDataAvailabilityOverheadGas: 0,
92-
DestGasPerDataAvailabilityByte: 0,
93-
DestDataAvailabilityMultiplierBps: 0,
94-
ChainFamilySelector: 0,
95-
EnforceOutOfOrder: false,
96-
DefaultTokenFeeUsdCents: 0,
97-
DefaultTokenDestGasOverhead: 0,
98-
DefaultTxGasLimit: 1,
99-
GasMultiplierWeiPerEth: 0,
100-
GasPriceStalenessThreshold: 0,
101-
NetworkFeeUsdCents: 0,
102-
},
103-
TokenTransferFeeConfigs: map[uint64]feequoter.UpdateTokenTransferFeeConfig{
104-
// TODO:
86+
FeeQuoterDestChainConfig: ton_ops.DefaultFeeQuoterDestChainConfig(true, evmSelector),
87+
TokenTransferFeeConfigs: map[uint64]feequoter.UpdateTokenTransferFeeConfig{
88+
// TODO: populate when token transfer enabled
10589
},
10690
},
10791
Dest: config.EVMChainDefinition{
@@ -129,10 +113,19 @@ func TestDeploy(t *testing.T) {
129113
require.NoError(t, err)
130114

131115
// -- TON Accessor tests
132-
116+
lpCfg := logpoller.DefaultConfigSet
117+
filterStore := inmemorystore.NewFilterStore()
118+
opts := &logpoller.ServiceOptions{
119+
Config: lpCfg,
120+
Client: tonChain.Client,
121+
Filters: filterStore,
122+
TxLoader: account.NewTxLoader(tonChain.Client, lggr, lpCfg.PageSize),
123+
TxParser: txparser.NewTxParser(lggr, filterStore),
124+
Store: inmemorystore.NewLogStore(),
125+
}
126+
lp := logpoller.NewService(lggr, opts)
133127
addrCodec := codec.NewAddressCodec()
134-
135-
accessor, err := chainaccessor.NewTONAccessor(lggr, ccipocr3.ChainSelector(chainSelector), tonChain.Client, nil, addrCodec)
128+
accessor, err := chainaccessor.NewTONAccessor(lggr, ccipocr3.ChainSelector(chainSelector), tonChain.Client, lp, addrCodec)
136129
require.NoError(t, err)
137130

138131
ctx := t.Context()

0 commit comments

Comments
 (0)