Skip to content
Draft
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
2 changes: 1 addition & 1 deletion docs/.misc/dev-guides/nix/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ cd pkg && golint ./... # lint your pkg directory
cd integration-tests && golint ./... # lint integration tests

# Or run directly without alias:
cd pkg && golangci-lint run --config <(curl -sSL https://raw.githubusercontent.com/smartcontractkit/chainlink/develop/.golangci.yml | yq e '.formatters.settings.goimports.local-prefixes = ["github.com/smartcontractkit/chainlink-ton"]' -) --path-mode "abs" ./...
cd pkg && golangci-lint run --config <(curl -sSL https://raw.githubusercontent.com/smartcontractkit/chainlink/develop/.golangci.yml | yq e '.formatters.settings.goimports.local-prefixes = ["github.com/smartcontractkit/chainlink-ton"] | .linters.enable += ["errcheck", "nilnil", "govet", "staticcheck"] | .linters.settings.errcheck = {"check-type-assertions": true, "check-blank": true} | .linters.settings.govet.enable += ["nilness"]' -) --path-mode "abs" ./...
```

This ensures you're always using the exact same lint rules as our CI without writing any config files locally.
5 changes: 3 additions & 2 deletions integration-tests/deployment/ccip/cs_add_lanes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import (

"github.com/Masterminds/semver/v3"
chainselectors "github.com/smartcontractkit/chain-selectors"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms"
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink-ton/deployment/utils/sequence"

Expand Down Expand Up @@ -75,7 +76,7 @@ func TestAddLanes(t *testing.T) {
},
})
require.NoError(t, err, "Failed to apply DeployChainContracts changeset")
_ = out.DataStore.Merge(env.DataStore)
require.NoError(t, out.DataStore.Merge(env.DataStore))
env.DataStore = out.DataStore.Seal()

// Get OnRamp Address from EVM
Expand Down
5 changes: 3 additions & 2 deletions integration-tests/deployment/ccip/cs_fast_curse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (

"github.com/Masterminds/semver/v3"
chainselectors "github.com/smartcontractkit/chain-selectors"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms"
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink-ton/deployment/utils/sequence"

Expand Down Expand Up @@ -70,7 +71,7 @@ func TestFastCurseTON(t *testing.T) {
},
})
require.NoError(t, err, "Failed to apply DeployChainContracts changeset")
_ = out.DataStore.Merge(env.DataStore)
require.NoError(t, out.DataStore.Merge(env.DataStore))
env.DataStore = out.DataStore.Seal()
// </deploy-evm>

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/monitor/balance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func TestBalanceMonitor_Polling(t *testing.T) {
err = balanceMonitor.Start(t.Context())
require.NoError(t, err)
defer func() {
_ = balanceMonitor.Close()
require.NoError(t, balanceMonitor.Close())
}()

// Wait a bit to allow the monitor to poll at least once
Expand Down
33 changes: 14 additions & 19 deletions integration-tests/smoke/chainaccessor/accessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ func Test_TonAccessor_MsgsBetweenSeqNums(t *testing.T) {
func Test_TonAccessorCommitEventQueries(t *testing.T) {
// Note: we don't test the API client interaction here, so we return empty client
clientProvider := func(ctx context.Context) (ton.APIClientWrapped, error) {
//nolint:nilnil // mock
return nil, nil
}

Expand Down Expand Up @@ -639,7 +640,8 @@ func testCommitReportsBasicHelper(t *testing.T, lp logpoller.Service, logStore l
require.Equal(t, ccipocr3.SeqNum(1), merkleRoot.SeqNumsRange.Start(), "MinSeqNr should be 1")
require.Equal(t, ccipocr3.SeqNum(1), merkleRoot.SeqNumsRange.End(), "MaxSeqNr should be 1")

expectedMerkleRootBytes, _ := hex.DecodeString("bea275bb6614f85036536bc670e540bc748118e90537b8441c950672f74607d5")
expectedMerkleRootBytes, err := hex.DecodeString("bea275bb6614f85036536bc670e540bc748118e90537b8441c950672f74607d5")
require.NoError(t, err)
require.Equal(t, expectedMerkleRootBytes, merkleRoot.MerkleRoot[:], "MerkleRoot should match")

// Validate PriceUpdates should be empty for this test (since we used merkleRootOnlyCell)
Expand Down Expand Up @@ -695,11 +697,6 @@ func Test_TonAccessorExecutionStateChangedEventQueries(t *testing.T) {
}

func Test_TonAccessorExecutedMessages(t *testing.T) {
// Note: we don't test the API client interaction here, so we return empty client
clientProvider := func(ctx context.Context) (ton.APIClientWrapped, error) {
return nil, nil
}

// Setup in-memory store
lggr := logger.Test(t)
opts := &logpoller.ServiceOptions{
Expand All @@ -711,7 +708,8 @@ func Test_TonAccessorExecutedMessages(t *testing.T) {
lp, err := logpoller.NewService(
lggr,
"test-chain",
clientProvider,
// Note: we don't test the API client interaction here, so we return empty client
mockClientProvider,
opts,
)
require.NoError(t, err)
Expand All @@ -720,15 +718,15 @@ func Test_TonAccessorExecutedMessages(t *testing.T) {
testExecutedMessagesHelper(t, lp, opts.LogStore, 1)
}

func mockClientProvider(ctx context.Context) (ton.APIClientWrapped, error) {
//nolint:nilnil // mock
return nil, nil
}

// Test validation for MsgsBetweenSeqNums sequence number range
func Test_TonAccessor_MsgsBetweenSeqNums_SequenceRangeValidation(t *testing.T) {
lggr := logger.Test(t)

// Note: we don't test the API client interaction here, so we return empty client
clientProvider := func(ctx context.Context) (ton.APIClientWrapped, error) {
return nil, nil
}

opts := &logpoller.ServiceOptions{
Config: logpoller.DefaultConfigSet,
FilterStore: inmemorystore.NewFilterStore("test-chain", lggr),
Expand All @@ -738,7 +736,8 @@ func Test_TonAccessor_MsgsBetweenSeqNums_SequenceRangeValidation(t *testing.T) {
lp, err := logpoller.NewService(
lggr,
"test-chain",
clientProvider,
// Note: we don't test the API client interaction here, so we return empty client
mockClientProvider,
opts,
)
require.NoError(t, err)
Expand Down Expand Up @@ -788,11 +787,6 @@ func Test_TonAccessorExecutedMessages_WithPostgresStore(t *testing.T) {
t.Skip("Skipping postgres test in short mode")
}

// Note: we don't test the API client interaction here, so we return empty client
clientProvider := func(ctx context.Context) (ton.APIClientWrapped, error) {
return nil, nil
}

// Setup postgres store using testcontainers
lggr := logger.Test(t)
ds := pgtest.SetupTestDB(t)
Expand All @@ -814,7 +808,8 @@ func Test_TonAccessorExecutedMessages_WithPostgresStore(t *testing.T) {
lp, err := logpoller.NewService(
lggr,
"test-chain",
clientProvider,
// Note: we don't test the API client interaction here, so we return empty client
mockClientProvider,
opts,
)
require.NoError(t, err)
Expand Down
21 changes: 14 additions & 7 deletions integration-tests/smoke/logpoller/log_poller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ func Test_LogPoller(t *testing.T) {

indexedCells := make([]*cell.Cell, 0, len(txs))
for _, tx := range txs {
msgs, _ := tx.Transaction.IO.Out.ToSlice()
msgs, serr := tx.Transaction.IO.Out.ToSlice()
require.NoError(t, serr)
for _, msg := range msgs {
// test contract only emits ExternalMessageOut
if msg.MsgType == tlb.MsgTypeExternalOut {
Expand Down Expand Up @@ -152,7 +153,8 @@ func Test_LogPoller(t *testing.T) {

// Extract messages from the loaded transactions
for _, tx := range txs {
msgs, _ := tx.Transaction.IO.Out.ToSlice()
msgs, serr := tx.Transaction.IO.Out.ToSlice()
require.NoError(t, serr)
for _, msg := range msgs {
if msg.MsgType == tlb.MsgTypeExternalOut {
if extOut := msg.AsExternalOut(); extOut != nil {
Expand Down Expand Up @@ -894,7 +896,8 @@ func Test_LogPoller(t *testing.T) {
return counterValue == preReplayEvents
}, 30*time.Second, 1*time.Second, "counter should reach expected value")

counterValue, _ := counter.GetValue(t.Context(), tonChain.Client, emitter.ContractAddress())
counterValue, err := counter.GetValue(t.Context(), tonChain.Client, emitter.ContractAddress())
require.NoError(t, err)
require.Equal(t, preReplayEvents, int(counterValue))

// 3. Start LogPoller (with in-memory stores)
Expand Down Expand Up @@ -922,10 +925,11 @@ func Test_LogPoller(t *testing.T) {
defer func() { require.NoError(t, lp.Close()) }()

// 5. Verify no logs before replay
logs, _, _, _ := lp.NewQuery().
logs, _, _, err := lp.NewQuery().
WithSource(emitter.ContractAddress()).
WithEventSig(counter.TopicCountIncreased).
Execute(t.Context())
require.NoError(t, err)
require.Empty(t, logs, "should have no logs before replay")

// 6. Request replay from block before events were emitted
Expand Down Expand Up @@ -956,7 +960,8 @@ func Test_LogPoller(t *testing.T) {
return false
}

result, _ := query.DecodedLogs[counter.CountIncreased](logs)
result, serr := query.DecodedLogs[counter.CountIncreased](logs)
require.NoError(t, serr)
t.Logf("found %d logs after replay", len(result))
return len(result) == preReplayEvents
}, 60*time.Second, 2*time.Second, "replay should complete and index all events")
Expand All @@ -969,11 +974,13 @@ func Test_LogPoller(t *testing.T) {
}

require.Eventually(t, func() bool {
logs, _, _, _ := lp.NewQuery().
logs, _, _, err := lp.NewQuery().
WithSource(emitter.ContractAddress()).
WithEventSig(counter.TopicCountIncreased).
Execute(t.Context())
result, _ := query.DecodedLogs[counter.CountIncreased](logs)
require.NoError(t, err)
result, err := query.DecodedLogs[counter.CountIncreased](logs)
require.NoError(t, err)
return len(result) == preReplayEvents+postReplayEvents
}, 30*time.Second, 2*time.Second, "should index new events after replay")
})
Expand Down
4 changes: 4 additions & 0 deletions pkg/bindings/test/examples/jetton/simple_jetton_receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ func (r SimpleJettonReceiver) GetAmountChecker() (*tlb.Coins, error) {
return &coins, nil
}

// GetPayloadChecker retrieves the payload checker cell, if set
// Returns nil if no payload checker is set
// Returns an error if retrieval or parsing fails
func (r SimpleJettonReceiver) GetPayloadChecker() (*cell.Cell, error) {
result, err := r.Contract.Get("payloadChecker")
if err != nil {
Expand All @@ -85,6 +88,7 @@ func (r SimpleJettonReceiver) GetPayloadChecker() (*cell.Cell, error) {
if isPayloadCheckerNil {
fmt.Printf("Payload checker is nil, no payload validation will be performed\n")
fmt.Printf("As tupple: %v\n", result.AsTuple())
//nolint: nilnil // Explicit nil return
return nil, nil // No payload checker set
}

Expand Down
42 changes: 23 additions & 19 deletions pkg/ccip/bindings/common/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,9 @@ func TestLoadCrossChainAddressWithoutPrefix_Validation(t *testing.T) {
setupFunc: func() *cell.Slice {
builder := cell.BeginCell()
addr := []byte{0x01, 0x02, 0x03, 0x04, 0x05}
_ = builder.StoreSlice(addr, uint(len(addr))*8)
if err := builder.StoreSlice(addr, uint(len(addr))*8); err != nil {
panic(err)
}
return builder.EndCell().BeginParse()
},
expectErr: "",
Expand All @@ -502,7 +504,9 @@ func TestLoadCrossChainAddressWithoutPrefix_Validation(t *testing.T) {
setupFunc: func() *cell.Slice {
builder := cell.BeginCell()
addr := make([]byte, 65)
_ = builder.StoreSlice(addr, uint(len(addr))*8)
if err := builder.StoreSlice(addr, uint(len(addr))*8); err != nil {
panic(err)
}
return builder.EndCell().BeginParse()
},
expectErr: "exceeds maximum of 64 bytes",
Expand Down Expand Up @@ -531,14 +535,14 @@ func TestUnloadCellToByteArray_Validation(t *testing.T) {
t.Run("exceeds maximum cell chain depth", func(t *testing.T) {
// Create a cell chain that exceeds MaxCellChainDepth
builder := cell.BeginCell()
_ = builder.StoreSlice([]byte{0x01}, 8)
require.NoError(t, builder.StoreSlice([]byte{0x01}, 8))
root := builder.EndCell()

// Build a chain longer than MaxCellChainDepth
for i := 0; i < MaxCellChainDepth+1; i++ {
builder = cell.BeginCell()
_ = builder.StoreSlice([]byte{0x01}, 8)
_ = builder.StoreRef(root)
require.NoError(t, builder.StoreSlice([]byte{0x01}, 8))
require.NoError(t, builder.StoreRef(root))
root = builder.EndCell()
}

Expand Down Expand Up @@ -577,28 +581,28 @@ func TestUnpackArrayWithRefChaining_Validation(t *testing.T) {
// Create a cell chain that exceeds MaxCellChainDepth by building a deep chain
// Start with a valid element cell
elemBuilder := cell.BeginCell()
_ = elemBuilder.StoreSlice([]byte{0x01}, 8)
require.NoError(t, elemBuilder.StoreSlice([]byte{0x01}, 8))
elemCell := elemBuilder.EndCell()

// Build initial cell with 3 data refs and 1 chain ref
builder := cell.BeginCell()
for i := 0; i < 3; i++ {
_ = builder.StoreRef(elemCell)
require.NoError(t, builder.StoreRef(elemCell))
}
// Add a chain ref to continue
chainBuilder := cell.BeginCell()
_ = chainBuilder.StoreRef(elemCell)
require.NoError(t, chainBuilder.StoreRef(elemCell))
chainCell := chainBuilder.EndCell()
_ = builder.StoreRef(chainCell)
require.NoError(t, builder.StoreRef(chainCell))
root := builder.EndCell()

// Now extend the chain beyond MaxCellChainDepth
for i := 0; i < MaxCellChainDepth; i++ {
builder = cell.BeginCell()
for j := 0; j < 3; j++ {
_ = builder.StoreRef(elemCell)
require.NoError(t, builder.StoreRef(elemCell))
}
_ = builder.StoreRef(root)
require.NoError(t, builder.StoreRef(root))
root = builder.EndCell()
}

Expand Down Expand Up @@ -682,24 +686,24 @@ func TestMaxArrayLength_Validation(t *testing.T) {
// We'll create a chain with 4 refs each, where each ref contains data
// This should be caught during unpacking
elemBuilder := cell.BeginCell()
_ = elemBuilder.StoreSlice([]byte{0x01}, 8)
require.NoError(t, elemBuilder.StoreSlice([]byte{0x01}, 8))
elemCell := elemBuilder.EndCell()

// Build chains that would exceed MaxArrayLength
// Each cell can have 3 data refs + 1 chain ref
// We need > 1000 elements, so > 334 cells (1000/3 = 333.33)
builder := cell.BeginCell()
_ = builder.StoreRef(elemCell)
_ = builder.StoreRef(elemCell)
_ = builder.StoreRef(elemCell)
require.NoError(t, builder.StoreRef(elemCell))
require.NoError(t, builder.StoreRef(elemCell))
require.NoError(t, builder.StoreRef(elemCell))

root := builder.EndCell()
for i := 0; i < MaxArrayLength/3+2; i++ {
builder = cell.BeginCell()
_ = builder.StoreRef(elemCell)
_ = builder.StoreRef(elemCell)
_ = builder.StoreRef(elemCell)
_ = builder.StoreRef(root)
require.NoError(t, builder.StoreRef(elemCell))
require.NoError(t, builder.StoreRef(elemCell))
require.NoError(t, builder.StoreRef(elemCell))
require.NoError(t, builder.StoreRef(root))
root = builder.EndCell()
}

Expand Down
1 change: 1 addition & 0 deletions pkg/ccip/chainaccessor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ func (a *TONAccessor) GetOffRampSourceChainConfigs(ctx context.Context, block *t

// if the dictionary is empty, we get back nil
if len(sourceConfigsGot) == 0 {
//nolint:nilnil // returning nil map is acceptable here?
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we return an empty map?

return nil, nil
}

Expand Down
1 change: 1 addition & 0 deletions pkg/ccip/chainaccessor/ton_accessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ func (a *TONAccessor) ExecutedMessages(

if len(nonEmptyRangesPerChain) == 0 {
lggr.Debugw("no sequence numbers to query", "nonEmptyRangesPerChain", nonEmptyRangesPerChain)
//nolint:nilnil // returning nil map is acceptable here?
return nil, nil
Comment on lines +624 to 625
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we return an empty map?

}

Expand Down
5 changes: 4 additions & 1 deletion pkg/ccip/codec/commitcodec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ func TestCommitPluginCodecV1(t *testing.T) {

func randomBytes32() (r [32]byte) {
b := make([]byte, 32)
_, _ = cryptorand.Read(b) // Assignment for errcheck. Only used in tests so we can ignore.
_, err := cryptorand.Read(b)
if err != nil {
panic(err)
}
copy(r[:], b)
return
}
Expand Down
Loading
Loading