-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a changeset for deploying LLO contracts.
- Loading branch information
Showing
10 changed files
with
287 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
### LLO Deployments and Configurations | ||
|
||
This module contains workflows for deploying and configuring Data Streams LLO contracts. | ||
|
||
The contracts in question can be found under contracts/src/v0.8/llo-feeds. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package changeset |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package changeset | ||
|
||
import ( | ||
"github.com/smartcontractkit/chainlink/integration-tests/deployment" | ||
llodeployment "github.com/smartcontractkit/chainlink/integration-tests/deployment/llo" | ||
) | ||
|
||
func DeployChannelConfigStoreChangeSet(env deployment.Environment, c llodeployment.DeployLLOContractConfig) (deployment.ChangesetOutput, error) { | ||
ab := deployment.NewMemoryAddressBook() | ||
err := llodeployment.DeployChannelConfigStore(env, ab, c) | ||
if err != nil { | ||
env.Logger.Errorw("Failed to deploy ChannelConfigStore", "err", err, "addresses", ab) | ||
return deployment.ChangesetOutput{AddressBook: ab}, deployment.MaybeDataErr(err) | ||
} | ||
return deployment.ChangesetOutput{ | ||
AddressBook: ab, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package changeset | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/smartcontractkit/chainlink/integration-tests/deployment/llo" | ||
"github.com/smartcontractkit/chainlink/v2/core/logger" | ||
) | ||
|
||
func TestDeployChannelConfigStoreChangeSet(t *testing.T) { | ||
lggr := logger.TestLogger(t) | ||
tenv := llo.NewMemoryEnvironment(t, lggr) | ||
e := tenv.Env | ||
|
||
c := llo.DeployLLOContractConfig{ | ||
ChainsToDeploy: []uint64{llo.TestChain.Selector}, | ||
} | ||
out, err := DeployChannelConfigStoreChangeSet(e, c) | ||
require.NoError(t, err) | ||
|
||
ab, err := out.AddressBook.Addresses() | ||
require.NoError(t, err) | ||
require.Len(t, ab, 1) | ||
|
||
for sel, addrMap := range ab { | ||
require.Equal(t, llo.TestChain.Selector, sel) | ||
for _, tv := range addrMap { | ||
require.Equal(t, tv.Type, llo.ChannelConfigStore) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package llo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package llo | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/ethereum/go-ethereum/accounts/abi/bind" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/pkg/errors" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/logger" | ||
|
||
"github.com/smartcontractkit/chainlink/integration-tests/deployment" | ||
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" | ||
) | ||
|
||
type DeployLLOContractConfig struct { | ||
ChainsToDeploy []uint64 // Chain Selectors | ||
} | ||
|
||
// LLOContract covers contracts such as channel_config_store.ChannelConfigStore and fee_manager.FeeManager. | ||
type LLOContract interface { | ||
// Caller: | ||
Owner(opts *bind.CallOpts) (common.Address, error) | ||
SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) | ||
TypeAndVersion(opts *bind.CallOpts) (string, error) | ||
// Transactor: | ||
AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) | ||
TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) | ||
} | ||
|
||
type ContractDeploy[C LLOContract] struct { | ||
Address common.Address | ||
Contract C | ||
Tx *types.Transaction | ||
Tv deployment.TypeAndVersion | ||
Err error | ||
} | ||
|
||
var ( | ||
ChannelConfigStore deployment.ContractType = "ChannelConfigStore" | ||
) | ||
|
||
func DeployChannelConfigStore(e deployment.Environment, ab deployment.AddressBook, c DeployLLOContractConfig) error { | ||
nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) | ||
if err != nil || len(nodes) == 0 { | ||
e.Logger.Errorw("Failed to get node info", "err", err) | ||
return err | ||
} | ||
|
||
for _, chainSel := range c.ChainsToDeploy { | ||
chain, ok := e.Chains[chainSel] | ||
if !ok { | ||
return fmt.Errorf("Chain %d not found", chainSel) | ||
} | ||
_, err = deployChannelConfigStoreToChain(e, chain, ab) | ||
if err != nil { | ||
return err | ||
} | ||
chainAddresses, err := ab.AddressesForChain(chain.Selector) | ||
if err != nil { | ||
e.Logger.Errorw("Failed to get chain addresses", "err", err) | ||
return err | ||
} | ||
chainState, err := LoadChainState(chain, chainAddresses) | ||
if err != nil { | ||
e.Logger.Errorw("Failed to load chain state", "err", err) | ||
return err | ||
} | ||
if chainState.ChannelConfigStore == nil { | ||
errNoCCS := errors.New("no ChannelConfigStore on chain") | ||
e.Logger.Error(errNoCCS) | ||
return errNoCCS | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// deployChannelConfigStoreToChain deploys ChannelConfigStore to a specific chain. | ||
// | ||
// Note that this function modifies the given address book variable. | ||
func deployChannelConfigStoreToChain(e deployment.Environment, chain deployment.Chain, ab deployment.AddressBook) (*ContractDeploy[*channel_config_store.ChannelConfigStore], error) { | ||
return deployContract(e.Logger, chain, ab, func(chain deployment.Chain) ContractDeploy[*channel_config_store.ChannelConfigStore] { | ||
ccsAddr, ccsTx, ccs, err := channel_config_store.DeployChannelConfigStore( | ||
chain.DeployerKey, | ||
chain.Client, | ||
) | ||
if err != nil { | ||
return ContractDeploy[*channel_config_store.ChannelConfigStore]{ | ||
Err: err, | ||
} | ||
} | ||
return ContractDeploy[*channel_config_store.ChannelConfigStore]{ | ||
Address: ccsAddr, | ||
Contract: ccs, | ||
Tx: ccsTx, | ||
Tv: deployment.NewTypeAndVersion(ChannelConfigStore, deployment.Version1_0_0), | ||
Err: nil, | ||
} | ||
}) | ||
} | ||
|
||
func deployContract[C LLOContract]( | ||
lggr logger.Logger, | ||
chain deployment.Chain, | ||
addressBook deployment.AddressBook, | ||
deploy func(chain deployment.Chain) ContractDeploy[C], | ||
) (*ContractDeploy[C], error) { | ||
contractDeploy := deploy(chain) | ||
if contractDeploy.Err != nil { | ||
lggr.Errorw("Failed to deploy contract", "err", contractDeploy.Err) | ||
return nil, contractDeploy.Err | ||
} | ||
_, err := chain.Confirm(contractDeploy.Tx) | ||
if err != nil { | ||
lggr.Errorw("Failed to confirm deployment", "err", err) | ||
return nil, err | ||
} | ||
err = addressBook.Save(chain.Selector, contractDeploy.Address.String(), contractDeploy.Tv) | ||
if err != nil { | ||
lggr.Errorw("Failed to save contract address", "err", err) | ||
return nil, err | ||
} | ||
return &contractDeploy, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package llo | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
|
||
"github.com/smartcontractkit/chainlink/integration-tests/deployment" | ||
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/llo-feeds/generated/channel_config_store" | ||
) | ||
|
||
// LLOChainState holds a Go binding for all the currently deployed LLO contracts | ||
// on a chain. If a binding is nil, it means here is no such contract on the chain. | ||
type LLOChainState struct { | ||
ChannelConfigStore *channel_config_store.ChannelConfigStore | ||
} | ||
|
||
// LoadChainState Loads all state for a chain into state | ||
func LoadChainState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (LLOChainState, error) { | ||
var state LLOChainState | ||
for address, tvStr := range addresses { | ||
switch tvStr.String() { | ||
case deployment.NewTypeAndVersion(ChannelConfigStore, deployment.Version1_0_0).String(): | ||
ccs, err := channel_config_store.NewChannelConfigStore(common.HexToAddress(address), chain.Client) | ||
if err != nil { | ||
return state, err | ||
} | ||
state.ChannelConfigStore = ccs | ||
default: | ||
return state, fmt.Errorf("unknown contract %s", tvStr) | ||
} | ||
} | ||
return state, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package llo | ||
|
||
import ( | ||
"testing" | ||
|
||
chain_selectors "github.com/smartcontractkit/chain-selectors" | ||
"github.com/stretchr/testify/require" | ||
"go.uber.org/zap/zapcore" | ||
|
||
"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" | ||
|
||
"github.com/smartcontractkit/chainlink/integration-tests/deployment" | ||
"github.com/smartcontractkit/chainlink/integration-tests/deployment/memory" | ||
"github.com/smartcontractkit/chainlink/v2/core/logger" | ||
) | ||
|
||
type DeployedEnv struct { | ||
Env deployment.Environment | ||
Ab deployment.AddressBook | ||
HomeChainSel uint64 | ||
FeedChainSel uint64 | ||
ReplayBlocks map[uint64]uint64 | ||
} | ||
|
||
var ( | ||
// TestChain is the chain used by the in-memory environment. | ||
TestChain = chain_selectors.Chain{ | ||
EvmChainID: 90000001, | ||
Selector: 909606746561742123, | ||
Name: "Test Chain", | ||
VarName: "", | ||
} | ||
) | ||
|
||
// NewMemoryEnvironment creates a new LLO environment with capreg, fee tokens, feeds and nodes set up. | ||
func NewMemoryEnvironment(t *testing.T, lggr logger.Logger) DeployedEnv { | ||
chains := memory.NewMemoryChains(t, 1) | ||
rc := deployment.CapabilityRegistryConfig{} | ||
nodes := memory.NewNodes(t, zapcore.InfoLevel, chains, 4, 1, rc) | ||
ctx := testcontext.Get(t) | ||
for _, node := range nodes { | ||
require.NoError(t, node.App.Start(ctx)) | ||
t.Cleanup(func() { | ||
require.NoError(t, node.App.Stop()) | ||
}) | ||
} | ||
|
||
e := memory.NewMemoryEnvironmentFromChainsNodes(t, lggr, chains, nodes) | ||
return DeployedEnv{ | ||
Ab: deployment.NewMemoryAddressBook(), | ||
Env: e, | ||
} | ||
} |