Skip to content

Conversation

@huangzhen1997
Copy link
Contributor

@huangzhen1997 huangzhen1997 commented Dec 10, 2025

Copilot AI review requested due to automatic review settings December 10, 2025 03:08
@huangzhen1997 huangzhen1997 requested a review from a team as a code owner December 10, 2025 03:08
@changeset-bot
Copy link

changeset-bot bot commented Dec 10, 2025

🦋 Changeset detected

Latest commit: a06f6eb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
chainlink-deployments-framework Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@huangzhen1997 huangzhen1997 marked this pull request as draft December 10, 2025 03:08
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds TON blockchain analyzer support to the chainlink-deployments-framework. The implementation follows existing patterns for other chain families (Aptos, Sui, Solana) by integrating TON-specific MCMS SDK functionality.

Key changes:

  • Added TON transaction analysis capabilities with decoder integration
  • Updated dependency versions including Go runtime, MCMS SDK, and various libraries
  • Refactored transaction encoding logic to use family-based routing

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

File Description
go.mod Updated Go version to 1.25.3 and bumped various dependencies including MCMS SDK, TON utilities, and added chainlink-ton package
experimental/analyzer/upf/upf.go Integrated TON family support in UPF decoding with mcmstonsdk decoder and simplified encoding logic
experimental/analyzer/ton_analyzer.go New file implementing TON transaction analysis functions mirroring Sui/Aptos patterns
experimental/analyzer/report_builder.go Added TON family handling in proposal and timelock report builders

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@smartcontractkit smartcontractkit deleted a comment from github-actions bot Dec 10, 2025
}

// Use a TON chain selector - TON family is not handled in the switch statement
// Use a TRON chain selector - TRON family is not handled in the switch statement

Choose a reason for hiding this comment

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

Why TRON in this PR?

Also, there's multiple tests ran across multiple chain families in this file, we should add a TON test to those.

Copy link
Contributor Author

@huangzhen1997 huangzhen1997 Dec 10, 2025

Choose a reason for hiding this comment

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

This unit test is for checking the behavior of the unsupported chain. Previous TON Analyzer was not supported so they used TON here. Switching to TRON now as TON is supported. The Chain-selector pkg requires all chain selector to have a chain family, but here we are okay with certain chain family missing analyzer support. Not sure what would be a better way to handle the default test case here besides update the chain family to another unsupported family.

I will add TON analyzer test coverage

Choose a reason for hiding this comment

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

TRON == EVM, so it should be supported out of the box (or close).

Why not add an ACME imaginary chain as a not-supported example?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we do have a separate TRON family, which is returned using chainsel.TRON_DEVNET.Selector. This is a bit awkward, since modifying chain-selector to return a imaginary chain family would be weird (current behavior is return error when chain selector is not registered for its family).

@huangzhen1997 huangzhen1997 marked this pull request as ready for review December 12, 2025 02:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings December 12, 2025 04:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// Sui: mcms::timelock_schedule_batch, mcms::timelock_bypasser_execute_batch
// Aptos: package::module::timelock_schedule_batch, package::module::timelock_bypasser_execute_batch
// TON: ContractType::ScheduleBatch(0x...), ContractType::BypasserExecuteBatch(0x...)

Choose a reason for hiding this comment

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

WIll TON type will be provided like this? (e.g., "com.chainlink.ton.lib.access.RBAC::GrantRole(0x0)")

Copy link
Contributor Author

@huangzhen1997 huangzhen1997 Dec 15, 2025

Choose a reason for hiding this comment

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

I didn't check the contract type, because with the timelock converter it would be converted to RBACTimelock::ScheduleBatch(0x0)

Comment on lines +210 to +211
expectedMsg: "EVM registry is not available",
wantErr: true,

Choose a reason for hiding this comment

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

Can't this be simplified as wantErr: string which if set is the expected error string?

name: "TON_decode_failure",
selector: chainsel.TON_TESTNET.Selector,
expectedMsg: "failed to decode TON transaction",
wantErr: false, // TON doesn't unmarshal AdditionalFields, so decode errors go to Method field

Choose a reason for hiding this comment

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

Hmm, not sure why is here a difference for TON? There shouldn't be one...

Choose a reason for hiding this comment

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

Doesn't SUI impl also surfaces errors via .Method member:

Copy link
Contributor Author

@huangzhen1997 huangzhen1997 Dec 16, 2025

Choose a reason for hiding this comment

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

This test is for default unhappy pass, where the analyze function suppose to fail immediately. Unlike SUI we don't need extra field Unmarshal, so the first error will be hiding in Method field.

}

// Use a TON chain selector - TON family is not handled in the switch statement
// Use a TRON chain selector - TRON family is not handled in the switch statement

Choose a reason for hiding this comment

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

TRON == EVM, so it should be supported out of the box (or close).

Why not add an ACME imaginary chain as a not-supported example?

name: "TON_decode_failure",
selector: chainsel.TON_TESTNET.Selector,
expectedMsg: "failed to decode TON transaction",
wantErr: false, // TON doesn't unmarshal AdditionalFields, so decode errors go to Method field

Choose a reason for hiding this comment

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

Shouldn't diverge from other test cases

Copilot AI review requested due to automatic review settings December 15, 2025 23:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings December 16, 2025 21:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +14 to +19
var typeToTLBMap = map[string]lib.TLBMap{
"com.chainlink.ton.lib.access.RBAC": rbac.TLBs,
"com.chainlink.ton.mcms.MCMS": mcms.TLBs,
"com.chainlink.ton.mcms.Timelock": timelock.TLBs,
"RBACTimelock": timelock.TLBs,
}
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

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

The typeToTLBMap variable lacks documentation explaining why 'RBACTimelock' maps to the same TLB as 'com.chainlink.ton.mcms.Timelock', and what the contract type naming convention is. This mapping appears in multiple contexts throughout the code and should be documented to explain the relationship between these contract types.

Copilot uses AI. Check for mistakes.
decodedTxs := make([]*DecodedCall, len(txs))
for i, op := range txs {
analyzedTransaction, err := AnalyzeSuiTransaction(ctx, decoder, chainSelector, op)
analyzedTransaction, err := AnalyzeSuiTransaction(ctx, chainSelector, op)
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we need to create new decoder for every transaction?

"github.com/smartcontractkit/mcms/types"
)

var typeToTLBMap = map[string]lib.TLBMap{
Copy link
Contributor

@gustavogama-cll gustavogama-cll Dec 19, 2025

Choose a reason for hiding this comment

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

is the plan to expand this with more contracts from the product team? If so, this needs to be handled in the same way we handle the EVM and Solana contracts: you need to create a "ton contract registry" type and expose it through the ProposalContext interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the context, this binding map is still wip from the sdk side, we will probably not have the map hardcoded here and import by the sdk instead. cc @krebernisak

Copy link
Contributor

@gustavogama-cll gustavogama-cll left a comment

Choose a reason for hiding this comment

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

Please don't forget to add a changeset and a proper comment to the PR's description.

Copilot AI review requested due to automatic review settings December 21, 2025 16:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
}

func TestUpfConvertTimelockProposalWithTon(t *testing.T) {
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

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

The function name 'TestUpfConvertTimelockProposalWithTon' is inconsistent with Go naming conventions. 'Ton' should be 'TON' to match the established pattern in other test names like 'TestUpfConvertTimelockProposalWithSui'.

Suggested change
func TestUpfConvertTimelockProposalWithTon(t *testing.T) {
func TestUpfConvertTimelockProposalWithTON(t *testing.T) {

Copilot uses AI. Check for mistakes.
name: "TON_decode_failure",
selector: chainsel.TON_TESTNET.Selector,
expectedMsg: "failed to decode TON transaction",
wantErr: false, // TON doesn't unmarshal AdditionalFields, so decode errors go to Method field
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

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

The comment explains TON's behavior of not unmarshaling AdditionalFields, but this is misleading in the context of decode failures. The actual reason decode errors don't return as errors is stated in ton_analyzer.go:48 - it's to prevent blocking the whole proposal. Consider updating the comment to: '// TON returns decode errors in Method field to avoid blocking proposal processing'.

Suggested change
wantErr: false, // TON doesn't unmarshal AdditionalFields, so decode errors go to Method field
wantErr: false, // TON returns decode errors in Method field to avoid blocking proposal processing

Copilot uses AI. Check for mistakes.
name: "TON_decode_failure",
selector: chainsel.TON_TESTNET.Selector,
expectedMsg: "failed to decode TON transaction",
wantErr: false, // TON doesn't unmarshal AdditionalFields, so decode errors go to Method field
Copy link

Copilot AI Dec 21, 2025

Choose a reason for hiding this comment

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

Same issue as Comment 4 - the comment is misleading about why decode errors go to the Method field. The reason is to avoid blocking proposal processing, not specifically about AdditionalFields unmarshaling.

Suggested change
wantErr: false, // TON doesn't unmarshal AdditionalFields, so decode errors go to Method field
wantErr: false, // decode errors are reported in the Method field so proposal processing is not blocked

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings December 21, 2025 17:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@cl-sonarqube-production
Copy link

Copy link
Contributor

@ecPablo ecPablo left a comment

Choose a reason for hiding this comment

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

LGTM! Left a couple nit comments but nothing blocking

// Instead, put the error message in the Method field so it's visible in the report.
errStr := fmt.Errorf("failed to decode TON transaction: %w", err)

return &DecodedCall{
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering if we should double check this with security. From one side I agree that a failure to decode should not be a blocker for operational activity, but on the other side I know security wants to push for us to reduce blind signing of proposals as much as possible. Will it be common to see decode of operations failing?

// across different chain families (EVM, Solana, Sui, Aptos, TON).
func isTimelockBatchFunction(functionName string) bool {
// EVM function signatures
if functionName == "function scheduleBatch((address,uint256,bytes)[] calls, bytes32 predecessor, bytes32 salt, uint256 delay) returns()" ||
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: we could move this to small per chain family helpers to keep this function a bit more concise and readable


namedArgs, err := toNamedFields(decodedOp)
if err != nil {
return nil, fmt.Errorf("failed to convert decoded operation to named arguments: %w", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

should we do the same thing of not returning an error and instead putting it on the Decoded call for the same reasons as the comment above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants