Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
c6dc3d6
Copy of llo integration test
cll-gg May 26, 2025
c889993
Remove other tests
cll-gg May 26, 2025
ad34149
Remove more unused code
cll-gg May 26, 2025
e640516
Remove a bit more
cll-gg May 26, 2025
6fdedd9
Remove more unused code
cll-gg May 26, 2025
e42d99d
Just run one test
cll-gg May 26, 2025
7a5a0ea
Remove a bit more
cll-gg May 26, 2025
07132ea
WIP addSecureMintOCRJobs (fails atm)
cll-gg May 26, 2025
ea79090
Add some logging
cll-gg May 27, 2025
f4d3d4c
Typo
cll-gg May 27, 2025
535cd32
Create eth key in node to have a transmitter
cll-gg May 27, 2025
dc91356
Allow no bootstrappers to make the job start up
cll-gg May 27, 2025
69d5525
Fix parameters (broken two commits ago)
cll-gg May 27, 2025
05eba5f
Use non-zero contract address so that logpoller starts up
cll-gg May 27, 2025
eea5b31
Bridge is now called and returns data (observation fails)
cll-gg May 27, 2025
ab11de2
Add some notes
cll-gg May 27, 2025
8418fe9
WIP: validate jobs running successfully
cll-gg May 27, 2025
8911317
Make test logging more manageable
cll-gg May 28, 2025
7dad43c
Fix observation
cll-gg May 28, 2025
1df5dc5
Improve logging
cll-gg May 28, 2025
dfb1a4d
Make it work by not asserting on saved pipeline runs (secure mint pip…
cll-gg May 28, 2025
b87c271
Enable validation
cll-gg May 28, 2025
43140df
Use pluginType = securemint now. All parts to update are tagged with …
cll-gg May 28, 2025
3f08384
Fix unit test
cll-gg May 28, 2025
d0c9106
Use plugin config from new plugin repo repo
cll-gg May 29, 2025
2421772
Create NewSecureMintServices
cll-gg May 29, 2025
9a0c1bc
Implemented part of the delegate and part of the service
cll-gg May 29, 2025
b4ca53a
Use SecureMintOCR3OnchainKeyringAdapter to make it possible to use th…
cll-gg May 30, 2025
0fca34e
Try to set contract config - plugin doesn't get created otherwise (WIP)
cll-gg May 30, 2025
f2ab95c
Set the onchain config
cll-gg May 30, 2025
96702ca
Use stub contract transmitter
cll-gg May 30, 2025
af75e5c
WIP onchain config
cll-gg May 30, 2025
1864a58
Use mock dependencies for now
cll-gg Jun 2, 2025
35a35c4
Deploy DF Cache contract and set onchain config on it
cll-gg Jun 2, 2025
a3725c7
More clarity on onchain contract usage
cll-gg Jun 2, 2025
097eef4
Set secureMintOnchainConfigUsingEvmSimpleConfig
cll-gg Jun 3, 2025
f6e4b14
Step further in using the simple config
cll-gg Jun 3, 2025
b5999d7
Two vibe-coded files to help
cll-gg Jun 3, 2025
2d30733
One step further: configPollerEVMSimple reads on-chain config
cll-gg Jun 3, 2025
46def63
Bit more print
cll-gg Jun 3, 2025
3cd1e55
Use aggregator for onchain ocr config now in the test
cll-gg Jun 4, 2025
b4b66b5
Got the oracle running!
cll-gg Jun 4, 2025
c9881d7
Make llo part of the test succeed again - to start from a successful …
cll-gg Jun 4, 2025
8e54595
Remove a lot of the LLO stuff from the test
cll-gg Jun 4, 2025
aecc9b4
Remove more unused things
cll-gg Jun 5, 2025
afc2e28
Cleanup of the implementation (so far)
cll-gg Jun 5, 2025
4ef7900
One more not-needed change
cll-gg Jun 5, 2025
65f690b
Create sm bootstrap job
cll-gg Jun 5, 2025
d331844
Make nodes and secure mint job use bootstrap node
cll-gg Jun 5, 2025
e693745
Waiting a bit longer lets the oracle run and generate an outcome
cll-gg Jun 6, 2025
d3331e8
Add more logging, rename test, start data source
cll-gg Jun 6, 2025
073798c
Pipeline completes now, observation fails in parsing the result
cll-gg Jun 6, 2025
c83c630
Make the bridge return por.Mintables and wait for pipeline completion
cll-gg Jun 9, 2025
ea53dab
Add a bit more output to the bridge
cll-gg Jun 9, 2025
03dba0c
Use sm plugin second iteration branch
cll-gg Jun 9, 2025
677bafa
Parse EA response
cll-gg Jun 9, 2025
10bc711
Updating ea
cll-gg Jun 9, 2025
9d0cf17
Let bridge respond as real EA with initial and later response + send …
cll-gg Jun 9, 2025
d7488da
Transmit is called!
cll-gg Jun 9, 2025
632f9f1
Assert on report being (stub) transmitted
cll-gg Jun 9, 2025
36420b5
Remove duplicate code
cll-gg Jun 9, 2025
0a82b63
Clean up todos
cll-gg Jun 10, 2025
135bd49
Merge branch 'develop' into sm-integration-test
cll-gg Jun 10, 2025
28e52f9
Fixes after merging with develop
cll-gg Jun 10, 2025
8ca9591
Done: validate secure mint plugin spec
cll-gg Jun 10, 2025
18d531b
Add test for ea and use intermediate types based on Michael's message
cll-gg Jun 10, 2025
0e8960a
Clean up EA request/response usage
cll-gg Jun 11, 2025
fbcaf80
Clean up ea.go a bit more
cll-gg Jun 11, 2025
5c8b418
Fix some more todos
cll-gg Jun 11, 2025
b6b9fe1
Small test cleanup
cll-gg Jun 11, 2025
26cfca1
Move all chain-write-related todos out of the PR into a ticket
cll-gg Jun 11, 2025
1c75908
Remove temporary tracing
cll-gg Jun 11, 2025
4fda889
Remove newline
cll-gg Jun 11, 2025
cc537da
Done: consolidated two securemint packages into one
cll-gg Jun 11, 2025
9a5253b
Update plugin to fourth_iteration (commit cdd3409730eb2122d118f8324d2…
cll-gg Jun 11, 2025
fa9d8d0
Bit more cleanup
cll-gg Jun 11, 2025
b8bc503
Rename LatestRelevantBlocks to LatestBlocks in EA response
cll-gg Jun 12, 2025
04ca0a2
Make 'reserve' and 'platform' configurable through plugin config jobspec
cll-gg Jun 12, 2025
8c4e087
Leave a todo
cll-gg Jun 12, 2025
8d7fb36
Clean up delegate + services, remove all LOOPP-related things for now
cll-gg Jun 12, 2025
861669b
Use promwrapper for metrics
cll-gg Jun 12, 2025
f0b4742
Write readme
cll-gg Jun 12, 2025
0bb737d
Last todo done: improve stubContractReader
cll-gg Jun 12, 2025
a0bc180
Merge branch 'develop' into sm-integration-test
cll-gg Jun 12, 2025
a92d9fe
Remove unrelated change
cll-gg Jun 12, 2025
2d1e45a
Merge branch 'develop' into sm-integration-test
cll-gg Jun 18, 2025
9c50a3c
Deploy & configure the ocr3 configurator contract
cll-gg Jun 18, 2025
9294fcf
Debug instructions
cll-gg Jun 19, 2025
d76e765
Use llo config provider in bootstrap job
cll-gg Jun 19, 2025
b543e80
Using the public csa key as transmitter, similar to LLO (WIP)
cll-gg Jun 19, 2025
7b14781
Made it work with stubs!
cll-gg Jun 19, 2025
63ab311
Clean up
cll-gg Jun 19, 2025
68ce6d8
Simplify
cll-gg Jun 19, 2025
aa55485
Small cleanup
cll-gg Jun 19, 2025
a4e0e63
Bit more small cleanup
cll-gg Jun 19, 2025
48ebe0f
Merge branch 'develop' into sm-integration-test
cll-gg Jun 26, 2025
145a2f3
Use correct chainlink-common version + temp fixes for that
cll-gg Jun 26, 2025
1257c96
Merge branch 'develop' into sm-integration-test
cll-gg Jun 26, 2025
bade218
Merge branch 'develop' into sm-integration-test
cll-gg Jul 4, 2025
cf43408
Use local chainlink-common temporarily to make it work (depends on ht…
cll-gg Jul 4, 2025
70d8bfc
Merge branch 'develop' into sm-integration-test
cll-gg Jul 7, 2025
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
19 changes: 10 additions & 9 deletions core/config/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ var (

// LOOPP commands and vars
var (
MedianPlugin = NewPlugin("median")
MercuryPlugin = NewPlugin("mercury")
AptosPlugin = NewPlugin("aptos")
EVMPlugin = NewPlugin("evm")
CosmosPlugin = NewPlugin("cosmos")
SolanaPlugin = NewPlugin("solana")
StarknetPlugin = NewPlugin("starknet")
TronPlugin = NewPlugin("tron")
TONPlugin = NewPlugin("ton")
MedianPlugin = NewPlugin("median")
MercuryPlugin = NewPlugin("mercury")
AptosPlugin = NewPlugin("aptos")
EVMPlugin = NewPlugin("evm")
CosmosPlugin = NewPlugin("cosmos")
SecureMintPlugin = NewPlugin("securemint")
SolanaPlugin = NewPlugin("solana")
StarknetPlugin = NewPlugin("starknet")
TronPlugin = NewPlugin("tron")
TONPlugin = NewPlugin("ton")
// PrometheusDiscoveryHostName is the externally accessible hostname
// published by the node in the `/discovery` endpoint. Generally, it is expected to match
// the public hostname of node.
Expand Down
4 changes: 2 additions & 2 deletions core/services/job/orm.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (o *orm) AssertBridgesExist(ctx context.Context, p pipeline.Pipeline) error
return nil
}

// CreateJob creates the job, and it's associated spec record.
// CreateJob creates the job, and its associated spec record.
// Expects an unmarshalled job spec as the jb argument i.e. output from ValidatedXX.
// Scans all persisted records back into jb
func (o *orm) CreateJob(ctx context.Context, jb *Job) error {
Expand Down Expand Up @@ -643,7 +643,7 @@ func (o *orm) insertGatewaySpec(ctx context.Context, spec *GatewaySpec) (specID
// ValidateKeyStoreMatch confirms that the key has a valid match in the keystore
func ValidateKeyStoreMatch(ctx context.Context, spec *OCR2OracleSpec, keyStore keystore.Master, key string) (err error) {
switch spec.PluginType {
case types.Mercury, types.LLO:
case types.Mercury, types.LLO, types.SecureMint:
_, err = keyStore.CSA().Get(key)
if err != nil {
err = errors.Errorf("no CSA key matching: %q", key)
Expand Down
53 changes: 53 additions & 0 deletions core/services/ocr2/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
datastreamsllo "github.com/smartcontractkit/chainlink-data-streams/llo"
"github.com/smartcontractkit/chainlink-evm/pkg/chains/legacyevm"
"github.com/smartcontractkit/chainlink-evm/pkg/keys"
"github.com/smartcontractkit/por_mock_ocr3plugin/por"

"github.com/smartcontractkit/chainlink/v2/core/bridges"
gatewayconnector "github.com/smartcontractkit/chainlink/v2/core/capabilities/gateway_connector"
Expand All @@ -67,6 +68,8 @@ import (
ocr2keeper21core "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/core"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/vault"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint"
sm_adapter "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint/keyringadapter"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
Expand Down Expand Up @@ -550,6 +553,8 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, jb job.Job) ([]job.Servi

case types.VaultPlugin:
return d.newServicesVaultPlugin(ctx, lggr, jb, d.gatewayConnectorServiceWrapper)
case types.SecureMint:
return d.newServicesSecureMint(ctx, lggr, jb, bootstrapPeers, kb, ocrDB, lc)

default:
return nil, errors.Errorf("plugin type %s not supported", spec.PluginType)
Expand Down Expand Up @@ -1202,6 +1207,54 @@ func (d *Delegate) newServicesMedian(
return medianServices, err2
}

func (d *Delegate) newServicesSecureMint(
ctx context.Context,
lggr logger.SugaredLogger,
jb job.Job,
bootstrapPeers []commontypes.BootstrapperLocator,
kb ocr2key.KeyBundle,
ocrDB *db,
lc ocrtypes.LocalConfig,
) ([]job.ServiceCtx, error) {
spec := jb.OCR2OracleSpec
rid, err := spec.RelayID()
if err != nil {
return nil, ErrJobSpecNoRelayer{Err: err, PluginName: "securemint"}
}

ocrLogger := ocrcommon.NewOCRWrapper(lggr, d.cfg.OCR2().TraceLogging(), func(ctx context.Context, msg string) {
lggr.ErrorIf(d.jobORM.RecordError(ctx, jb.ID, msg), "unable to record error")
})

oracleArgsNoPlugin := libocr2.OCR3OracleArgs[por.ChainSelector]{
Comment thread
cll-gg marked this conversation as resolved.
BinaryNetworkEndpointFactory: d.peerWrapper.Peer2,
V2Bootstrappers: bootstrapPeers,
Database: ocrDB,
LocalConfig: lc,
Logger: ocrLogger,
MonitoringEndpoint: d.monitoringEndpointGen.GenMonitoringEndpoint(rid.Network, rid.ChainID, spec.ContractID, synchronization.OCR2Median),
OffchainKeyring: kb,
OnchainKeyring: sm_adapter.NewSecureMintOCR3OnchainKeyringAdapter(kb),
MetricsRegisterer: prometheus.WrapRegistererWith(map[string]string{"job_name": jb.Name.ValueOrZero()}, prometheus.DefaultRegisterer),
}

smConfig := securemint.NewJobConfig(
d.cfg.JobPipeline().MaxSuccessfulRuns(),
d.cfg.JobPipeline().ResultWriteQueueDepth(),
d.cfg,
)

relayer, err := d.RelayGetter.Get(rid)
if err != nil {
return nil, ErrRelayNotEnabled{Err: err, PluginName: "securemint", Relay: spec.Relay}
}

secureMintServices, err := securemint.NewSecureMintServices(ctx, jb, d.isNewlyCreatedJob, relayer, d.pipelineRunner, lggr, oracleArgsNoPlugin, smConfig)
secureMintServices = append(secureMintServices, ocrLogger)

return secureMintServices, err
}

func (d *Delegate) newServicesOCR2Keepers(
ctx context.Context,
lggr logger.SugaredLogger,
Expand Down
25 changes: 22 additions & 3 deletions core/services/ocr2/validate/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@ import (
"github.com/pelletier/go-toml"
pkgerrors "github.com/pkg/errors"

libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus"

"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/loop/reportingplugins"
"github.com/smartcontractkit/chainlink-common/pkg/types"

"github.com/smartcontractkit/chainlink/v2/core/config/env"
"github.com/smartcontractkit/chainlink/v2/core/services/job"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config"
lloconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/llo/config"
mercuryconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/mercury/config"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/vault"
sm_config "github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint/config"
"github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline"
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
evmtypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types"
"github.com/smartcontractkit/chainlink/v2/plugins"
libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus"
)

// ValidatedOracleSpecToml validates an oracle spec that came from TOML
Expand Down Expand Up @@ -129,6 +128,9 @@ func validateSpec(ctx context.Context, tree *toml.Tree, spec job.Job, rc plugins
return validateGenericPluginSpec(ctx, spec.OCR2OracleSpec, rc)
case types.VaultPlugin:
return validateVaultPluginSpec(spec.OCR2OracleSpec.PluginConfig)
case types.SecureMint:
return validateSecureMintSpec(spec.OCR2OracleSpec.PluginConfig)

case "":
return errors.New("no plugin specified")
default:
Expand Down Expand Up @@ -390,3 +392,20 @@ func validateOCR2LLOSpec(jsonConfig job.JSONConfig) error {
}
return pkgerrors.Wrap(pluginConfig.Validate(), "LLO PluginConfig is invalid")
}

func validateSecureMintSpec(jsonConfig job.JSONConfig) error {
if jsonConfig == nil {
return errors.New("secure mint plugin config is empty")
}

smConfig, err := sm_config.Parse(jsonConfig.Bytes())
if err != nil {
return pkgerrors.Wrap(err, "error while parsing secure mint plugin config")
}

if err := smConfig.Validate(); err != nil {
return fmt.Errorf("invalid secure mint plugin config: %#v, err: %w", smConfig, err)
}

return nil
}
75 changes: 75 additions & 0 deletions core/services/ocr3/securemint/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# SecureMint Plugin

## Overview

The SecureMint plugin is a plugin that allows for secure minting of tokens.

## Validation

Validating whether the SecureMint plugin is working as expected is done by running the integration test.

The test is located in the `core/services/ocr3/securemint` directory.

### Prerequisites:
```bash
docker run --name cl-postgres -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=dbname -p 5432:5432 -d postgres
make setup-testdb
```

### Run test:
```bash
time CL_DATABASE_URL=postgresql://chainlink_dev:insecurepassword@localhost:5432/chainlink_development_test?sslmode=disable go test -timeout 2m -run ^TestIntegration_SecureMint_happy_path$ github.com/smartcontractkit/chainlink/v2/core/services/ocr3/securemint -v 2>&1 | tee all.log | awk '/DEBUG|INFO|WARN|ERROR/ { print > "node_logs.log"; next }; { print > "other.log" }; tail all.log'
```

### If you change any dependencies:
```bash
go mod tidy && go mod vendor
modvendor -copy="**/*.a **/*.h" -v
```

(the `modvendor` step might not be necessary, but for me it was (see also https://github.com/marcboeker/go-duckdb/issues/174#issuecomment-1979097864))

### Logs

* other.log: Contains all non-node output from the test run, this can be used to quickly see test failures
* node_logs.log: Contains all logs from the nodes started up in the test run, this can be used to see the full output of the test run
* all.log: Contains the complete output of the test run, this can be used to see test failures within the context of the node logs


### Debug test with VSCode:

Create a launch.json file in the .vscode directory with the following content:

```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Secure Mint Integration Test",
"type": "go",
"request": "launch",
"mode": "test",
"program": "${workspaceFolder}/core/services/ocr3/securemint/integrationtest",
"args": [
"-test.run",
"^TestIntegration_SecureMint_happy_path$",
"-test.v",
"-test.timeout",
"2m",
"2>&1",
"|",
"tee",
"all.log",
"|",
"awk '/DEBUG|INFO|WARN|ERROR/ { print > 'node_logs.log'; next }; { print > 'other.log' }'",
],
"env": {
"ENV": "test",
"CL_DATABASE_URL": "postgresql://chainlink_dev:insecurepassword@localhost:5432/chainlink_development_test?sslmode=disable",
}
}
]
}
```

Then run the test by Cmd+P: "Start Debugging".
44 changes: 44 additions & 0 deletions core/services/ocr3/securemint/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package config

import (
"encoding/json"

"github.com/pkg/errors"
)

// SecureMintConfig holds secure mint specific configuration
type SecureMintConfig struct {
Token string `json:"token"`
Reserves string `json:"reserves"`
}

// Parse parses the secure mint configuration from JSON bytes
func Parse(configBytes []byte) (*SecureMintConfig, error) {
if len(configBytes) == 0 {
return nil, errors.New("secure mint config cannot be empty")
}

var config SecureMintConfig
if err := json.Unmarshal(configBytes, &config); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal SecureMintConfig")
}

return &config, nil
}

// Validate validates the secure mint plugin-specific config.
func (cfg *SecureMintConfig) Validate() error {
if cfg == nil {
return errors.New("secure mint plugin config cannot be nil")
}

if cfg.Token == "" {
return errors.New("token cannot be empty")
}

if cfg.Reserves == "" {
return errors.New("reserves cannot be empty")
}

return nil
}
Loading
Loading