Skip to content

Commit

Permalink
moving ABI to config, cleaning things up
Browse files Browse the repository at this point in the history
  • Loading branch information
patrick-dowell committed May 23, 2024
1 parent 2fed377 commit cbcf299
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 10 deletions.
16 changes: 6 additions & 10 deletions core/capabilities/targets/write_target.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,9 @@ import (
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types"
"github.com/smartcontractkit/chainlink/v2/core/chains/legacyevm"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/forwarder"
"github.com/smartcontractkit/chainlink/v2/core/logger"
)

var forwardABI = evmtypes.MustGetABI(forwarder.KeystoneForwarderMetaData.ABI)

func InitializeWrite(registry core.CapabilitiesRegistry, legacyEVMChains legacyevm.LegacyChainContainer, lggr logger.Logger) error {
for _, chain := range legacyEVMChains.Slice() {
capability := NewEvmWrite(chain, lggr)
Expand All @@ -39,8 +36,6 @@ var (
_ capabilities.ActionCapability = &EvmWrite{}
)

const defaultGasLimit = 200000

type EvmWrite struct {
chain legacyevm.Chain
capabilities.CapabilityInfo
Expand Down Expand Up @@ -121,13 +116,14 @@ func (cap *EvmWrite) Execute(ctx context.Context, request capabilities.Capabilit

// TODO: validate encoded report is prefixed with workflowID and executionID that match the request meta

txMeta := make(map[string]interface{})
txMeta := make(map[string]interface{}) // TODO: Consider just using the TxMeta struct here and pass it to submitTransaction
txMeta["WorkflowExecutionID"] = request.Metadata.WorkflowExecutionID

err = cap.submitTransaction(ctx, cap.chain.Config().EVM().ChainWriter(), inputs.Report, inputs.Signatures, reqConfig.Address, txMeta)
err = cap.submitSignedTransaction(ctx, cap.chain.Config().EVM().ChainWriter(), inputs.Report, inputs.Signatures, reqConfig.Address, txMeta)
if err != nil {
return nil, err
}
// TODO: Do we want to log something here about whether the transaction was submitted successfully?
//cap.lggr.Debugw("Transaction submitted", "request", request, "transaction", tx)

callback := make(chan capabilities.CapabilityResponse)
Expand All @@ -142,10 +138,9 @@ func (cap *EvmWrite) Execute(ctx context.Context, request capabilities.Capabilit
return callback, nil
}

func (cap *EvmWrite) submitTransaction(ctx context.Context, chainWriterConfig config.ChainWriter, report []byte, signatures [][]byte, toAddress string, txMeta map[string]interface{}) error {
cap.lggr.Debugw("submitTransaction", "chainWriterConfig", chainWriterConfig, "report", report, "signatures", signatures, "toAddress", toAddress, "txMeta", txMeta)
func (cap *EvmWrite) submitSignedTransaction(ctx context.Context, chainWriterConfig config.ChainWriter, report []byte, signatures [][]byte, toAddress string, txMeta map[string]interface{}) error {
// construct forwarder payload
// TODO: we can't assume we have the ABI locally here, we need to get it from the chain
forwardABI := evmtypes.MustGetABI(chainWriterConfig.ABI())
calldata, err := forwardABI.Pack("report", common.HexToAddress(toAddress), report, signatures)
if err != nil {
return err
Expand All @@ -159,6 +154,7 @@ func (cap *EvmWrite) submitTransaction(ctx context.Context, chainWriterConfig co
// TODO: Turn this into config
strategy := txmgrcommon.NewSendEveryStrategy()

// TODO: validate the config's checker string to ensure it's a valid checker
var checker txmgr.TransmitCheckerSpec
if chainWriterConfig.Checker() != "" {
checker.CheckerType = types.TransmitCheckerType(chainWriterConfig.Checker())
Expand Down
2 changes: 2 additions & 0 deletions core/capabilities/targets/write_target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ func TestEvmWrite(t *testing.T) {

checker := "simulate"
c.EVM[0].ChainWriter.Checker = &checker

c.EVM[0].ChainWriter.ABI = &forwarder.KeystoneForwarderMetaData.ABI
})
evmcfg := evmtest.NewChainScopedConfig(t, cfg)
chain.On("Config").Return(evmcfg)
Expand Down
8 changes: 8 additions & 0 deletions core/chains/evm/config/chain_scoped_chain_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ func (b *chainWriterConfig) ForwarderAddress() *types.EIP55Address {
func (b *chainWriterConfig) GasLimit() uint64 {
return *b.c.GasLimit
}

func (b *chainWriterConfig) Checker() string {
return *b.c.Checker
}

func (b *chainWriterConfig) ABI() string {
return *b.c.ABI
}
2 changes: 2 additions & 0 deletions core/chains/evm/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ type ChainWriter interface {
FromAddress() *types.EIP55Address
ForwarderAddress() *types.EIP55Address
GasLimit() uint64
Checker() string
ABI() string
}

type NodePool interface {
Expand Down
8 changes: 8 additions & 0 deletions core/chains/evm/config/toml/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ type ChainWriter struct {
FromAddress *types.EIP55Address `toml:",omitempty"`
ForwarderAddress *types.EIP55Address `toml:",omitempty"`
GasLimit *uint64 `toml:",omitempty"`
Checker *string `toml:",omitempty"`
ABI *string `toml:",omitempty"`
}

func (m *ChainWriter) setFrom(f *ChainWriter) {
Expand All @@ -468,6 +470,12 @@ func (m *ChainWriter) setFrom(f *ChainWriter) {
if v := f.GasLimit; v != nil {
m.GasLimit = v
}
if v := f.Checker; v != nil {
m.Checker = v
}
if v := f.ABI; v != nil {
m.ABI = v
}
}

type BalanceMonitor struct {
Expand Down
4 changes: 4 additions & 0 deletions core/config/docs/chains-evm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,7 @@ FromAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example
ForwarderAddress = '0x2a3e23c6f242F5345320814aC8a1b4E58707D292' # Example
# GasLimit controls the gas limit to be used for transactions sent via ChainWriter
GasLimit = 200000 # Default
# Checker determines which checks get performed before a transaction is broadcasted by the TXM
Checker = "simulate"
# ABI is the ABI for the keystone forwarder, to be used by ChainWriter for packing the payload to the TXM
ABI = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"DuplicateSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"InvalidDonId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"received\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"}],\"name\":\"ReportAlreadyProcessed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"name\":\"ReportProcessed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]"
4 changes: 4 additions & 0 deletions core/config/docs/docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,13 @@ func TestDoc(t *testing.T) {
require.Empty(t, docDefaults.ChainWriter.FromAddress)
require.Empty(t, docDefaults.ChainWriter.ForwarderAddress)
require.Zero(t, docDefaults.ChainWriter.GasLimit)
require.Equal(t, "", docDefaults.ChainWriter.Checker)
require.Equal(t, "", docDefaults.ChainWriter.ABI)
docDefaults.ChainWriter.FromAddress = nil
docDefaults.ChainWriter.ForwarderAddress = nil
docDefaults.ChainWriter.GasLimit = nil
docDefaults.ChainWriter.Checker = nil
docDefaults.ChainWriter.ABI = nil
docDefaults.NodePool.Errors = evmcfg.ClientErrors{}

assertTOML(t, fallbackDefaults, docDefaults)
Expand Down
8 changes: 8 additions & 0 deletions core/services/chainlink/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,14 @@ func TestConfig_full(t *testing.T) {
if got.EVM[c].ChainWriter.GasLimit == nil {
got.EVM[c].ChainWriter.GasLimit = ptr(uint64(200000))
}
if got.EVM[c].ChainWriter.Checker == nil {
checker := "simulate"
got.EVM[c].ChainWriter.Checker = &checker
}
if got.EVM[c].ChainWriter.ABI == nil {
abi := "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"DuplicateSigner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxSigners\",\"type\":\"uint256\"}],\"name\":\"ExcessSigners\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FaultToleranceMustBePositive\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"numSigners\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minSigners\",\"type\":\"uint256\"}],\"name\":\"InsufficientSigners\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"}],\"name\":\"InvalidDonId\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"received\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureCount\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"signer\",\"type\":\"address\"}],\"name\":\"InvalidSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReentrantCall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"reportId\",\"type\":\"bytes32\"}],\"name\":\"ReportAlreadyProcessed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"workflowOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"result\",\"type\":\"bool\"}],\"name\":\"ReportProcessed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"workflowExecutionId\",\"type\":\"bytes32\"}],\"name\":\"getTransmitter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiverAddress\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"rawReport\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"signatures\",\"type\":\"bytes[]\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"donId\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]"
got.EVM[c].ChainWriter.ABI = &abi
}
for n := range got.EVM[c].Nodes {
if got.EVM[c].Nodes[n].WSURL == nil {
got.EVM[c].Nodes[n].WSURL = new(commoncfg.URL)
Expand Down
Loading

0 comments on commit cbcf299

Please sign in to comment.