Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,6 @@ cmd/chainlink-ton/chainlink-ton

# Experimental files
pkg/ton/codec/jsoncodec/

# Agents
.cursor/
17 changes: 7 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
module github.com/smartcontractkit/chainlink-ton

go 1.25.5
go 1.26.2

require (
Comment thread
ogtownsend marked this conversation as resolved.
github.com/Masterminds/semver/v3 v3.4.0
github.com/TyphonHill/go-mermaid v1.0.0
github.com/block-vision/sui-go-sdk v1.1.4
github.com/ethereum/go-ethereum v1.17.2
github.com/gagliardetto/solana-go v1.13.0
github.com/hashicorp/go-plugin v1.7.0
github.com/hashicorp/go-plugin v1.8.0
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/jpillora/backoff v1.0.0
github.com/pelletier/go-toml/v2 v2.2.4
github.com/prometheus/client_golang v1.23.2
github.com/samber/lo v1.52.0
github.com/smartcontractkit/chain-selectors v1.0.98
github.com/smartcontractkit/chainlink-ccip v0.1.1-solana.0.20260415165642-49f23e4d76cc
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260406055916-9aa6b6c0ae81
github.com/smartcontractkit/chainlink-common v0.11.2-0.20260507124402-5637bdfdf811
github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340
Comment thread
ogtownsend marked this conversation as resolved.
Outdated
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251210101658-1c5c8e4c4f15
github.com/smartcontractkit/libocr v0.0.0-20250912173940-f3ab0246e23d
Expand Down Expand Up @@ -72,14 +72,10 @@ require (
github.com/holiman/uint256 v1.3.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/invopop/jsonschema v0.13.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.3 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgtype v1.14.4 // indirect
github.com/jackc/pgx/v4 v4.18.3 // indirect
github.com/jackc/pgx/v5 v5.9.2 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/copier v0.4.0 // indirect
github.com/jmank88/gomods v0.1.6 // indirect
github.com/jmank88/modgraph v0.1.1 // indirect
Expand Down Expand Up @@ -110,7 +106,7 @@ require (
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 // indirect
github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f // indirect
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260420204255-a3f3bdd56877 // indirect
github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect
github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260205130626-db2a2aab956b // indirect
github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad // indirect
Expand Down Expand Up @@ -142,6 +138,7 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
go.opentelemetry.io/otel/trace v1.43.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
go.uber.org/goleak v1.3.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/crypto v0.49.0 // indirect
Expand Down
170 changes: 12 additions & 158 deletions go.sum

Large diffs are not rendered by default.

109 changes: 109 additions & 0 deletions pkg/logpoller/leak_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package logpoller

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/require"
"github.com/xssnick/tonutils-go/address"
"github.com/xssnick/tonutils-go/tl"
"github.com/xssnick/tonutils-go/tlb"
"github.com/xssnick/tonutils-go/ton"

commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"

"github.com/smartcontractkit/chainlink-ton/pkg/logpoller/models"
)

// TestLogPollerServiceLeak runs the real engine ticks, polling loop, pruning ticker, and loader goroutines
// under goleak. After Start, it exercises filter management (Register/Has/Unregister) and Replay so the
// public service surface runs real code beyond Start/Close.
func TestLogPollerServiceLeak(t *testing.T) {
tests.VerifyNoLeaks(t)

lggr := logger.Test(t)
chainID := "leak-lp"
ctx := context.Background()

cfg := DefaultConfigSet
cfg.PollPeriod = commonconfig.MustNewDuration(100 * time.Millisecond)
cfg.PruningInterval = commonconfig.MustNewDuration(1 * time.Minute)
cfg.PruningStartDelay = commonconfig.MustNewDuration(0)
cfg.MCBlockResolveMaxRetries = 1
cfg.MCBlockResolveBaseDelay = commonconfig.MustNewDuration(time.Millisecond)
cfg.ApplyDefaults()
require.NoError(t, cfg.ValidateConfig())

poll := cfg.PollPeriod.Duration()

currentMC := &ton.BlockIDExt{Workchain: address.MasterchainID, SeqNo: 100, Shard: 1}
lite := &mockLiteClient{
queryFunc: func(_ context.Context, _ tl.Serializable, resp tl.Serializable) error {
ptr := resp.(*tl.Serializable)
*ptr = ton.ShardBlockProof{
MasterchainID: &ton.BlockIDExt{Workchain: address.MasterchainID, SeqNo: 50},
}
return nil
},
}
mockClient := &mockAPIClient{
masterchainInfo: currentMC,
lookupBlockFunc: func(seqNo uint32) *ton.BlockIDExt {
return &ton.BlockIDExt{Workchain: address.MasterchainID, SeqNo: seqNo, Shard: 1}
},
liteClient: lite,
}

opts := &ServiceOptions{
Config: cfg,
FilterStore: newMockFilterStore(),
TxLoader: &testTxLoader{}, // empty stream; still exercises per-address goroutines in loadTxsForAddresses
LogStore: &testLogStore{},
}
Comment thread
ogtownsend marked this conversation as resolved.

clientProvider := func(context.Context) (ton.APIClientWrapped, error) {
return mockClient, nil
}

svc, err := NewService(lggr, chainID, clientProvider, opts)
require.NoError(t, err)

addr := testAddress(t)
_, err = svc.RegisterFilter(ctx, models.Filter{
Name: "leak-filter",
Address: addr,
MsgType: tlb.MsgTypeExternalOut,
EventSig: 0xcafebabe,
})
require.NoError(t, err)

servicetest.RunHealthy(t, svc)

// Wait several poll periods so processBlockRange runs at least once (fans out per-address
// loader goroutines and the resolveTxsMCBlock goroutine).
time.Sleep(3 * poll)

// Exercise additional public service methods while the engine is running.
exists, err := svc.HasFilter(ctx, "leak-filter")
require.NoError(t, err)
require.True(t, exists)

_, err = svc.RegisterFilter(ctx, models.Filter{
Name: "leak-filter-2",
Address: testAddress2(t),
MsgType: tlb.MsgTypeExternalOut,
EventSig: 0xfeedface,
})
require.NoError(t, err)

require.NoError(t, svc.Replay(ctx, 50))

require.NoError(t, svc.UnregisterFilter(ctx, "leak-filter"))

// Give the poller time for more ticks after filter and replay mutations.
time.Sleep(2 * poll)
}
Loading
Loading