Skip to content

Commit df67e61

Browse files
Merge branch 'main' into DAPP-7236-ts-standard-tests
2 parents 5dfd052 + d3af2df commit df67e61

File tree

9 files changed

+236
-12
lines changed

9 files changed

+236
-12
lines changed

pkg/capabilities/consensus/ocr3/datafeeds/securemint_aggregator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func (f *evmReportFormatter) packReport(lggr logger.Logger, report *secureMintRe
126126
map[EVMEncoderKey]any{
127127
DataIDOutputFieldName: f.dataID,
128128
AnswerOutputFieldName: smReportAsAnswer,
129-
TimestampOutputFieldName: uint32(report.Block),
129+
TimestampOutputFieldName: uint32(report.SeqNr),
130130
},
131131
}
132132

@@ -166,13 +166,13 @@ func (f *solanaReportFormatter) packReport(lggr logger.Logger, report *secureMin
166166
accountContextHash := sha256.Sum256(accounts)
167167
lggr.Debugw("calculated account context hash", "accountContextHash", accountContextHash)
168168

169-
if report.Block > (1<<32 - 1) { // timestamp must fit in u32 in solana
170-
return nil, fmt.Errorf("timestamp exceeds u32 bounds: %v", report.Block)
169+
if report.SeqNr > (1<<32 - 1) { // timestamp must fit in u32 in solana
170+
return nil, fmt.Errorf("timestamp exceeds u32 bounds: %v", report.SeqNr)
171171
}
172172

173173
toWrap := []any{
174174
map[SolanaEncoderKey]any{
175-
SolTimestampOutputFieldName: uint32(report.Block), // TODO: Verify with Michael/Geert timestamp should be block number?
175+
SolTimestampOutputFieldName: uint32(report.SeqNr),
176176
SolAnswerOutputFieldName: smReportAsAnswer,
177177
SolDataIDOutputFieldName: f.dataID,
178178
},

pkg/capabilities/consensus/ocr3/datafeeds/securemint_aggregator_test.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func TestSecureMintAggregator_Aggregate(t *testing.T) {
3737
dataID string
3838
solAccounts [][32]byte
3939
previousOutcome *types.AggregationOutcome
40+
seqNr uint64
4041
observations map[ocrcommon.OracleID][]values.Value
4142
f int
4243
expectedShouldReport bool
@@ -69,7 +70,7 @@ func TestSecureMintAggregator_Aggregate(t *testing.T) {
6970
assert.NotNil(t, answer)
7071

7172
timestamp := report[TimestampOutputFieldName].(int64)
72-
assert.Equal(t, int64(1000), timestamp)
73+
assert.Equal(t, int64(tc.seqNr), timestamp)
7374
}
7475

7576
solReportAssertFn := func(t *testing.T, tc tcase, topLevelMap map[string]any) {
@@ -100,14 +101,15 @@ func TestSecureMintAggregator_Aggregate(t *testing.T) {
100101
assert.NotNil(t, answer)
101102

102103
timestamp := report[SolTimestampOutputFieldName].(int64)
103-
assert.Equal(t, int64(1000), timestamp)
104+
assert.Equal(t, int64(tc.seqNr), timestamp)
104105
}
105106

106107
tests := []tcase{
107108
{
108109
name: "successful eth report extraction",
109110
chainSelector: "16015286601757825753",
110111
dataID: "0x01c508f42b0201320000000000000000",
112+
seqNr: 10,
111113
observations: createSecureMintObservations(t, []ocrTriggerEventData{
112114
{
113115
chainSelector: ethSepoliaChainSelector,
@@ -121,10 +123,10 @@ func TestSecureMintAggregator_Aggregate(t *testing.T) {
121123
},
122124
{
123125
chainSelector: bnbTestnetChainSelector,
124-
seqNr: 11,
126+
seqNr: 10,
125127
report: &secureMintReport{
126128
ConfigDigest: ocr2types.ConfigDigest{0: 2, 31: 3},
127-
SeqNr: 11,
129+
SeqNr: 10,
128130
Block: 1100,
129131
Mintable: big.NewInt(200),
130132
},
@@ -139,6 +141,7 @@ func TestSecureMintAggregator_Aggregate(t *testing.T) {
139141
name: "no matching chain selector found",
140142
chainSelector: "16015286601757825753",
141143
dataID: "0x01c508f42b0201320000000000000000",
144+
seqNr: 10,
142145
observations: createSecureMintObservations(t, []ocrTriggerEventData{
143146
{
144147
chainSelector: bnbTestnetChainSelector,
@@ -160,6 +163,7 @@ func TestSecureMintAggregator_Aggregate(t *testing.T) {
160163
name: "no observations",
161164
chainSelector: "16015286601757825753",
162165
dataID: "0x01c508f42b0201320000000000000000",
166+
seqNr: 10,
163167
observations: map[ocrcommon.OracleID][]values.Value{},
164168
f: 1,
165169
expectError: true,
@@ -169,6 +173,7 @@ func TestSecureMintAggregator_Aggregate(t *testing.T) {
169173
name: "successful sol report extraction",
170174
chainSelector: "16423721717087811551", // solana devnet
171175
dataID: "0x01c508f42b0201320000000000000000",
176+
seqNr: 10,
172177
solAccounts: [][32]byte{acc1, acc2},
173178
observations: createSecureMintObservations(t, []ocrTriggerEventData{
174179
{
@@ -183,10 +188,10 @@ func TestSecureMintAggregator_Aggregate(t *testing.T) {
183188
},
184189
{
185190
chainSelector: bnbTestnetChainSelector,
186-
seqNr: 11,
191+
seqNr: 10,
187192
report: &secureMintReport{
188193
ConfigDigest: ocr2types.ConfigDigest{0: 2, 31: 3},
189-
SeqNr: 11,
194+
SeqNr: 10,
190195
Block: 1100,
191196
Mintable: big.NewInt(200),
192197
},

pkg/config/rate.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ func ParseRate(s string) (Rate, error) {
3333
}
3434
rateLimit.Limit = rate.Every(d)
3535
} else {
36-
s = strings.TrimSuffix(s, "rps") // allowed but not required
37-
f, err := strconv.ParseFloat(s, 64)
36+
parts[0] = strings.TrimSuffix(parts[0], "rps") // allowed but not required
37+
f, err := strconv.ParseFloat(parts[0], 64)
3838
if err != nil {
3939
return Rate{}, err
4040
}

pkg/settings/cresettings/settings.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
package cresettings
33

44
import (
5+
"encoding/json"
56
"log"
7+
"os"
68
"time"
79

810
"golang.org/x/time/rate"
@@ -12,6 +14,12 @@ import (
1214
)
1315

1416
func init() {
17+
if v, ok := os.LookupEnv("CL_CRE_SETTINGS"); ok {
18+
err := json.Unmarshal([]byte(v), &Default)
19+
if err != nil {
20+
log.Fatalf("failed to initialize defaults: %v", err)
21+
}
22+
}
1523
err := InitConfig(&Default)
1624
if err != nil {
1725
log.Fatalf("failed to initialize keys: %v", err)

pkg/settings/cresettings/settings_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import (
77
"log"
88
"os"
99
"testing"
10+
"time"
1011

1112
"github.com/pelletier/go-toml/v2"
13+
"github.com/stretchr/testify/assert"
1214
"github.com/stretchr/testify/require"
15+
"golang.org/x/time/rate"
16+
17+
"github.com/smartcontractkit/chainlink-common/pkg/config"
1318
)
1419

1520
var update = flag.Bool("update", false, "update the golden files of this test")
@@ -52,3 +57,54 @@ func TestDefault(t *testing.T) {
5257
}
5358
})
5459
}
60+
61+
func TestSchema_Unmarshal(t *testing.T) {
62+
cfg := Default
63+
require.NoError(t, json.Unmarshal([]byte(`{
64+
"WorkflowLimit": "500",
65+
"HTTPTrigger": {
66+
"AuthRateLimit": "200rps:50"
67+
},
68+
"PerOrg": {
69+
"ZeroBalancePruningTimeout": "48h"
70+
},
71+
"PerOwner": {
72+
"WorkflowExecutionConcurrencyLimit": "99"
73+
},
74+
"PerWorkflow": {
75+
"WASMMemoryLimit": "250mb",
76+
"CRONTrigger": {
77+
"RateLimit": "every10s:5"
78+
},
79+
"HTTPTrigger": {
80+
"IncomingPayloadSizeLimit": "14kb"
81+
},
82+
"LogTrigger": {
83+
"EventRateLimit": "every13s:6"
84+
},
85+
"HTTPAction": {
86+
"RateLimit": "every3s:5"
87+
},
88+
"ChainWrite": {
89+
"EVM": {
90+
"TransactionGasLimit": "500000"
91+
}
92+
},
93+
"ChainRead": {
94+
"CallLimit": "3"
95+
}
96+
}
97+
}`), &cfg))
98+
99+
assert.Equal(t, 500, cfg.WorkflowLimit.DefaultValue)
100+
assert.Equal(t, config.Rate{Limit: 200, Burst: 50}, cfg.HTTPTrigger.AuthRateLimit.DefaultValue)
101+
assert.Equal(t, 48*time.Hour, cfg.PerOrg.ZeroBalancePruningTimeout.DefaultValue)
102+
assert.Equal(t, 99, cfg.PerOwner.WorkflowExecutionConcurrencyLimit.DefaultValue)
103+
assert.Equal(t, 250*config.MByte, cfg.PerWorkflow.WASMMemoryLimit.DefaultValue)
104+
assert.Equal(t, config.Rate{Limit: rate.Every(10 * time.Second), Burst: 5}, cfg.PerWorkflow.CRONTrigger.RateLimit.DefaultValue)
105+
assert.Equal(t, 14*config.KByte, cfg.PerWorkflow.HTTPTrigger.IncomingPayloadSizeLimit.DefaultValue)
106+
assert.Equal(t, config.Rate{Limit: rate.Every(13 * time.Second), Burst: 6}, cfg.PerWorkflow.LogTrigger.EventRateLimit.DefaultValue)
107+
assert.Equal(t, config.Rate{Limit: rate.Every(3 * time.Second), Burst: 5}, cfg.PerWorkflow.HTTPAction.RateLimit.DefaultValue)
108+
assert.Equal(t, 500000, cfg.PerWorkflow.ChainWrite.EVM.TransactionGasLimit.DefaultValue)
109+
assert.Equal(t, 3, cfg.PerWorkflow.ChainRead.CallLimit.DefaultValue)
110+
}

pkg/settings/settings.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,17 @@ func (s Setting[T]) MarshalText() ([]byte, error) {
4444
return []byte(fmt.Sprintf("%v", s.DefaultValue)), nil
4545
}
4646

47+
func (s *Setting[T]) UnmarshalText(b []byte) (err error) {
48+
if len(b) >= 2 && b[0] == '"' && b[len(b)-1] == '"' {
49+
b = b[1 : len(b)-1] // unquote string
50+
}
51+
s.DefaultValue, err = s.Parse(string(b))
52+
if err != nil {
53+
err = fmt.Errorf("%s: failed to parse %s: %w", s.Key, string(b), err)
54+
}
55+
return
56+
}
57+
4758
func (s *Setting[T]) initSetting(key string, scope Scope, unit *string) error {
4859
s.Key = key
4960
s.Scope = scope

pkg/types/aptos/contract_reader.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package aptos
2+
3+
import (
4+
"github.com/smartcontractkit/chainlink-common/pkg/types"
5+
)
6+
7+
type ContractReaderConfig struct {
8+
IsLoopPlugin bool
9+
Modules map[string]*ContractReaderModule
10+
}
11+
12+
type ContractReaderModule struct {
13+
// The module name (optional). When not provided, the key in the map under which this module
14+
// is stored is used.
15+
Name string
16+
Functions map[string]*ContractReaderFunction
17+
Events map[string]*ContractReaderEvent
18+
}
19+
20+
type ContractReaderFunction struct {
21+
// The function name (optional). When not provided, the key in the map under which this function
22+
// is stored is used.
23+
Name string
24+
Params []FunctionParam
25+
26+
ResultFieldRenames map[string]RenamedField
27+
ResultTupleToStruct []string
28+
ResultUnwrapStruct []string
29+
}
30+
31+
type FunctionParam struct {
32+
// The function parameter name.
33+
Name string
34+
// The function parameter Move type.
35+
Type string
36+
// True if this is a required parameter, false otherwise.
37+
Required bool
38+
// If this is not a required parameter and it is not provided, this default value will be used.
39+
DefaultValue any
40+
}
41+
42+
type ContractReaderEvent struct {
43+
// The struct where the event handle is defined.
44+
EventHandleStructName string
45+
46+
// The name of the event handle field.
47+
// This field can be defined as path to the nested
48+
// struct that stores the event, e.g. "token_pool_state.burned_events"
49+
EventHandleFieldName string
50+
51+
// The event account address.
52+
// This field can be defined in several ways:
53+
// - Empty string, which means the event account address is the address of the bound contract.
54+
// - An exact address hex string (eg. 0x1234 or 1234) containing the events.
55+
// - A fully qualified function name (eg. 0x1234::my_contract::get_event_address) which
56+
// takes no parameters and returns the actual event account address.
57+
// - A name containing the module name and function name components
58+
// (eg. my_first_contract::get_event_address) stored at the address of the bound contract,
59+
// which takes no parameters and returns the actual event account address.
60+
EventAccountAddress string
61+
62+
// Renames of event field names (optional). When not provided, the field names are used as-is.
63+
EventFieldRenames map[string]RenamedField
64+
65+
// Renames provided filters to match the event field names (optional). When not provided, the filters are used as-is.
66+
EventFilterRenames map[string]string
67+
}
68+
69+
type RenamedField struct {
70+
// The new field name (optional). This does not need to be provided if this field does not need
71+
// to be renamed.
72+
NewName string
73+
74+
// Rename sub-fields. This assumes that the event field value is a struct or a map with string keys.
75+
SubFieldRenames map[string]RenamedField
76+
}
77+
78+
type SequenceWithMetadata struct {
79+
Sequence types.Sequence
80+
TxVersion uint64
81+
TxHash string
82+
}

pkg/types/aptos/contract_writer.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package aptos
2+
3+
type FeeStrategy int
4+
5+
const (
6+
DeprioritizedFeeStrategy FeeStrategy = -1
7+
DefaultFeeStrategy FeeStrategy = 0
8+
PrioritizedFeeStrategy FeeStrategy = 1
9+
)
10+
11+
type ContractWriterConfig struct {
12+
Modules map[string]*ContractWriterModule
13+
FeeStrategy FeeStrategy
14+
}
15+
16+
type ContractWriterModule struct {
17+
// The module name (optional). When not provided, the key in the map under which this module
18+
// is stored is used.
19+
Name string
20+
Functions map[string]*ContractWriterFunction
21+
}
22+
23+
type ContractWriterFunction struct {
24+
// The function name (optional). When not provided, the key in the map under which this function
25+
// is stored is used.
26+
Name string
27+
// The public key of the sending account.
28+
PublicKey string
29+
// The account address (optional). When not provided, the address is calculated
30+
// from the public key.
31+
FromAddress string
32+
Params []FunctionParam
33+
}

pkg/types/core/gateway_connector.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package core
33
import (
44
"context"
55
"encoding/json"
6+
"fmt"
67

78
jsonrpc "github.com/smartcontractkit/chainlink-common/pkg/jsonrpc2"
89
)
@@ -30,3 +31,31 @@ type GatewayConnectorHandler interface {
3031
// HandleGatewayMessage is called when a message is received from a gateway
3132
HandleGatewayMessage(ctx context.Context, gatewayID string, req *jsonrpc.Request[json.RawMessage]) error
3233
}
34+
35+
var _ GatewayConnector = (*UnimplementedGatewayConnector)(nil)
36+
37+
type UnimplementedGatewayConnector struct{}
38+
39+
func (u *UnimplementedGatewayConnector) AddHandler(ctx context.Context, methods []string, handler GatewayConnectorHandler) error {
40+
return fmt.Errorf("not implemented")
41+
}
42+
43+
func (u *UnimplementedGatewayConnector) SendToGateway(ctx context.Context, gatewayID string, resp *jsonrpc.Response[json.RawMessage]) error {
44+
return fmt.Errorf("not implemented")
45+
}
46+
47+
func (u *UnimplementedGatewayConnector) SignMessage(ctx context.Context, msg []byte) ([]byte, error) {
48+
return nil, fmt.Errorf("not implemented")
49+
}
50+
51+
func (u *UnimplementedGatewayConnector) GatewayIDs(ctx context.Context) ([]string, error) {
52+
return nil, fmt.Errorf("not implemented")
53+
}
54+
55+
func (u *UnimplementedGatewayConnector) DonID(ctx context.Context) (string, error) {
56+
return "", fmt.Errorf("not implemented")
57+
}
58+
59+
func (u *UnimplementedGatewayConnector) AwaitConnection(ctx context.Context, gatewayID string) error {
60+
return fmt.Errorf("not implemented")
61+
}

0 commit comments

Comments
 (0)