diff --git a/.idea/libocr.iml b/.idea/libocr.iml
new file mode 100644
index 00000000..5e764c4f
--- /dev/null
+++ b/.idea/libocr.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..5190b27b
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..94a25f7f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 00000000..6ff207b3
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "keyToString": {
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "RunOnceActivity.go.format.on.save.advertiser.fired": "true",
+ "RunOnceActivity.go.formatter.settings.were.checked": "true",
+ "RunOnceActivity.go.migrated.go.modules.settings": "true",
+ "RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
+ "RunOnceActivity.go.watchers.conflict.with.on.save.actions.check.performed": "true",
+ "WebServerToolWindowFactoryState": "false",
+ "configurable..is.expanded": "false",
+ "configurable.GoLibrariesConfigurable.is.expanded": "true",
+ "go.import.settings.migrated": "true",
+ "go.sdk.automatically.set": "true",
+ "last_opened_file_path": "/home/matthewpendrey/Projects/libocr",
+ "nodejs_package_manager_path": "npm",
+ "settings.editor.selected.configurable": "com.goide.configuration.GoLibrariesConfigurableProvider"
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
\ No newline at end of file
diff --git a/gethwrappers2/ocr2abstract/ocr2abstract.go b/gethwrappers2/ocr2abstract/ocr2abstract.go
index 2321eecd..05616690 100644
--- a/gethwrappers2/ocr2abstract/ocr2abstract.go
+++ b/gethwrappers2/ocr2abstract/ocr2abstract.go
@@ -5,6 +5,7 @@ package ocr2abstract
import (
"errors"
+ "fmt"
"math/big"
"strings"
@@ -99,6 +100,8 @@ type OCR2AbstractTransactorRaw struct {
// NewOCR2Abstract creates a new instance of OCR2Abstract, bound to a specific deployed contract.
func NewOCR2Abstract(address common.Address, backend bind.ContractBackend) (*OCR2Abstract, error) {
+ fmt.Printf("OCRDEBUG: NewOCR2Abstract: Creating new OCR2Abstract instance at address %s", address.Hex())
+
contract, err := bindOCR2Abstract(address, backend, backend, backend)
if err != nil {
return nil, err
@@ -108,6 +111,7 @@ func NewOCR2Abstract(address common.Address, backend bind.ContractBackend) (*OCR
// NewOCR2AbstractCaller creates a new read-only instance of OCR2Abstract, bound to a specific deployed contract.
func NewOCR2AbstractCaller(address common.Address, caller bind.ContractCaller) (*OCR2AbstractCaller, error) {
+ fmt.Printf("OCRDEBUG: NewOCR2AbstractCaller: Creating new OCR2AbstractCaller instance at address %s", address.Hex())
contract, err := bindOCR2Abstract(address, caller, nil, nil)
if err != nil {
return nil, err
@@ -117,6 +121,7 @@ func NewOCR2AbstractCaller(address common.Address, caller bind.ContractCaller) (
// NewOCR2AbstractTransactor creates a new write-only instance of OCR2Abstract, bound to a specific deployed contract.
func NewOCR2AbstractTransactor(address common.Address, transactor bind.ContractTransactor) (*OCR2AbstractTransactor, error) {
+ fmt.Printf("OCRDEBUG: NewOCR2AbstractTransactor: Creating new OCR2AbstractTransactor instance at address %s", address.Hex())
contract, err := bindOCR2Abstract(address, nil, transactor, nil)
if err != nil {
return nil, err
@@ -126,7 +131,9 @@ func NewOCR2AbstractTransactor(address common.Address, transactor bind.ContractT
// NewOCR2AbstractFilterer creates a new log filterer instance of OCR2Abstract, bound to a specific deployed contract.
func NewOCR2AbstractFilterer(address common.Address, filterer bind.ContractFilterer) (*OCR2AbstractFilterer, error) {
+ fmt.Printf("OCRDEBUG: NewOCR2AbstractFilterer: Creating new OCR2AbstractFilterer instance at address %s", address.Hex())
contract, err := bindOCR2Abstract(address, nil, nil, filterer)
+
if err != nil {
return nil, err
}
@@ -191,6 +198,7 @@ func (_OCR2Abstract *OCR2AbstractCaller) LatestConfigDetails(opts *bind.CallOpts
var out []interface{}
err := _OCR2Abstract.contract.Call(opts, &out, "latestConfigDetails")
+
outstruct := new(struct {
ConfigCount uint32
BlockNumber uint32
diff --git a/offchainreporting/internal/managed/track_config.go b/offchainreporting/internal/managed/track_config.go
index eae8948d..07edf5f1 100644
--- a/offchainreporting/internal/managed/track_config.go
+++ b/offchainreporting/internal/managed/track_config.go
@@ -132,7 +132,7 @@ func (state *trackConfigState) checkLatestConfigDetails() (
return nil, false
}
if latestConfigDigest == (types.ConfigDigest{}) {
- state.logger.Warn("TrackConfig: LatestConfigDetails() returned a zero configDigest. Looks like the contract has not been configured", commontypes.LogFields{
+ state.logger.Warn("TrackConfig: LatestConfigDetails() returned a zero configDigest, oh poo. Looks like the contract has not been configured", commontypes.LogFields{
"configDigest": latestConfigDigest,
})
return nil, false
diff --git a/offchainreporting2plus/internal/config/ocr3config/public_config.go b/offchainreporting2plus/internal/config/ocr3config/public_config.go
index 2785dd3f..63ef4bb4 100644
--- a/offchainreporting2plus/internal/config/ocr3config/public_config.go
+++ b/offchainreporting2plus/internal/config/ocr3config/public_config.go
@@ -139,6 +139,9 @@ func PublicConfigFromContractConfig(skipResourceExhaustionChecks bool, change ty
}
func publicConfigFromContractConfig(skipResourceExhaustionChecks bool, change types.ContractConfig) (PublicConfig, config.SharedSecretEncryptions, error) {
+ fmt.Printf("OCRDEBUG: publicConfigFromContractConfig: change: %+v\n", change)
+ fmt.Printf("OCRDEBUG: publicConfigFromContractConfig: change signers: %+v\n", change.Signers)
+
if change.OffchainConfigVersion != config.OCR3OffchainConfigVersion {
return PublicConfig{}, config.SharedSecretEncryptions{}, fmt.Errorf("unsuppported OffchainConfigVersion %v, supported OffchainConfigVersion is %v", change.OffchainConfigVersion, config.OCR3OffchainConfigVersion)
}
@@ -148,6 +151,8 @@ func publicConfigFromContractConfig(skipResourceExhaustionChecks bool, change ty
return PublicConfig{}, config.SharedSecretEncryptions{}, err
}
+ fmt.Printf("OCRDEBUG: publicConfigFromContractConfig: deserialized offchain config: %+v\n", oc)
+
if err := checkIdentityListsHaveNoDuplicates(change, oc); err != nil {
return PublicConfig{}, config.SharedSecretEncryptions{}, err
}
@@ -168,6 +173,8 @@ func publicConfigFromContractConfig(skipResourceExhaustionChecks bool, change ty
})
}
+ fmt.Printf("OCRDEBUG: publicConfigFromContractConfig: identities: %+v\n", identities)
+
cfg := PublicConfig{
oc.DeltaProgress,
oc.DeltaResend,
diff --git a/offchainreporting2plus/internal/config/ocr3config/shared_config.go b/offchainreporting2plus/internal/config/ocr3config/shared_config.go
index 283424fb..0b57dda0 100644
--- a/offchainreporting2plus/internal/config/ocr3config/shared_config.go
+++ b/offchainreporting2plus/internal/config/ocr3config/shared_config.go
@@ -52,17 +52,26 @@ func SharedConfigFromContractConfig[RI any](
peerID string,
transmitAccount types.Account,
) (SharedConfig, commontypes.OracleID, error) {
+ fmt.Printf("SharedConfigFromContractConfig: at the start")
+
publicConfig, encSharedSecret, err := publicConfigFromContractConfig(skipResourceExhaustionChecks, change)
if err != nil {
return SharedConfig{}, 0, err
}
+ fmt.Printf("SharedConfigFromContractConfig: publicConfig: %+v\n", publicConfig)
+
oracleID := commontypes.OracleID(math.MaxUint8)
{
onchainPublicKey := onchainKeyring.PublicKey()
+ fmt.Printf("SharedConfigFromContractConfig: onchainPublicKey: %x\n", onchainPublicKey)
+
offchainPublicKey := offchainKeyring.OffchainPublicKey()
+
+ fmt.Printf("SharedConfigFromContractConfig: offchainPublicKey: %x\n", offchainPublicKey)
var found bool
for i, identity := range publicConfig.OracleIdentities {
+ fmt.Printf("Comparing identity %d: %x with onchainPublicKey: %x\n", i, identity.OnchainPublicKey, onchainPublicKey)
if bytes.Equal(identity.OnchainPublicKey, onchainPublicKey) {
if identity.OffchainPublicKey != offchainPublicKey {
return SharedConfig{}, 0, errors.Errorf(
@@ -99,6 +108,8 @@ func SharedConfigFromContractConfig[RI any](
return SharedConfig{}, 0, fmt.Errorf("could not decrypt shared secret: %w", err)
}
+ fmt.Printf("returning public config and oracleID: %v, %d\n", publicConfig, oracleID)
+
return SharedConfig{
publicConfig,
x,
diff --git a/offchainreporting2plus/internal/managed/managed_ocr3_oracle.go b/offchainreporting2plus/internal/managed/managed_ocr3_oracle.go
index d8d9ae1a..de48695b 100644
--- a/offchainreporting2plus/internal/managed/managed_ocr3_oracle.go
+++ b/offchainreporting2plus/internal/managed/managed_ocr3_oracle.go
@@ -44,6 +44,8 @@ func RunManagedOCR3Oracle[RI any](
subs := subprocesses.Subprocesses{}
defer subs.Wait()
+ fmt.Print("OCRDEBUG: ManagedOCR3Oracle: RunManagedOCR3Oracle called\n")
+
var chTelemetrySend chan<- *serialization.TelemetryWrapper
{
chTelemetry := make(chan *serialization.TelemetryWrapper, 100)
@@ -63,11 +65,15 @@ func RunManagedOCR3Oracle[RI any](
func(ctx context.Context, logger loghelper.LoggerWithContext, contractConfig types.ContractConfig) (err error, retry bool) {
skipResourceExhaustionChecks := localConfig.DevelopmentMode == types.EnableDangerousDevelopmentMode
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: runWithContractConfig called with contractConfig: %+v\n", contractConfig)
+
fromAccount, err := contractTransmitter.FromAccount(ctx)
if err != nil {
return fmt.Errorf("ManagedOCR3Oracle: error getting FromAccount: %w", err), true
}
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: FromAccount: %s\n", fromAccount)
+
sharedConfig, oid, err := ocr3config.SharedConfigFromContractConfig(
skipResourceExhaustionChecks,
contractConfig,
@@ -76,10 +82,15 @@ func RunManagedOCR3Oracle[RI any](
netEndpointFactory.PeerID(),
fromAccount,
)
+
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: SharedConfigFromContractConfig returned sharedConfig: %+v, oid: %s\n", sharedConfig, oid)
if err != nil {
+ fmt.Printf("ManagedOCR3Oracle: error while decoding ContractConfig: %v\n", err)
return fmt.Errorf("ManagedOCR3Oracle: error while decoding ContractConfig: %w", err), false
}
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 0")
+
registerer := prometheus.WrapRegistererWith(
prometheus.Labels{
// disambiguate different protocol instances by configDigest
@@ -90,12 +101,14 @@ func RunManagedOCR3Oracle[RI any](
metricsRegistererWrapper,
)
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 1")
// Run with new config
peerIDs := []string{}
for _, identity := range sharedConfig.OracleIdentities {
peerIDs = append(peerIDs, identity.PeerID)
}
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 2")
childLogger := logger.MakeChild(commontypes.LogFields{
"oid": oid,
})
@@ -104,6 +117,7 @@ func RunManagedOCR3Oracle[RI any](
initCtx, initCancel := context.WithTimeout(ctx, maxDurationInitialization)
defer initCancel()
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 3")
ins := loghelper.NewIfNotStopped(
maxDurationInitialization+protocol.ReportingPluginTimeoutWarningGracePeriod,
func() {
@@ -113,6 +127,7 @@ func RunManagedOCR3Oracle[RI any](
},
)
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 4")
reportingPlugin, reportingPluginInfo, err := reportingPluginFactory.NewReportingPlugin(initCtx, ocr3types.ReportingPluginConfig{
sharedConfig.ConfigDigest,
oid,
@@ -126,8 +141,10 @@ func RunManagedOCR3Oracle[RI any](
sharedConfig.MaxDurationShouldAcceptAttestedReport,
sharedConfig.MaxDurationShouldTransmitAcceptedReport,
})
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 5")
ins.Stop()
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 6")
if err != nil {
return fmt.Errorf("ManagedOCR3Oracle: error during NewReportingPlugin(): %w", err), true
@@ -138,6 +155,7 @@ func RunManagedOCR3Oracle[RI any](
"ManagedOCR3Oracle: error during reportingPlugin.Close()",
)
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 7")
if err := validateOCR3ReportingPluginLimits(reportingPluginInfo.Limits); err != nil {
logger.Error("ManagedOCR3Oracle: invalid ReportingPluginInfo", commontypes.LogFields{
"error": err,
@@ -145,6 +163,7 @@ func RunManagedOCR3Oracle[RI any](
})
return fmt.Errorf("ManagedOCR3Oracle: invalid MercuryPluginInfo"), false
}
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 8")
maxSigLen := onchainKeyring.MaxSignatureLength()
lims, err := limits.OCR3Limits(sharedConfig.PublicConfig, reportingPluginInfo.Limits, maxSigLen)
@@ -157,6 +176,7 @@ func RunManagedOCR3Oracle[RI any](
})
return fmt.Errorf("ManagedOCR3Oracle: error during limits"), false
}
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 9")
binNetEndpoint, err := netEndpointFactory.NewEndpoint(
sharedConfig.ConfigDigest,
peerIDs,
@@ -173,6 +193,8 @@ func RunManagedOCR3Oracle[RI any](
return fmt.Errorf("ManagedOCR3Oracle: error during NewEndpoint"), true
}
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 10")
+
// No need to binNetEndpoint.Start/Close since netEndpoint will handle that for us
netEndpoint := shim.NewOCR3SerializingEndpoint[RI](
@@ -189,12 +211,15 @@ func RunManagedOCR3Oracle[RI any](
if err := netEndpoint.Start(); err != nil {
return fmt.Errorf("ManagedOCR3Oracle: error during netEndpoint.Start(): %w", err), true
}
+
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 11")
defer loghelper.CloseLogError(
netEndpoint,
logger,
"ManagedOCR3Oracle: error during netEndpoint.Close()",
)
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 12")
protocol.RunOracle[RI](
ctx,
sharedConfig,
@@ -211,6 +236,8 @@ func RunManagedOCR3Oracle[RI any](
shim.NewOCR3TelemetrySender(chTelemetrySend, childLogger, localConfig.EnableTransmissionTelemetry),
)
+ fmt.Printf("OCRDEBUG: ManagedOCR3Oracle: 13")
+
return nil, false
},
localConfig,
diff --git a/offchainreporting2plus/internal/managed/run_with_contract_config.go b/offchainreporting2plus/internal/managed/run_with_contract_config.go
index 6f1a1e0b..f9ab3c42 100644
--- a/offchainreporting2plus/internal/managed/run_with_contract_config.go
+++ b/offchainreporting2plus/internal/managed/run_with_contract_config.go
@@ -2,6 +2,7 @@ package managed
import (
"context"
+ "fmt"
"math/rand"
"time"
@@ -83,6 +84,8 @@ type runWithContractConfigState struct {
}
func (rwcc *runWithContractConfigState) run() {
+ fmt.Println("OCRDEBUG: runWithContractConfig: run called")
+
// Restore config from database, so that we can run even if the ethereum node
// isn't working.
rwcc.restoreFromDatabase()
diff --git a/offchainreporting2plus/internal/managed/track_config.go b/offchainreporting2plus/internal/managed/track_config.go
index 6e667d98..0792a820 100644
--- a/offchainreporting2plus/internal/managed/track_config.go
+++ b/offchainreporting2plus/internal/managed/track_config.go
@@ -2,6 +2,7 @@ package managed
import (
"context"
+ "fmt"
"time"
"github.com/smartcontractkit/libocr/commontypes"
@@ -91,6 +92,10 @@ func (state *trackConfigState) checkLatestConfigDetails() (
ctx, cancel := context.WithTimeout(state.ctx, state.localConfig.ContractConfigLoadTimeout)
defer cancel()
+ state.logger.Info("Here we are again", commontypes.LogFields{
+ "error": "oohhere2",
+ })
+
blockheight, err := state.configTracker.LatestBlockHeight(ctx)
if err != nil {
state.logger.ErrorIfNotCanceled("TrackConfig: error during LatestBlockHeight()", ctx, commontypes.LogFields{
@@ -99,6 +104,21 @@ func (state *trackConfigState) checkLatestConfigDetails() (
return nil, false
}
+ fmt.Printf("Type of configTracker: %T\n", state.configTracker)
+
+ changedInBlockl, latestConfigDigestl, err1 := state.configTracker.LatestConfigDetails(ctx)
+ latestBlockHeight, err2 := state.configTracker.LatestBlockHeight(ctx)
+ config, err3 := state.configTracker.LatestConfig(ctx, changedInBlockl)
+
+ fmt.Printf("changedInBlock: %v\n", changedInBlockl)
+ fmt.Printf("latestConfigDigest: %v\n", latestConfigDigestl)
+ if err1 != nil || err2 != nil || err3 != nil {
+ fmt.Printf("Error in TrackConfig: %v, %v, %v\n", err1, err2, err3)
+ }
+
+ fmt.Printf("LatestBlockHeight from configTracker: %d\n", latestBlockHeight)
+ fmt.Printf("Config from configTracker: %+v\n", config)
+
changedInBlock, latestConfigDigest, err := state.configTracker.LatestConfigDetails(ctx)
if err != nil {
state.logger.ErrorIfNotCanceled("TrackConfig: error during LatestConfigDetails()", ctx, commontypes.LogFields{
@@ -106,18 +126,25 @@ func (state *trackConfigState) checkLatestConfigDetails() (
})
return nil, false
}
+ fmt.Println("This is a debug trial line 1")
+
if latestConfigDigest == (types.ConfigDigest{}) {
- state.logger.Warn("TrackConfig: LatestConfigDetails() returned a zero configDigest. Looks like the contract has not been configured", commontypes.LogFields{
+ state.logger.Warn("TrackConfig: LatestConfigDetails() returned a zero configDigest, oh crap. Looks like the contract has not been configured", commontypes.LogFields{
"configDigest": latestConfigDigest,
})
return nil, false
}
+
+ fmt.Println("This is a debug trial line 2")
if state.configDigest == latestConfigDigest {
return nil, false
}
+
+ fmt.Println("This is a debug trial line 3")
if !state.localConfig.SkipContractConfigConfirmations && blockheight < changedInBlock+uint64(state.localConfig.ContractConfigConfirmations)-1 {
return nil, true
}
+ fmt.Println("This is a debug trial line 4")
contractConfig, err := state.configTracker.LatestConfig(ctx, changedInBlock)
if err != nil {
@@ -127,6 +154,8 @@ func (state *trackConfigState) checkLatestConfigDetails() (
return nil, true
}
+ fmt.Println("This is a debug trial line 5")
+
if latestConfigDigest != contractConfig.ConfigDigest {
state.logger.Error("TrackConfig: received config change with ConfigDigest mismatch", commontypes.LogFields{
"error": err,
@@ -136,6 +165,8 @@ func (state *trackConfigState) checkLatestConfigDetails() (
return nil, false
}
+ fmt.Println("This is a debug trial line 6")
+
// Ignore configs where the configDigest doesn't match, they might have
// been corrupted somehow.
if err := state.configDigester.CheckContractConfig(ctx, contractConfig); err != nil {
@@ -146,6 +177,8 @@ func (state *trackConfigState) checkLatestConfigDetails() (
return nil, false
}
+ fmt.Println("This is a debug trial line 5")
+
return &contractConfig, false
}
diff --git a/offchainreporting2plus/internal/ocr3/protocol/oracle.go b/offchainreporting2plus/internal/ocr3/protocol/oracle.go
index 83fe68b0..8fe780d1 100644
--- a/offchainreporting2plus/internal/ocr3/protocol/oracle.go
+++ b/offchainreporting2plus/internal/ocr3/protocol/oracle.go
@@ -129,6 +129,8 @@ type oracleState[RI any] struct {
// Finally, all sub-goroutines spawned in the protocol are attached to o.subprocesses
// This enables us to wait for their completion before exiting.
func (o *oracleState[RI]) run() {
+ fmt.Printf("OCRDEBUG: Oracle: run called")
+
o.logger.Info("Oracle: running", commontypes.LogFields{
"localConfig": fmt.Sprintf("%+v", o.localConfig),
"publicConfig": fmt.Sprintf("%+v", o.config.PublicConfig),
diff --git a/offchainreporting2plus/oracle.go b/offchainreporting2plus/oracle.go
index 92f6a33f..8a7878a9 100644
--- a/offchainreporting2plus/oracle.go
+++ b/offchainreporting2plus/oracle.go
@@ -224,6 +224,8 @@ func (args OCR3OracleArgs[RI]) localConfig() types.LocalConfig { return args.Loc
func (args OCR3OracleArgs[RI]) runManaged(ctx context.Context) {
logger := loghelper.MakeRootLoggerWithContext(args.Logger)
+ fmt.Printf("OCRDEBUG: run managed")
+
managed.RunManagedOCR3Oracle(
ctx,
@@ -290,6 +292,8 @@ func (o *oracle) Start() error {
o.lock.Lock()
defer o.lock.Unlock()
+ fmt.Printf("OCRDEBUG: Starting Oracle with config: %s\n", o.oracleArgs.localConfig())
+
if o.state != oracleStateUnstarted {
return fmt.Errorf("can only start Oracle once")
}
@@ -310,6 +314,8 @@ func (o *oracle) Close() error {
o.lock.Lock()
defer o.lock.Unlock()
+ fmt.Printf("OCRDEBUG: Closing Oracle with config: %s\n", o.oracleArgs.localConfig())
+
if o.state != oracleStateStarted {
return fmt.Errorf("can only close a started oracle")
}