Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 88 additions & 70 deletions go.mod

Large diffs are not rendered by default.

436 changes: 239 additions & 197 deletions go.sum

Large diffs are not rendered by default.

159 changes: 82 additions & 77 deletions integration-tests/go.mod

Large diffs are not rendered by default.

291 changes: 190 additions & 101 deletions integration-tests/go.sum

Large diffs are not rendered by default.

123 changes: 123 additions & 0 deletions pkg/cosmos/CONFIG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
TODO header
## Example

```toml
TODO example
```

## Global
```toml
ChainID = 'Malaga-420' # Example
Enabled = true # Default
Bech32Prefix = 'wasm' # Default
BlockRate = '6s' # Default
BlocksUntilTxTimeout = 30 # Default
ConfirmPollPeriod = '1s' # Default
FallbackGasPrice = '0.015' # Default
GasToken = 'ucosm' # Default
GasLimitMultiplier = '1.5' # Default
MaxMsgsPerBatch = 100 # Default
OCR2CachePollPeriod = '4s' # Default
OCR2CacheTTL = '1m' # Default
TxMsgTimeout = '10m' # Default
```


### ChainID
```toml
ChainID = 'Malaga-420' # Example
```
ChainID TODO

### Enabled
```toml
Enabled = true # Default
```
Enabled TODO

### Bech32Prefix
```toml
Bech32Prefix = 'wasm' # Default
```
Bech32Prefix TODO

### BlockRate
```toml
BlockRate = '6s' # Default
```
BlockRate TODO

### BlocksUntilTxTimeout
```toml
BlocksUntilTxTimeout = 30 # Default
```
BlocksUntilTxTimeout TODO

### ConfirmPollPeriod
```toml
ConfirmPollPeriod = '1s' # Default
```
ConfirmPollPeriod TODO

### FallbackGasPrice
```toml
FallbackGasPrice = '0.015' # Default
```
FallbackGasPrice TODO

### GasToken
```toml
GasToken = 'ucosm' # Default
```
GasToken TODO

### GasLimitMultiplier
```toml
GasLimitMultiplier = '1.5' # Default
```
GasLimitMultiplier TODO

### MaxMsgsPerBatch
```toml
MaxMsgsPerBatch = 100 # Default
```
MaxMsgsPerBatch TODO

### OCR2CachePollPeriod
```toml
OCR2CachePollPeriod = '4s' # Default
```
OCR2CachePollPeriod TODO

### OCR2CacheTTL
```toml
OCR2CacheTTL = '1m' # Default
```
OCR2CacheTTL TODO

### TxMsgTimeout
```toml
TxMsgTimeout = '10m' # Default
```
TxMsgTimeout TODO

## Nodes
```toml
[[Nodes]]
Name = 'primary' # Example
TendermintURL = 'http://tender.mint' # Example
```


### Name
```toml
Name = 'primary' # Example
```
Name TODO

### TendermintURL
```toml
TendermintURL = 'http://tender.mint' # Example
```
TendermintURL TODO

12 changes: 12 additions & 0 deletions pkg/cosmos/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/pelletier/go-toml/v2"
chain_selectors "github.com/smartcontractkit/chain-selectors"

"github.com/smartcontractkit/chainlink-common/pkg/chains"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
Expand Down Expand Up @@ -82,6 +83,15 @@ type chain struct {
lggr logger.Logger
}

func (c *chain) GetChainInfo(ctx context.Context) (types.ChainInfo, error) {
return types.ChainInfo{
FamilyName: chain_selectors.FamilyCosmos,
ChainID: c.id,
NetworkName: "", //TODO
NetworkNameFull: "", //TODO
}, nil
}

func newChain(id string, cfg *config.TOMLConfig, ds sqlutil.DataSource, ks loop.Keystore, lggr logger.Logger) (*chain, error) {
lggr = logger.With(lggr, "cosmosChainID", id)
var ch = chain{
Expand Down Expand Up @@ -128,6 +138,8 @@ func (c *chain) Reader(name string) (client.Reader, error) {
return c.getClient(name)
}

func (c *chain) Replay(context.Context, string, map[string]any) error { return nil }

// getClient returns a client, optionally requiring a specific node by name.
func (c *chain) getClient(name string) (client.ReaderWriter, error) {
var node db.Node
Expand Down
2 changes: 1 addition & 1 deletion pkg/cosmos/cmd/chainlink-cosmos/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type pluginRelayer struct {
ds sqlutil.DataSource
}

func (c *pluginRelayer) NewRelayer(ctx context.Context, config string, keystore loop.Keystore, capRegistry core.CapabilitiesRegistry) (loop.Relayer, error) {
func (c *pluginRelayer) NewRelayer(ctx context.Context, config string, keystore, csaKeystore core.Keystore, capRegistry core.CapabilitiesRegistry) (loop.Relayer, error) {
d := toml.NewDecoder(strings.NewReader(config))
d.DisallowUnknownFields()

Expand Down
24 changes: 24 additions & 0 deletions pkg/cosmos/cmd/config-docs/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"flag"
"fmt"
"log"
"os"
"path"

"github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/config"
)

var outDir = flag.String("o", "", "output directory")

func main() {
s, err := config.GenerateDocs()
if err != nil {
log.Fatalln("Failed to generate docs:", err)
}
if err = os.WriteFile(path.Join(*outDir, "CONFIG.md"), []byte(s), 0600); err != nil {
fmt.Fprintf(os.Stderr, "failed to write config docs: %v\n", err)
os.Exit(1)
}
}
91 changes: 21 additions & 70 deletions pkg/cosmos/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,33 @@ package config
import (
"errors"
"fmt"
"log"
"net/url"
"slices"
"strings"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/pelletier/go-toml/v2"
"github.com/shopspring/decimal"

"github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/config/configtest"

"github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/client"
"github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db"
)

// Global defaults.
var defaultConfigSet = configSet{
BlockRate: 6 * time.Second,
// ~6s per block, so ~3m until we give up on the tx getting confirmed
// Anecdotally it appears anything more than 4 blocks would be an extremely long wait,
// In practice during the UST depegging and subsequent extreme congestion, we saw
// ~16 block FIFO lineups.
BlocksUntilTxTimeout: 30,
ConfirmPollPeriod: time.Second,
FallbackGasPrice: sdk.MustNewDecFromStr("0.015"),
// This is high since we simulate before signing the transaction.
// There's a chicken and egg problem: need to sign to simulate accurately
// but you need to specify a gas limit when signing.
// TODO: Determine how much gas a signature adds and then
// add that directly so we can be more accurate.
GasLimitMultiplier: client.DefaultGasLimitMultiplier,
// The max gas limit per block is 1_000_000_000
// https://github.com/terra-money/core/blob/d6037b9a12c8bf6b09fe861c8ad93456aac5eebb/app/legacy/migrate.go#L69.
// The max msg size is 10KB https://github.com/terra-money/core/blob/d6037b9a12c8bf6b09fe861c8ad93456aac5eebb/x/wasm/types/params.go#L15.
// Our msgs are only OCR reports for now, which will not exceed that size.
// There appears to be no gas limit per tx, only per block, so theoretically
// we could include 1000 msgs which use up to 1M gas.
// To be conservative and since the number of messages we'd
// have in a batch on average roughly corresponds to the number of terra ocr jobs we're running (do not expect more than 100),
// we can set a max msgs per batch of 100.
MaxMsgsPerBatch: 100,
OCR2CachePollPeriod: 4 * time.Second,
OCR2CacheTTL: time.Minute,
TxMsgTimeout: 10 * time.Minute,
Bech32Prefix: "wasm", // note: this shouldn't be used outside of tests
GasToken: "ucosm", // note: this shouldn't be used outside of tests
var defaults TOMLConfig

func init() {
if err := configtest.DocDefaultsOnly(strings.NewReader(docsTOML), &defaults, config.DecodeTOML); err != nil {
log.Fatalf("Failed to initialize defaults from docs: %v", err)
}
}

func Defaults() (c TOMLConfig) {
c.SetFrom(&defaults)
return
}

type Config interface {
Expand Down Expand Up @@ -93,44 +75,6 @@ type Chain struct {
TxMsgTimeout *config.Duration
}

func (c *Chain) SetDefaults() {
if c.Bech32Prefix == nil {
c.Bech32Prefix = &defaultConfigSet.Bech32Prefix
}
if c.BlockRate == nil {
c.BlockRate = config.MustNewDuration(defaultConfigSet.BlockRate)
}
if c.BlocksUntilTxTimeout == nil {
c.BlocksUntilTxTimeout = &defaultConfigSet.BlocksUntilTxTimeout
}
if c.ConfirmPollPeriod == nil {
c.ConfirmPollPeriod = config.MustNewDuration(defaultConfigSet.ConfirmPollPeriod)
}
if c.FallbackGasPrice == nil {
d := decimal.NewFromBigInt(defaultConfigSet.FallbackGasPrice.BigInt(), -sdk.Precision)
c.FallbackGasPrice = &d
}
if c.GasToken == nil {
c.GasToken = &defaultConfigSet.GasToken
}
if c.GasLimitMultiplier == nil {
d := decimal.NewFromFloat(defaultConfigSet.GasLimitMultiplier)
c.GasLimitMultiplier = &d
}
if c.MaxMsgsPerBatch == nil {
c.MaxMsgsPerBatch = &defaultConfigSet.MaxMsgsPerBatch
}
if c.OCR2CachePollPeriod == nil {
c.OCR2CachePollPeriod = config.MustNewDuration(defaultConfigSet.OCR2CachePollPeriod)
}
if c.OCR2CacheTTL == nil {
c.OCR2CacheTTL = config.MustNewDuration(defaultConfigSet.OCR2CacheTTL)
}
if c.TxMsgTimeout == nil {
c.TxMsgTimeout = config.MustNewDuration(defaultConfigSet.TxMsgTimeout)
}
}

type Node struct {
Name *string
TendermintURL *config.URL
Expand Down Expand Up @@ -249,6 +193,13 @@ func (c *TOMLConfig) IsEnabled() bool {
return c.Enabled == nil || *c.Enabled
}

func (c *TOMLConfig) SetDefaults() {
def := Defaults()
def.SetFrom(c)
*c = def

}

func (c *TOMLConfig) SetFrom(f *TOMLConfig) {
if f.ChainID != nil {
c.ChainID = f.ChainID
Expand Down
41 changes: 41 additions & 0 deletions pkg/cosmos/config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package config

import (
_ "embed"
"reflect"
"testing"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/shopspring/decimal"
"github.com/stretchr/testify/assert"

"github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/config/configtest"

"github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos/db"
)
Expand Down Expand Up @@ -94,3 +97,41 @@ func TestCosmosConfig_GetNode(t *testing.T) {
func ptr[T any](t T) *T {
return &t
}

func TestDefaults_fieldsNotNil(t *testing.T) {
configtest.AssertFieldsNotNil(t, Defaults())
}

func TestDocsTOMLComplete(t *testing.T) {
configtest.AssertDocsTOMLComplete[TOMLConfig](t, docsTOML)
}

//go:embed testdata/config-full.toml
var fullTOML string

func TestTOMLConfig_FullMarshal(t *testing.T) {
full := TOMLConfig{
ChainID: ptr("Ibiza-808"),
Enabled: ptr(true),
Chain: Chain{
Bech32Prefix: ptr("wasm"),
BlockRate: config.MustNewDuration(time.Minute),
BlocksUntilTxTimeout: ptr[int64](12),
ConfirmPollPeriod: config.MustNewDuration(time.Second),
FallbackGasPrice: ptr(decimal.RequireFromString("0.001")),
GasToken: ptr("ucosm"),
GasLimitMultiplier: ptr(decimal.RequireFromString("1.2")),
MaxMsgsPerBatch: ptr[int64](17),
OCR2CachePollPeriod: config.MustNewDuration(time.Minute),
OCR2CacheTTL: config.MustNewDuration(time.Hour),
TxMsgTimeout: config.MustNewDuration(time.Second),
},
Nodes: []*Node{
{
Name: ptr("primary"),
TendermintURL: config.MustParseURL("http://columbus.cosmos.com"),
},
},
}
configtest.AssertFullMarshal(t, full, fullTOML)
}
15 changes: 15 additions & 0 deletions pkg/cosmos/config/docs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package config

import (
_ "embed"

"github.com/smartcontractkit/chainlink-common/pkg/config/configdoc"
)

//go:embed docs.toml
var docsTOML string

func GenerateDocs() (string, error) {
//TODO auto-insert newline?
return configdoc.Generate(docsTOML, "TODO header", "TODO example\n", nil)
}
Loading
Loading