@@ -200,6 +200,11 @@ func buildExecuteOperationv2Cmd(lggr logger.Logger, domain cldf_domain.Domain, p
200200 if err != nil {
201201 return fmt .Errorf ("error converting proposal to executable: %w" , err )
202202 }
203+ inspector , err := getInspectorFromChainSelector (* cfg )
204+ if err != nil {
205+ return fmt .Errorf ("failed to get inspector: %w" , err )
206+ }
207+
203208 if cfg .fork {
204209 lggr .Info ("Fork mode is on, all transactions will be executed on a forked chain" )
205210 }
@@ -213,6 +218,20 @@ func buildExecuteOperationv2Cmd(lggr logger.Logger, domain cldf_domain.Domain, p
213218 return fmt .Errorf ("operation %d is not for chain %d" , index , cfg .chainSelector )
214219 }
215220
221+ opCount , err := inspector .GetOpCount (cmd .Context (), cfg .proposal .ChainMetadata [types .ChainSelector (cfg .chainSelector )].MCMAddress )
222+ if err != nil {
223+ return fmt .Errorf ("failed to get opcount for chain %d: %w" , cfg .chainSelector , err )
224+ }
225+ txNonce := executable .TxNonce (index )
226+ if txNonce < opCount {
227+ lggr .Infow ("operation already executed" , "index" , index , "txNonce" , txNonce , "opCount" , opCount )
228+ return nil
229+ }
230+ if txNonce > opCount {
231+ lggr .Warnw ("txNonce too large" , "index" , index , "txNonce" , txNonce , "opCount" , opCount )
232+ return fmt .Errorf ("txNonce too large (%d; expected %d)" , txNonce , opCount )
233+ }
234+
216235 tx , err := executable .Execute (cmd .Context (), index )
217236 if err != nil {
218237 err = cldf .DecodeErr (bindings .ManyChainMultiSigABI , err )
@@ -1173,6 +1192,11 @@ func executeChainCommand(ctx context.Context, lggr logger.Logger, cfg *cfgv2, sk
11731192 if err != nil {
11741193 return fmt .Errorf ("error converting proposal to executable: %w" , err )
11751194 }
1195+ inspector , err := getInspectorFromChainSelector (* cfg )
1196+ if err != nil {
1197+ return fmt .Errorf ("failed to get inspector: %w" , err )
1198+ }
1199+
11761200 if cfg .fork {
11771201 lggr .Info ("Fork mode is on, all transactions will be executed on a forked chain" )
11781202 }
@@ -1183,6 +1207,20 @@ func executeChainCommand(ctx context.Context, lggr logger.Logger, cfg *cfgv2, sk
11831207 continue
11841208 }
11851209
1210+ opCount , err := inspector .GetOpCount (ctx , cfg .proposal .ChainMetadata [types .ChainSelector (cfg .chainSelector )].MCMAddress )
1211+ if err != nil {
1212+ return fmt .Errorf ("failed to get opcount for chain %d: %w" , cfg .chainSelector , err )
1213+ }
1214+ txNonce := executable .TxNonce (i )
1215+ if txNonce < opCount {
1216+ lggr .Infow ("operation already executed" , "index" , i , "txNonce" , txNonce , "opCount" , opCount )
1217+ continue
1218+ }
1219+ if txNonce > opCount {
1220+ lggr .Warnw ("txNonce too large" , "index" , i , "txNonce" , txNonce , "opCount" , opCount )
1221+ break
1222+ }
1223+
11861224 tx , err := executable .Execute (ctx , i )
11871225 if err != nil {
11881226 lggr .Errorf ("error executing operation %d: %s" , i , err )
@@ -1225,6 +1263,27 @@ func setRootCommand(ctx context.Context, lggr logger.Logger, cfg *cfgv2) error {
12251263 lggr .Info ("Fork mode is on, all transactions will be executed on a forked chain" )
12261264 }
12271265
1266+ inspector , err := getInspectorFromChainSelector (* cfg )
1267+ if err != nil {
1268+ return fmt .Errorf ("failed to get inspector: %w" , err )
1269+ }
1270+
1271+ proposalMerkleTree , err := cfg .proposal .MerkleTree ()
1272+ if err != nil {
1273+ return fmt .Errorf ("failed to compute the proposal's merkle tree: %w" , err )
1274+ }
1275+
1276+ mcmAddress := cfg .proposal .ChainMetadata [types .ChainSelector (cfg .chainSelector )].MCMAddress
1277+ mcmRoot , _ , err := inspector .GetRoot (ctx , mcmAddress )
1278+ if err != nil {
1279+ return fmt .Errorf ("failed to get the merkle tree root from the MCM contract (%v): %w" , mcmAddress , err )
1280+ }
1281+
1282+ if mcmRoot == proposalMerkleTree .Root {
1283+ lggr .Infof ("Root %v already set in MCM contract %v" , mcmRoot , mcmAddress )
1284+ return nil
1285+ }
1286+
12281287 executable , err := createExecutable (cfg )
12291288 if err != nil {
12301289 return fmt .Errorf ("error converting proposal to executable: %w" , err )
0 commit comments