Skip to content

Commit b84df77

Browse files
committed
feat: add cursing/uncursing sequences and changesets
1 parent 6764fb5 commit b84df77

2 files changed

Lines changed: 136 additions & 3 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package changesets
2+
3+
import (
4+
"fmt"
5+
6+
evm_datastore_utils "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/utils/datastore"
7+
evm_sequences "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/utils/sequences"
8+
"github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_1_0/sequences"
9+
"github.com/smartcontractkit/chainlink-ccip/deployment/utils/changesets"
10+
datastore_utils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore"
11+
"github.com/smartcontractkit/chainlink-deployments-framework/chain/evm"
12+
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
13+
cldf_deployment "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
14+
)
15+
16+
// CurseRMNCfg is the configuration for the CurseRMN changeset.
17+
// It curses the given subjects on an already-deployed RMN v2.1.0 contract.
18+
type CurseRMNCfg struct {
19+
ChainSel uint64
20+
// RMN is an address ref used to look up the deployed RMN contract in the datastore.
21+
RMN datastore.AddressRef
22+
Subjects [][16]byte
23+
}
24+
25+
func (c CurseRMNCfg) ChainSelector() uint64 {
26+
return c.ChainSel
27+
}
28+
29+
// CurseRMN curses one or more subjects on an RMN v2.1.0 contract.
30+
var CurseRMN = changesets.NewFromOnChainSequence(changesets.NewFromOnChainSequenceParams[
31+
sequences.SeqCurseInput,
32+
evm.Chain,
33+
CurseRMNCfg,
34+
]{
35+
Sequence: sequences.RmnCurse,
36+
ResolveInput: func(e cldf_deployment.Environment, cfg CurseRMNCfg) (sequences.SeqCurseInput, error) {
37+
rmnAddr, err := datastore_utils.FindAndFormatRef(e.DataStore, cfg.RMN, cfg.ChainSel, evm_datastore_utils.ToEVMAddress)
38+
if err != nil {
39+
return sequences.SeqCurseInput{}, fmt.Errorf("failed to resolve RMN ref on chain with selector %d: %w", cfg.ChainSel, err)
40+
}
41+
return sequences.SeqCurseInput{
42+
RMNAddress: rmnAddr,
43+
Subjects: cfg.Subjects,
44+
}, nil
45+
},
46+
ResolveDep: evm_sequences.ResolveEVMChainDep[CurseRMNCfg],
47+
})
48+
49+
// UncurseRMNCfg is the configuration for the UncurseRMN changeset.
50+
// It uncurses the given subjects on an already-deployed RMN v2.1.0 contract.
51+
type UncurseRMNCfg struct {
52+
ChainSel uint64
53+
// RMN is an address ref used to look up the deployed RMN contract in the datastore.
54+
RMN datastore.AddressRef
55+
Subjects [][16]byte
56+
}
57+
58+
func (c UncurseRMNCfg) ChainSelector() uint64 {
59+
return c.ChainSel
60+
}
61+
62+
// UncurseRMN uncurses one or more subjects on an RMN v2.1.0 contract.
63+
var UncurseRMN = changesets.NewFromOnChainSequence(changesets.NewFromOnChainSequenceParams[
64+
sequences.SeqUncurseInput,
65+
evm.Chain,
66+
UncurseRMNCfg,
67+
]{
68+
Sequence: sequences.RmnUncurse,
69+
ResolveInput: func(e cldf_deployment.Environment, cfg UncurseRMNCfg) (sequences.SeqUncurseInput, error) {
70+
rmnAddr, err := datastore_utils.FindAndFormatRef(e.DataStore, cfg.RMN, cfg.ChainSel, evm_datastore_utils.ToEVMAddress)
71+
if err != nil {
72+
return sequences.SeqUncurseInput{}, fmt.Errorf("failed to resolve RMN ref on chain with selector %d: %w", cfg.ChainSel, err)
73+
}
74+
return sequences.SeqUncurseInput{
75+
RMNAddress: rmnAddr,
76+
Subjects: cfg.Subjects,
77+
}, nil
78+
},
79+
ResolveDep: evm_sequences.ResolveEVMChainDep[UncurseRMNCfg],
80+
})

chains/evm/deployment/v2_1_0/sequences/rmn.go

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package sequences
33
import (
44
"fmt"
55

6-
"github.com/Masterminds/semver/v3"
76
"github.com/ethereum/go-ethereum/common"
87
"github.com/smartcontractkit/chainlink-deployments-framework/chain/evm"
98
"github.com/smartcontractkit/chainlink-deployments-framework/datastore"
@@ -26,7 +25,7 @@ type ConfigureRMNCurseAdminsInput struct {
2625
// ConfigureRMNCurseAdmins applies authorized caller (curse admin) updates to an already-deployed RMN contract.
2726
var ConfigureRMNCurseAdmins = cldf_ops.NewSequence(
2827
"configure-rmn-curse-admins",
29-
semver.MustParse("1.0.0"),
28+
rmnops.Version,
3029
"Applies authorized caller (curse admin) updates to the RMN contract",
3130
func(b cldf_ops.Bundle, chain evm.Chain, input ConfigureRMNCurseAdminsInput) (output sequences.OnChainOutput, err error) {
3231
if input.ChainSelector != chain.Selector {
@@ -66,7 +65,7 @@ type DeployRMNInput struct {
6665
// DeployRMN deploys a new RMN contract or returns the existing address from the datastore.
6766
var DeployRMN = cldf_ops.NewSequence(
6867
"deploy-rmn",
69-
semver.MustParse("1.0.0"),
68+
rmnops.Version,
7069
"Deploys the RMN (curse / IRMN) contract",
7170
func(b cldf_ops.Bundle, chain evm.Chain, input DeployRMNInput) (output sequences.OnChainOutput, err error) {
7271
if input.ChainSelector != chain.Selector {
@@ -89,3 +88,57 @@ var DeployRMN = cldf_ops.NewSequence(
8988
return output, nil
9089
},
9190
)
91+
92+
// SeqCurseInput holds the parameters for cursing one or more subjects on an RMN v2.1.0 contract.
93+
type SeqCurseInput struct {
94+
RMNAddress common.Address
95+
Subjects [][16]byte
96+
}
97+
98+
// SeqUncurseInput holds the parameters for uncursing one or more subjects on an RMN v2.1.0 contract.
99+
type SeqUncurseInput struct {
100+
RMNAddress common.Address
101+
Subjects [][16]byte
102+
}
103+
104+
// RmnCurse curses one or more subjects on an RMN v2.1.0 contract.
105+
var RmnCurse = cldf_ops.NewSequence(
106+
"rmn-curse",
107+
rmnops.Version,
108+
"Cursing subjects with RMN",
109+
func(b cldf_ops.Bundle, chain evm.Chain, in SeqCurseInput) (output sequences.OnChainOutput, err error) {
110+
opOutput, err := cldf_ops.ExecuteOperation(b, rmnops.Curse0, chain, contract.FunctionInput[[][16]byte]{
111+
Address: in.RMNAddress,
112+
ChainSelector: chain.Selector,
113+
Args: in.Subjects,
114+
})
115+
if err != nil {
116+
return sequences.OnChainOutput{}, fmt.Errorf("failed to curse with RMN at %s on chain %d: %w", in.RMNAddress.String(), chain.Selector, err)
117+
}
118+
batchOp, err := contract.NewBatchOperationFromWrites([]contract.WriteOutput{opOutput.Output})
119+
if err != nil {
120+
return sequences.OnChainOutput{}, fmt.Errorf("failed to create batch operation from writes: %w", err)
121+
}
122+
return sequences.OnChainOutput{BatchOps: []mcms_types.BatchOperation{batchOp}}, nil
123+
})
124+
125+
// RmnUncurse uncurses one or more subjects on an RMN v2.1.0 contract.
126+
var RmnUncurse = cldf_ops.NewSequence(
127+
"rmn-uncurse",
128+
rmnops.Version,
129+
"Uncursing subjects with RMN",
130+
func(b cldf_ops.Bundle, chain evm.Chain, in SeqUncurseInput) (output sequences.OnChainOutput, err error) {
131+
opOutput, err := cldf_ops.ExecuteOperation(b, rmnops.Uncurse0, chain, contract.FunctionInput[[][16]byte]{
132+
Address: in.RMNAddress,
133+
ChainSelector: chain.Selector,
134+
Args: in.Subjects,
135+
})
136+
if err != nil {
137+
return sequences.OnChainOutput{}, fmt.Errorf("failed to uncurse with RMN at %s on chain %d: %w", in.RMNAddress.String(), chain.Selector, err)
138+
}
139+
batchOp, err := contract.NewBatchOperationFromWrites([]contract.WriteOutput{opOutput.Output})
140+
if err != nil {
141+
return sequences.OnChainOutput{}, fmt.Errorf("failed to create batch operation from writes: %w", err)
142+
}
143+
return sequences.OnChainOutput{BatchOps: []mcms_types.BatchOperation{batchOp}}, nil
144+
})

0 commit comments

Comments
 (0)