-
Notifications
You must be signed in to change notification settings - Fork 1
feat(analyzer): Implement SUI analyzer #482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
881485d
62ba95a
e6d3122
ec7a775
92eaea6
c61f1c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"chainlink-deployments-framework": minor | ||
--- | ||
|
||
Implement SUI proposal analyzer |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,8 @@ import ( | |
"go.uber.org/zap" | ||
"go.uber.org/zap/zapcore" | ||
|
||
suibindings "github.com/smartcontractkit/chainlink-sui/bindings" | ||
|
||
"github.com/smartcontractkit/chainlink-deployments-framework/chain" | ||
"github.com/smartcontractkit/chainlink-deployments-framework/datastore" | ||
cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" | ||
|
@@ -1335,8 +1337,9 @@ func getExecutorWithChainOverride(cfg *cfgv2, chainSelector types.ChainSelector) | |
return nil, fmt.Errorf("error getting sui metadata from proposal: %w", err) | ||
} | ||
chain := cfg.blockchains.SuiChains()[uint64(chainSelector)] | ||
entrypointEncoder := suibindings.NewCCIPEntrypointArgEncoder() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just noticed the Please use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where can I get the value of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
return sui.NewExecutor(chain.Client, chain.Signer, encoder, metadata.McmsPackageID, metadata.Role, cfg.timelockProposal.ChainMetadata[chainSelector].MCMAddress, metadata.AccountObj, metadata.RegistryObj, metadata.TimelockObj) | ||
return sui.NewExecutor(chain.Client, chain.Signer, encoder, entrypointEncoder, metadata.McmsPackageID, metadata.Role, cfg.timelockProposal.ChainMetadata[chainSelector].MCMAddress, metadata.AccountObj, metadata.RegistryObj, metadata.TimelockObj) | ||
default: | ||
return nil, fmt.Errorf("unsupported chain family %s", family) | ||
} | ||
|
@@ -1381,7 +1384,8 @@ func getTimelockExecutorWithChainOverride(cfg *cfgv2, chainSelector types.ChainS | |
if err != nil { | ||
return nil, fmt.Errorf("error getting sui metadata from proposal: %w", err) | ||
} | ||
executor, err = sui.NewTimelockExecutor(chain.Client, chain.Signer, metadata.McmsPackageID, metadata.RegistryObj, metadata.AccountObj) | ||
entrypointEncoder := suibindings.NewCCIPEntrypointArgEncoder() | ||
executor, err = sui.NewTimelockExecutor(chain.Client, chain.Signer, entrypointEncoder, metadata.McmsPackageID, metadata.RegistryObj, metadata.AccountObj) | ||
if err != nil { | ||
return nil, fmt.Errorf("error creating sui timelock executor: %w", err) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package analyzer | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/smartcontractkit/chainlink-deployments-framework/experimental/proposalutils" | ||
"github.com/smartcontractkit/chainlink-sui/bindings/generated" | ||
mcmssuisdk "github.com/smartcontractkit/mcms/sdk/sui" | ||
"github.com/smartcontractkit/mcms/types" | ||
) | ||
|
||
func AnalyzeSuiTransactions(ctx ProposalContext, chainSelector uint64, txs []types.Transaction) ([]*proposalutils.DecodedCall, error) { | ||
decoder := mcmssuisdk.NewDecoder() | ||
decodedTxs := make([]*proposalutils.DecodedCall, len(txs)) | ||
for i, op := range txs { | ||
analyzedTransaction, err := AnalyzeSuiTransaction(ctx, decoder, chainSelector, op) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to analyze Sui transaction %d: %w", i, err) | ||
} | ||
decodedTxs[i] = analyzedTransaction | ||
} | ||
|
||
return decodedTxs, nil | ||
} | ||
|
||
func AnalyzeSuiTransaction(ctx ProposalContext, decoder *mcmssuisdk.Decoder, chainSelector uint64, mcmsTx types.Transaction) (*proposalutils.DecodedCall, error) { | ||
var additionalFields mcmssuisdk.AdditionalFields | ||
if err := json.Unmarshal(mcmsTx.AdditionalFields, &additionalFields); err != nil { | ||
return nil, fmt.Errorf("failed to unmarshal Sui additional fields: %w", err) | ||
} | ||
|
||
functionInfo := generated.FunctionInfoByModule[additionalFields.ModuleName] | ||
decodedOp, err := decoder.Decode(mcmsTx, functionInfo) | ||
if err != nil { | ||
// Don't return an error to not block the whole proposal decoding because of a single missing method | ||
errStr := fmt.Errorf("failed to decode Sui transaction: %w", err) | ||
|
||
return &proposalutils.DecodedCall{ | ||
Address: mcmsTx.To, | ||
Method: errStr.Error(), | ||
}, nil | ||
} | ||
namedArgs, err := toNamedArguments(decodedOp) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to convert decoded operation to named arguments: %w", err) | ||
} | ||
|
||
return &proposalutils.DecodedCall{ | ||
Address: mcmsTx.To, | ||
Method: decodedOp.MethodName(), | ||
Inputs: namedArgs, | ||
Outputs: []proposalutils.NamedArgument{}, | ||
}, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean the encoder won't work with contracts from other products? (if/when they are created)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It means that new products will need their own product encoders, or extend the existing one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we should figure out a way to allow product teams to specify their encoders from within their domain and pass it to the mcms CLI. See, for example, how the encoder for EVM is implemented (though I think that implementation can be simplified).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I'll look into the EVM encoder.
For this case I thought on allowing multiple Encoders to be passed to the MCMS lib, and probably the proposal would indicate the product is using, and select the Encoder based on it. I'll note to dive and add this into MCMS